blob: 8e57d61b073ae48794c4036734fde0696cf41d52 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Include test fixture.
GEN_INCLUDE(['panel_test_base.js']);
/**
* Test fixture for Panel.
*/
ChromeVoxPanelTest = class extends ChromeVoxPanelTestBase {
fireMockEvent(key) {
return function() {
const obj = {};
obj.preventDefault = function() {};
obj.stopPropagation = function() {};
obj.key = key;
this.getPanel().onKeyDown(obj);
}.bind(this);
}
fireMockQuery(query) {
return function() {
const evt = {};
evt.target = {};
evt.target.value = query;
this.getPanel().onSearchBarQuery(evt);
}.bind(this);
}
async waitForMenu(menuMsg) {
// Menu and menu item updates occur in a different js context, so tests need
// to wait until an update has been made. Swap in our hook, wait, then
// restore after.
const makeAssertions = () => {
const menu = this.getPanel().activeMenu_;
assertEquals(menuMsg, menu.menuMsg);
};
return new Promise(resolve => {
const Panel = this.getPanel();
const original = Panel.activateMenu;
Panel.activateMenu = (menu, activateFirstItem) => {
original(menu, activateFirstItem);
makeAssertions();
Panel.activateMenu = original;
resolve();
};
});
}
assertActiveMenuItem(menuMsg, menuItemTitle, opt_menuItemShortcut) {
const menu = this.getPanel().activeMenu_;
const menuItem = menu.items_[menu.activeIndex_];
assertEquals(menuMsg, menu.menuMsg);
assertEquals(menuItemTitle, menuItem.menuItemTitle);
if (opt_menuItemShortcut) {
assertEquals(opt_menuItemShortcut, menuItem.menuItemShortcut);
}
}
assertActiveSearchMenuItem(menuItemTitle) {
const searchMenu = this.getPanel().searchMenu;
const activeIndex = searchMenu.activeIndex_;
const activeItem = searchMenu.items_[activeIndex];
assertEquals(menuItemTitle, activeItem.menuItemTitle);
}
isMenuTitleMessage(menuTitleMessage) {
const menu = this.getPanel().activeMenu_;
return menuTitleMessage === menu.menuMsg;
}
get linksDoc() {
return `
<p>start</p>
<a href="#">apple</a>
<a href="#">grape</a>
<a href="#">banana</a>
`;
}
get internationalButtonDoc() {
return `
<button lang="en">Test</button>
<button lang="es">Prueba</button>
`;
}
};
TEST_F('ChromeVoxPanelTest', 'ActivateMenu', function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
new PanelCommand(PanelCommandType.OPEN_MENUS).send();
await this.waitForMenu('panel_search_menu');
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem('panel_menu_jump', 'Go To Beginning Of Table');
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem(
'panel_menu_speech', 'Announce Current Battery Status');
});
});
// TODO(https://crbug.com/1299765): Re-enable once flaky timeouts are fixed.
TEST_F('ChromeVoxPanelTest', 'DISABLED_LinkMenu', function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
CommandHandler.onCommand('showLinksList');
await this.waitForMenu('role_link');
this.fireMockEvent('ArrowLeft')();
this.assertActiveMenuItem('role_landmark', 'No items');
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem('role_link', 'apple Internal link');
this.fireMockEvent('ArrowUp')();
this.assertActiveMenuItem('role_link', 'banana Internal link');
});
});
TEST_F('ChromeVoxPanelTest', 'FormControlsMenu', function() {
this.runWithLoadedTree(
`<button>Cancel</button><button>OK</button>`, async function(root) {
CommandHandler.onCommand('showFormsList');
await this.waitForMenu('panel_menu_form_controls');
this.fireMockEvent('ArrowDown')();
this.assertActiveMenuItem('panel_menu_form_controls', 'OK Button');
this.fireMockEvent('ArrowUp')();
this.assertActiveMenuItem('panel_menu_form_controls', 'Cancel Button');
});
});
TEST_F('ChromeVoxPanelTest', 'SearchMenu', function() {
const mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.linksDoc, async function(root) {
new PanelCommand(PanelCommandType.OPEN_MENUS).send();
await this.waitForMenu('panel_search_menu');
await mockFeedback
.expectSpeech('Search the menus', /Type to search the menus/)
.call(() => {
this.fireMockQuery('jump')();
this.assertActiveSearchMenuItem('Jump To Details');
})
.expectSpeech(/Jump/, 'Menu item', /[0-9]+ of [0-9]+/)
.call(() => {
this.fireMockEvent('ArrowDown')();
this.assertActiveSearchMenuItem('Jump To The Bottom Of The Page');
})
.expectSpeech(/Jump/, 'Menu item', /[0-9]+ of [0-9]+/)
.call(() => {
this.fireMockEvent('ArrowDown')();
this.assertActiveSearchMenuItem('Jump To The Top Of The Page');
})
.expectSpeech(/Jump/, 'Menu item', /[0-9]+ of [0-9]+/)
.call(() => {
this.fireMockEvent('ArrowDown')();
this.assertActiveSearchMenuItem('Jump To Details');
})
.expectSpeech(/Jump/, 'Menu item', /[0-9]+ of [0-9]+/)
.replay();
});
});
// TODO(crbug.com/1088438): flaky crashes.
TEST_F('ChromeVoxPanelTest', 'DISABLED_Gestures', function() {
const doGestureAsync = async (gesture) => {
doGesture(gesture)();
};
this.runWithLoadedTree(
`<button>Cancel</button><button>OK</button>`, async function(root) {
doGestureAsync(Gesture.TAP4);
await this.waitForMenu('panel_search_menu');
// GestureCommandHandler behaves in special ways only with range over
// the panel. Fake this out by setting range there.
const desktop = root.parent.root;
const panelNode = desktop.find(
{role: 'rootWebArea', attributes: {name: 'ChromeVox Panel'}});
ChromeVoxState.instance.setCurrentRange(
cursors.Range.fromNode(panelNode));
doGestureAsync(Gesture.SWIPE_RIGHT1);
await this.waitForMenu('panel_menu_jump');
doGestureAsync(Gesture.SWIPE_RIGHT1);
await this.waitForMenu('panel_menu_speech');
doGestureAsync(Gesture.SWIPE_LEFT1);
await this.waitForMenu('panel_menu_jump');
});
});
TEST_F('ChromeVoxPanelTest', 'InternationalFormControlsMenu', function() {
this.runWithLoadedTree(this.internationalButtonDoc, async function(root) {
// Turn on language switching and set available voice list.
localStorage['languageSwitching'] = 'true';
this.getPanelWindow().LocaleOutputHelper.instance.availableVoices_ =
[{'lang': 'en-US'}, {'lang': 'es-ES'}];
CommandHandler.onCommand('showFormsList');
await this.waitForMenu('panel_menu_form_controls');
this.fireMockEvent('ArrowDown')();
this.assertActiveMenuItem(
'panel_menu_form_controls', 'espaƱol: Prueba Button');
this.fireMockEvent('ArrowUp')();
this.assertActiveMenuItem('panel_menu_form_controls', 'Test Button');
});
});
TEST_F('ChromeVoxPanelTest', 'ActionsMenu', function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
CommandHandler.onCommand('showActionsMenu');
await this.waitForMenu('panel_menu_actions');
this.fireMockEvent('ArrowDown')();
this.assertActiveMenuItem('panel_menu_actions', 'Start Or End Selection');
this.fireMockEvent('ArrowUp')();
this.assertActiveMenuItem('panel_menu_actions', 'Click On Current Item');
});
});
TEST_F('ChromeVoxPanelTest', 'ShortcutsAreInternationalized', function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
new PanelCommand(PanelCommandType.OPEN_MENUS).send();
await this.waitForMenu('panel_search_menu');
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem(
'panel_menu_jump', 'Go To Beginning Of Table',
'Search+Alt+Shift+ArrowLeft');
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem(
'panel_menu_speech', 'Announce Current Battery Status',
'Search+O, then B');
// Skip the tabs menu.
this.fireMockEvent('ArrowRight')();
this.fireMockEvent('ArrowRight')();
this.assertActiveMenuItem(
'panel_menu_chromevox', 'Open keyboard shortcuts menu', 'Ctrl+Alt+/');
});
});
// Ensure 'Touch Gestures' is not in the panel menus by default.
TEST_F(
'ChromeVoxPanelTest', 'TouchGesturesMenuNotAvailableWhenNotInTouchMode',
function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
new PanelCommand(PanelCommandType.OPEN_MENUS).send();
await this.waitForMenu('panel_search_menu');
do {
this.fireMockEvent('ArrowRight')();
assertFalse(this.isMenuTitleMessage('panel_menu_touchgestures'));
} while (!this.isMenuTitleMessage('panel_search_menu'));
});
});
// Ensure 'Touch Gesture' is in the panel menus when touch mode is enabled.
TEST_F(
'ChromeVoxPanelTest', 'TouchGesturesMenuAvailableWhenInTouchMode',
function() {
this.runWithLoadedTree(this.linksDoc, async function(root) {
this.getPanel().setTouchGestureSourceForTesting();
new PanelCommand(PanelCommandType.OPEN_MENUS).send();
await this.waitForMenu('panel_search_menu');
// Look for Touch Gestures menu, fail if getting back to start.
do {
this.fireMockEvent('ArrowRight')();
assertFalse(this.isMenuTitleMessage('panel_search_menu'));
} while (!this.isMenuTitleMessage('panel_menu_touchgestures'));
this.assertActiveMenuItem(
'panel_menu_touchgestures', 'Click on current item');
});
});