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

Unified Diff: chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js

Issue 2356643003: Fix cr-shared-menu focus issues. (Closed)
Patch Set: Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js
diff --git a/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js b/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js
index c35bb2bbe2ae9d4ee6a7d4ec99dfa40ceaafc6be..b5ac54a50e53f35a5180091cca8b905db7af2758 100644
--- a/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js
@@ -9,9 +9,7 @@ suite('cr-shared-menu', function() {
var button;
var button2;
- var item1;
- var item2;
- var item3;
+ var items = [];
function afterOpen(callback) {
menu.addEventListener('iron-overlay-opened', function f() {
@@ -34,17 +32,10 @@ suite('cr-shared-menu', function() {
setup(function() {
PolymerTest.clearBody();
- // Basic wiring to set up a menu which opens when a button is pressed.
+ // Basic wiring to set up an empty menu that opens when a button is pressed.
menu = document.createElement('cr-shared-menu');
menu.$$('#dropdown').noAnimations = true;
- item1 = document.createElement('paper-item');
- menu.appendChild(item1);
- item2 = document.createElement('paper-item');
- menu.appendChild(item2);
- item3 = document.createElement('paper-item');
- menu.appendChild(item3);
-
button = document.createElement('button');
button.addEventListener('tap', function(e) {
menu.toggleMenu(button, {});
@@ -62,105 +53,173 @@ suite('cr-shared-menu', function() {
document.body.appendChild(button2);
});
- test('opening and closing menu', function(done) {
- MockInteractions.tap(button);
- assertTrue(menu.menuOpen);
+ suite('basic', function() {
+ setup(function() {
+ // Populate the menu with paper-items.
+ for (var i = 0; i < 3; i++) {
+ items[i] = document.createElement('paper-item');
+ menu.appendChild(items[i]);
+ }
+ });
+
+ test('opening and closing menu', function(done) {
+ MockInteractions.tap(button);
+ assertTrue(menu.menuOpen);
- afterOpen(function() {
- // Using tap to close the menu requires that the iron-overlay-behavior
- // has finished initializing, which happens asynchronously between
- // tapping the button and firing iron-overlay-opened.
- MockInteractions.tap(document.body);
- assertFalse(menu.menuOpen);
+ afterOpen(function() {
+ // Using tap to close the menu requires that the iron-overlay-behavior
+ // has finished initializing, which happens asynchronously between
+ // tapping the button and firing iron-overlay-opened.
+ MockInteractions.tap(document.body);
+ assertFalse(menu.menuOpen);
- done();
+ done();
+ });
});
- });
- test('open and close menu with escape', function(done) {
- MockInteractions.tap(button);
- assertTrue(menu.menuOpen);
- afterOpen(function() {
- // Pressing escape should close the menu.
- MockInteractions.pressAndReleaseKeyOn(menu, 27);
- assertFalse(menu.menuOpen);
- done();
+ test('open and close menu with escape', function(done) {
+ MockInteractions.tap(button);
+ assertTrue(menu.menuOpen);
+ afterOpen(function() {
+ // Pressing escape should close the menu.
+ MockInteractions.pressAndReleaseKeyOn(menu, 27);
+ assertFalse(menu.menuOpen);
+ done();
+ });
});
- });
- test('refocus button on close', function(done) {
- button.focus();
- MockInteractions.tap(button);
+ test('refocus button on close', function(done) {
+ button.focus();
+ MockInteractions.tap(button);
- afterOpen(function() {
- assertTrue(menu.menuOpen);
- // Focus is applied asynchronously after the menu is opened.
- assertEquals(item1, menu.shadowRoot.activeElement);
+ afterOpen(function() {
+ assertTrue(menu.menuOpen);
+ // Focus is applied asynchronously after the menu is opened.
+ assertEquals(items[0], menu.shadowRoot.activeElement);
- menu.closeMenu();
+ menu.closeMenu();
+
+ afterClose(function() {
+ assertFalse(menu.menuOpen);
+ // Button should regain focus after closing the menu.
+ assertEquals(button, document.activeElement);
+ done();
+ });
- afterClose(function() {
- assertFalse(menu.menuOpen);
- // Button should regain focus after closing the menu.
- assertEquals(button, document.activeElement);
- done();
});
+ });
+ test('refocus latest button on close', function(done) {
+ // Regression test for crbug.com/628080.
+ button.focus();
+ MockInteractions.tap(button);
+
+ afterOpen(function() {
+ button2.focus();
+ MockInteractions.tap(button2);
+
+ afterOpen(function() {
+ menu.closeMenu();
+ afterClose(function() {
+ assertEquals(button2, document.activeElement);
+ done();
+ });
+ });
+ });
});
- });
- test('refocus latest button on close', function(done) {
- // Regression test for crbug.com/628080.
- button.focus();
- MockInteractions.tap(button);
+ test('closeMenu does not refocus button when focus moves', function(done) {
+ var input = document.createElement('input');
+ document.body.appendChild(input);
- afterOpen(function() {
- button2.focus();
- MockInteractions.tap(button2);
+ button.focus();
+ MockInteractions.tap(button);
afterOpen(function() {
+ input.focus();
menu.closeMenu();
+
afterClose(function() {
- assertEquals(button2, document.activeElement);
+ assertEquals(input, document.activeElement);
done();
});
});
});
- });
-
- test('closeMenu does not refocus button when focus moves', function(done) {
- var input = document.createElement('input');
- document.body.appendChild(input);
- button.focus();
- MockInteractions.tap(button);
+ test('focus is trapped inside the menu', function(done) {
+ button.focus();
+ MockInteractions.tap(button);
- afterOpen(function() {
- input.focus();
- menu.closeMenu();
+ afterOpen(function() {
+ // Simulate shift-tab on first element.
+ assertEquals(items[0], menu.shadowRoot.activeElement);
+ MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']);
+ assertEquals(items[2], menu.shadowRoot.activeElement);
+
+ // Simulate tab on last element.
+ MockInteractions.pressAndReleaseKeyOn(items[2], 9);
+ assertEquals(items[0], menu.shadowRoot.activeElement);
+
+ // Simulate shift-tab on first element.
+ assertEquals(items[0], menu.shadowRoot.activeElement);
+ MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']);
+ assertEquals(items[2], menu.shadowRoot.activeElement);
+
+ // Simulate shift-tab on last element. This should simply cause the
+ // browser to focus the previous item in the tab order, since
+ // cr-shared-menu should not wrap in this case. However, we can't mimic
+ // native events from JS, so the focus won't actually move unless
+ // cr-shared--menu misbehaves.
+ MockInteractions.pressAndReleaseKeyOn(items[2], 9, ['shift']);
+ assertEquals(items[2], menu.shadowRoot.activeElement);
- afterClose(function() {
- assertEquals(input, document.activeElement);
done();
});
});
});
- test('focus is trapped inside the menu', function(done) {
- button.focus();
- MockInteractions.tap(button);
+ suite('different item types', function() {
+ setup(function() {
+ // Populate the menu with tabbable and untabbable items.
+ items[0] = document.createElement('paper-item');
+ items[0].disabled = true;
+ menu.appendChild(items[0]);
+
+ items[1] = document.createElement('paper-item');
+ menu.appendChild(items[1]);
+
+ items[2] = document.createElement('button');
+ menu.appendChild(items[2]);
- afterOpen(function() {
- // Simulate shift-tab on first element.
- assertEquals(item1, menu.shadowRoot.activeElement);
- MockInteractions.pressAndReleaseKeyOn(item1, 9, ['shift']);
- assertEquals(item3, menu.shadowRoot.activeElement);
+ items[3] = document.createElement('button');
+ items[3].disabled = true;
- // Simulate tab on last element.
- MockInteractions.pressAndReleaseKeyOn(item3, 9);
- assertEquals(item1, menu.shadowRoot.activeElement);
+ items[4] = document.createElement('paper-item');
+ items[4].hidden = true;
+ menu.appendChild(items[4]);
+ });
+
+ test('focus does not start/end with untabbable elements', function(done) {
+ button.focus();
+ MockInteractions.tap(button);
- done();
+ afterOpen(function() {
+ // The first item is disabled, so the second item is the first tabbable
+ // item and should be focusced.
+ assertEquals(items[1], menu.shadowRoot.activeElement);
+
+ // The last two items are disabled or hidden, so they should be skipped
+ // too.
+ MockInteractions.pressAndReleaseKeyOn(items[1], 9, ['shift']);
+ assertEquals(items[2], menu.shadowRoot.activeElement);
+
+ // Simulate tab on last tabbable element to wrap to the first tabbable
+ // element again.
+ MockInteractions.pressAndReleaseKeyOn(items[2], 9);
+ assertEquals(items[1], menu.shadowRoot.activeElement);
+
+ done();
+ });
});
});
});
« no previous file with comments | « no previous file | ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698