select-synthetic-events.html (3849B)
1 <!DOCTYPE html> 2 <link rel=author href="mailto:jarhar@chromium.org"> 3 <link rel=help href="https://github.com/whatwg/html/issues/10762"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/resources/testdriver.js"></script> 7 <script src="/resources/testdriver-vendor.js"></script> 8 9 <style> 10 select, ::picker(select) { 11 appearance: base-select; 12 } 13 </style> 14 15 <select id=defaultbutton> 16 <option class=one>one</option> 17 <option class=two>two</option> 18 </select> 19 20 <select id=custombutton> 21 <button>button</button> 22 <option class=one>one</option> 23 <option class=two>two</option> 24 </select> 25 26 <script> 27 const keyCodes = ['Enter', 'Space', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']; 28 29 function dispatchKeyboardEvents(element, code) { 30 const key = code == 'Space' ? ' ' : code; 31 element.dispatchEvent(new KeyboardEvent('keydown', {key, code})); 32 element.dispatchEvent(new KeyboardEvent('keypress', {key, code})); 33 element.dispatchEvent(new KeyboardEvent('keyup', {key, code})); 34 } 35 36 function dispatchMouseEvents(element) { 37 element.dispatchEvent(new MouseEvent('pointerdown')); 38 element.dispatchEvent(new MouseEvent('mousedown')); 39 element.dispatchEvent(new MouseEvent('pointerup')); 40 element.dispatchEvent(new MouseEvent('mouseup')); 41 element.dispatchEvent(new MouseEvent('click')); 42 } 43 44 ['defaultbutton', 'custombutton'].forEach(id => { 45 promise_test(async () => { 46 assert_true(CSS.supports('appearance', 'base-select'), 47 'This test requires appearance:base-select in order to run.'); 48 49 const select = document.getElementById(id); 50 const firstOption = select.querySelector('option.one'); 51 const secondOption = select.querySelector('option.two'); 52 53 select.click(); 54 assert_false(select.matches(':open'), 55 'select.click() should not open the picker.'); 56 57 dispatchMouseEvents(select); 58 assert_false(select.matches(':open'), 59 'Synthetic mouse/pointer events should not open the picker.'); 60 61 for (const keyCode of keyCodes) { 62 dispatchKeyboardEvents(select, keyCode); 63 assert_false(select.matches(':open'), 64 `Synthetic ${keyCode} events should not open the picker.`); 65 assert_equals(select.value, 'one', 66 `Synthetic ${keyCode} events should not change the selects value.`); 67 } 68 69 await test_driver.click(select); 70 assert_true(select.matches(':open'), 71 'Select should open after a real click occurs.'); 72 assert_equals(document.activeElement, firstOption, 73 'Selected <option> should be focused after opening the picker.'); 74 75 secondOption.click(); 76 assert_true(select.matches(':open'), 77 'option.click() should not close the picker.'); 78 assert_equals(select.value, 'one', 79 'option.click() should not change select.value.'); 80 81 dispatchMouseEvents(secondOption); 82 assert_true(select.matches(':open'), 83 'Synthetic mouse/pointer events should not close the picker.'); 84 assert_equals(select.value, 'one', 85 'Synthetic mouse/pointer events should not change select.value.'); 86 87 for (const keyCode of keyCodes) { 88 dispatchKeyboardEvents(firstOption, keyCode); 89 assert_true(select.matches(':open'), 90 `Synthetic ${keyCode} events on selected <option> should not close the picker.`); 91 assert_equals(select.value, 'one', 92 `Synthetic ${keyCode} events on selected <option> should not change select.value.`); 93 94 dispatchKeyboardEvents(secondOption, keyCode); 95 assert_true(select.matches(':open'), 96 `Synthetic ${keyCode} events on non-selected <option> should not close the picker.`); 97 assert_equals(select.value, 'one', 98 `Synthetic ${keyCode} events on non-selected <option> should not change select.value.`); 99 } 100 }, `${id}: Synthetic events should not trigger behaviors of select element.`); 101 }); 102 </script>