switch-picker-appearance.html (9719B)
1 <!DOCTYPE html> 2 <meta name=timeout content=long> 3 <link rel=author href="mailto:masonf@chromium.org"> 4 <link rel=help href="https://github.com/w3c/csswg-drafts/issues/10775"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/resources/testdriver.js"></script> 8 <script src="/resources/testdriver-actions.js"></script> 9 <script src="/resources/testdriver-vendor.js"></script> 10 <script src="../../../popovers/resources/popover-utils.js"></script> 11 12 <select id=test1 style="appearance:base-select"> 13 <option>option</option> 14 <option>option</option> 15 </select> 16 17 <style> 18 #test1::picker(select) { 19 background-color: red; 20 } 21 #test1::picker(select):popover-open { 22 background-color: green; 23 } 24 </style> 25 26 <script> 27 const select1 = document.querySelector('select#test1'); 28 const red = 'rgb(255, 0, 0)'; 29 const green = 'rgb(0, 128, 0)'; 30 31 promise_test(async (t) => { 32 const style = document.createElement('style'); 33 document.head.append(style); 34 t.add_cleanup(() => style.remove()); 35 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 36 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red); 37 style.innerHTML = '#test1::picker(select) {appearance: base-select}'; 38 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); 39 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red,'still closed, so popover-open doesn\'t match'); 40 41 // Now open the picker 42 assert_throws_dom('NotAllowedError',() => select1.showPicker(),'showPicker requires user activation'); 43 assert_false(select1.matches(':open')); 44 await test_driver.bless('showPicker'); 45 select1.showPicker(); 46 assert_true(select1.matches(':open')); 47 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); 48 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,green,'now open, so popover-open matches'); 49 50 // Close the picker 51 await clickOn(select1); 52 assert_false(select1.matches(':open')); 53 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red,'back to closed'); 54 }, 'Basic functionality of select picker and appearance'); 55 56 promise_test(async (t) => { 57 const style = document.createElement('style'); 58 document.head.append(style); 59 t.add_cleanup(() => style.remove()); 60 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 61 style.innerHTML = '#test1::picker(select) {appearance: auto}'; 62 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'auto'); 63 await test_driver.bless('showPicker'); 64 select1.showPicker(); 65 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red,'appearance:auto picker is never open'); 66 // Close the picker 67 await clickOn(select1); 68 assert_false(select1.matches(':open')); 69 }, 'Basic functionality of select picker with appearance:auto'); 70 71 promise_test(async (t) => { 72 const style = document.createElement('style'); 73 document.head.append(style); 74 t.add_cleanup(() => style.remove()); 75 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 76 style.innerHTML = '#test1::picker(select) {appearance: none}'; 77 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 78 await test_driver.bless('showPicker'); 79 select1.showPicker(); 80 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red,'appearance:none picker is never open'); 81 // Close the picker 82 await clickOn(select1); 83 assert_false(select1.matches(':open')); 84 }, 'Basic functionality of select picker with appearance:none'); 85 86 promise_test(async (t) => { 87 const style = document.createElement('style'); 88 document.head.append(style); 89 t.add_cleanup(() => style.remove()); 90 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 91 style.innerHTML = ` 92 #test1::picker(select) {appearance: base-select} 93 #test1::picker(select):popover-open {appearance: auto} 94 `; 95 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); 96 await test_driver.bless('showPicker'); 97 select1.showPicker(); 98 assert_false(select1.matches(':open'),'Switching appearance in :popover-open should re-close the picker'); 99 assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red); 100 await new Promise(resolve => requestAnimationFrame(resolve)); 101 assert_false(select1.matches(':open'),'There should be no oscillation or re-opening the picker'); 102 await new Promise(resolve => requestAnimationFrame(resolve)); 103 assert_false(select1.matches(':open'),'There should be no oscillation or re-opening the picker (2)'); 104 await new Promise(resolve => requestAnimationFrame(resolve)); 105 assert_false(select1.matches(':open'),'There should be no oscillation or re-opening the picker (3)'); 106 }, 'Switching appearance in popover-open should close the picker'); 107 108 promise_test(async (t) => { 109 const style = document.createElement('style'); 110 document.head.append(style); 111 t.add_cleanup(() => style.remove()); 112 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 113 style.innerHTML = '#test1::picker(select) {appearance: base-select}'; 114 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); 115 await test_driver.bless('showPicker'); 116 select1.showPicker(); 117 assert_true(select1.matches(':open')); 118 style.remove(); 119 assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); 120 await new Promise(requestAnimationFrame); 121 await new Promise(requestAnimationFrame); 122 await new Promise(requestAnimationFrame); 123 await new Promise(requestAnimationFrame); 124 assert_false(select1.matches(':open'),'changing appearance while the picker is open should close it'); 125 }, 'Switching appearance in JS after picker is open should close the picker'); 126 </script> 127 128 <button id=reset>Reset</button> 129 <select id=test2> 130 <button><selectedcontent></selectedcontent></button> 131 <option>option one</option> 132 <option>option two</option> 133 <option>option three</option> 134 </select> 135 136 <style> 137 #test2, #test2::picker(select) { 138 appearance: base-select; 139 } 140 #test2.controlswitch:open { 141 appearance: auto; 142 } 143 #test2.pickerswitch:open::picker(select) { 144 appearance: auto; 145 } 146 </style> 147 148 <script> 149 const select2 = document.querySelector('select#test2'); 150 const secondOption = select2.querySelector('option:nth-of-type(2)'); 151 152 promise_test(async (t) => { 153 assert_false(select2.matches(':open'),'setup'); 154 assert_equals(select2.value,'option one'); 155 assert_equals(getComputedStyle(select2).appearance,'base-select'); 156 await clickOn(select2); 157 assert_true(select2.matches(':open'),'picker should open when clicked'); 158 assert_equals(secondOption.textContent,'option two'); 159 await clickOn(secondOption); 160 assert_false(select2.matches(':open')); 161 assert_equals(select2.value,'option two'); 162 },'Test of the test harness'); 163 164 promise_test(async (t) => { 165 assert_false(select2.matches(':open'),'setup'); 166 assert_equals(select2.className,''); 167 assert_equals(getComputedStyle(select2).appearance,'base-select'); 168 await clickOn(select2); 169 assert_true(select2.matches(':open'),'picker should open when clicked'); 170 assert_equals(getComputedStyle(select2).appearance,'base-select'); 171 await clickOn(secondOption); // Choose an option 172 assert_false(select2.matches(':open')); 173 t.add_cleanup(() => select2.removeAttribute('class')); 174 select2.classList.add('controlswitch'); 175 assert_false(select2.matches(':open')); 176 assert_equals(getComputedStyle(select2).appearance,'base-select','appearance should not have changed yet'); 177 await clickOn(select2); 178 assert_false(select2.matches(':open'),'picker should get closed when the appearance value changes'); 179 assert_equals(getComputedStyle(select2).appearance,'base-select','appearance should be back to base-select'); 180 },'The select picker is closed if the <select> appearance value is changed via CSS while the picker is open'); 181 182 promise_test(async (t) => { 183 assert_false(select2.matches(':open'),'setup'); 184 assert_equals(select2.className,''); 185 assert_equals(getComputedStyle(select2).appearance,'base-select'); 186 await clickOn(select2); 187 assert_true(select2.matches(':open'),'picker should open when clicked'); 188 assert_equals(getComputedStyle(select2).appearance,'base-select'); 189 await clickOn(secondOption); // Choose an option 190 assert_false(select2.matches(':open')); 191 t.add_cleanup(() => select2.removeAttribute('class')); 192 select2.classList.add('pickerswitch'); 193 await clickOn(select2); 194 assert_false(select2.matches(':open'),'picker should get closed when the appearance value changes'); 195 assert_equals(getComputedStyle(select2).appearance,'base-select','appearance should be back to base-select'); 196 },'The select picker is closed if the ::picker() appearance value is changed via CSS while the picker is open'); 197 198 promise_test(async (t) => { 199 assert_false(select2.matches(':open'),'setup'); 200 assert_equals(select2.className,''); 201 assert_equals(getComputedStyle(select2).appearance,'base-select'); 202 await clickOn(select2); 203 assert_true(select2.matches(':open'),'picker should open when clicked'); 204 assert_equals(getComputedStyle(select2).appearance,'base-select'); 205 t.add_cleanup(() => select2.removeAttribute('style')); 206 select2.setAttribute('style','appearance:auto'); 207 assert_equals(getComputedStyle(select2).appearance,'auto','appearance should still be auto from inline style'); 208 assert_false(select2.matches(':open'),'Adding inline style should close the picker'); 209 },'The select picker is closed if the <select> inline appearance value is changed while the picker is open'); 210 </script>