Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js

Issue 2272553002: MD WebUI: Use arrow keys for navigation in cr-shared-menu, close on tab (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Expand tests Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** @fileoverview Suite of tests for cr-shared-menu. */ 5 /** @fileoverview Suite of tests for cr-shared-menu. */
6 suite('cr-shared-menu', function() { 6 suite('cr-shared-menu', function() {
7 var menu; 7 var menu;
8 8
9 var button; 9 var button;
10 var button2; 10 var button2;
11 11
12 var items = []; 12 var items = [];
13 13
14 function afterOpen(callback) { 14 function afterOpen(callback) {
15 menu.addEventListener('iron-overlay-opened', function f() { 15 menu.addEventListener('iron-overlay-opened', function f() {
Dan Beam 2016/09/29 03:22:59 btw, listenOnce() is now a thing: https://cs.chro
tsergeant 2016/09/29 06:59:56 Neat, done.
16 menu.removeEventListener('iron-overlay-opened', f); 16 menu.removeEventListener('iron-overlay-opened', f);
17 callback(); 17 // paper-listbox applies focus after opening with microtask timing.
18 // Delay until that has happened:
19 setTimeout(callback, 0);
18 }); 20 });
19 } 21 }
20 22
21 function afterClose(callback) { 23 function afterClose(callback) {
22 menu.addEventListener('iron-overlay-closed', function f() { 24 menu.addEventListener('iron-overlay-closed', function f() {
23 menu.removeEventListener('iron-overlay-closed', f); 25 menu.removeEventListener('iron-overlay-closed', f);
24 callback(); 26 callback();
25 }); 27 });
26 } 28 }
27 29
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 input.focus(); 141 input.focus();
140 menu.closeMenu(); 142 menu.closeMenu();
141 143
142 afterClose(function() { 144 afterClose(function() {
143 assertEquals(input, document.activeElement); 145 assertEquals(input, document.activeElement);
144 done(); 146 done();
145 }); 147 });
146 }); 148 });
147 }); 149 });
148 150
149 test('focus is trapped inside the menu', function(done) { 151 test('tab closes menu', function(done) {
150 button.focus(); 152 button.focus();
151 MockInteractions.tap(button); 153 MockInteractions.tap(button);
152 154
153 afterOpen(function() { 155 afterOpen(function() {
154 // Simulate shift-tab on first element. 156 MockInteractions.pressAndReleaseKeyOn(items[0], 9);
155 assertEquals(items[0], menu.shadowRoot.activeElement); 157 afterClose(function() {
158 // Focus should move to a different element, but we can't simulate
159 // the right events to test this.
160 done();
161 });
162 });
163 });
164
165 test('shift-tab closes menu', function(done) {
166 button.focus();
167 MockInteractions.tap(button);
168
169 afterOpen(function() {
156 MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']); 170 MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']);
157 assertEquals(items[2], menu.shadowRoot.activeElement); 171 afterClose(done);
172 });
173 });
158 174
159 // Simulate tab on last element. 175 test('up and down change focus', function(done) {
160 MockInteractions.pressAndReleaseKeyOn(items[2], 9); 176 button.focus();
161 assertEquals(items[0], menu.shadowRoot.activeElement); 177 MockInteractions.tap(button);
162 178
163 // Simulate shift-tab on first element. 179 afterOpen(function() {
164 assertEquals(items[0], menu.shadowRoot.activeElement); 180 // Pressing down on first item goes to second item.
165 MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']); 181 assertEquals(items[0], document.activeElement);
166 assertEquals(items[2], menu.shadowRoot.activeElement); 182 MockInteractions.pressAndReleaseKeyOn(items[0], 40);
183 assertEquals(items[1], document.activeElement);
167 184
168 // Simulate shift-tab on last element. This should simply cause the 185 // Pressing down twice more cycles back to first item.
169 // browser to focus the previous item in the tab order, since 186 MockInteractions.pressAndReleaseKeyOn(items[1], 40);
170 // cr-shared-menu should not wrap in this case. However, we can't mimic 187 MockInteractions.pressAndReleaseKeyOn(items[2], 40);
171 // native events from JS, so the focus won't actually move unless 188 assertEquals(items[0], document.activeElement);
172 // cr-shared--menu misbehaves. 189
173 MockInteractions.pressAndReleaseKeyOn(items[2], 9, ['shift']); 190 // Pressing up cycles to last item.
174 assertEquals(items[2], menu.shadowRoot.activeElement); 191 MockInteractions.pressAndReleaseKeyOn(items[0], 38);
192 assertEquals(items[2], document.activeElement);
175 193
176 done(); 194 done();
177 }); 195 });
178 }); 196 });
179 }); 197 });
180 198
181 suite('different item types', function() { 199 suite('different item types', function() {
182 setup(function() { 200 setup(function() {
183 // Populate the menu with tabbable and untabbable items. 201 // Populate the menu with tabbable and untabbable items.
184 items[0] = document.createElement('paper-item'); 202 items[0] = document.createElement('paper-item');
185 items[0].disabled = true; 203 items[0].disabled = true;
186 menu.appendChild(items[0]); 204 menu.appendChild(items[0]);
187 205
188 items[1] = document.createElement('paper-item'); 206 items[1] = document.createElement('paper-item');
189 menu.appendChild(items[1]); 207 menu.appendChild(items[1]);
190 208
191 items[2] = document.createElement('button'); 209 items[2] = document.createElement('button');
192 menu.appendChild(items[2]); 210 menu.appendChild(items[2]);
193 211
194 items[3] = document.createElement('button'); 212 items[3] = document.createElement('button');
195 items[3].disabled = true; 213 items[3].disabled = true;
214 menu.appendChild(items[3]);
196 215
197 items[4] = document.createElement('paper-item'); 216 items[4] = document.createElement('paper-item');
198 items[4].hidden = true; 217 items[4].hidden = true;
199 menu.appendChild(items[4]); 218 menu.appendChild(items[4]);
200 }); 219 });
201 220
202 test('focus does not start/end with untabbable elements', function(done) { 221 test('focus does not start/end with untabbable elements', function(done) {
203 button.focus(); 222 button.focus();
204 MockInteractions.tap(button); 223 MockInteractions.tap(button);
205 224
206 afterOpen(function() { 225 afterOpen(function() {
207 // The first item is disabled, so the second item is the first tabbable 226 // The first item is disabled, so the second item is the first tabbable
208 // item and should be focusced. 227 // item and should be focusced.
209 assertEquals(items[1], menu.shadowRoot.activeElement); 228 assertEquals(items[1], menu.shadowRoot.activeElement);
210 229
211 // The last two items are disabled or hidden, so they should be skipped 230 // The last two items are disabled or hidden, so they should be skipped
212 // too. 231 // when pressing up.
213 MockInteractions.pressAndReleaseKeyOn(items[1], 9, ['shift']); 232 MockInteractions.pressAndReleaseKeyOn(items[1], 38);
214 assertEquals(items[2], menu.shadowRoot.activeElement); 233 assertEquals(items[2], menu.shadowRoot.activeElement);
215 234
216 // Simulate tab on last tabbable element to wrap to the first tabbable 235 // Simulate pressing down on last focusable element to wrap to first
217 // element again. 236 // focusable element.
218 MockInteractions.pressAndReleaseKeyOn(items[2], 9); 237 MockInteractions.pressAndReleaseKeyOn(items[2], 40);
219 assertEquals(items[1], menu.shadowRoot.activeElement); 238 assertEquals(items[1], menu.shadowRoot.activeElement);
220 239
221 done(); 240 done();
222 }); 241 });
223 }); 242 });
224 }); 243 });
225 }); 244 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698