Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 }); |
| OLD | NEW |