Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
/**
* This test ensures the placeholder is set correctly for different search
* engines.
*/
"use strict";
ChromeUtils.defineESModuleGetters(this, {
ConfigSearchEngine:
"moz-src:///toolkit/components/search/ConfigSearchEngine.sys.mjs",
});
const { sinon } = ChromeUtils.importESModule(
);
const CONFIG = [
{
identifier: "defaultEngine",
base: {
urls: {
// We need a default engine with trending results so the urlbar view will open.
trending: {
base: "https://example.com/browser/browser/components/search/test/browser/trendingSuggestionEngine.sjs",
method: "GET",
},
},
},
},
{
identifier: "generalEngine",
base: {
classification: "general",
},
},
];
let appDefaultEngine, extraEngine, extraPrivateEngine, expectedString;
let tabs = [];
let noEngineString;
let keywordDisabledString;
SearchTestUtils.init(this);
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.scotchBonnet.enableOverride", false]],
});
let originalOrder = (await SearchService.getEngines()).map(e => e.id);
await SearchTestUtils.updateRemoteSettingsConfig(CONFIG);
appDefaultEngine = await SearchService.getDefault();
[noEngineString, expectedString, keywordDisabledString] = (
await document.l10n.formatMessages([
{ id: "urlbar-placeholder" },
{
id: "urlbar-placeholder-with-name",
args: { name: appDefaultEngine.name },
},
{ id: "urlbar-placeholder-keyword-disabled" },
])
).map(msg => msg.attributes[0].value);
let rootUrl = getRootDirectory(gTestPath).replace(
);
await SearchTestUtils.installSearchExtension({
name: "extraEngine",
suggest_url: `${rootUrl}/searchSuggestionEngine.sjs`,
});
extraEngine = SearchService.getEngineByName("extraEngine");
await SearchTestUtils.installSearchExtension({
name: "extraPrivateEngine",
suggest_url: `${rootUrl}/searchSuggestionEngine.sjs`,
});
extraPrivateEngine = SearchService.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.urlbar.recentsearches.featureGate", false],
["browser.urlbar.trending.featureGate", true],
["browser.urlbar.suggest.searches", true],
["browser.urlbar.suggest.trending", true],
],
});
registerCleanupFunction(async () => {
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
// At this point, the app provided engines have already been
// restored by SearchTestUtils's cleanup but their order has not.
for (let [index, id] of originalOrder.entries()) {
let engine = SearchService.getEngineById(id);
SearchService.moveEngine(engine, index);
}
});
});
add_task(async function test_change_default_engine_updates_placeholder() {
tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser));
await SearchService.setDefault(
extraEngine,
SearchService.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 SearchService.setDefault(
appDefaultEngine,
SearchService.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() {
await doDelayedUpdatePlaceholderTest({ defaultEngine: extraEngine });
await doDelayedUpdatePlaceholderTest({ defaultEngine: appDefaultEngine });
});
async function doDelayedUpdatePlaceholderTest({ defaultEngine }) {
info("Set default search engine");
await SearchService.setDefault(
defaultEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
// Let default change handlers run before messing
// with the search service init status.
await TestUtils.waitForTick();
info("Clear placeholder cache");
Services.prefs.clearUserPref("browser.urlbar.placeholderName");
info("Pretend we're on startup and the search service hasn't started yet.");
let { promise, resolve } = Promise.withResolvers();
let stub = sinon.stub(SearchService, "promiseInitialized").get(() => promise);
SearchService.forceInitializationStatusForTests("started");
info("Open a new window");
let newWin = await BrowserTestUtils.openNewBrowserWindow();
Assert.equal(
newWin.gURLBar.placeholder,
noEngineString,
"Placeholder should be unchanged."
);
Assert.deepEqual(
newWin.document.l10n.getAttributes(newWin.gURLBar.inputField),
{ id: "urlbar-placeholder", args: null },
"Placeholder data should be unchanged."
);
info("Pretend the search service has finished initializing.");
stub.restore();
resolve();
SearchService.forceInitializationStatusForTests("success");
info("Simulate user interaction");
let urlTab = BrowserTestUtils.addTab(newWin.gBrowser, "about:mozilla");
await BrowserTestUtils.switchTab(newWin.gBrowser, urlTab);
if (defaultEngine instanceof ConfigSearchEngine) {
await TestUtils.waitForCondition(
() => newWin.gURLBar.placeholder == expectedString,
"The placeholder should include the engine name for built-in engines."
);
Assert.ok(true, "Placeholder should be updated");
} else {
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(r => setTimeout(r, 1000));
Assert.equal(
newWin.gURLBar.placeholder,
noEngineString,
"Placeholder should be unchanged."
);
}
await BrowserTestUtils.closeWindow(newWin);
}
add_task(async function test_private_window_no_separate_engine() {
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
await SearchService.setDefault(
extraEngine,
SearchService.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 SearchService.setDefault(
appDefaultEngine,
SearchService.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 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 SearchService.setDefault(
appDefaultEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
await SearchService.setDefaultPrivate(
extraPrivateEngine,
SearchService.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 SearchService.setDefault(
extraEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
await SearchService.setDefaultPrivate(
appDefaultEngine,
SearchService.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
await SearchService.setDefault(
appDefaultEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
await SearchService.setDefaultPrivate(
extraPrivateEngine,
SearchService.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() {
await SearchService.setDefault(
appDefaultEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
await doSearchModeTest(
{
source: UrlbarShared.RESULT_SOURCE.SEARCH,
engineName: "generalEngine",
},
{
id: "urlbar-placeholder-search-mode-web-2",
args: { name: "generalEngine" },
}
);
});
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: UrlbarShared.RESULT_SOURCE.BOOKMARKS },
{ id: "urlbar-placeholder-search-mode-other-bookmarks", args: null }
);
});
add_task(async function test_search_mode_tabs() {
await doSearchModeTest(
{ source: UrlbarShared.RESULT_SOURCE.TABS },
{ id: "urlbar-placeholder-search-mode-other-tabs", args: null }
);
});
add_task(async function test_search_mode_history() {
await doSearchModeTest(
{ source: UrlbarShared.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 SearchService.setDefault(
extraEngine,
SearchService.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 ${appDefaultEngine.name}`);
await SearchService.setDefault(
appDefaultEngine,
SearchService.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.
gURLBar._setPlaceholder("");
await TestUtils.waitForCondition(
() => gURLBar.placeholder == noEngineString,
"The placeholder should have been reset."
);
info("Show search engine removal info bar");
BrowserUtils.callModulesFromCategory(
{ categoryName: "search-service-notification" },
"search-engine-removal",
extraEngine.name,
appDefaultEngine.name
);
await TestUtils.waitForCondition(
() => gNotificationBox.getNotificationWithValue("search-engine-removal"),
"Waiting for message to be displayed"
);
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();
});
add_task(async function test_keyword_disabled() {
tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser));
await SpecialPowers.pushPrefEnv({
set: [["keyword.enabled", false]],
});
await TestUtils.waitForCondition(
() => gURLBar.placeholder == keywordDisabledString
);
Assert.ok(true, "Updated the placeholder to the keyword disabled one.");
await SpecialPowers.popPrefEnv();
await TestUtils.waitForCondition(() => gURLBar.placeholder == expectedString);
Assert.ok(true, "Updated the placeholder to the keyword enabled one.");
});
/**
* 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);
}