From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../urlbar/tests/browser/browser_hideHeuristic.js | 513 +++++++++++++++++++++ 1 file changed, 513 insertions(+) create mode 100644 browser/components/urlbar/tests/browser/browser_hideHeuristic.js (limited to 'browser/components/urlbar/tests/browser/browser_hideHeuristic.js') diff --git a/browser/components/urlbar/tests/browser/browser_hideHeuristic.js b/browser/components/urlbar/tests/browser/browser_hideHeuristic.js new file mode 100644 index 0000000000..e8f8774e01 --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_hideHeuristic.js @@ -0,0 +1,513 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Basic smoke tests for the `browser.urlbar.experimental.hideHeuristic` pref, +// which hides the heuristic result. Each task performs a search that triggers a +// specific heuristic, verifies that it's hidden or shown as appropriate, and +// verifies that it's picked when enter is pressed. +// +// If/when it becomes the default, we should update existing tests as necessary +// and remove this one. + +"use strict"; + +// Allow more time for Mac machines so they don't time out in verify mode. +if (AppConstants.platform == "macosx") { + requestLongerTimeout(3); +} + +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.experimental.hideHeuristic", true], + ["browser.urlbar.suggest.quickactions", false], + ], + }); + await PlacesUtils.bookmarks.eraseEverything(); + await PlacesUtils.history.clear(); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_EXTENSION should be hidden. +add_task(async function extension() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Add an extension provider that returns a heuristic. + let url = "http://example.com/extension-test"; + let provider = new UrlbarTestUtils.TestProvider({ + name: "ExtensionTest", + type: UrlbarUtils.PROVIDER_TYPE.EXTENSION, + results: [ + Object.assign( + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, + { + url, + title: "Test", + } + ), + { heuristic: true } + ), + ], + }); + UrlbarProvidersManager.registerProvider(provider); + + // Do a search that fetches the provider's result and check it. + let heuristic = await search({ + value: "test", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_EXTENSION, + }); + Assert.equal(heuristic.payload.url, url, "Heuristic URL is correct"); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad(url); + + UrlbarProvidersManager.unregisterProvider(provider); + }); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_OMNIBOX should be hidden. +add_task(async function omnibox() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + // Load an extension. + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + omnibox: { + keyword: "omniboxtest", + }, + }, + background() { + /* global browser */ + browser.omnibox.onInputEntered.addListener(() => { + browser.test.sendMessage("onInputEntered"); + }); + }, + }); + await extension.startup(); + + // Do a search using the omnibox keyword and check the hidden heuristic + // result. + let heuristic = await search({ + value: "omniboxtest foo", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_OMNIBOX, + }); + Assert.equal( + heuristic.payload.keyword, + "omniboxtest", + "Heuristic keyword is correct" + ); + + // Press enter to verify the heuristic result is picked. + let messagePromise = extension.awaitMessage("onInputEntered"); + EventUtils.synthesizeKey("KEY_Enter"); + await messagePromise; + + await extension.unload(); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_SEARCH_TIP should be shown. +add_task(async function searchTip() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.searchTips.test.ignoreShowLimits", true]], + }); + await BrowserTestUtils.withNewTab( + { + gBrowser: window.gBrowser, + url: "about:newtab", + // `withNewTab` hangs waiting for about:newtab to load without this. + waitForLoad: false, + }, + async () => { + await UrlbarTestUtils.promisePopupOpen(window, () => {}); + Assert.ok(true, "View opened"); + Assert.equal(UrlbarTestUtils.getResultCount(window), 1); + let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 0); + Assert.equal(result.type, UrlbarUtils.RESULT_TYPE.TIP); + Assert.ok(result.heuristic); + Assert.ok(UrlbarTestUtils.getSelectedElement(window), "Selection exists"); + } + ); + await SpecialPowers.popPrefEnv(); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_ENGINE_ALIAS should be hidden. +add_task(async function engineAlias() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Add an engine with an alias. + await withEngine({ keyword: "test" }, async () => { + // Do a search using the alias and check the hidden heuristic result. + // The heuristic will be HEURISTIC_FALLBACK, not HEURISTIC_ENGINE_ALIAS, + // because two searches are performed and + // `UrlbarTestUtils.promiseAutocompleteResultPopup` waits for both. The + // first returns a HEURISTIC_ENGINE_ALIAS that triggers search mode and + // then an immediate second search, which returns HEURISTIC_FALLBACK. + let heuristic = await search({ + value: "test foo", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK, + }); + Assert.equal( + heuristic.payload.engine, + "Example", + "Heuristic engine is correct" + ); + Assert.equal( + heuristic.payload.query, + "foo", + "Heuristic query is correct" + ); + await UrlbarTestUtils.assertSearchMode(window, { + engineName: "Example", + entry: "typed", + }); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad("https://example.com/?q=foo"); + }); + }); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_BOOKMARK_KEYWORD should be hidden. +add_task(async function bookmarkKeyword() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Add a bookmark with a keyword. + let keyword = "bm"; + let bm = await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + url: "http://example.com/?q=%s", + title: "test", + }); + await PlacesUtils.keywords.insert({ keyword, url: bm.url }); + + // Do a search using the keyword and check the hidden heuristic result. + let heuristic = await search({ + value: "bm foo", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_BOOKMARK_KEYWORD, + }); + Assert.equal( + heuristic.payload.keyword, + keyword, + "Heuristic keyword is correct" + ); + let heuristicURL = "http://example.com/?q=foo"; + Assert.equal( + heuristic.payload.url, + heuristicURL, + "Heuristic URL is correct" + ); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad(heuristicURL); + + await PlacesUtils.bookmarks.eraseEverything(); + await UrlbarTestUtils.formHistory.clear(window); + }); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_AUTOFILL should be hidden. +add_task(async function autofill() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Do a search that triggers autofill and check the hidden heuristic + // result. + let heuristic = await search({ + value: "ex", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_AUTOFILL, + }); + Assert.ok(heuristic.autofill, "Heuristic is autofill"); + let heuristicURL = "http://example.com/"; + Assert.equal( + heuristic.payload.url, + heuristicURL, + "Heuristic URL is correct" + ); + Assert.equal(gURLBar.value, "example.com/", "Input has been autofilled"); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad(heuristicURL); + }); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK with an unknown URL should be +// hidden. +add_task(async function fallback_unknownURL() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + // Do a search for an unknown URL and check the hidden heuristic result. + let url = "http://example.com/unknown-url"; + let heuristic = await search({ + value: url, + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK, + }); + Assert.equal(heuristic.payload.url, url, "Heuristic URL is correct"); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad(url); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK with the search restriction token +// should be hidden. +add_task(async function fallback_searchRestrictionToken() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Add a mock default engine so we don't hit the network. + await withEngine({ makeDefault: true }, async () => { + // Do a search with `?` and check the hidden heuristic result. + let heuristic = await search({ + value: UrlbarTokenizer.RESTRICT.SEARCH + " foo", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK, + }); + Assert.equal( + heuristic.payload.engine, + "Example", + "Heuristic engine is correct" + ); + Assert.equal( + heuristic.payload.query, + "foo", + "Heuristic query is correct" + ); + await UrlbarTestUtils.assertSearchMode(window, { + engineName: "Example", + entry: "typed", + }); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad("https://example.com/?q=foo"); + + await UrlbarTestUtils.formHistory.clear(window); + }); + }); + }); +}); + +// UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK with a search string that falls +// back to a search result should be hidden. +add_task(async function fallback_search() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Add a mock default engine so we don't hit the network. + await withEngine({ makeDefault: true }, async () => { + // Do a search and check the hidden heuristic result. + let heuristic = await search({ + value: "foo", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK, + }); + Assert.equal( + heuristic.payload.engine, + "Example", + "Heuristic engine is correct" + ); + Assert.equal( + heuristic.payload.query, + "foo", + "Heuristic query is correct" + ); + + // Check the other visit results. + await checkVisitResults(visitURLs); + + // Press enter to verify the heuristic result is loaded. + await synthesizeEnterAndAwaitLoad("https://example.com/?q=foo"); + + await UrlbarTestUtils.formHistory.clear(window); + }); + }); + }); +}); + +// Picking a non-heuristic result should work correctly (and not pick the +// heuristic). +add_task(async function pickNonHeuristic() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await withVisits(async visitURLs => { + // Do a search that triggers autofill and check the hidden heuristic + // result. + let heuristic = await search({ + value: "ex", + expectedGroup: UrlbarUtils.RESULT_GROUP.HEURISTIC_AUTOFILL, + }); + Assert.ok(heuristic.autofill, "Heuristic is autofill"); + Assert.equal( + heuristic.payload.url, + "http://example.com/", + "Heuristic URL is correct" + ); + + // Pick the first visit result. + Assert.notEqual( + heuristic.payload.url, + visitURLs[0], + "Sanity check: Heuristic and first results have different URLs" + ); + EventUtils.synthesizeKey("KEY_ArrowDown"); + await synthesizeEnterAndAwaitLoad(visitURLs[0]); + }); + }); +}); + +/** + * Adds `maxRichResults` visits, calls your callback, and clears history. We add + * `maxRichResults` visits to verify that the view correctly contains the + * maximum number of results when the heuristic is hidden. + * + * @param {Function} callback + * The callback to call after adding visits. Can be async + */ +async function withVisits(callback) { + let urls = []; + for (let i = 0; i < UrlbarPrefs.get("maxRichResults"); i++) { + urls.push("http://example.com/foo/" + i); + } + await PlacesTestUtils.addVisits(urls); + + // The URLs will appear in the view in reverse order so that newer visits are + // first. Reverse the array now so callers to `checkVisitResults` or + // `checkVisitResults` itself doesn't need to do it. + urls.reverse(); + + await callback(urls); + await PlacesUtils.history.clear(); +} + +/** + * Adds a search engine, calls your callback, and removes the engine. + * + * @param {object} options + * Options object + * @param {string} [options.keyword] + * The keyword/alias for the engine. + * @param {boolean} [options.makeDefault] + * Whether to make the engine default. + * @param {Function} callback + * The callback to call after changing the default search engine. Can be async + */ +async function withEngine( + { keyword = undefined, makeDefault = false }, + callback +) { + await SearchTestUtils.installSearchExtension({ keyword }); + let engine = Services.search.getEngineByName("Example"); + let originalEngine; + if (makeDefault) { + originalEngine = await Services.search.getDefault(); + await Services.search.setDefault( + engine, + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); + } + await callback(); + if (originalEngine) { + await Services.search.setDefault( + originalEngine, + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); + } + await Services.search.removeEngine(engine); +} + +/** + * Asserts the view contains visit results with the given URLs. + * + * @param {Array} expectedURLs + * The expected urls. + */ +async function checkVisitResults(expectedURLs) { + Assert.equal( + UrlbarTestUtils.getResultCount(window), + expectedURLs.length, + "The view has other results" + ); + for (let i = 0; i < expectedURLs.length; i++) { + let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i); + Assert.equal( + result.type, + UrlbarUtils.RESULT_TYPE.URL, + "Other result type is correct at index " + i + ); + Assert.equal( + result.source, + UrlbarUtils.RESULT_SOURCE.HISTORY, + "Other result source is correct at index " + i + ); + Assert.equal( + result.url, + expectedURLs[i], + "Other result URL is correct at index " + i + ); + } +} + +/** + * Performs a search and makes some basic assertions under the assumption that + * the heuristic should be hidden. + * + * @param {object} options + * Options object + * @param {string} options.value + * The search string. + * @param {UrlbarUtils.RESULT_GROUP} options.expectedGroup + * The expected result group of the hidden heuristic. + * @returns {UrlbarResult} + * The hidden heuristic result. + */ +async function search({ value, expectedGroup }) { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + waitForFocus, + value, + fireInputEvent: true, + }); + + // _resultForCurrentValue should be the hidden heuristic result. + let { _resultForCurrentValue: result } = gURLBar; + Assert.ok(result, "_resultForCurrentValue is defined"); + Assert.ok(result.heuristic, "_resultForCurrentValue.heuristic is true"); + Assert.equal( + UrlbarUtils.getResultGroup(result), + expectedGroup, + "_resultForCurrentValue has expected group" + ); + + Assert.ok(!UrlbarTestUtils.getSelectedElement(window), "No selection exists"); + + return result; +} + +/** + * Synthesizes the enter key and waits for a load in the current tab. + * + * @param {string} expectedURL + * The URL that should load. + */ +async function synthesizeEnterAndAwaitLoad(expectedURL) { + let loadPromise = BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + expectedURL + ); + EventUtils.synthesizeKey("KEY_Enter"); + await loadPromise; + await PlacesUtils.history.clear(); +} -- cgit v1.2.3