select-home-end-pagedown-pageup-detailed.optional.html (6660B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <meta charset="utf-8"> 4 <meta name="timeout" content="long"> 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 11 <!-- This test is marked as optional because the specification does not mandate 12 the specific behavior of keyboard keys like Home/End/etc. Support and 13 implementation of the behavior for these keys varies across browsers and 14 platforms. This test reflects picker support in desktop Chromium. 15 16 This test is quite similar to the WPT here: 17 external/wpt/html/semantics/forms/the-select-element/customizable-select/select-home-end-keys.tentative.html 18 But this test is able to more exactly check the behavior of the 19 (non-standardized) Home/End/PageDown/PageUp keys. --> 20 21 <style> 22 select,::picker(select) { 23 appearance: base-select; 24 } 25 </style> 26 27 <select></select> 28 29 <script> 30 const keyMap = { 31 'Home': '\uE011', 32 'End': '\uE010', 33 'PageUp': '\uE00E', 34 'PageDown': '\uE00F' 35 }; 36 const select = document.querySelector('select'); 37 38 const nOptions = 1000; 39 for(let i=1;i<=nOptions;++i) { 40 const option = document.createElement('option'); 41 option.textContent = `Option #${i}`; 42 option.id=i; 43 select.appendChild(option); 44 } 45 function getOption(n) { 46 return document.getElementById(n); 47 } 48 49 async function testStart(firstOption) { 50 assert_false(select.matches(':open')); 51 select.value = firstOption.value; 52 assert_equals(select.value, firstOption.value,'Initial value'); 53 await test_driver.click(select); 54 assert_true(select.matches(':open')); 55 assert_equals(select.value, firstOption.value,'Value doesn\'t change when opening picker'); 56 assert_equals(document.activeElement, firstOption, 'Selected option should be focused'); 57 } 58 59 promise_test(async () => { 60 assert_equals(Math.round(nOptions/2),nOptions/2,'nOptions must be even'); 61 const middleOption = getOption(nOptions/2); 62 await testStart(middleOption); 63 await test_driver.send_keys(document.activeElement, keyMap.Home); 64 assert_equals(select.value, middleOption.value, 'Selected option should not change'); 65 assert_equals(document.activeElement, getOption(1), 'Focus should move up to the first option'); 66 67 await test_driver.send_keys(document.activeElement, keyMap.End); 68 assert_equals(select.value, middleOption.value, 'Selected option should not change'); 69 assert_equals(document.activeElement, getOption(nOptions), 'Focus should move down to the last option'); 70 71 await test_driver.click(select); 72 assert_equals(select.value, middleOption.value, 'Selected option should not change'); 73 assert_false(select.matches(':open'),'Clicking select should close picker'); 74 }, 'Behavior of Home and End for customizable-<select>'); 75 76 promise_test(async () => { 77 const firstOption = getOption(1); 78 await testStart(firstOption); 79 await test_driver.send_keys(document.activeElement, keyMap.Home); 80 assert_equals(select.value, firstOption.value, 'Selected option should not change'); 81 assert_equals(document.activeElement, firstOption, 'Focus should not change - already at the top'); 82 83 await test_driver.send_keys(document.activeElement, keyMap.End); 84 assert_equals(select.value, firstOption.value, 'Selected option should not change'); 85 assert_equals(document.activeElement, getOption(nOptions), 'Focus should move down to the last option'); 86 87 await test_driver.click(select); 88 assert_equals(select.value, firstOption.value, 'Selected option should not change'); 89 assert_false(select.matches(':open'),'Clicking select should close picker'); 90 }, 'Behavior of Home and End for customizable-<select>, starting at the top'); 91 92 promise_test(async () => { 93 const lastOption = getOption(nOptions); 94 await testStart(lastOption); 95 await test_driver.send_keys(document.activeElement, keyMap.End); 96 assert_equals(select.value, lastOption.value, 'Selected option should not change'); 97 assert_equals(document.activeElement, lastOption, 'Focus should not change - already at the bottom'); 98 99 await test_driver.send_keys(document.activeElement, keyMap.Home); 100 assert_equals(select.value, lastOption.value, 'Selected option should not change'); 101 assert_equals(document.activeElement, getOption(1), 'Focus should move up to the first option'); 102 103 await test_driver.click(select); 104 assert_equals(select.value, lastOption.value, 'Selected option should not change'); 105 assert_false(select.matches(':open'),'Clicking select should close picker'); 106 }, 'Behavior of Home and End for customizable-<select>, starting at the bottom'); 107 108 promise_test(async () => { 109 const middleOption = getOption(nOptions/2); 110 await testStart(middleOption); 111 assert_equals(document.activeElement, middleOption, 'Focus should be on the middle option'); 112 const middleOptionPos = middleOption.getBoundingClientRect().top; 113 assert_not_equals(middleOptionPos,0,'Middle option should be scrolled into view, to start'); 114 115 await test_driver.send_keys(document.activeElement, keyMap.PageDown); 116 assert_equals(middleOption.getBoundingClientRect().top,middleOptionPos,'First page down should not scroll'); 117 const focusedOption2 = document.activeElement; 118 assert_not_equals(focusedOption2, middleOption, 'Focused option should change'); 119 120 await test_driver.send_keys(document.activeElement, keyMap.PageDown); 121 assert_not_equals(middleOption.getBoundingClientRect().top,middleOptionPos,'Second page down should scroll down by one page'); 122 const focusedOption3 = document.activeElement; 123 assert_not_equals(focusedOption3, focusedOption2, 'Focused option should change'); 124 const focusedOption3ScrollPos = focusedOption3.getBoundingClientRect().top; 125 126 await test_driver.send_keys(document.activeElement, keyMap.PageUp); 127 assert_equals(focusedOption3.getBoundingClientRect().top,focusedOption3ScrollPos,'Page up from here should not scroll'); 128 const focusedOption4 = document.activeElement; 129 assert_not_equals(focusedOption4, focusedOption3, 'Focused option should change'); 130 131 await test_driver.send_keys(document.activeElement, keyMap.PageUp); 132 assert_not_equals(focusedOption3.getBoundingClientRect().top,focusedOption3ScrollPos,'Page up should scroll up by one page'); 133 assert_not_equals(document.activeElement, focusedOption4, 'Focused option should change'); 134 135 await test_driver.click(select); 136 assert_equals(select.value, middleOption.value, 'Selected option should not change'); 137 assert_false(select.matches(':open'),'Clicking select should close picker'); 138 }, 'Behavior of PageUp and PageDown for customizable-<select>'); 139 </script>