Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
ChromeUtils.defineESModuleGetters(this, {
UrlbarProviderInterventions:
"resource:///modules/UrlbarProviderInterventions.sys.mjs",
});
add_setup(async function () {
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
makeProfileResettable();
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.scotchBonnet.enableOverride", false]],
});
});
// Tests the refresh tip.
add_task(async function refresh() {
// Pick the tip, which should open the refresh dialog. Click its cancel
// button.
await checkIntervention({
searchString: SEARCH_STRINGS.REFRESH,
tip: UrlbarProviderInterventions.TIP_TYPE.REFRESH,
title:
"Restore default settings and remove old add-ons for optimal performance.",
button: /^Refresh .+…$/,
awaitCallback() {
return BrowserTestUtils.promiseAlertDialog(
"cancel",
"chrome://global/content/resetProfile.xhtml",
{ isSubDialog: true }
);
},
});
});
// Tests the clear tip.
add_task(async function clear() {
// Pick the tip, which should open the refresh dialog. Click its cancel
// button.
let useOldClearHistoryDialog = Services.prefs.getBoolPref(
"privacy.sanitize.useOldClearHistoryDialog"
);
let dialogURL = useOldClearHistoryDialog
? "chrome://browser/content/sanitize.xhtml"
: "chrome://browser/content/sanitize_v2.xhtml";
await checkIntervention({
searchString: SEARCH_STRINGS.CLEAR,
tip: UrlbarProviderInterventions.TIP_TYPE.CLEAR,
title: "Clear your cache, cookies, history and more.",
button: "Choose What to Clear…",
awaitCallback() {
return BrowserTestUtils.promiseAlertDialog("cancel", dialogURL, {
isSubDialog: true,
});
},
});
});
// Tests the clear tip in a private window. The clear tip shouldn't appear in
// private windows.
add_task(async function clear_private() {
let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
// First, make sure the extension works in PBM by triggering a non-clear
// tip.
let result = (await awaitTip(SEARCH_STRINGS.REFRESH, win))[0];
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.REFRESH
);
// Blur the urlbar so that the engagement is ended.
await UrlbarTestUtils.promisePopupClose(win, () => win.gURLBar.blur());
// Now do a search that would trigger the clear tip.
await awaitNoTip(SEARCH_STRINGS.CLEAR, win);
// Blur the urlbar so that the engagement is ended.
await UrlbarTestUtils.promisePopupClose(win, () => win.gURLBar.blur());
await BrowserTestUtils.closeWindow(win);
});
// Tests that only the intervention visible at the time of abandonment or
// engagement is registered in Telemetry.
add_task(async function multipleInterventionsInOneEngagement() {
Services.telemetry.clearScalars();
let result = (await awaitTip(SEARCH_STRINGS.REFRESH, window))[0];
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.REFRESH
);
result = (await awaitTip(SEARCH_STRINGS.CLEAR, window))[0];
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.CLEAR
);
result = (await awaitTip(SEARCH_STRINGS.REFRESH, window))[0];
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.REFRESH
);
// Blur the urlbar so that the engagement is ended.
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, true);
// We should only record one impression for the Refresh tip. Although it was
// seen twice, it was in the same engagement.
TelemetryTestUtils.assertKeyedScalar(
scalars,
"urlbar.tips",
`${UrlbarProviderInterventions.TIP_TYPE.REFRESH}-shown`,
1
);
Assert.ok(
!scalars["urlbar.tips"][
`${UrlbarProviderInterventions.TIP_TYPE.CLEAR}-shown`
],
`${UrlbarProviderInterventions.TIP_TYPE.CLEAR}-shown is not recorded as an
impression`
);
});
// Test the result of UrlbarProviderInterventions.isActive()
// and whether or not the function calucates the score.
add_task(async function testIsActive() {
const testData = [
{
description: "Test for search string that activates the intervention",
searchString: "firefox slow",
expectedActive: true,
expectedScoreCalculated: true,
},
{
description:
"Test for search string that does not activate the intervention",
searchString: "example slow",
expectedActive: false,
expectedScoreCalculated: true,
},
{
description: "Test for empty search string",
searchString: "",
expectedActive: false,
expectedScoreCalculated: false,
},
{
description: "Test for an URL",
searchString: "https://firefox/slow",
expectedActive: false,
expectedScoreCalculated: false,
},
{
description: "Test for a data URL",
searchString: "data:text/html,<div>firefox slow</div>",
expectedActive: false,
expectedScoreCalculated: false,
},
{
description: "Test for string like URL",
searchString: "firefox://slow",
expectedActive: false,
expectedScoreCalculated: false,
},
];
for (const {
description,
searchString,
expectedActive,
expectedScoreCalculated,
} of testData) {
info(description);
// Set null to currentTip to know whether or not UrlbarProviderInterventions
// calculated the score.
UrlbarProviderInterventions.currentTip = null;
const isActive = UrlbarProviderInterventions.isActive({ searchString });
Assert.equal(isActive, expectedActive, "Result of isAcitive is correct");
const isScoreCalculated = UrlbarProviderInterventions.currentTip !== null;
Assert.equal(
isScoreCalculated,
expectedScoreCalculated,
"The score is calculated correctly"
);
}
});
add_task(async function tipsAreEnglishOnly() {
// Test that Interventions are working in en-US.
let result = (await awaitTip(SEARCH_STRINGS.REFRESH, window))[0];
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.REFRESH
);
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
// We will need to fetch new engines when we switch locales.
let enginesReloaded =
SearchTestUtils.promiseSearchNotification("engines-reloaded");
const originalAvailable = Services.locale.availableLocales;
const originalRequested = Services.locale.requestedLocales;
Services.locale.availableLocales = ["en-US", "de"];
Services.locale.requestedLocales = ["de"];
let cleanup = async () => {
let reloadPromise =
SearchTestUtils.promiseSearchNotification("engines-reloaded");
Services.locale.requestedLocales = originalRequested;
Services.locale.availableLocales = originalAvailable;
await reloadPromise;
cleanup = null;
};
registerCleanupFunction(() => cleanup?.());
let appLocales = Services.locale.appLocalesAsBCP47;
Assert.equal(appLocales[0], "de");
await enginesReloaded;
// Interventions should no longer work in the new locale.
await awaitNoTip(SEARCH_STRINGS.CLEAR, window);
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
await cleanup();
});
// Tests the help command (using the clear intervention). It should open the
// help page and it should not trigger the primary intervention behavior.
add_task(async function pickHelp() {
await BrowserTestUtils.withNewTab("about:blank", async () => {
// Do a search that triggers the clear tip.
let [result] = await awaitTip(SEARCH_STRINGS.CLEAR);
Assert.strictEqual(
result.payload.type,
UrlbarProviderInterventions.TIP_TYPE.CLEAR
);
// Click the help command and wait for the help page to load.
Assert.ok(
!!result.payload.helpUrl,
"The result's helpUrl should be defined and non-empty: " +
JSON.stringify(result.payload.helpUrl)
);
let loadPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser,
false,
result.payload.helpUrl
);
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h", {
openByMouse: true,
resultIndex: 1,
});
info("Waiting for help URL to load in the current tab");
await loadPromise;
// Wait a bit and make sure the clear recent history dialog did not open.
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(r => setTimeout(r, 2000));
Assert.strictEqual(gDialogBox.isOpen, false, "No dialog should be open");
// Check telemetry.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"urlbar.tips",
`${UrlbarProviderInterventions.TIP_TYPE.CLEAR}-help`,
1
);
});
});