Bug 1693550 - Update about:welcome to use ExperimentFeature r=k88hudson
Differential Revision: https://phabricator.services.mozilla.com/D105738
This commit is contained in:
@@ -1467,7 +1467,7 @@ pref("trailhead.firstrun.newtab.triplets", "");
|
||||
// Separate about welcome
|
||||
pref("browser.aboutwelcome.enabled", true);
|
||||
// Used to set multistage welcome UX
|
||||
pref("browser.aboutwelcome.overrideContent", "");
|
||||
pref("browser.aboutwelcome.screens", "");
|
||||
pref("browser.aboutwelcome.skipFocus", false);
|
||||
|
||||
// The pref that controls if the What's New panel is enabled.
|
||||
|
||||
@@ -24,6 +24,13 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
return new Logger("AboutWelcomeChild");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "aboutWelcomeFeature", () => {
|
||||
const { ExperimentFeature } = ChromeUtils.import(
|
||||
"resource://nimbus/ExperimentAPI.jsm"
|
||||
);
|
||||
return new ExperimentFeature("aboutwelcome");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "tippyTopProvider", () =>
|
||||
(async () => {
|
||||
const provider = new TippyTopProvider();
|
||||
@@ -32,25 +39,6 @@ XPCOMUtils.defineLazyGetter(this, "tippyTopProvider", () =>
|
||||
})()
|
||||
);
|
||||
|
||||
function _parseOverrideContent(value) {
|
||||
let result = {};
|
||||
try {
|
||||
result = value ? JSON.parse(value) : {};
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"multiStageAboutWelcomeContent",
|
||||
"browser.aboutwelcome.overrideContent",
|
||||
"",
|
||||
null,
|
||||
_parseOverrideContent
|
||||
);
|
||||
|
||||
const SEARCH_REGION_PREF = "browser.search.region";
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
@@ -164,20 +152,14 @@ class AboutWelcomeChild extends JSWindowActorChild {
|
||||
exportFunctions() {
|
||||
let window = this.contentWindow;
|
||||
|
||||
Cu.exportFunction(this.AWGetExperimentData.bind(this), window, {
|
||||
defineAs: "AWGetExperimentData",
|
||||
Cu.exportFunction(this.AWGetFeatureConfig.bind(this), window, {
|
||||
defineAs: "AWGetFeatureConfig",
|
||||
});
|
||||
|
||||
Cu.exportFunction(this.AWGetAttributionData.bind(this), window, {
|
||||
defineAs: "AWGetAttributionData",
|
||||
});
|
||||
|
||||
// For local dev, checks for JSON content inside pref browser.aboutwelcome.overrideContent
|
||||
// that is used to override default welcome UI
|
||||
Cu.exportFunction(this.AWGetWelcomeOverrideContent.bind(this), window, {
|
||||
defineAs: "AWGetWelcomeOverrideContent",
|
||||
});
|
||||
|
||||
Cu.exportFunction(this.AWGetFxAMetricsFlowURI.bind(this), window, {
|
||||
defineAs: "AWGetFxAMetricsFlowURI",
|
||||
});
|
||||
@@ -228,16 +210,6 @@ class AboutWelcomeChild extends JSWindowActorChild {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multistage welcome JSON data read from aboutwelcome.overrideConetent pref to page
|
||||
*/
|
||||
AWGetWelcomeOverrideContent() {
|
||||
return Cu.cloneInto(
|
||||
multiStageAboutWelcomeContent || {},
|
||||
this.contentWindow
|
||||
);
|
||||
}
|
||||
|
||||
AWSelectTheme(data) {
|
||||
return this.wrapPromise(
|
||||
this.sendQuery("AWPage:SELECT_THEME", data.toUpperCase())
|
||||
@@ -309,21 +281,31 @@ class AboutWelcomeChild extends JSWindowActorChild {
|
||||
/**
|
||||
* Send initial data to page including experiment information
|
||||
*/
|
||||
AWGetExperimentData() {
|
||||
// Note that we specifically don't wait for experiments to be loaded from disk so if
|
||||
AWGetFeatureConfig() {
|
||||
// Note that we specifically don't wait for `ready` so if
|
||||
// about:welcome loads outside of the "FirstStartup" scenario this will likely not be ready
|
||||
let experimentData = ExperimentAPI.getExperiment({
|
||||
featureId: "aboutwelcome",
|
||||
});
|
||||
let experimentMetadata =
|
||||
ExperimentAPI.getExperimentMetaData({
|
||||
featureId: "aboutwelcome",
|
||||
}) || {};
|
||||
let featureConfig = aboutWelcomeFeature.getValue({ defaultValue: {} });
|
||||
|
||||
if (experimentData?.slug) {
|
||||
if (experimentMetadata?.slug) {
|
||||
log.debug(
|
||||
`Loading about:welcome with experiment: ${experimentData.slug}`
|
||||
`Loading about:welcome with experiment: ${experimentMetadata.slug}`
|
||||
);
|
||||
} else {
|
||||
log.debug("Loading about:welcome without experiment");
|
||||
}
|
||||
return Cu.cloneInto(experimentData || {}, this.contentWindow);
|
||||
return Cu.cloneInto(
|
||||
{
|
||||
// All experimentation right now is using the multistage template
|
||||
template: "multistage",
|
||||
...experimentMetadata,
|
||||
...featureConfig,
|
||||
},
|
||||
this.contentWindow
|
||||
);
|
||||
}
|
||||
|
||||
AWGetFxAMetricsFlowURI() {
|
||||
|
||||
@@ -212,49 +212,25 @@ function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) {
|
||||
}
|
||||
|
||||
async function retrieveRenderContent() {
|
||||
var _aboutWelcomeProps;
|
||||
// Check for featureConfig and retrieve content
|
||||
const featureConfig = await window.AWGetFeatureConfig();
|
||||
let aboutWelcomeProps;
|
||||
|
||||
// Check for override content in pref browser.aboutwelcome.overrideContent
|
||||
let aboutWelcomeProps = await window.AWGetWelcomeOverrideContent();
|
||||
|
||||
if ((_aboutWelcomeProps = aboutWelcomeProps) !== null && _aboutWelcomeProps !== void 0 && _aboutWelcomeProps.template) {
|
||||
let {
|
||||
messageId,
|
||||
UTMTerm
|
||||
} = ComputeTelemetryInfo(aboutWelcomeProps);
|
||||
return {
|
||||
aboutWelcomeProps,
|
||||
messageId,
|
||||
UTMTerm
|
||||
};
|
||||
} // Check for experiment and retrieve content
|
||||
|
||||
|
||||
const {
|
||||
slug,
|
||||
branch
|
||||
} = await window.AWGetExperimentData();
|
||||
aboutWelcomeProps = branch !== null && branch !== void 0 && branch.feature ? branch.feature.value : {}; // Check if there is any attribution data, this could take a while to await in series
|
||||
// especially when there is an add-on that requires remote lookup
|
||||
// Moving RTAMO as part of another screen of multistage is one option to fix the delay
|
||||
// as it will allow the initial page to be fast while we fetch attribution data in parallel for a later screen.
|
||||
|
||||
const attribution = await window.AWGetAttributionData();
|
||||
|
||||
if (attribution !== null && attribution !== void 0 && attribution.template) {
|
||||
var _aboutWelcomeProps2;
|
||||
|
||||
aboutWelcomeProps = { ...aboutWelcomeProps,
|
||||
// If part of an experiment, render experiment template
|
||||
template: (_aboutWelcomeProps2 = aboutWelcomeProps) !== null && _aboutWelcomeProps2 !== void 0 && _aboutWelcomeProps2.template ? aboutWelcomeProps.template : attribution.template,
|
||||
if (!featureConfig.screens) {
|
||||
const attribution = await window.AWGetAttributionData();
|
||||
aboutWelcomeProps = {
|
||||
template: attribution.template,
|
||||
...attribution.extraProps
|
||||
};
|
||||
} else {
|
||||
// If screens is defined then we have multi stage AW content to show
|
||||
aboutWelcomeProps = featureConfig.screens ? featureConfig : {};
|
||||
}
|
||||
|
||||
let {
|
||||
messageId,
|
||||
UTMTerm
|
||||
} = ComputeTelemetryInfo(aboutWelcomeProps, slug, branch && branch.slug);
|
||||
} = ComputeTelemetryInfo(aboutWelcomeProps, featureConfig.slug, featureConfig.branch && featureConfig.branch.slug);
|
||||
return {
|
||||
aboutWelcomeProps,
|
||||
messageId,
|
||||
|
||||
@@ -105,37 +105,25 @@ function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) {
|
||||
}
|
||||
|
||||
async function retrieveRenderContent() {
|
||||
// Check for override content in pref browser.aboutwelcome.overrideContent
|
||||
let aboutWelcomeProps = await window.AWGetWelcomeOverrideContent();
|
||||
if (aboutWelcomeProps?.template) {
|
||||
let { messageId, UTMTerm } = ComputeTelemetryInfo(aboutWelcomeProps);
|
||||
return { aboutWelcomeProps, messageId, UTMTerm };
|
||||
}
|
||||
// Check for featureConfig and retrieve content
|
||||
const featureConfig = await window.AWGetFeatureConfig();
|
||||
let aboutWelcomeProps;
|
||||
|
||||
// Check for experiment and retrieve content
|
||||
const { slug, branch } = await window.AWGetExperimentData();
|
||||
aboutWelcomeProps = branch?.feature ? branch.feature.value : {};
|
||||
|
||||
// Check if there is any attribution data, this could take a while to await in series
|
||||
// especially when there is an add-on that requires remote lookup
|
||||
// Moving RTAMO as part of another screen of multistage is one option to fix the delay
|
||||
// as it will allow the initial page to be fast while we fetch attribution data in parallel for a later screen.
|
||||
const attribution = await window.AWGetAttributionData();
|
||||
if (attribution?.template) {
|
||||
if (!featureConfig.screens) {
|
||||
const attribution = await window.AWGetAttributionData();
|
||||
aboutWelcomeProps = {
|
||||
...aboutWelcomeProps,
|
||||
// If part of an experiment, render experiment template
|
||||
template: aboutWelcomeProps?.template
|
||||
? aboutWelcomeProps.template
|
||||
: attribution.template,
|
||||
template: attribution.template,
|
||||
...attribution.extraProps,
|
||||
};
|
||||
} else {
|
||||
// If screens is defined then we have multi stage AW content to show
|
||||
aboutWelcomeProps = featureConfig.screens ? featureConfig : {};
|
||||
}
|
||||
|
||||
let { messageId, UTMTerm } = ComputeTelemetryInfo(
|
||||
aboutWelcomeProps,
|
||||
slug,
|
||||
branch && branch.slug
|
||||
featureConfig.slug,
|
||||
featureConfig.branch && featureConfig.branch.slug
|
||||
);
|
||||
return { aboutWelcomeProps, messageId, UTMTerm };
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ prefs =
|
||||
[browser_aboutwelcome_simplified.js]
|
||||
[browser_aboutwelcome_multistage.js]
|
||||
[browser_aboutwelcome_rtamo.js]
|
||||
skip-if = (os == "linux") # Test setup only implemented for OSX and Windows
|
||||
[browser_aboutwelcome_attribution.js]
|
||||
skip-if = (os == "linux") # Test setup only implemented for OSX and Windows
|
||||
[browser_aboutwelcome_observer.js]
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF =
|
||||
"browser.aboutwelcome.overrideContent";
|
||||
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF = "browser.aboutwelcome.screens";
|
||||
const ABOUT_WELCOME_FOCUS_PREF = "browser.aboutwelcome.skipFocus";
|
||||
|
||||
const TEST_MULTISTAGE_JSON = {
|
||||
id: "multi-stage-welcome",
|
||||
template: "multistage",
|
||||
screens: [
|
||||
{
|
||||
id: "AW_STEP1",
|
||||
order: 0,
|
||||
content: {
|
||||
title: "Step 1",
|
||||
},
|
||||
const TEST_MULTISTAGE_JSON = [
|
||||
{
|
||||
id: "AW_STEP1",
|
||||
order: 0,
|
||||
content: {
|
||||
title: "Step 1",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
];
|
||||
|
||||
async function setAboutWelcomeOverrideContent(value) {
|
||||
return pushPrefs([ABOUT_WELCOME_OVERRIDE_CONTENT_PREF, value]);
|
||||
|
||||
@@ -11,122 +11,111 @@ const { FxAccounts } = ChromeUtils.import(
|
||||
);
|
||||
|
||||
const SEPARATE_ABOUT_WELCOME_PREF = "browser.aboutwelcome.enabled";
|
||||
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF =
|
||||
"browser.aboutwelcome.overrideContent";
|
||||
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF = "browser.aboutwelcome.screens";
|
||||
const DID_SEE_ABOUT_WELCOME_PREF = "trailhead.firstrun.didSeeAboutWelcome";
|
||||
|
||||
const TEST_MULTISTAGE_CONTENT = {
|
||||
id: "multi-stage-welcome",
|
||||
template: "multistage",
|
||||
screens: [
|
||||
{
|
||||
id: "AW_STEP1",
|
||||
order: 0,
|
||||
content: {
|
||||
zap: true,
|
||||
title: "Step 1",
|
||||
tiles: {
|
||||
type: "theme",
|
||||
action: {
|
||||
theme: "<event>",
|
||||
const TEST_MULTISTAGE_CONTENT = [
|
||||
{
|
||||
id: "AW_STEP1",
|
||||
order: 0,
|
||||
content: {
|
||||
zap: true,
|
||||
title: "Step 1",
|
||||
tiles: {
|
||||
type: "theme",
|
||||
action: {
|
||||
theme: "<event>",
|
||||
},
|
||||
data: [
|
||||
{
|
||||
theme: "automatic",
|
||||
label: "theme-1",
|
||||
tooltip: "test-tooltip",
|
||||
},
|
||||
data: [
|
||||
{
|
||||
theme: "automatic",
|
||||
label: "theme-1",
|
||||
tooltip: "test-tooltip",
|
||||
},
|
||||
{
|
||||
theme: "dark",
|
||||
label: "theme-2",
|
||||
},
|
||||
],
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
{
|
||||
theme: "dark",
|
||||
label: "theme-2",
|
||||
},
|
||||
],
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
secondary_button: {
|
||||
label: "link",
|
||||
},
|
||||
secondary_button_top: {
|
||||
label: "link top",
|
||||
action: {
|
||||
type: "SHOW_FIREFOX_ACCOUNTS",
|
||||
data: { entrypoint: "test" },
|
||||
},
|
||||
},
|
||||
help_text: {
|
||||
text: { string_id: "onboarding-multistage-set-default-subtitle" },
|
||||
position: "footer",
|
||||
},
|
||||
secondary_button: {
|
||||
label: "link",
|
||||
},
|
||||
secondary_button_top: {
|
||||
label: "link top",
|
||||
action: {
|
||||
type: "SHOW_FIREFOX_ACCOUNTS",
|
||||
data: { entrypoint: "test" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "AW_STEP2",
|
||||
order: 1,
|
||||
content: {
|
||||
zap: true,
|
||||
title: "Step 2 longzaptest",
|
||||
tiles: {
|
||||
type: "topsites",
|
||||
info: true,
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: "link",
|
||||
},
|
||||
help_text: {
|
||||
text: "Here's some helptext with an icon",
|
||||
img: {
|
||||
src:
|
||||
"chrome://activity-stream/content/data/content/assets/cfr_fb_container.png",
|
||||
},
|
||||
position: "footer",
|
||||
},
|
||||
{
|
||||
id: "AW_STEP2",
|
||||
order: 1,
|
||||
content: {
|
||||
zap: true,
|
||||
title: "Step 2 longzaptest",
|
||||
tiles: {
|
||||
type: "topsites",
|
||||
info: true,
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "AW_STEP3",
|
||||
order: 2,
|
||||
content: {
|
||||
title: "Step 3",
|
||||
tiles: {
|
||||
type: "image",
|
||||
media_type: "test-img",
|
||||
source: {
|
||||
default:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iIzQ1YTFmZiIgZmlsbC1vcGFjaXR5PSJjb250ZXh0LWZpbGwtb3BhY2l0eSIgZD0iTTE1Ljg0NSA2LjA2NEExLjEgMS4xIDAgMCAwIDE1IDUuMzMxTDEwLjkxMSA0LjYgOC45ODUuNzM1YTEuMSAxLjEgMCAwIDAtMS45NjkgMEw1LjA4OSA0LjZsLTQuMDgxLjcyOWExLjEgMS4xIDAgMCAwLS42MTUgMS44MzRMMy4zMiAxMC4zMWwtLjYwOSA0LjM2YTEuMSAxLjEgMCAwIDAgMS42IDEuMTI3TDggMTMuODczbDMuNjkgMS45MjdhMS4xIDEuMSAwIDAgMCAxLjYtMS4xMjdsLS42MS00LjM2MyAyLjkyNi0zLjE0NmExLjEgMS4xIDAgMCAwIC4yMzktMS4xeiIvPjwvc3ZnPg==",
|
||||
},
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: "Import",
|
||||
action: {
|
||||
type: "SHOW_MIGRATION_WIZARD",
|
||||
data: { source: "chrome" },
|
||||
},
|
||||
},
|
||||
help_text: {
|
||||
text: "Here's some sample help text",
|
||||
position: "default",
|
||||
},
|
||||
secondary_button: {
|
||||
label: "link",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
{
|
||||
id: "AW_STEP3",
|
||||
order: 2,
|
||||
content: {
|
||||
title: "Step 3",
|
||||
tiles: {
|
||||
type: "image",
|
||||
media_type: "test-img",
|
||||
source: {
|
||||
default:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iIzQ1YTFmZiIgZmlsbC1vcGFjaXR5PSJjb250ZXh0LWZpbGwtb3BhY2l0eSIgZD0iTTE1Ljg0NSA2LjA2NEExLjEgMS4xIDAgMCAwIDE1IDUuMzMxTDEwLjkxMSA0LjYgOC45ODUuNzM1YTEuMSAxLjEgMCAwIDAtMS45NjkgMEw1LjA4OSA0LjZsLTQuMDgxLjcyOWExLjEgMS4xIDAgMCAwLS42MTUgMS44MzRMMy4zMiAxMC4zMWwtLjYwOSA0LjM2YTEuMSAxLjEgMCAwIDAgMS42IDEuMTI3TDggMTMuODczbDMuNjkgMS45MjdhMS4xIDEuMSAwIDAgMCAxLjYtMS4xMjdsLS42MS00LjM2MyAyLjkyNi0zLjE0NmExLjEgMS4xIDAgMCAwIC4yMzktMS4xeiIvPjwvc3ZnPg==",
|
||||
},
|
||||
},
|
||||
primary_button: {
|
||||
label: "Next",
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: "Import",
|
||||
action: {
|
||||
type: "SHOW_MIGRATION_WIZARD",
|
||||
data: { source: "chrome" },
|
||||
},
|
||||
},
|
||||
help_text: {
|
||||
text: "Here's some sample help text",
|
||||
position: "default",
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
async function getAboutWelcomeParent(browser) {
|
||||
let windowGlobalParent = browser.browsingContext.currentWindowGlobal;
|
||||
return windowGlobalParent.getActor("AboutWelcome");
|
||||
}
|
||||
|
||||
const TEST_MULTISTAGE_JSON = JSON.stringify(TEST_MULTISTAGE_CONTENT);
|
||||
/**
|
||||
* Sets the aboutwelcome pref to enabled simplified welcome UI
|
||||
@@ -135,7 +124,7 @@ async function setAboutWelcomePref(value) {
|
||||
return pushPrefs([SEPARATE_ABOUT_WELCOME_PREF, value]);
|
||||
}
|
||||
|
||||
async function setAboutWelcomeMultiStage(value) {
|
||||
async function setAboutWelcomeMultiStage(value = "") {
|
||||
return pushPrefs([ABOUT_WELCOME_OVERRIDE_CONTENT_PREF, value]);
|
||||
}
|
||||
|
||||
@@ -277,7 +266,6 @@ add_task(async function test_multistage_zeroOnboarding_experimentAPI() {
|
||||
);
|
||||
|
||||
await doExperimentCleanup();
|
||||
Assert.equal(ExperimentAPI._store.getAll().length, 0, "Cleanup done");
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -297,7 +285,10 @@ add_task(async function test_multistage_aboutwelcome_experimentAPI() {
|
||||
feature: {
|
||||
enabled: true,
|
||||
featureId: "aboutwelcome",
|
||||
value: TEST_MULTISTAGE_CONTENT,
|
||||
value: {
|
||||
id: "my-mochitest-experiment",
|
||||
screens: TEST_MULTISTAGE_CONTENT,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -313,12 +304,18 @@ add_task(async function test_multistage_aboutwelcome_experimentAPI() {
|
||||
"about:welcome",
|
||||
true
|
||||
);
|
||||
registerCleanupFunction(() => {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
const browser = tab.linkedBrowser;
|
||||
|
||||
let aboutWelcomeActor = await getAboutWelcomeParent(browser);
|
||||
const sandbox = sinon.createSandbox();
|
||||
// Stub AboutWelcomeParent Content Message Handler
|
||||
sandbox.spy(aboutWelcomeActor, "onContentMessage");
|
||||
registerCleanupFunction(() => {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
await test_screen_content(
|
||||
browser,
|
||||
"multistage step 1",
|
||||
@@ -335,13 +332,22 @@ add_task(async function test_multistage_aboutwelcome_experimentAPI() {
|
||||
"label.theme",
|
||||
"input[type='radio']",
|
||||
"div.indicator.current",
|
||||
"p.helptext.footer[data-l10n-id='onboarding-multistage-set-default-subtitle']",
|
||||
],
|
||||
// Unexpected selectors:
|
||||
["main.AW_STEP2", "main.AW_STEP3", "div.tiles-container.info"]
|
||||
);
|
||||
|
||||
await onButtonClick(browser, "button.primary");
|
||||
|
||||
Assert.ok(
|
||||
aboutWelcomeActor.onContentMessage.args.find(
|
||||
args =>
|
||||
args[1].event === "CLICK_BUTTON" &&
|
||||
args[1].message_id === "MY-MOCHITEST-EXPERIMENT_AW_STEP1"
|
||||
),
|
||||
"Telemetry should join id defined in feature value with screen"
|
||||
);
|
||||
|
||||
await test_screen_content(
|
||||
browser,
|
||||
"multistage step 2",
|
||||
@@ -353,8 +359,6 @@ add_task(async function test_multistage_aboutwelcome_experimentAPI() {
|
||||
"h1.welcomeZap",
|
||||
"span.zap.long",
|
||||
"div.tiles-container.info",
|
||||
"p.helptext",
|
||||
"img.helptext-img",
|
||||
],
|
||||
// Unexpected selectors:
|
||||
["main.AW_STEP1", "main.AW_STEP3", "div.secondary-cta.top", "div.test-img"]
|
||||
@@ -386,7 +390,6 @@ add_task(async function test_multistage_aboutwelcome_experimentAPI() {
|
||||
);
|
||||
|
||||
await doExperimentCleanup();
|
||||
Assert.equal(ExperimentAPI._store.getAll().length, 0, "Cleanup done");
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -499,11 +502,6 @@ add_task(async function test_Multistage_About_Welcome_navigation() {
|
||||
);
|
||||
});
|
||||
|
||||
async function getAboutWelcomeParent(browser) {
|
||||
let windowGlobalParent = browser.browsingContext.currentWindowGlobal;
|
||||
return windowGlobalParent.getActor("AboutWelcome");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the multistage welcome UI primary button action
|
||||
*/
|
||||
@@ -572,7 +570,7 @@ add_task(async function test_AWMultistage_Primary_Action() {
|
||||
);
|
||||
Assert.equal(
|
||||
impressionCall.args[1].message_id,
|
||||
`${TEST_MULTISTAGE_CONTENT.id}_SITES`.toUpperCase(),
|
||||
"DEFAULT_ABOUTWELCOME_SITES",
|
||||
"SITES MessageId sent in impression event telemetry"
|
||||
);
|
||||
}
|
||||
@@ -606,7 +604,7 @@ add_task(async function test_AWMultistage_Primary_Action() {
|
||||
);
|
||||
Assert.equal(
|
||||
performanceCall.args[1].message_id,
|
||||
TEST_MULTISTAGE_CONTENT.id.toUpperCase(),
|
||||
"DEFAULT_ABOUTWELCOME",
|
||||
"MessageId sent in performance event telemetry"
|
||||
);
|
||||
}
|
||||
@@ -628,12 +626,14 @@ add_task(async function test_AWMultistage_Primary_Action() {
|
||||
);
|
||||
Assert.equal(
|
||||
clickCall.args[1].message_id,
|
||||
`${TEST_MULTISTAGE_CONTENT.id}_${TEST_MULTISTAGE_CONTENT.screens[0].id}`.toUpperCase(),
|
||||
`DEFAULT_ABOUTWELCOME_${TEST_MULTISTAGE_CONTENT[0].id}`.toUpperCase(),
|
||||
"MessageId sent in click event telemetry"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_AWMultistage_Secondary_Open_URL_Action() {
|
||||
let { doExperimentCleanup } = ExperimentFakes.enrollmentHelper();
|
||||
await doExperimentCleanup();
|
||||
let browser = await openAboutWelcome();
|
||||
let aboutWelcomeActor = await getAboutWelcomeParent(browser);
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
"use strict";
|
||||
|
||||
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF =
|
||||
"browser.aboutwelcome.overrideContent";
|
||||
|
||||
const TEST_RTAMO_WELCOME_CONTENT = {
|
||||
template: "return_to_amo",
|
||||
name: "Test add on",
|
||||
url: "https://test.xpi",
|
||||
iconURL: "https://test.svg",
|
||||
content: {
|
||||
header: { string_id: "onboarding-welcome-header" },
|
||||
subtitle: { string_id: "return-to-amo-subtitle" },
|
||||
text: {
|
||||
string_id: "return-to-amo-addon-title",
|
||||
},
|
||||
primary_button: {
|
||||
label: { string_id: "return-to-amo-add-extension-label" },
|
||||
action: {
|
||||
type: "INSTALL_ADDON_FROM_URL",
|
||||
data: { url: null, telemetrySource: "rtamo" },
|
||||
},
|
||||
},
|
||||
startButton: {
|
||||
label: {
|
||||
string_id: "onboarding-start-browsing-button-label",
|
||||
},
|
||||
message_id: "RTAMO_START_BROWSING_BUTTON",
|
||||
action: {
|
||||
type: "OPEN_AWESOME_BAR",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const TEST_RTAMO_WELCOME_JSON = JSON.stringify(TEST_RTAMO_WELCOME_CONTENT);
|
||||
|
||||
async function setAboutWelcomeOverride(value) {
|
||||
return pushPrefs([ABOUT_WELCOME_OVERRIDE_CONTENT_PREF, value]);
|
||||
}
|
||||
const { ASRouter } = ChromeUtils.import(
|
||||
"resource://activity-stream/lib/ASRouter.jsm"
|
||||
);
|
||||
const { AddonRepository } = ChromeUtils.import(
|
||||
"resource://gre/modules/addons/AddonRepository.jsm"
|
||||
);
|
||||
const { AttributionCode } = ChromeUtils.import(
|
||||
"resource:///modules/AttributionCode.jsm"
|
||||
);
|
||||
|
||||
async function openRTAMOWelcomePage() {
|
||||
await setAboutWelcomeOverride(TEST_RTAMO_WELCOME_JSON);
|
||||
let sandbox = sinon.createSandbox();
|
||||
// Can't properly stub the child/parent actors so instead
|
||||
// we stub the modules they depend on for the RTAMO flow
|
||||
// to ensure the right thing is rendered.
|
||||
await ASRouter.forceAttribution({
|
||||
source: "addons.mozilla.org",
|
||||
medium: "referral",
|
||||
campaign: "non-fx-button",
|
||||
content: "iridium@particlecore.github.io",
|
||||
experiment: "ua-onboarding",
|
||||
variation: "chrome",
|
||||
ua: "Google Chrome 123",
|
||||
dltoken: "00000000-0000-0000-0000-000000000000",
|
||||
});
|
||||
|
||||
sandbox
|
||||
.stub(AddonRepository, "getAddonsByIDs")
|
||||
.resolves([
|
||||
{ sourceURI: { scheme: "https", spec: "https://test.xpi" }, icons: {} },
|
||||
]);
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"about:welcome",
|
||||
true
|
||||
);
|
||||
registerCleanupFunction(() => {
|
||||
registerCleanupFunction(async () => {
|
||||
sandbox.restore();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
pushPrefs([ABOUT_WELCOME_OVERRIDE_CONTENT_PREF, ""]);
|
||||
// Clear cache call is only possible in a testing environment
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
env.set("XPCSHELL_TEST_PROFILE_DIR", "testing");
|
||||
|
||||
// Clear and refresh Attribution, and then fetch the messages again to update
|
||||
AttributionCode._clearCache();
|
||||
await AttributionCode.getAttrDataAsync();
|
||||
});
|
||||
|
||||
return tab.linkedBrowser;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ const MANIFEST = {
|
||||
description: "The about:welcome page",
|
||||
enabledFallbackPref: "browser.aboutwelcome.enabled",
|
||||
variables: {
|
||||
screens: {
|
||||
type: "json",
|
||||
fallbackPref: "browser.aboutwelcome.screens",
|
||||
},
|
||||
skipFocus: {
|
||||
type: "boolean",
|
||||
fallbackPref: "browser.aboutwelcome.skipFocus",
|
||||
|
||||
Reference in New Issue
Block a user