/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** * This test ensures the placeholder is set correctly for different search * engines. */ "use strict"; var originalEngine, extraEngine, extraPrivateEngine, expectedString; var tabs = []; var noEngineString; add_setup(async function () { originalEngine = await Services.search.getDefault(); [noEngineString, expectedString] = ( await document.l10n.formatMessages([ { id: "urlbar-placeholder" }, { id: "urlbar-placeholder-with-name", args: { name: originalEngine.name }, }, ]) ).map(msg => msg.attributes[0].value); let rootUrl = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://mochi.test:8888/" ); await SearchTestUtils.installSearchExtension({ name: "extraEngine", search_url: "https://mochi.test:8888/", suggest_url: `${rootUrl}/searchSuggestionEngine.sjs`, }); extraEngine = Services.search.getEngineByName("extraEngine"); await SearchTestUtils.installSearchExtension({ name: "extraPrivateEngine", search_url: "https://mochi.test:8888/", suggest_url: `${rootUrl}/searchSuggestionEngine.sjs`, }); extraPrivateEngine = Services.search.getEngineByName("extraPrivateEngine"); // Force display of a tab with a URL bar, to clear out any possible placeholder // initialization listeners that happen on startup. let urlTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:mozilla" ); BrowserTestUtils.removeTab(urlTab); await SpecialPowers.pushPrefEnv({ set: [ ["browser.search.separatePrivateDefault.ui.enabled", true], ["browser.search.separatePrivateDefault", false], ["browser.urlbar.suggest.quickactions", false], ], }); registerCleanupFunction(async () => { await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); for (let tab of tabs) { BrowserTestUtils.removeTab(tab); } }); }); add_task(async function test_change_default_engine_updates_placeholder() { tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser)); await Services.search.setDefault( extraEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => gURLBar.placeholder == noEngineString, "The placeholder should match the default placeholder for non-built-in engines." ); Assert.equal(gURLBar.placeholder, noEngineString); await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); Assert.equal(gURLBar.placeholder, expectedString); }); add_task(async function test_delayed_update_placeholder() { // We remove the change of engine listener here as that is set so that // if the engine is changed by the user then the placeholder is always updated // straight away. As we want to test the delay update here, we remove the // listener and call the placeholder update manually with the delay flag. Services.obs.removeObserver(BrowserSearch, "browser-search-engine-modified"); // Since we can't easily test for startup changes, we'll at least test the delay // of update for the placeholder works. let urlTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:mozilla" ); tabs.push(urlTab); // Open a tab with a blank URL bar. let blankTab = await BrowserTestUtils.openNewForegroundTab(gBrowser); tabs.push(blankTab); await Services.search.setDefault( extraEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); // Pretend we've "initialized". BrowserSearch._updateURLBarPlaceholder(extraEngine.name, false, true); Assert.equal( gURLBar.placeholder, expectedString, "Placeholder should be unchanged." ); // Now switch to a tab with something in the URL Bar. await BrowserTestUtils.switchTab(gBrowser, urlTab); await TestUtils.waitForCondition( () => gURLBar.placeholder == noEngineString, "The placeholder should have updated in the background." ); // Do it the other way to check both named engine and fallback code paths. await BrowserTestUtils.switchTab(gBrowser, blankTab); await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); BrowserSearch._updateURLBarPlaceholder(originalEngine.name, false, true); Assert.equal( gURLBar.placeholder, noEngineString, "Placeholder should be unchanged." ); Assert.deepEqual( document.l10n.getAttributes(gURLBar.inputField), { id: "urlbar-placeholder", args: null }, "Placeholder data should be unchanged." ); await BrowserTestUtils.switchTab(gBrowser, urlTab); await TestUtils.waitForCondition( () => gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); // Now check when we have a URL displayed, the placeholder is updated straight away. BrowserSearch._updateURLBarPlaceholder(extraEngine.name, false); await TestUtils.waitForCondition( () => gURLBar.placeholder == noEngineString, "The placeholder should go back to the default" ); Assert.equal( gURLBar.placeholder, noEngineString, "Placeholder should be the default." ); Services.obs.addObserver(BrowserSearch, "browser-search-engine-modified"); }); add_task(async function test_private_window_no_separate_engine() { const win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); await Services.search.setDefault( extraEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => win.gURLBar.placeholder == noEngineString, "The placeholder should match the default placeholder for non-built-in engines." ); Assert.equal(win.gURLBar.placeholder, noEngineString); await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => win.gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); Assert.equal(win.gURLBar.placeholder, expectedString); await BrowserTestUtils.closeWindow(win); }); add_task(async function test_private_window_separate_engine() { await SpecialPowers.pushPrefEnv({ set: [["browser.search.separatePrivateDefault", true]], }); const originalPrivateEngine = await Services.search.getDefaultPrivate(); registerCleanupFunction(async () => { await Services.search.setDefaultPrivate( originalPrivateEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); }); const win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); // Keep the normal default as a different string to the private, so that we // can be sure we're testing the right thing. await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.setDefaultPrivate( extraPrivateEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => win.gURLBar.placeholder == noEngineString, "The placeholder should match the default placeholder for non-built-in engines." ); Assert.equal(win.gURLBar.placeholder, noEngineString); await Services.search.setDefault( extraEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.setDefaultPrivate( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => win.gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); Assert.equal(win.gURLBar.placeholder, expectedString); await BrowserTestUtils.closeWindow(win); // Verify that the placeholder for private windows is updated even when no // private window is visible (https://bugzilla.mozilla.org/1792816). await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.setDefaultPrivate( extraPrivateEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); const win2 = await BrowserTestUtils.openNewBrowserWindow({ private: true }); Assert.equal(win2.gURLBar.placeholder, noEngineString); await BrowserTestUtils.closeWindow(win2); // And ensure this doesn't affect the placeholder for non private windows. tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser)); Assert.equal(win.gURLBar.placeholder, expectedString); }); add_task(async function test_search_mode_engine_web() { // Add our test engine to WEB_ENGINE_NAMES so that it's recognized as a web // engine. SearchUtils.GENERAL_SEARCH_ENGINE_IDS.add( extraEngine.wrappedJSObject._extensionID ); await doSearchModeTest( { source: UrlbarUtils.RESULT_SOURCE.SEARCH, engineName: extraEngine.name, }, { id: "urlbar-placeholder-search-mode-web-2", args: { name: extraEngine.name }, } ); SearchUtils.GENERAL_SEARCH_ENGINE_IDS.delete( extraEngine.wrappedJSObject._extensionID ); }); add_task(async function test_search_mode_engine_other() { await doSearchModeTest( { engineName: extraEngine.name }, { id: "urlbar-placeholder-search-mode-other-engine", args: { name: extraEngine.name }, } ); }); add_task(async function test_search_mode_bookmarks() { await doSearchModeTest( { source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS }, { id: "urlbar-placeholder-search-mode-other-bookmarks", args: null } ); }); add_task(async function test_search_mode_tabs() { await doSearchModeTest( { source: UrlbarUtils.RESULT_SOURCE.TABS }, { id: "urlbar-placeholder-search-mode-other-tabs", args: null } ); }); add_task(async function test_search_mode_history() { await doSearchModeTest( { source: UrlbarUtils.RESULT_SOURCE.HISTORY }, { id: "urlbar-placeholder-search-mode-other-history", args: null } ); }); add_task(async function test_change_default_engine_updates_placeholder() { tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser)); info(`Set engine to ${extraEngine.name}`); await Services.search.setDefault( extraEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => gURLBar.placeholder == noEngineString, "The placeholder should match the default placeholder for non-built-in engines." ); Assert.equal(gURLBar.placeholder, noEngineString); info(`Set engine to ${originalEngine.name}`); await Services.search.setDefault( originalEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await TestUtils.waitForCondition( () => gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); // Simulate the placeholder not having changed due to the delayed update // on startup. BrowserSearch._setURLBarPlaceholder(""); await TestUtils.waitForCondition( () => gURLBar.placeholder == noEngineString, "The placeholder should have been reset." ); info("Show search engine removal info bar"); BrowserSearch.removalOfSearchEngineNotificationBox( extraEngine.name, originalEngine.name ); const notificationBox = gNotificationBox.getNotificationWithValue( "search-engine-removal" ); Assert.ok(notificationBox, "Search engine removal should be shown."); await TestUtils.waitForCondition( () => gURLBar.placeholder == expectedString, "The placeholder should include the engine name for built-in engines." ); Assert.equal(gURLBar.placeholder, expectedString); notificationBox.close(); }); /** * Opens the view, clicks a one-off button to enter search mode, and asserts * that the placeholder is corrrect. * * @param {object} expectedSearchMode * The expected search mode object for the one-off. * @param {object} expectedPlaceholderL10n * The expected l10n object for the one-off. */ async function doSearchModeTest(expectedSearchMode, expectedPlaceholderL10n) { // Click the urlbar to open the top-sites view. if (gURLBar.getAttribute("pageproxystate") == "invalid") { gURLBar.handleRevert(); } await UrlbarTestUtils.promisePopupOpen(window, () => { EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {}); }); // Enter search mode. await UrlbarTestUtils.enterSearchMode(window, expectedSearchMode); // Check the placeholder. Assert.deepEqual( document.l10n.getAttributes(gURLBar.inputField), expectedPlaceholderL10n, "Placeholder has expected l10n" ); await UrlbarTestUtils.exitSearchMode(window, { clickClose: true }); await UrlbarTestUtils.promisePopupClose(window); }