diff options
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_result_menu_general.js')
-rw-r--r-- | browser/components/urlbar/tests/browser/browser_result_menu_general.js | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_result_menu_general.js b/browser/components/urlbar/tests/browser/browser_result_menu_general.js new file mode 100644 index 0000000000..ece48de20a --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_result_menu_general.js @@ -0,0 +1,416 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// General tests for the result menu that aren't related to specific result +// types. + +"use strict"; + +const MAX_RESULTS = UrlbarPrefs.get("maxRichResults"); +const RESULT_URL = "https://example.com/test"; +const RESULT_HELP_URL = "https://example.com/help"; + +add_setup(async function () { + // Add enough results to fill up the view. + await PlacesUtils.history.clear(); + for (let i = 0; i < MAX_RESULTS; i++) { + await PlacesTestUtils.addVisits("https://example.com/" + i); + } + registerCleanupFunction(async () => { + await PlacesUtils.history.clear(); + }); +}); + +// Sets `helpUrl` on a result payload and makes sure the result menu ends up +// with a help command. +add_task(async function help() { + let provider = registerTestProvider(1); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + value: "example", + window, + }); + + await assertIsTestResult(1); + + let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 1); + let menuButton = result.element.row._buttons.get("menu"); + Assert.ok(menuButton, "Sanity check: menu button should exist"); + + let menuitem = await UrlbarTestUtils.openResultMenuAndGetItem({ + window, + command: "help", + resultIndex: 1, + openByMouse: true, + }); + Assert.ok(menuitem, "Help menu item should exist"); + + let l10nAttrs = document.l10n.getAttributes(menuitem); + Assert.deepEqual( + l10nAttrs, + { id: "urlbar-result-menu-tip-get-help", args: null }, + "The l10n ID attribute was correctly set" + ); + + // The result menu needs to be closed before calling + // `openResultMenuAndClickItem()` below; otherwise it will wait on a + // `popupshown` event that will never come. + gURLBar.view.resultMenu.hidePopup(true); + + // We assume clicking "help" will load a page in a new tab. + let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser); + + await UrlbarTestUtils.openResultMenuAndClickItem(window, "help", { + resultIndex: 1, + openByMouse: true, + }); + + info("Waiting for load"); + await loadPromise; + await TestUtils.waitForTick(); + Assert.equal( + gBrowser.currentURI.spec, + RESULT_HELP_URL, + "The load URL should be the help URL" + ); + BrowserTestUtils.removeTab(gBrowser.selectedTab); + + UrlbarProvidersManager.unregisterProvider(provider); +}); + +// (SHIFT+)TABs through a result with a menu button. The result is the second +// result and has other results after it. +add_task(async function keyboardSelection_secondResult() { + let provider = registerTestProvider(1); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + value: "example", + window, + }); + + // Sanity-check initial state. + Assert.equal( + UrlbarTestUtils.getResultCount(window), + MAX_RESULTS, + "There should be MAX_RESULTS results in the view" + ); + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + 0, + "The heuristic result should be selected" + ); + await assertIsTestResult(1); + + info("Arrow down to the main part of the result."); + EventUtils.synthesizeKey("KEY_ArrowDown"); + assertMainPartSelected(1); + + info("TAB to the button."); + EventUtils.synthesizeKey("KEY_Tab"); + assertButtonSelected(2); + + info("TAB to the next (third) result."); + EventUtils.synthesizeKey("KEY_Tab"); + assertOtherResultSelected(3, "next result"); + + info("SHIFT+TAB to the menu button."); + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + assertButtonSelected(2); + + info("SHIFT+TAB to the main part of the result."); + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + assertMainPartSelected(1); + + info("Arrow up to the previous (first) result."); + EventUtils.synthesizeKey("KEY_ArrowUp"); + assertOtherResultSelected(0, "previous result"); + + await UrlbarTestUtils.promisePopupClose(window); + UrlbarProvidersManager.unregisterProvider(provider); +}); + +// (SHIFT+)TABs through a result with a help button. The result is the +// last result. +add_task(async function keyboardSelection_lastResult() { + let provider = registerTestProvider(MAX_RESULTS - 1); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + value: "example", + window, + }); + + // Sanity-check initial state. + Assert.equal( + UrlbarTestUtils.getResultCount(window), + MAX_RESULTS, + "There should be MAX_RESULTS results in the view" + ); + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + 0, + "The heuristic result should be selected" + ); + await assertIsTestResult(MAX_RESULTS - 1); + + let numSelectable = MAX_RESULTS * 2 - 2; + + // Arrow down to the main part of the result. + EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: MAX_RESULTS - 1 }); + assertMainPartSelected(numSelectable - 1); + + // TAB to the menu button. + EventUtils.synthesizeKey("KEY_Tab"); + assertButtonSelected(numSelectable); + + // Arrow down to the first one-off. If this test is running alone, the + // one-offs will rebuild themselves when the view is opened above, and they + // may not be visible yet. Wait for the first one to become visible before + // trying to select it. + await TestUtils.waitForCondition(() => { + return ( + gURLBar.view.oneOffSearchButtons.buttons.firstElementChild && + BrowserTestUtils.isVisible( + gURLBar.view.oneOffSearchButtons.buttons.firstElementChild + ) + ); + }, "Waiting for first one-off to become visible."); + + EventUtils.synthesizeKey("KEY_ArrowDown"); + await TestUtils.waitForCondition(() => { + return gURLBar.view.oneOffSearchButtons.selectedButton; + }, "Waiting for one-off to become selected."); + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + -1, + "No results should be selected." + ); + + // SHIFT+TAB to the menu button. + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + assertButtonSelected(numSelectable); + + // SHIFT+TAB to the main part of the result. + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + assertMainPartSelected(numSelectable - 1); + + // Arrow up to the previous result. + EventUtils.synthesizeKey("KEY_ArrowUp"); + assertOtherResultSelected(numSelectable - 3, "previous result"); + + await UrlbarTestUtils.promisePopupClose(window); + UrlbarProvidersManager.unregisterProvider(provider); +}); + +// Picks the main part of the test result with the keyboard. +add_task(async function pick_mainPart_keyboard() { + await doPickTest({ pickHelp: false, useKeyboard: true }); +}); + +// Picks the help command with the keyboard. +add_task(async function pick_help_keyboard() { + await doPickTest({ pickHelp: true, useKeyboard: true }); +}); + +// Picks the main part of the test result with the mouse. +add_task(async function pick_mainPart_mouse() { + await doPickTest({ pickHelp: false, useKeyboard: false }); +}); + +// Picks the help command with the mouse. +add_task(async function pick_help_mouse() { + await doPickTest({ pickHelp: true, useKeyboard: false }); +}); + +async function doPickTest({ pickHelp, useKeyboard }) { + await BrowserTestUtils.withNewTab("about:blank", async () => { + let index = 1; + let provider = registerTestProvider(index); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + value: "example", + window, + }); + + // Sanity-check initial state. + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + 0, + "The heuristic result should be selected" + ); + await assertIsTestResult(index); + + if (useKeyboard) { + // Arrow down to the result. + EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: index }); + assertMainPartSelected(index * 2 - 1); + } + + // Pick the result. The appropriate URL should load. + let loadPromise = pickHelp + ? BrowserTestUtils.waitForNewTab(gBrowser) + : BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + await Promise.all([ + loadPromise, + UrlbarTestUtils.promisePopupClose(window, async () => { + if (pickHelp) { + await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h", { + openByMouse: !useKeyboard, + resultIndex: index, + }); + } else if (useKeyboard) { + EventUtils.synthesizeKey("KEY_Enter"); + } else { + let result = await UrlbarTestUtils.getDetailsOfResultAt( + window, + index + ); + EventUtils.synthesizeMouseAtCenter(result.element.row._content, {}); + } + }), + ]); + Assert.equal( + gBrowser.selectedBrowser.currentURI.spec, + pickHelp ? RESULT_HELP_URL : RESULT_URL, + "Expected URL should have loaded" + ); + + if (pickHelp) { + BrowserTestUtils.removeTab(gBrowser.selectedTab); + } + UrlbarProvidersManager.unregisterProvider(provider); + + // Avoid showing adaptive history autofill. + await PlacesTestUtils.clearInputHistory(); + }); +} + +/** + * Registers a provider that creates a result with a help URL. + * + * @param {number} suggestedIndex + * The result's suggestedIndex. + * @returns {UrlbarProvider} + * The new provider. + */ +function registerTestProvider(suggestedIndex) { + let results = [ + Object.assign( + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, + { + url: RESULT_URL, + helpUrl: RESULT_HELP_URL, + helpL10n: { + id: "urlbar-result-menu-tip-get-help", + }, + } + ), + { suggestedIndex } + ), + ]; + let provider = new UrlbarTestUtils.TestProvider({ results }); + UrlbarProvidersManager.registerProvider(provider); + return provider; +} + +/** + * Asserts that the result at the given index is our test result with a menu + * button. + * + * @param {number} index + * The expected index of the test result. + */ +async function assertIsTestResult(index) { + let result = await UrlbarTestUtils.getDetailsOfResultAt(window, index); + Assert.equal( + result.type, + UrlbarUtils.RESULT_TYPE.URL, + "The second result should be a URL" + ); + Assert.equal( + result.url, + RESULT_URL, + "The result's URL should be the expected URL" + ); + + let { row } = result.element; + Assert.ok(row._buttons.get("menu"), "The result should have a menu button"); + Assert.ok(row._content.id, "Row-inner has an ID"); + Assert.equal( + row.getAttribute("role"), + "presentation", + "Row should have role=presentation" + ); + Assert.equal( + row._content.getAttribute("role"), + "option", + "Row-inner should have role=option" + ); +} + +/** + * Asserts that a particular element is selected. + * + * @param {number} expectedSelectedElementIndex + * The expected selected element index. + * @param {string} expectedClassName + * A class name of the expected selected element. + * @param {string} msg + * A string to include in the assertion message. + */ +function assertSelection(expectedSelectedElementIndex, expectedClassName, msg) { + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + expectedSelectedElementIndex, + "Expected selected element index: " + msg + ); + Assert.ok( + UrlbarTestUtils.getSelectedElement(window).classList.contains( + expectedClassName + ), + `Expected selected element: ${msg} (${ + UrlbarTestUtils.getSelectedElement(window).classList + } == ${expectedClassName})` + ); +} + +/** + * Asserts that the main part of our test result is selected. + * + * @param {number} expectedSelectedElementIndex + * The expected selected element index. + */ +function assertMainPartSelected(expectedSelectedElementIndex) { + assertSelection( + expectedSelectedElementIndex, + "urlbarView-row-inner", + "main part of test result" + ); +} + +/** + * Asserts that the menu button is selected. + * + * @param {number} expectedSelectedElementIndex + * The expected selected element index. + */ +function assertButtonSelected(expectedSelectedElementIndex) { + assertSelection( + expectedSelectedElementIndex, + "urlbarView-button-menu", + "menu button" + ); +} + +/** + * Asserts that a result other than our test result is selected. + * + * @param {number} expectedSelectedElementIndex + * The expected selected element index. + * @param {string} msg + * A string to include in the assertion message. + */ +function assertOtherResultSelected(expectedSelectedElementIndex, msg) { + Assert.equal( + UrlbarTestUtils.getSelectedElementIndex(window), + expectedSelectedElementIndex, + "Expected other selected element index: " + msg + ); +} |