From 24042ff483160c6932c33065694e3e1a81e0f8af Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Mon, 14 Sep 2020 17:05:08 +0000 Subject: [PATCH] Bug 1662509 - Add a pref to experiment with zero-prefix search in search mode. r=harry Differential Revision: https://phabricator.services.mozilla.com/D89914 --- browser/app/profile/firefox.js | 5 + browser/components/urlbar/UrlbarPrefs.jsm | 6 + .../UrlbarProviderSearchSuggestions.jsm | 16 +- .../urlbar/UrlbarProviderUnifiedComplete.jsm | 7 + .../urlbar/tests/browser/browser.ini | 7 + .../browser/browser_searchMode_suggestions.js | 51 +++ .../browser/browser_separatePrivateDefault.js | 283 +------------ ..._separatePrivateDefault_differentEngine.js | 385 ++++++++++++++++++ 8 files changed, 474 insertions(+), 286 deletions(-) create mode 100644 browser/components/urlbar/tests/browser/browser_separatePrivateDefault_differentEngine.js diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index a28d16c01252..6246282a0b42 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -355,6 +355,11 @@ pref("browser.urlbar.update2.localOneOffs", false); pref("browser.urlbar.update2.oneOffsRefresh", false); #endif +// Controls the empty search behavior in Search Mode: +// 0 - Show nothing +// 1 - Show search history +// 2 - Show search and browsing history +pref("browser.urlbar.update2.emptySearchBehavior", 2); // Whether we display a tab-to-complete result when the user types an engine // name. pref("browser.urlbar.update2.tabToComplete", false); diff --git a/browser/components/urlbar/UrlbarPrefs.jsm b/browser/components/urlbar/UrlbarPrefs.jsm index cffefb0f6269..44eca9a42ee7 100644 --- a/browser/components/urlbar/UrlbarPrefs.jsm +++ b/browser/components/urlbar/UrlbarPrefs.jsm @@ -167,6 +167,12 @@ const PREF_URLBAR_DEFAULTS = new Map([ // one-off buttons. ["update2.disableOneOffsHorizontalKeyNavigation", false], + // Controls the empty search behavior in Search Mode: + // 0 - Show nothing + // 1 - Show search history + // 2 - Show search and browsing history + ["update2.emptySearchBehavior", 2], + // Whether the urlbar displays one-offs to filter searches to history, // bookmarks, or tabs. ["update2.localOneOffs", false], diff --git a/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm b/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm index 0d9d0d282f30..97f567f4b7ae 100644 --- a/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm +++ b/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm @@ -95,11 +95,17 @@ class ProviderSearchSuggestions extends UrlbarProvider { return false; } - return ( - this._allowSuggestions(queryContext) && - (UrlbarPrefs.get("maxHistoricalSearchSuggestions") || - this._allowRemoteSuggestions(queryContext)) - ); + if (!this._allowSuggestions(queryContext)) { + return false; + } + + let wantsLocalSuggestions = + UrlbarPrefs.get("maxHistoricalSearchSuggestions") && + (!UrlbarPrefs.get("update2") || + queryContext.trimmedSearchString || + UrlbarPrefs.get("update2.emptySearchBehavior") != 0); + + return wantsLocalSuggestions || this._allowRemoteSuggestions(queryContext); } /** diff --git a/browser/components/urlbar/UrlbarProviderUnifiedComplete.jsm b/browser/components/urlbar/UrlbarProviderUnifiedComplete.jsm index 1e4984a93869..dcbe5d16adf3 100644 --- a/browser/components/urlbar/UrlbarProviderUnifiedComplete.jsm +++ b/browser/components/urlbar/UrlbarProviderUnifiedComplete.jsm @@ -63,6 +63,13 @@ class ProviderUnifiedComplete extends UrlbarProvider { * @returns {boolean} Whether this provider should be invoked for the search. */ isActive(queryContext) { + if ( + !queryContext.trimmedSearchString && + UrlbarPrefs.get("update2") && + UrlbarPrefs.get("update2.emptySearchBehavior") < 2 + ) { + return false; + } return true; } diff --git a/browser/components/urlbar/tests/browser/browser.ini b/browser/components/urlbar/tests/browser/browser.ini index 9851e2c23e87..2ffb2d4da8b6 100644 --- a/browser/components/urlbar/tests/browser/browser.ini +++ b/browser/components/urlbar/tests/browser/browser.ini @@ -181,6 +181,13 @@ support-files = searchSuggestionEngine.xml searchSuggestionEngine.sjs [browser_separatePrivateDefault.js] +support-files = + POSTSearchEngine.xml + print_postdata.sjs + searchSuggestionEngine.xml + searchSuggestionEngine.sjs + searchSuggestionEngine2.xml +[browser_separatePrivateDefault_differentEngine.js] support-files = POSTSearchEngine.xml print_postdata.sjs diff --git a/browser/components/urlbar/tests/browser/browser_searchMode_suggestions.js b/browser/components/urlbar/tests/browser/browser_searchMode_suggestions.js index f33703fa6626..32fbfb8136c0 100644 --- a/browser/components/urlbar/tests/browser/browser_searchMode_suggestions.js +++ b/browser/components/urlbar/tests/browser/browser_searchMode_suggestions.js @@ -81,6 +81,9 @@ add_task(async function setup() { add_task(async function emptySearch() { await BrowserTestUtils.withNewTab("about:robots", async function(browser) { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.update2.emptySearchBehavior", 2]], + }); await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "", @@ -92,6 +95,7 @@ add_task(async function emptySearch() { await checkResults(expectedFormHistoryResults); await UrlbarTestUtils.exitSearchMode(window, { clickClose: true }); await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); }); }); @@ -108,6 +112,9 @@ add_task(async function emptySearch_withHistory() { }, ]); await BrowserTestUtils.withNewTab("about:robots", async function(browser) { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.update2.emptySearchBehavior", 2]], + }); await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "", @@ -134,6 +141,50 @@ add_task(async function emptySearch_withHistory() { await UrlbarTestUtils.exitSearchMode(window, { clickClose: true }); await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); + }); + + await PlacesUtils.history.clear(); +}); + +add_task(async function emptySearch_behavior() { + // URLs with the same host as the search engine. + await PlacesTestUtils.addVisits([`http://mochi.test/`]); + + await BrowserTestUtils.withNewTab("about:robots", async function(browser) { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.update2.emptySearchBehavior", 0]], + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "", + }); + await UrlbarTestUtils.enterSearchMode(window); + Assert.equal(gURLBar.value, "", "Urlbar value should be cleared."); + // For the empty search case, we expect to get the form history relative to + // the picked engine, history without redirects, and no heuristic. + await checkResults([]); + await UrlbarTestUtils.exitSearchMode(window, { clickClose: true }); + await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); + }); + + await BrowserTestUtils.withNewTab("about:robots", async function(browser) { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.update2.emptySearchBehavior", 1]], + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "", + }); + await UrlbarTestUtils.enterSearchMode(window); + Assert.equal(gURLBar.value, "", "Urlbar value should be cleared."); + // For the empty search case, we expect to get the form history relative to + // the picked engine, history without redirects, and no heuristic. + await checkResults([...expectedFormHistoryResults]); + await UrlbarTestUtils.exitSearchMode(window, { clickClose: true }); + await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); }); await PlacesUtils.history.clear(); diff --git a/browser/components/urlbar/tests/browser/browser_separatePrivateDefault.js b/browser/components/urlbar/tests/browser/browser_separatePrivateDefault.js index df3765fb85b4..25917e89aa94 100644 --- a/browser/components/urlbar/tests/browser/browser_separatePrivateDefault.js +++ b/browser/components/urlbar/tests/browser/browser_separatePrivateDefault.js @@ -4,6 +4,8 @@ "use strict"; // Tests the 'Search in a Private Window' result of the address bar. +// Tests here don't have a different private engine, for that see +// browser_separatePrivateDefault_differentPrivateEngine.js const serverInfo = { scheme: "http", @@ -211,284 +213,3 @@ add_task(async function test_oneoff_selected_mouse() { await BrowserTestUtils.closeWindow(win); await SpecialPowers.popPrefEnv(); }); - -// Tests from here on have a different default private engine. - -add_task(async function test_search_private_engine() { - info( - "Test that 'Search in a Private Window' reports a separate private engine" - ); - let engine = await SearchTestUtils.promiseNewSearchEngine( - getRootDirectory(gTestPath) + "searchSuggestionEngine2.xml" - ); - await Services.search.setDefaultPrivate(engine); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "unique198273982173", - }); - await AssertPrivateResult(window, engine, true); -}); - -add_task(async function test_privateWindow() { - info( - "Test that 'Search in a Private Window' does not appear in a private window" - ); - let privateWin = await BrowserTestUtils.openNewBrowserWindow({ - private: true, - }); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window: privateWin, - value: "unique198273982173", - }); - await AssertNoPrivateResult(privateWin); - await BrowserTestUtils.closeWindow(privateWin); -}); - -add_task(async function test_permanentPB() { - info( - "Test that 'Search in a Private Window' does not appear in Permanent Private Browsing" - ); - await SpecialPowers.pushPrefEnv({ - set: [["browser.privatebrowsing.autostart", true]], - }); - let win = await BrowserTestUtils.openNewBrowserWindow(); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window: win, - value: "unique198273982173", - }); - await AssertNoPrivateResult(win); - await BrowserTestUtils.closeWindow(win); - await SpecialPowers.popPrefEnv(); -}); - -add_task(async function test_openPBWindow() { - info( - "Test that 'Search in a Private Window' opens the search in a new Private Window" - ); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "unique198273982173", - }); - await AssertPrivateResult( - window, - await Services.search.getDefaultPrivate(), - true - ); - - await withHttpServer(serverInfo, async () => { - let promiseWindow = BrowserTestUtils.waitForNewWindow({ - url: "http://localhost:20709/?terms=unique198273982173", - maybeErrorPage: true, - }); - EventUtils.synthesizeKey("KEY_ArrowDown"); - EventUtils.synthesizeKey("VK_RETURN"); - let win = await promiseWindow; - Assert.ok( - PrivateBrowsingUtils.isWindowPrivate(win), - "Should open a private window" - ); - await BrowserTestUtils.closeWindow(win); - }); -}); - -// TODO: (Bug 1658620) Write a new subtest for this behaviour with the update2 -// pref on. -add_task(async function test_oneoff_selected_with_private_engine_mouse() { - info( - "Test that 'Search in a Private Window' opens the private engine even if a one-off is selected" - ); - await SpecialPowers.pushPrefEnv({ - set: [ - ["browser.urlbar.update2", false], - ["browser.urlbar.update2.oneOffsRefresh", false], - ], - }); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "unique198273982173", - }); - await AssertPrivateResult( - window, - await Services.search.getDefaultPrivate(), - true - ); - - await withHttpServer(serverInfo, async () => { - // Select the 'Search in a Private Window' result, alt down to select the - // first one-off button, Click on the result. It should open a pb window using - // the private search engine, because it has been set. - let promiseWindow = BrowserTestUtils.waitForNewWindow({ - url: "http://localhost:20709/?terms=unique198273982173", - maybeErrorPage: true, - }); - // Select the private result. - EventUtils.synthesizeKey("KEY_ArrowDown"); - // Select the first one-off button. - EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true }); - // Click on the result. - let element = UrlbarTestUtils.getSelectedRow(window); - EventUtils.synthesizeMouseAtCenter(element, {}); - let win = await promiseWindow; - Assert.ok( - PrivateBrowsingUtils.isWindowPrivate(win), - "Should open a private window" - ); - await BrowserTestUtils.closeWindow(win); - }); - await SpecialPowers.popPrefEnv(); -}); - -// TODO: (Bug 1658620) Write a new subtest for this behaviour with the update2 -// pref on. -add_task(async function test_oneoff_selected_with_private_engine_keyboard() { - info( - "Test that 'Search in a Private Window' opens the private engine even if a one-off is selected" - ); - await SpecialPowers.pushPrefEnv({ - set: [ - ["browser.urlbar.update2", false], - ["browser.urlbar.update2.oneOffsRefresh", false], - ], - }); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "unique198273982173", - }); - await AssertPrivateResult( - window, - await Services.search.getDefaultPrivate(), - true - ); - - await withHttpServer(serverInfo, async () => { - // Select the 'Search in a Private Window' result, alt down to select the - // first one-off button, Enter. It should open a pb window, but using the - // selected one-off engine. - let promiseWindow = BrowserTestUtils.waitForNewWindow({ - url: "http://localhost:20709/?terms=unique198273982173", - maybeErrorPage: true, - }); - // Select the private result. - EventUtils.synthesizeKey("KEY_ArrowDown"); - // Select the first one-off button. - EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true }); - EventUtils.synthesizeKey("VK_RETURN"); - let win = await promiseWindow; - Assert.ok( - PrivateBrowsingUtils.isWindowPrivate(win), - "Should open a private window" - ); - await BrowserTestUtils.closeWindow(win); - }); - await SpecialPowers.popPrefEnv(); -}); - -add_task(async function test_alias_no_query() { - await SpecialPowers.pushPrefEnv({ - set: [["browser.urlbar.update2", true]], - }); - info( - "Test that 'Search in a Private Window' doesn't appear if an alias is typed with no query" - ); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "alias ", - }); - // Wait for the second new search that starts when search mode is entered. - await UrlbarTestUtils.promiseSearchComplete(window); - await UrlbarTestUtils.assertSearchMode(window, { - engineName: aliasEngine.name, - entry: "typed", - }); - await AssertNoPrivateResult(window); - await UrlbarTestUtils.exitSearchMode(window); - await UrlbarTestUtils.promisePopupClose(window); - await SpecialPowers.popPrefEnv(); -}); - -add_task(async function test_alias_query() { - await SpecialPowers.pushPrefEnv({ - set: [["browser.urlbar.update2", true]], - }); - info( - "Test that 'Search in a Private Window' appears when an alias is typed with a query" - ); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "alias something", - }); - // Wait for the second new search that starts when search mode is entered. - await UrlbarTestUtils.promiseSearchComplete(window); - await UrlbarTestUtils.assertSearchMode(window, { - engineName: "MozSearch", - entry: "typed", - }); - await AssertPrivateResult(window, aliasEngine, true); - await UrlbarTestUtils.exitSearchMode(window); - await UrlbarTestUtils.promisePopupClose(window); - await SpecialPowers.popPrefEnv(); -}); - -add_task(async function test_alias_legacy() { - await SpecialPowers.pushPrefEnv({ - set: [["browser.urlbar.update2", false]], - }); - info( - "Test that 'Search in a Private Window' doesn't appear if an alias is typed" - ); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "alias", - }); - await AssertNoPrivateResult(window); - - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "alias something", - }); - await AssertNoPrivateResult(window); - await SpecialPowers.popPrefEnv(); -}); - -add_task(async function test_restrict() { - info( - "Test that 'Search in a Private Window' doesn's appear for just the restriction token" - ); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: UrlbarTokenizer.RESTRICT.SEARCH, - }); - await AssertNoPrivateResult(window); - - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: UrlbarTokenizer.RESTRICT.SEARCH + " ", - }); - await AssertNoPrivateResult(window); - - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: " " + UrlbarTokenizer.RESTRICT.SEARCH, - }); - await AssertNoPrivateResult(window); -}); - -add_task(async function test_restrict_search() { - info( - "Test that 'Search in a Private Window' has the right string with the restriction token" - ); - let engine = await Services.search.getDefaultPrivate(); - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: UrlbarTokenizer.RESTRICT.SEARCH + "test", - }); - let result = await AssertPrivateResult(window, engine, true); - Assert.equal(result.searchParams.query, "test"); - - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: "test" + UrlbarTokenizer.RESTRICT.SEARCH, - }); - result = await AssertPrivateResult(window, engine, true); - Assert.equal(result.searchParams.query, "test"); -}); diff --git a/browser/components/urlbar/tests/browser/browser_separatePrivateDefault_differentEngine.js b/browser/components/urlbar/tests/browser/browser_separatePrivateDefault_differentEngine.js new file mode 100644 index 000000000000..dba3516a7083 --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_separatePrivateDefault_differentEngine.js @@ -0,0 +1,385 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests the 'Search in a Private Window' result of the address bar. + +const serverInfo = { + scheme: "http", + host: "localhost", + port: 20709, // Must be identical to what is in searchSuggestionEngine2.xml +}; + +let gAliasEngine; +let gPrivateEngine; + +add_task(async function setup() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.search.separatePrivateDefault.ui.enabled", true], + ["browser.search.separatePrivateDefault", true], + ["browser.urlbar.suggest.searches", true], + ], + }); + + // Add some history for the empty panel. + await PlacesTestUtils.addVisits([ + { + uri: "http://example.com/", + transition: PlacesUtils.history.TRANSITIONS.TYPED, + }, + ]); + + // Add a search suggestion engine and move it to the front so that it appears + // as the first one-off. + let oldDefaultEngine = await Services.search.getDefault(); + let oldDefaultPrivateEngine = await Services.search.getDefaultPrivate(); + let engine = await SearchTestUtils.promiseNewSearchEngine( + getRootDirectory(gTestPath) + "searchSuggestionEngine.xml" + ); + await Services.search.setDefault(engine); + gPrivateEngine = await SearchTestUtils.promiseNewSearchEngine( + getRootDirectory(gTestPath) + "searchSuggestionEngine2.xml" + ); + await Services.search.setDefaultPrivate(gPrivateEngine); + + // Add another engine in the first one-off position. + let engine2 = await SearchTestUtils.promiseNewSearchEngine( + getRootDirectory(gTestPath) + "POSTSearchEngine.xml" + ); + await Services.search.moveEngine(engine2, 0); + + // Add an engine with an alias. + gAliasEngine = await Services.search.addEngineWithDetails("MozSearch", { + alias: "alias", + method: "GET", + template: "http://example.com/?q={searchTerms}", + }); + + registerCleanupFunction(async () => { + await Services.search.setDefault(oldDefaultEngine); + await Services.search.setDefaultPrivate(oldDefaultPrivateEngine); + await Services.search.removeEngine(gAliasEngine); + await PlacesUtils.history.clear(); + }); +}); + +async function AssertNoPrivateResult(win) { + let count = await UrlbarTestUtils.getResultCount(win); + Assert.ok(count > 0, "Sanity check result count"); + for (let i = 0; i < count; ++i) { + let result = await UrlbarTestUtils.getDetailsOfResultAt(win, i); + Assert.ok( + result.type != UrlbarUtils.RESULT_TYPE.SEARCH || + !result.searchParams.inPrivateWindow, + "Check this result is not a 'Search in a Private Window' one" + ); + } +} + +async function AssertPrivateResult(win, engine, isPrivateEngine) { + let count = await UrlbarTestUtils.getResultCount(win); + Assert.ok(count > 1, "Sanity check result count"); + let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 1); + Assert.equal( + result.type, + UrlbarUtils.RESULT_TYPE.SEARCH, + "Check result type" + ); + Assert.ok(result.searchParams.inPrivateWindow, "Check inPrivateWindow"); + Assert.equal( + result.searchParams.isPrivateEngine, + isPrivateEngine, + "Check isPrivateEngine" + ); + Assert.equal( + result.searchParams.engine, + engine.name, + "Check the search engine" + ); + return result; +} + +// Tests from here on have a different default private engine. + +add_task(async function test_search_private_engine() { + info( + "Test that 'Search in a Private Window' reports a separate private engine" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "unique198273982173", + }); + await AssertPrivateResult(window, gPrivateEngine, true); +}); + +add_task(async function test_privateWindow() { + info( + "Test that 'Search in a Private Window' does not appear in a private window" + ); + let privateWin = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window: privateWin, + value: "unique198273982173", + }); + await AssertNoPrivateResult(privateWin); + await BrowserTestUtils.closeWindow(privateWin); +}); + +add_task(async function test_permanentPB() { + info( + "Test that 'Search in a Private Window' does not appear in Permanent Private Browsing" + ); + await SpecialPowers.pushPrefEnv({ + set: [["browser.privatebrowsing.autostart", true]], + }); + let win = await BrowserTestUtils.openNewBrowserWindow(); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window: win, + value: "unique198273982173", + }); + await AssertNoPrivateResult(win); + await BrowserTestUtils.closeWindow(win); + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function test_openPBWindow() { + info( + "Test that 'Search in a Private Window' opens the search in a new Private Window" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "unique198273982173", + }); + await AssertPrivateResult( + window, + await Services.search.getDefaultPrivate(), + true + ); + + await withHttpServer(serverInfo, async () => { + let promiseWindow = BrowserTestUtils.waitForNewWindow({ + url: "http://localhost:20709/?terms=unique198273982173", + maybeErrorPage: true, + }); + EventUtils.synthesizeKey("KEY_ArrowDown"); + EventUtils.synthesizeKey("VK_RETURN"); + let win = await promiseWindow; + Assert.ok( + PrivateBrowsingUtils.isWindowPrivate(win), + "Should open a private window" + ); + await BrowserTestUtils.closeWindow(win); + }); +}); + +// TODO: (Bug 1658620) Write a new subtest for this behaviour with the update2 +// pref on. +add_task(async function test_oneoff_selected_with_private_engine_mouse() { + info( + "Test that 'Search in a Private Window' opens the private engine even if a one-off is selected" + ); + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.update2", false], + ["browser.urlbar.update2.oneOffsRefresh", false], + ], + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "unique198273982173", + }); + await AssertPrivateResult( + window, + await Services.search.getDefaultPrivate(), + true + ); + + await withHttpServer(serverInfo, async () => { + // Select the 'Search in a Private Window' result, alt down to select the + // first one-off button, Click on the result. It should open a pb window using + // the private search engine, because it has been set. + let promiseWindow = BrowserTestUtils.waitForNewWindow({ + url: "http://localhost:20709/?terms=unique198273982173", + maybeErrorPage: true, + }); + // Select the private result. + EventUtils.synthesizeKey("KEY_ArrowDown"); + // Select the first one-off button. + EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true }); + // Click on the result. + let element = UrlbarTestUtils.getSelectedRow(window); + EventUtils.synthesizeMouseAtCenter(element, {}); + let win = await promiseWindow; + Assert.ok( + PrivateBrowsingUtils.isWindowPrivate(win), + "Should open a private window" + ); + await BrowserTestUtils.closeWindow(win); + }); + await SpecialPowers.popPrefEnv(); +}); + +// TODO: (Bug 1658620) Write a new subtest for this behaviour with the update2 +// pref on. +add_task(async function test_oneoff_selected_with_private_engine_keyboard() { + info( + "Test that 'Search in a Private Window' opens the private engine even if a one-off is selected" + ); + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.update2", false], + ["browser.urlbar.update2.oneOffsRefresh", false], + ], + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "unique198273982173", + }); + await AssertPrivateResult( + window, + await Services.search.getDefaultPrivate(), + true + ); + + await withHttpServer(serverInfo, async () => { + // Select the 'Search in a Private Window' result, alt down to select the + // first one-off button, Enter. It should open a pb window, but using the + // selected one-off engine. + let promiseWindow = BrowserTestUtils.waitForNewWindow({ + url: "http://localhost:20709/?terms=unique198273982173", + maybeErrorPage: true, + }); + // Select the private result. + EventUtils.synthesizeKey("KEY_ArrowDown"); + // Select the first one-off button. + EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true }); + EventUtils.synthesizeKey("VK_RETURN"); + let win = await promiseWindow; + Assert.ok( + PrivateBrowsingUtils.isWindowPrivate(win), + "Should open a private window" + ); + await BrowserTestUtils.closeWindow(win); + }); + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function test_alias_no_query() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.update2", true], + ["browser.urlbar.update2.emptySearchBehavior", 2], + ], + }); + info( + "Test that 'Search in a Private Window' doesn't appear if an alias is typed with no query" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "alias ", + }); + // Wait for the second new search that starts when search mode is entered. + await UrlbarTestUtils.promiseSearchComplete(window); + await UrlbarTestUtils.assertSearchMode(window, { + engineName: gAliasEngine.name, + entry: "typed", + }); + await AssertNoPrivateResult(window); + await UrlbarTestUtils.exitSearchMode(window); + await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function test_alias_query() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.update2", true], + ["browser.urlbar.update2.emptySearchBehavior", 2], + ], + }); + info( + "Test that 'Search in a Private Window' appears when an alias is typed with a query" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "alias something", + }); + // Wait for the second new search that starts when search mode is entered. + await UrlbarTestUtils.promiseSearchComplete(window); + await UrlbarTestUtils.assertSearchMode(window, { + engineName: "MozSearch", + entry: "typed", + }); + await AssertPrivateResult(window, gAliasEngine, true); + await UrlbarTestUtils.exitSearchMode(window); + await UrlbarTestUtils.promisePopupClose(window); + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function test_alias_legacy() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.update2", false]], + }); + info( + "Test that 'Search in a Private Window' doesn't appear if an alias is typed" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "alias", + }); + await AssertNoPrivateResult(window); + + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "alias something", + }); + await AssertNoPrivateResult(window); + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function test_restrict() { + info( + "Test that 'Search in a Private Window' doesn's appear for just the restriction token" + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: UrlbarTokenizer.RESTRICT.SEARCH, + }); + await AssertNoPrivateResult(window); + + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: UrlbarTokenizer.RESTRICT.SEARCH + " ", + }); + await AssertNoPrivateResult(window); + + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: " " + UrlbarTokenizer.RESTRICT.SEARCH, + }); + await AssertNoPrivateResult(window); +}); + +add_task(async function test_restrict_search() { + info( + "Test that 'Search in a Private Window' has the right string with the restriction token" + ); + let engine = await Services.search.getDefaultPrivate(); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: UrlbarTokenizer.RESTRICT.SEARCH + "test", + }); + let result = await AssertPrivateResult(window, engine, true); + Assert.equal(result.searchParams.query, "test"); + + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test" + UrlbarTokenizer.RESTRICT.SEARCH, + }); + result = await AssertPrivateResult(window, engine, true); + Assert.equal(result.searchParams.query, "test"); +});