File: select-events.tentative.html

package info (click to toggle)
firefox-esr 140.4.0esr-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,539,276 kB
  • sloc: cpp: 7,381,286; javascript: 6,388,710; ansic: 3,710,139; python: 1,393,780; xml: 628,165; asm: 426,918; java: 184,004; sh: 65,742; makefile: 19,302; objc: 13,059; perl: 12,912; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,226; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (231 lines) | stat: -rw-r--r-- 10,986 bytes parent folder | download | duplicates (7)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<!DOCTYPE html>
<link rel=author href="mailto:masonf@chromium.org">
<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>

<div class=wrapper data-description="implicit button">
  <select class=select>
    <option class=option1>one</option>
    <option class=option2>two</option>
    <option class=option3>three</option>
  </select>
</div>

<div class=wrapper data-description="explicit button">
  <select class=select>
    <button>Click</button>
    <option class=option1>one</option>
    <option class=option2>two</option>
    <option class=option3>three</option>
  </select>
</div>

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

<script>
  const events = ['click','keydown','keyup','mousedown','mouseup','pointerdown','pointerup',
      'focusin','focusout','input','change','beforetoggle','toggle'];
  const keys = {Enter:'\uE007',Escape:'\uE00C',ArrowLeft:'\uE012',ArrowUp:'\uE013',ArrowRight:'\uE014',ArrowDown:'\uE015',Space:' ',Tab:'\uE004',Shift:'\uE008'};

  document.querySelectorAll('.wrapper').forEach(wrapper => {
    const select = wrapper.querySelector('select');
    const option1 = wrapper.querySelector('.option1');
    const option2 = wrapper.querySelector('.option2');
    const option3 = wrapper.querySelector('.option3');
    promise_test(async (t) => {
      assert_false(select.matches(':open'),'select should be closed at the start of the test');
      let eventList = [];
      function assert_events(expectedEvents,message) {
        message = message || "Mismatch";
        assert_array_equals(eventList,expectedEvents,message);
        eventList = [];
      }
      function getEventHandler(description) {
        return (e) => {
          let focused = '';
          if (e.type == 'keydown' || e.type == 'keyup') {
            focused = ` focused: ${document.activeElement.className || document.activeElement.tagName}.`;
          }
          eventList.push(`${e.type} on ${e.target.className} at ${description}. open: ${select.matches(':open')}.${focused}`);
        };
      }
      events.forEach(evt => wrapper.addEventListener(evt,getEventHandler('wrapper')));
      events.forEach(evt => select.addEventListener(evt,getEventHandler('select')));
      assert_events([]);

      // Open the picker by clicking on it, which will focus the currently selected option.
      await test_driver.click(select);
      assert_true(select.matches(':open'));
      assert_events([
        'pointerdown on select at select. open: false.',
        'pointerdown on select at wrapper. open: false.',
        'mousedown on select at select. open: false.',
        'mousedown on select at wrapper. open: false.',
        'focusin on option1 at select. open: true.',
        'focusin on option1 at wrapper. open: true.',
        'pointerup on select at select. open: true.',
        'pointerup on select at wrapper. open: true.',
        'mouseup on select at select. open: true.',
        'mouseup on select at wrapper. open: true.',
        'click on select at select. open: true.',
        'click on select at wrapper. open: true.'
      ],'after showing, events from test_driver.click');

      // Press arrow-down, and preventDefault
      wrapper.addEventListener('keydown',(e) => e.preventDefault(),{once:true});
      await test_driver.send_keys(document.activeElement, keys.ArrowDown);
      assert_equals(select.selectedOptions[0].innerText,'one');
      assert_events([
        'keydown on option1 at select. open: true. focused: option1.',
        'keydown on option1 at wrapper. open: true. focused: option1.',
        'keyup on option1 at select. open: true. focused: option1.',
        'keyup on option1 at wrapper. open: true. focused: option1.'
      ],'arrow down, with preventDefault');

      // Press arrow-down, no preventDefault
      await test_driver.send_keys(document.activeElement, keys.ArrowDown);
      assert_equals(select.selectedOptions[0].innerText,'one','selection does not follow focus');
      assert_events([
        'keydown on option1 at select. open: true. focused: option1.',
        'keydown on option1 at wrapper. open: true. focused: option1.',
        'focusout on option1 at select. open: true.',
        'focusout on option1 at wrapper. open: true.',
        'focusin on option2 at select. open: true.',
        'focusin on option2 at wrapper. open: true.',
        'keyup on option2 at select. open: true. focused: option2.',
        'keyup on option2 at wrapper. open: true. focused: option2.'
      ],'arrow down, no preventDefault');

      // Press escape, and preventDefault
      wrapper.addEventListener('keydown',(e) => e.preventDefault(),{once:true});
      await test_driver.send_keys(document.activeElement, keys.Escape);
      assert_true(select.matches(':open'));
      assert_events([
        'keydown on option2 at select. open: true. focused: option2.',
        'keydown on option2 at wrapper. open: true. focused: option2.',
        'keyup on option2 at select. open: true. focused: option2.',
        'keyup on option2 at wrapper. open: true. focused: option2.'
      ],'escape, with preventDefault');

      // Press escape, no preventDefault
      await test_driver.send_keys(document.activeElement, keys.Escape);
      assert_false(select.matches(':open'),'select should be closed escape no preventDefault');
      assert_events([
        'keydown on option2 at select. open: true. focused: option2.',
        'keydown on option2 at wrapper. open: true. focused: option2.',
        'focusout on option2 at select. open: false.',
        'focusout on option2 at wrapper. open: false.',
        'focusin on select at select. open: false.',
        'focusin on select at wrapper. open: false.',
        'keyup on select at select. open: false. focused: select.',
        'keyup on select at wrapper. open: false. focused: select.'
      ],'escape, no preventDefault');

      // Re-open the picker and hit arrow-down again.
      await test_driver.click(select);
      assert_true(select.matches(':open'));
      assert_equals(select.value,'one');
      await test_driver.send_keys(document.activeElement, keys.ArrowDown);
      assert_equals(select.value,'one','selection does not follow focus');
      eventList = [];

      // Press enter to select an option, with preventDefault
      wrapper.addEventListener('keydown',(e) => e.preventDefault(),{once:true});
      await test_driver.send_keys(document.activeElement, keys.Enter);
      assert_true(select.matches(':open'));
      assert_equals(select.value,'one','value has not changed');
      assert_events([
        'keydown on option2 at select. open: true. focused: option2.',
        'keydown on option2 at wrapper. open: true. focused: option2.',
        'keyup on option2 at select. open: true. focused: option2.',
        'keyup on option2 at wrapper. open: true. focused: option2.'
      ],'enter, with preventDefault');

      // Press enter to select an option, no preventDefault
      await test_driver.send_keys(document.activeElement, keys.Enter);
      assert_false(select.matches(':open'),'select should be closed enter no preventDefault');
      assert_equals(select.value,'two');
      assert_events([
        'keydown on option2 at select. open: true. focused: option2.',
        'keydown on option2 at wrapper. open: true. focused: option2.',
        'input on select at select. open: true.',
        'input on select at wrapper. open: true.',
        'change on select at select. open: true.',
        'change on select at wrapper. open: true.',
        'focusout on option2 at select. open: false.',
        'focusout on option2 at wrapper. open: false.',
        'focusin on select at select. open: false.',
        'focusin on select at wrapper. open: false.',
        'keyup on select at select. open: false. focused: select.',
        'keyup on select at wrapper. open: false. focused: select.'
      ],'enter, no preventDefault');

      // Re-open the picker.
      await test_driver.click(select);
      assert_true(select.matches(':open'));
      eventList = [];

      // Click on an option, with preventDefault
      wrapper.addEventListener('mouseup',(e) => e.preventDefault(),{once:true});
      assert_equals(select.selectedOptions[0].innerText,'two');
      await (new test_driver.Actions()
        .pointerMove(1, 1, {origin: option1})
        .pointerDown()
        .pointerUp())
        .send();
      assert_true(select.matches(':open'),'click should be cancelled');
      assert_events([
        'pointerdown on option1 at select. open: true.',
        'pointerdown on option1 at wrapper. open: true.',
        'mousedown on option1 at select. open: true.',
        'mousedown on option1 at wrapper. open: true.',
        'focusout on option2 at select. open: true.',
        'focusout on option2 at wrapper. open: true.',
        'focusin on option1 at select. open: true.',
        'focusin on option1 at wrapper. open: true.',
        'pointerup on option1 at select. open: true.',
        'pointerup on option1 at wrapper. open: true.',
        'mouseup on option1 at select. open: true.',
        'mouseup on option1 at wrapper. open: true.',
        'click on option1 at select. open: true.',
        'click on option1 at wrapper. open: true.'
      ],'click option, with preventDefault');

      // Click on an option, no preventDefault
      assert_equals(select.selectedOptions[0].innerText,'two');
      await (new test_driver.Actions()
        .pointerMove(1, 1, {origin: option1})
        .pointerDown()
        .pointerUp())
        .send();
      assert_false(select.matches(':open'),'select should be closed click option no preventDefault');
      assert_events([
        'pointerdown on option1 at select. open: true.',
        'pointerdown on option1 at wrapper. open: true.',
        'mousedown on option1 at select. open: true.',
        'mousedown on option1 at wrapper. open: true.',
        'pointerup on option1 at select. open: true.',
        'pointerup on option1 at wrapper. open: true.',
        'mouseup on option1 at select. open: true.',
        'mouseup on option1 at wrapper. open: true.',
        'input on select at select. open: true.',
        'input on select at wrapper. open: true.',
        'change on select at select. open: true.',
        'change on select at wrapper. open: true.',
        'focusout on option1 at select. open: false.',
        'focusout on option1 at wrapper. open: false.',
        'focusin on select at select. open: false.',
        'focusin on select at wrapper. open: false.',
        'click on option1 at select. open: false.',
        'click on option1 at wrapper. open: false.'
      ],'click option, no preventDefault');
    },`Events, ${wrapper.dataset.description}`);
  });
</script>