File: select-home-end-pagedown-pageup-detailed.optional.html

package info (click to toggle)
firefox 144.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,637,504 kB
  • sloc: cpp: 7,576,692; javascript: 6,430,831; ansic: 3,748,119; python: 1,398,978; xml: 628,810; asm: 438,679; java: 186,194; sh: 63,212; makefile: 19,159; objc: 13,086; perl: 12,986; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (139 lines) | stat: -rw-r--r-- 6,660 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<meta name="timeout" content="long">
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>

<!-- This test is marked as optional because the specification does not mandate
     the specific behavior of keyboard keys like Home/End/etc. Support and
     implementation of the behavior for these keys varies across browsers and
     platforms. This test reflects picker support in desktop Chromium.

     This test is quite similar to the WPT here:
     external/wpt/html/semantics/forms/the-select-element/customizable-select/select-home-end-keys.tentative.html
     But this test is able to more exactly check the behavior of the
     (non-standardized) Home/End/PageDown/PageUp keys. -->

<style>
select,::picker(select) {
  appearance: base-select;
}
</style>

<select></select>

<script>
const keyMap = {
  'Home': '\uE011',
  'End': '\uE010',
  'PageUp': '\uE00E',
  'PageDown': '\uE00F'
};
const select = document.querySelector('select');

const nOptions = 1000;
for(let i=1;i<=nOptions;++i) {
  const option = document.createElement('option');
  option.textContent = `Option #${i}`;
  option.id=i;
  select.appendChild(option);
}
function getOption(n) {
  return document.getElementById(n);
}

async function testStart(firstOption) {
  assert_false(select.matches(':open'));
  select.value = firstOption.value;
  assert_equals(select.value, firstOption.value,'Initial value');
  await test_driver.click(select);
  assert_true(select.matches(':open'));
  assert_equals(select.value, firstOption.value,'Value doesn\'t change when opening picker');
  assert_equals(document.activeElement, firstOption, 'Selected option should be focused');
}

promise_test(async () => {
  assert_equals(Math.round(nOptions/2),nOptions/2,'nOptions must be even');
  const middleOption = getOption(nOptions/2);
  await testStart(middleOption);
  await test_driver.send_keys(document.activeElement, keyMap.Home);
  assert_equals(select.value, middleOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, getOption(1), 'Focus should move up to the first option');

  await test_driver.send_keys(document.activeElement, keyMap.End);
  assert_equals(select.value, middleOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, getOption(nOptions), 'Focus should move down to the last option');

  await test_driver.click(select);
  assert_equals(select.value, middleOption.value, 'Selected option should not change');
  assert_false(select.matches(':open'),'Clicking select should close picker');
}, 'Behavior of Home and End for customizable-<select>');

promise_test(async () => {
  const firstOption = getOption(1);
  await testStart(firstOption);
  await test_driver.send_keys(document.activeElement, keyMap.Home);
  assert_equals(select.value, firstOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, firstOption, 'Focus should not change - already at the top');

  await test_driver.send_keys(document.activeElement, keyMap.End);
  assert_equals(select.value, firstOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, getOption(nOptions), 'Focus should move down to the last option');

  await test_driver.click(select);
  assert_equals(select.value, firstOption.value, 'Selected option should not change');
  assert_false(select.matches(':open'),'Clicking select should close picker');
}, 'Behavior of Home and End for customizable-<select>, starting at the top');

promise_test(async () => {
  const lastOption = getOption(nOptions);
  await testStart(lastOption);
  await test_driver.send_keys(document.activeElement, keyMap.End);
  assert_equals(select.value, lastOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, lastOption, 'Focus should not change - already at the bottom');

  await test_driver.send_keys(document.activeElement, keyMap.Home);
  assert_equals(select.value, lastOption.value, 'Selected option should not change');
  assert_equals(document.activeElement, getOption(1), 'Focus should move up to the first option');

  await test_driver.click(select);
  assert_equals(select.value, lastOption.value, 'Selected option should not change');
  assert_false(select.matches(':open'),'Clicking select should close picker');
}, 'Behavior of Home and End for customizable-<select>, starting at the bottom');

promise_test(async () => {
  const middleOption = getOption(nOptions/2);
  await testStart(middleOption);
  assert_equals(document.activeElement, middleOption, 'Focus should be on the middle option');
  const middleOptionPos = middleOption.getBoundingClientRect().top;
  assert_not_equals(middleOptionPos,0,'Middle option should be scrolled into view, to start');

  await test_driver.send_keys(document.activeElement, keyMap.PageDown);
  assert_equals(middleOption.getBoundingClientRect().top,middleOptionPos,'First page down should not scroll');
  const focusedOption2 = document.activeElement;
  assert_not_equals(focusedOption2, middleOption, 'Focused option should change');

  await test_driver.send_keys(document.activeElement, keyMap.PageDown);
  assert_not_equals(middleOption.getBoundingClientRect().top,middleOptionPos,'Second page down should scroll down by one page');
  const focusedOption3 = document.activeElement;
  assert_not_equals(focusedOption3, focusedOption2, 'Focused option should change');
  const focusedOption3ScrollPos = focusedOption3.getBoundingClientRect().top;

  await test_driver.send_keys(document.activeElement, keyMap.PageUp);
  assert_equals(focusedOption3.getBoundingClientRect().top,focusedOption3ScrollPos,'Page up from here should not scroll');
  const focusedOption4 = document.activeElement;
  assert_not_equals(focusedOption4, focusedOption3, 'Focused option should change');

  await test_driver.send_keys(document.activeElement, keyMap.PageUp);
  assert_not_equals(focusedOption3.getBoundingClientRect().top,focusedOption3ScrollPos,'Page up should scroll up by one page');
  assert_not_equals(document.activeElement, focusedOption4, 'Focused option should change');

  await test_driver.click(select);
  assert_equals(select.value, middleOption.value, 'Selected option should not change');
  assert_false(select.matches(':open'),'Clicking select should close picker');
}, 'Behavior of PageUp and PageDown for customizable-<select>');
</script>