summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_searchMode_preview.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_searchMode_preview.js')
-rw-r--r--browser/components/urlbar/tests/browser/browser_searchMode_preview.js489
1 files changed, 489 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_searchMode_preview.js b/browser/components/urlbar/tests/browser/browser_searchMode_preview.js
new file mode 100644
index 0000000000..19df744663
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_searchMode_preview.js
@@ -0,0 +1,489 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests search mode preview.
+ */
+
+"use strict";
+
+const TEST_ENGINE_NAME = "Test";
+
+add_setup(async function () {
+ await SearchTestUtils.installSearchExtension({
+ name: TEST_ENGINE_NAME,
+ keyword: "@test",
+ });
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.urlbar.suggest.quickactions", false]],
+ });
+
+ registerCleanupFunction(async () => {
+ await PlacesUtils.history.clear();
+ });
+});
+
+/**
+ * @param {Node} button
+ * A one-off button.
+ * @param {boolean} [isPreview]
+ * Whether the expected search mode should be a preview. Defaults to true.
+ * @returns {object}
+ * The search mode object expected when that one-off is selected.
+ */
+function getExpectedSearchMode(button, isPreview = true) {
+ let expectedSearchMode = {
+ entry: "oneoff",
+ isPreview,
+ };
+ if (button.engine) {
+ expectedSearchMode.engineName = button.engine.name;
+ let engine = Services.search.getEngineByName(button.engine.name);
+ if (engine.isGeneralPurposeEngine) {
+ expectedSearchMode.source = UrlbarUtils.RESULT_SOURCE.SEARCH;
+ }
+ } else {
+ expectedSearchMode.source = button.source;
+ }
+
+ return expectedSearchMode;
+}
+
+// Tests that cycling through token alias engines enters search mode preview.
+add_task(async function tokenAlias() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "@",
+ });
+
+ let result;
+ while (gURLBar.searchMode?.engineName != TEST_ENGINE_NAME) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ let index = UrlbarTestUtils.getSelectedRowIndex(window);
+ result = await UrlbarTestUtils.getDetailsOfResultAt(window, index);
+ let expectedSearchMode = {
+ engineName: result.searchParams.engine,
+ isPreview: true,
+ entry: "keywordoffer",
+ };
+ let engine = Services.search.getEngineByName(result.searchParams.engine);
+ if (engine.isGeneralPurposeEngine) {
+ expectedSearchMode.source = UrlbarUtils.RESULT_SOURCE.SEARCH;
+ }
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+ }
+ let searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeKey("KEY_Enter");
+ await searchPromise;
+ // Test that we are in confirmed search mode.
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: result.searchParams.engine,
+ entry: "keywordoffer",
+ });
+ await UrlbarTestUtils.exitSearchMode(window);
+});
+
+// Tests that starting to type a query exits search mode preview in favour of
+// full search mode.
+add_task(async function startTyping() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "@",
+ });
+ while (gURLBar.searchMode?.engineName != TEST_ENGINE_NAME) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: TEST_ENGINE_NAME,
+ isPreview: true,
+ entry: "keywordoffer",
+ });
+
+ let searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeKey("M");
+ await searchPromise;
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: TEST_ENGINE_NAME,
+ entry: "keywordoffer",
+ });
+ await UrlbarTestUtils.exitSearchMode(window);
+});
+
+// Tests that highlighting a search shortcut Top Site enters search mode
+// preview.
+add_task(async function topSites() {
+ // Enable search shortcut Top Sites.
+ await PlacesUtils.history.clear();
+ await updateTopSites(
+ sites => sites && sites[0] && sites[0].searchTopSite,
+ true
+ );
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ fireInputEvent: true,
+ });
+
+ // We previously verified that the first Top Site is a search shortcut.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ let searchTopSite = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: searchTopSite.searchParams.engine,
+ isPreview: true,
+ entry: "topsites_urlbar",
+ });
+ await UrlbarTestUtils.exitSearchMode(window);
+});
+
+// Tests that search mode preview is exited when the view is closed.
+add_task(async function closeView() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "@",
+ });
+
+ while (gURLBar.searchMode?.engineName != TEST_ENGINE_NAME) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: TEST_ENGINE_NAME,
+ isPreview: true,
+ entry: "keywordoffer",
+ });
+
+ // We should close search mode when closing the view.
+ await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
+ await UrlbarTestUtils.assertSearchMode(window, null);
+
+ // Check search mode isn't re-entered when re-opening the view.
+ await UrlbarTestUtils.promisePopupOpen(window, () => {
+ if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+ gURLBar.handleRevert();
+ }
+ EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {});
+ });
+ await UrlbarTestUtils.assertSearchMode(window, null);
+ await UrlbarTestUtils.promisePopupClose(window);
+});
+
+// Tests that search more preview is exited when the user switches tabs.
+add_task(async function tabSwitch() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "@",
+ });
+
+ while (gURLBar.searchMode?.engineName != TEST_ENGINE_NAME) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: TEST_ENGINE_NAME,
+ isPreview: true,
+ entry: "keywordoffer",
+ });
+
+ // Open a new tab then switch back to the original tab.
+ let tab1 = gBrowser.selectedTab;
+ let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser);
+ await BrowserTestUtils.switchTab(gBrowser, tab1);
+
+ await UrlbarTestUtils.assertSearchMode(window, null);
+ BrowserTestUtils.removeTab(tab2);
+});
+
+// Tests that search mode is previewed when the user down arrows through the
+// one-offs.
+add_task(async function oneOff_downArrow() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ let oneOffs = UrlbarTestUtils.getOneOffSearchButtons(window);
+ await TestUtils.waitForCondition(
+ () => !oneOffs._rebuilding,
+ "Waiting for one-offs to finish rebuilding"
+ );
+ let resultCount = UrlbarTestUtils.getResultCount(window);
+
+ // Key down through all results.
+ for (let i = 0; i < resultCount; i++) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+
+ // Key down again. The first one-off should be selected.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+
+ // Check for the one-off's search mode previews.
+ while (oneOffs.selectedButton != oneOffs.settingsButton) {
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton)
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+
+ // Check that selecting the search settings button leaves search mode preview.
+ Assert.equal(
+ oneOffs.selectedButton,
+ oneOffs.settingsButton,
+ "The settings button is selected."
+ );
+ await UrlbarTestUtils.assertSearchMode(window, null);
+
+ // Closing the view should also exit search mode preview.
+ await UrlbarTestUtils.promisePopupClose(window);
+ await UrlbarTestUtils.assertSearchMode(window, null);
+});
+
+// Tests that search mode is previewed when the user Alt+down arrows through the
+// one-offs. This subtest also highlights a keywordoffer result (the first Top
+// Site) before Alt+Arrowing to the one-offs. This checks that the search mode
+// previews from keywordoffer results are overwritten by selected one-offs.
+add_task(async function oneOff_alt_downArrow() {
+ // Add some visits to a URL so we have multiple Top Sites.
+ await PlacesUtils.history.clear();
+ for (let i = 0; i < 5; i++) {
+ await PlacesTestUtils.addVisits("https://example.com/");
+ }
+ await updateTopSites(
+ sites =>
+ sites &&
+ sites[0]?.searchTopSite &&
+ sites[1]?.url == "https://example.com/",
+ true
+ );
+
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ let oneOffs = UrlbarTestUtils.getOneOffSearchButtons(window);
+ await TestUtils.waitForCondition(
+ () => !oneOffs._rebuilding,
+ "Waiting for one-offs to finish rebuilding"
+ );
+
+ // Key down to the first result and check that it enters search mode preview.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ let searchTopSite = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: searchTopSite.searchParams.engine,
+ isPreview: true,
+ entry: "topsites_urlbar",
+ });
+
+ // Alt+down. The first one-off should be selected.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ // Check for the one-offs' search mode previews.
+ while (oneOffs.selectedButton) {
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton)
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ }
+
+ // Now key down without a modifier. We should move to the second result and
+ // have no search mode preview.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ Assert.equal(
+ UrlbarTestUtils.getSelectedRowIndex(window),
+ 1,
+ "The second result is selected."
+ );
+ await UrlbarTestUtils.assertSearchMode(window, null);
+
+ // Arrow back up to the keywordoffer result and check for search mode preview.
+ EventUtils.synthesizeKey("KEY_ArrowUp");
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: searchTopSite.searchParams.engine,
+ isPreview: true,
+ entry: "topsites_urlbar",
+ });
+
+ await PlacesUtils.history.clear();
+ await UrlbarTestUtils.promisePopupClose(window);
+ await UrlbarTestUtils.assertSearchMode(window, null);
+});
+
+// Tests that search mode is previewed when the user is in full search mode
+// and down arrows through the one-offs.
+add_task(async function fullSearchMode_oneOff_downArrow() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ let oneOffs = UrlbarTestUtils.getOneOffSearchButtons(window);
+ await TestUtils.waitForCondition(
+ () => !oneOffs._rebuilding,
+ "Waiting for one-offs to finish rebuilding"
+ );
+ let oneOffButtons = oneOffs.getSelectableButtons(true);
+
+ await UrlbarTestUtils.enterSearchMode(window);
+ let expectedSearchMode = getExpectedSearchMode(oneOffButtons[0], false);
+ // Sanity check: we are in the correct search mode.
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+
+ // Key down through all results.
+ let resultCount = UrlbarTestUtils.getResultCount(window);
+ for (let i = 0; i < resultCount; i++) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ // If the result is a shortcut, it will enter preview mode.
+ let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i);
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ Object.assign(expectedSearchMode, {
+ isPreview: !!result.searchParams.keyword,
+ })
+ );
+ }
+
+ // Key down again. The first one-off should be selected.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ // Check that we show the correct preview as we cycle through the one-offs.
+ while (oneOffs.selectedButton != oneOffs.settingsButton) {
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton, true)
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+
+ // We should still be in the same search mode after cycling through all the
+ // one-offs.
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+ await UrlbarTestUtils.exitSearchMode(window);
+ await UrlbarTestUtils.promisePopupClose(window);
+});
+
+// Tests that search mode is previewed when the user is in full search mode
+// and alt+down arrows through the one-offs. This subtest also checks that
+// exiting full search mode while alt+arrowing through the one-offs enters
+// search mode preview for subsequent one-offs.
+add_task(async function fullSearchMode_oneOff_alt_downArrow() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ let oneOffs = UrlbarTestUtils.getOneOffSearchButtons(window);
+ let oneOffButtons = oneOffs.getSelectableButtons(true);
+ await TestUtils.waitForCondition(
+ () => !oneOffs._rebuilding,
+ "Waiting for one-offs to finish rebuilding"
+ );
+
+ await UrlbarTestUtils.enterSearchMode(window);
+ let expectedSearchMode = getExpectedSearchMode(oneOffButtons[0], false);
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+
+ // Key down to the first result.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+
+ // Alt+down. The first one-off should be selected.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ // Cycle through the first half of the one-offs and verify that search mode
+ // preview is entered.
+ Assert.greater(
+ oneOffButtons.length,
+ 1,
+ "Sanity check: We should have at least two one-offs."
+ );
+ for (let i = 1; i < oneOffButtons.length / 2; i++) {
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton, true)
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ }
+ // Now click out of search mode.
+ await UrlbarTestUtils.exitSearchMode(window, { clickClose: true });
+ // Now check for the remaining one-offs' search mode previews.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ while (oneOffs.selectedButton) {
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton, true)
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ }
+
+ await UrlbarTestUtils.promisePopupClose(window);
+ await UrlbarTestUtils.assertSearchMode(window, null);
+});
+
+// Tests that the original search mode is preserved when going through some
+// one-off buttons and then back down in the results list.
+add_task(async function fullSearchMode_oneOff_restore_on_down() {
+ info("Add a few visits to top sites");
+ for (let i = 0; i < 5; i++) {
+ await PlacesTestUtils.addVisits([
+ "https://1.example.com/",
+ "https://2.example.com/",
+ "https://3.example.com/",
+ ]);
+ }
+ await updateTopSites(sites => sites?.length > 2, false);
+
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ let oneOffs = UrlbarTestUtils.getOneOffSearchButtons(window);
+ let oneOffButtons = oneOffs.getSelectableButtons(true);
+ await TestUtils.waitForCondition(
+ () => !oneOffs._rebuilding,
+ "Waiting for one-offs to finish rebuilding"
+ );
+
+ await UrlbarTestUtils.enterSearchMode(window, {
+ source: UrlbarUtils.RESULT_SOURCE.HISTORY,
+ });
+ let expectedSearchMode = getExpectedSearchMode(
+ oneOffButtons.find(b => b.source == UrlbarUtils.RESULT_SOURCE.HISTORY),
+ false
+ );
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+ info("Down to the first result");
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+ info("Alt+down to the first one-off.");
+ Assert.greater(
+ oneOffButtons.length,
+ 1,
+ "Sanity check: We should have at least two one-offs."
+ );
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton, true)
+ );
+ info("Go again down through the list of results");
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ await UrlbarTestUtils.assertSearchMode(window, expectedSearchMode);
+
+ // Now do a similar test without initial search mode.
+ info("Exit search mode.");
+ await UrlbarTestUtils.exitSearchMode(window);
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "",
+ });
+ info("Down to the first result");
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ await UrlbarTestUtils.assertSearchMode(window, null);
+ info("select a one-off to start preview");
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await UrlbarTestUtils.assertSearchMode(
+ window,
+ getExpectedSearchMode(oneOffs.selectedButton, true)
+ );
+ info("Go again through the list of results");
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ await UrlbarTestUtils.assertSearchMode(window, null);
+
+ await UrlbarTestUtils.promisePopupClose(window);
+ await PlacesUtils.history.clear();
+});