Source code

Revision control

Copy as Markdown

Other Tools

"use strict";
ChromeUtils.defineESModuleGetters(this, {
ASRouter: "resource:///modules/asrouter/ASRouter.sys.mjs",
FeatureCallout: "resource:///modules/asrouter/FeatureCallout.sys.mjs",
FeatureCalloutBroker:
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
FeatureCalloutMessages:
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs",
QueryCache: "resource:///modules/asrouter/ASRouterTargeting.sys.mjs",
AboutWelcomeParent: "resource:///actors/AboutWelcomeParent.sys.mjs",
});
const { FxAccounts } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
// We import sinon here to make it available across all mochitest test files
const { sinon } = ChromeUtils.importESModule(
);
const BROWSER_GLUE =
Cc["@mozilla.org/browser/browserglue;1"].getService().wrappedJSObject;
// Feature callout constants
const calloutId = "feature-callout";
const calloutSelector = `#${calloutId}.featureCallout`;
const calloutCTASelector = `#${calloutId} :is(.primary, .secondary)`;
const calloutDismissSelector = `#${calloutId} .dismiss-button`;
const CTASelector = `#${calloutId} :is(.primary, .secondary)`;
function pushPrefs(...prefs) {
return SpecialPowers.pushPrefEnv({ set: prefs });
}
async function clearHistoryAndBookmarks() {
await PlacesUtils.bookmarks.eraseEverything();
await PlacesUtils.history.clear();
QueryCache.expireAll();
}
/**
* Helper function to navigate and wait for page to load
*/
async function waitForUrlLoad(url) {
let browser = gBrowser.selectedBrowser;
BrowserTestUtils.startLoadingURIString(browser, url);
await BrowserTestUtils.browserLoaded(browser, false, url);
}
async function waitForCalloutScreen(target, screenId) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true, attributeFilter: ["class"] },
() => target.querySelector(`${calloutSelector}:not(.hidden) .${screenId}`)
);
}
async function waitForCalloutRemoved(target) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true },
() => !target.querySelector(calloutSelector)
);
}
/**
* A helper to check that correct telemetry was sent by AWSendEventTelemetry.
* This is a wrapper around sinon's spy functionality.
*
* @example
* let spy = new TelemetrySpy();
* element.click();
* spy.assertCalledWith({ event: "CLICK" });
* spy.restore();
*/
class TelemetrySpy {
/**
* @param {object} [sandbox] A pre-existing sinon sandbox to build the spy in.
* If not provided, a new sandbox will be created.
*/
constructor(sandbox = sinon.createSandbox()) {
this.sandbox = sandbox;
this.spy = this.sandbox
.spy(AboutWelcomeParent.prototype, "onContentMessage")
.withArgs("AWPage:TELEMETRY_EVENT");
registerCleanupFunction(() => this.restore());
}
/**
* Assert that AWSendEventTelemetry sent the expected telemetry object.
*
* @param {object} expectedData
*/
assertCalledWith(expectedData) {
let match = this.spy.calledWith("AWPage:TELEMETRY_EVENT", expectedData);
if (match) {
ok(true, "Expected telemetry sent");
} else if (this.spy.called) {
ok(
false,
`Wrong telemetry sent: ${JSON.stringify(this.spy.lastCall.args)}`
);
} else {
ok(false, "No telemetry sent");
}
}
reset() {
this.spy.resetHistory();
}
restore() {
this.sandbox.restore();
}
}
/**
* NOTE: Should be replaced with synthesizeMouseAtCenter for
* simulating user input. See Bug 1798322
*
* Clicks the primary button in the feature callout dialog
*
* @param {document} doc Document object
*/
const clickCTA = async doc => {
doc.querySelector(CTASelector).click();
};