/* Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/ */ /** * Tests that the "New" badge is shown for new application-provided engines in * the Unified Search Button dropdown menu, but is hidden when the application-provided * engine has been overridden by a third-party engine. */ "use strict"; const { RemoteSettings } = ChromeUtils.importESModule( "resource://services-settings/remote-settings.sys.mjs" ); let isNewUntil = Temporal.Now.plainDateISO().add({ days: 4 }).toString(); // A config to test new app-provided engine only. const CONFIG = [ { identifier: "basic", variants: [ { environment: { allRegionsAndLocales: true }, isNewUntil, }, ], }, ]; // A config to test a new app-provided engine is overridden by third-party engine. // Extends the original config by adding the engine that will be overridden. const CONFIG_OVERRIDDEN_ENGINE = [ ...CONFIG, { identifier: "engine-id", base: { name: "engine-name", urls: { search: { base: "https://example.com/search", params: [{ name: "pc", value: "{partnerCode}" }], searchTermParamName: "q", }, }, partnerCode: "partner-code", }, variants: [ { environment: { allRegionsAndLocales: true }, isNewUntil, }, ], }, ]; add_setup(async function setup() { await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.scotchBonnet.enableOverride", true]], }); let allowlist = RemoteSettings(SearchUtils.SETTINGS_ALLOWLIST_KEY); sinon.stub(allowlist, "get").returns([ { thirdPartyId: "thirdparty@tests.mozilla.org", overridesAppIdv2: "engine-id", urls: [ { search_url: "https://example.com/search-third-party", search_url_get_params: "?pc=thirdparty&q={searchTerms}", }, ], }, ]); await SearchTestUtils.updateRemoteSettingsConfig(CONFIG); registerCleanupFunction(async () => { sinon.restore(); }); }); add_task(async function test_new_badge_displayed_for_new_app_provided_engine() { let engine = SearchService.getEngineByName("basic"); Assert.ok(engine.isNew(), "Engine is new"); Assert.ok(!engine.overriddenById, "Engine is not overridden."); info("New application provided engine should show the New badge"); let unifiedDropDownMenu = await UrlbarTestUtils.openSearchModeSwitcher(window); let item = unifiedDropDownMenu.querySelector( `panel-item[data-engine-name="basic"]` ); Assert.ok( item, "The app-provided engine is in the unified button dropdown menu" ); Assert.equal(item.getAttribute("badge-type"), "new", "New badge is shown"); let unifiedDropDownMenuHidden = UrlbarTestUtils.searchModeSwitcherPopupClosed(window); EventUtils.synthesizeKey("KEY_Escape"); await unifiedDropDownMenuHidden; }); add_task( async function test_new_badge_hidden_when_app_provided_is_overridden() { let extension = await SearchTestUtils.installSearchExtension( { id: "thirdparty@tests.mozilla.org", name: "engine-name", is_default: true, search_url: "https://example.com/search-third-party", search_url_get_params: "?pc=thirdparty&q={searchTerms}", }, { setAsDefault: true, skipUnload: true } ); let addonEngine = SearchService.getEngineByName("engine-name"); Assert.ok(!addonEngine.isNew(), "The add-on engine is not new"); info("The add-on engine should not show the New badge"); let unifiedDropDownMenu = await UrlbarTestUtils.openSearchModeSwitcher(window); let item = unifiedDropDownMenu.querySelector( `panel-item[data-engine-name="engine-name"]` ); Assert.ok(item, "The add-on engine is in the unified button dropdown menu"); Assert.ok( !item.hasAttribute("badge-type"), "The add-on engine does not show the New badge" ); let unifiedDropDownMenuHidden = UrlbarTestUtils.searchModeSwitcherPopupClosed(window); EventUtils.synthesizeKey("KEY_Escape"); await unifiedDropDownMenuHidden; // Loading a new app-provided engine with the same name as the third-party // add-on that was set as default above causes the add-on to override the // app-provided engine, because the add-on is in the default override allowlist. info("Load the new app-provided engine with the same name as the add-on"); await SearchTestUtils.updateRemoteSettingsConfig(CONFIG_OVERRIDDEN_ENGINE); let engine = SearchService.getEngineByName("engine-name"); Assert.ok(engine.overriddenById, "The app-provided engine is overridden"); Assert.ok(!engine.isNew(), "The overriden app-provided engine is not new"); info("The overridden app-provided engine should not show the New badge"); unifiedDropDownMenu = await UrlbarTestUtils.openSearchModeSwitcher(window); item = unifiedDropDownMenu.querySelector( `panel-item[data-engine-name="engine-name"]` ); Assert.ok( item, "The app-provided engine is in the unified button dropdown menu" ); Assert.ok( !item.hasAttribute("badge-type"), "The overridden app-provided engine does not show the New badge" ); let submission = engine.getSubmission("test"); Assert.ok( submission.uri.spec.startsWith("https://example.com/search-third-party"), "The app-provided engine's search URL is overridden by the add-on" ); unifiedDropDownMenuHidden = UrlbarTestUtils.searchModeSwitcherPopupClosed(window); EventUtils.synthesizeKey("KEY_Escape"); await unifiedDropDownMenuHidden; await extension.unload(); } );