/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Tests UrlbarProviderTabToSearch. See also * browser/components/urlbar/tests/browser/browser_tabToSearch.js */ "use strict"; let testEngine; add_task(async function init() { // Disable search suggestions for a less verbose test. Services.prefs.setBoolPref("browser.search.suggest.enabled", false); // Disable tab-to-search onboarding results. Those are covered in // browser/components/urlbar/tests/browser/browser_tabToSearch.js. Services.prefs.setIntPref( "browser.urlbar.tabToSearch.onboard.interactionsLeft", 0 ); await SearchTestUtils.installSearchExtension({ name: "Test" }); testEngine = await Services.search.getEngineByName("Test"); registerCleanupFunction(async () => { Services.prefs.clearUserPref( "browser.urlbar.tabToSearch.onboard.interactionsLeft" ); Services.prefs.clearUserPref("browser.search.suggest.enabled"); }); }); // Tests that tab-to-search results appear when the engine's result domain is // autofilled. add_task(async function basic() { await PlacesTestUtils.addVisits(["https://example.com/"]); let context = createContext("examp", { isPrivate: false }); await check_results({ context, autofilled: "example.com/", completed: "https://example.com/", matches: [ makeVisitResult(context, { uri: "https://example.com/", title: "test visit for https://example.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: testEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(testEngine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); info("Repeat the search but with tab-to-search disabled through pref."); Services.prefs.setBoolPref("browser.urlbar.suggest.engines", false); await check_results({ context, autofilled: "example.com/", completed: "https://example.com/", matches: [ makeVisitResult(context, { uri: "https://example.com/", title: "test visit for https://example.com/", heuristic: true, providerName: "Autofill", }), ], }); Services.prefs.clearUserPref("browser.urlbar.suggest.engines"); await cleanupPlaces(); }); // Tests that tab-to-search results are shown when the typed string matches an // engine domain even when there is no autofill. add_task(async function noAutofill() { // Note we are not adding any history visits. let context = createContext("examp", { isPrivate: false }); await check_results({ context, matches: [ makeSearchResult(context, { engineName: Services.search.defaultEngine.name, engineIconUri: Services.search.defaultEngine.iconURI?.spec, heuristic: true, providerName: "HeuristicFallback", }), makeSearchResult(context, { engineName: testEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(testEngine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); }); // Tests that tab-to-search results are not shown when the typed string matches // an engine domain, but something else is being autofilled. add_task(async function autofillDoesNotMatchEngine() { await PlacesTestUtils.addVisits(["https://example.test.ca/"]); let context = createContext("example", { isPrivate: false }); await check_results({ context, autofilled: "example.test.ca/", completed: "https://example.test.ca/", matches: [ makeVisitResult(context, { uri: "https://example.test.ca/", title: "test visit for https://example.test.ca/", heuristic: true, providerName: "Autofill", }), ], }); await cleanupPlaces(); }); // Tests that www. is ignored for the purposes of matching autofill to // tab-to-search. add_task(async function ignoreWww() { // The history result has www., the engine does not. await PlacesTestUtils.addVisits(["https://www.example.com/"]); let context = createContext("www.examp", { isPrivate: false }); await check_results({ context, autofilled: "www.example.com/", completed: "https://www.example.com/", matches: [ makeVisitResult(context, { uri: "https://www.example.com/", title: "test visit for https://www.example.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: testEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(testEngine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); await cleanupPlaces(); // The engine has www., the history result does not. await PlacesTestUtils.addVisits(["https://foo.bar/"]); let extension = await SearchTestUtils.installSearchExtension( { name: "TestWww", search_url: "https://www.foo.bar/", }, { skipUnload: true } ); let wwwTestEngine = Services.search.getEngineByName("TestWww"); context = createContext("foo", { isPrivate: false }); await check_results({ context, autofilled: "foo.bar/", completed: "https://foo.bar/", matches: [ makeVisitResult(context, { uri: "https://foo.bar/", title: "test visit for https://foo.bar/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: wwwTestEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost( wwwTestEngine.searchUrlDomain ), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); await cleanupPlaces(); // Both the engine and the history result have www. await PlacesTestUtils.addVisits(["https://www.foo.bar/"]); context = createContext("foo", { isPrivate: false }); await check_results({ context, autofilled: "foo.bar/", completed: "https://www.foo.bar/", matches: [ makeVisitResult(context, { uri: "https://www.foo.bar/", title: "test visit for https://www.foo.bar/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: wwwTestEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost( wwwTestEngine.searchUrlDomain ), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); await cleanupPlaces(); await extension.unload(); }); // Tests that when a user's query causes autofill to replace one engine's domain // with another, the correct tab-to-search results are shown. add_task(async function conflictingEngines() { for (let i = 0; i < 3; i++) { await PlacesTestUtils.addVisits([ "https://foobar.com/", "https://foo.com/", ]); } let extension1 = await SearchTestUtils.installSearchExtension( { name: "TestFooBar", search_url: "https://foobar.com/", }, { skipUnload: true } ); let extension2 = await SearchTestUtils.installSearchExtension( { name: "TestFoo", search_url: "https://foo.com/", }, { skipUnload: true } ); let fooBarTestEngine = Services.search.getEngineByName("TestFooBar"); let fooTestEngine = Services.search.getEngineByName("TestFoo"); // Search for "foo", autofilling foo.com. Observe that the foo.com // tab-to-search result is shown, even though the foobar.com engine was added // first (and thus enginesForDomainPrefix puts it earlier in its returned // array.) let context = createContext("foo", { isPrivate: false }); await check_results({ context, autofilled: "foo.com/", completed: "https://foo.com/", matches: [ makeVisitResult(context, { uri: "https://foo.com/", title: "test visit for https://foo.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: fooTestEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost( fooTestEngine.searchUrlDomain ), providesSearchMode: true, query: "", providerName: "TabToSearch", }), makeVisitResult(context, { uri: "https://foobar.com/", title: "test visit for https://foobar.com/", providerName: "Places", }), ], }); // Search for "foob", autofilling foobar.com. Observe that the foo.com // tab-to-search result is replaced with the foobar.com tab-to-search result. context = createContext("foob", { isPrivate: false }); await check_results({ context, autofilled: "foobar.com/", completed: "https://foobar.com/", matches: [ makeVisitResult(context, { uri: "https://foobar.com/", title: "test visit for https://foobar.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: fooBarTestEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost( fooBarTestEngine.searchUrlDomain ), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); await cleanupPlaces(); await extension1.unload(); await extension2.unload(); }); add_task(async function multipleEnginesForHostname() { info( "In case of multiple engines only one tab-to-search result should be returned" ); let extension = await SearchTestUtils.installSearchExtension( { name: "TestMaps", search_url: "https://example.com/maps/", }, { skipUnload: true } ); let context = createContext("examp", { isPrivate: false }); let maxResultCount = UrlbarPrefs.get("maxRichResults"); // Add enough visits to autofill example.com. for (let i = 0; i < maxResultCount; i++) { await PlacesTestUtils.addVisits("https://example.com/"); } // Add enough visits to other URLs matching our query to fill up the list of // results. let otherVisitResults = []; for (let i = 0; i < maxResultCount; i++) { let url = "https://mochi.test:8888/example/" + i; await PlacesTestUtils.addVisits(url); otherVisitResults.unshift( makeVisitResult(context, { uri: url, title: "test visit for " + url, }) ); } await check_results({ context, autofilled: "example.com/", completed: "https://example.com/", matches: [ makeVisitResult(context, { uri: "https://example.com/", title: "test visit for https://example.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: testEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(testEngine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), // There should be `maxResultCount` - 2 other visit results. If this fails // because there are actually `maxResultCount` - 3 other results, then the // muxer is improperly including both TabToSearch results in its // calculation of the total available result span instead of only one, so // one fewer visit result appears than expected. ...otherVisitResults.slice(0, maxResultCount - 2), ], }); await cleanupPlaces(); await extension.unload(); }); add_task(async function test_casing() { info("Tab-to-search results appear also in case of different casing."); await PlacesTestUtils.addVisits(["https://example.com/"]); let context = createContext("eXAm", { isPrivate: false }); await check_results({ context, autofilled: "eXAmple.com/", completed: "https://example.com/", matches: [ makeVisitResult(context, { uri: "https://example.com/", title: "test visit for https://example.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: testEngine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(testEngine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); await cleanupPlaces(); }); add_task(async function test_publicSuffix() { info("Tab-to-search results appear also in case of partial host match."); let extension = await SearchTestUtils.installSearchExtension( { name: "MyTest", search_url: "https://test.mytest.it/", }, { skipUnload: true } ); let engine = Services.search.getEngineByName("MyTest"); await PlacesTestUtils.addVisits(["https://test.mytest.it/"]); let context = createContext("my", { isPrivate: false }); await check_results({ context, matches: [ makeSearchResult(context, { engineName: Services.search.defaultEngine.name, engineIconUri: Services.search.defaultEngine.iconURI?.spec, heuristic: true, providerName: "HeuristicFallback", }), makeSearchResult(context, { engineName: engine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(engine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", satisfiesAutofillThreshold: true, }), makeVisitResult(context, { uri: "https://test.mytest.it/", title: "test visit for https://test.mytest.it/", providerName: "Places", }), ], }); await cleanupPlaces(); await extension.unload(); }); add_task(async function test_publicSuffixIsHost() { info("Tab-to-search results does not appear in case we autofill a suffix."); let extension = await SearchTestUtils.installSearchExtension( { name: "SuffixTest", search_url: "https://somesuffix.com.mx/", }, { skipUnload: true } ); // The top level domain will be autofilled, not the full domain. await PlacesTestUtils.addVisits(["https://com.mx/"]); let context = createContext("co", { isPrivate: false }); await check_results({ context, autofilled: "com.mx/", completed: "https://com.mx/", matches: [ makeVisitResult(context, { uri: "https://com.mx/", title: "test visit for https://com.mx/", heuristic: true, providerName: "Autofill", }), ], }); await cleanupPlaces(); await extension.unload(); }); add_task(async function test_disabledEngine() { info("Tab-to-search results does not appear for a Pref-disabled engine."); let extension = await SearchTestUtils.installSearchExtension( { name: "Disabled", search_url: "https://disabled.com/", }, { skipUnload: true } ); let engine = Services.search.getEngineByName("Disabled"); await PlacesTestUtils.addVisits(["https://disabled.com/"]); let context = createContext("dis", { isPrivate: false }); info("Sanity check that the engine would appear."); await check_results({ context, autofilled: "disabled.com/", completed: "https://disabled.com/", matches: [ makeVisitResult(context, { uri: "https://disabled.com/", title: "test visit for https://disabled.com/", heuristic: true, providerName: "Autofill", }), makeSearchResult(context, { engineName: engine.name, engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS, uri: UrlbarUtils.stripPublicSuffixFromHost(engine.searchUrlDomain), providesSearchMode: true, query: "", providerName: "TabToSearch", }), ], }); info("Now disable the engine."); Services.prefs.setCharPref("browser.search.hiddenOneOffs", engine.name); await check_results({ context, autofilled: "disabled.com/", completed: "https://disabled.com/", matches: [ makeVisitResult(context, { uri: "https://disabled.com/", title: "test visit for https://disabled.com/", heuristic: true, providerName: "Autofill", }), ], }); Services.prefs.clearUserPref("browser.search.hiddenOneOffs"); await cleanupPlaces(); await extension.unload(); });