Bug 1829043 - Add actions for AboutWelcome embedded migration wizard. r=pdahiya,mconley
Add some properties to the migration wizard screen JSON to specify what action to perform when CTAs inside the embedded migration wizard are clicked. This lets us advance screens when the cancel or finish button is clicked, and send telemetry when the start button is clicked. In theory we could perform any special message actions too, but for now we only need telemetry and screen navigation. Differential Revision: https://phabricator.services.mozilla.com/D176358
This commit is contained in:
@@ -185,7 +185,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
||||
/* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
|
||||
/* harmony import */ var _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(17);
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@@ -493,6 +493,7 @@ class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
|
||||
props
|
||||
} = this;
|
||||
const value = event.currentTarget.value ?? event.currentTarget.getAttribute("value");
|
||||
const source = event.source || value;
|
||||
let targetContent = props.content[value] || props.content.tiles || props.content.languageSwitcher;
|
||||
|
||||
if (!(targetContent && targetContent.action)) {
|
||||
@@ -500,12 +501,12 @@ class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
|
||||
} // Send telemetry before waiting on actions
|
||||
|
||||
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(props.messageId, value, event.name); // Send additional telemetry if a messaging surface like feature callout is
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(props.messageId, source, event.name); // Send additional telemetry if a messaging surface like feature callout is
|
||||
// dismissed via the dismiss button. Other causes of dismissal will be
|
||||
// handled separately by the messaging surface's own code.
|
||||
|
||||
if (value === "dismiss_button" && !event.name) {
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendDismissTelemetry(props.messageId, value);
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendDismissTelemetry(props.messageId, source);
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -737,6 +738,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _HeroImage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(13);
|
||||
/* harmony import */ var _OnboardingVideo__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(14);
|
||||
/* harmony import */ var _AdditionalCTA__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(15);
|
||||
/* harmony import */ var _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(16);
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@@ -752,6 +754,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
|
||||
|
||||
|
||||
|
||||
const MultiStageProtonScreen = props => {
|
||||
const {
|
||||
autoAdvance,
|
||||
@@ -909,9 +912,9 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
||||
activeMultiSelect: this.props.activeMultiSelect,
|
||||
setActiveMultiSelect: this.props.setActiveMultiSelect,
|
||||
handleAction: this.props.handleAction
|
||||
}) : null, content.tiles && content.tiles.type === "migration-wizard" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("migration-wizard", {
|
||||
"auto-request-state": ""
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("panel-list", null)) : null);
|
||||
}) : null, content.tiles && content.tiles.type === "migration-wizard" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__.EmbeddedMigrationWizard, {
|
||||
handleAction: this.props.handleAction
|
||||
}) : null);
|
||||
}
|
||||
|
||||
renderNoodles() {
|
||||
@@ -1863,6 +1866,59 @@ const AdditionalCTA = ({
|
||||
/* 16 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "EmbeddedMigrationWizard": () => (/* binding */ EmbeddedMigrationWizard)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const EmbeddedMigrationWizard = ({
|
||||
handleAction
|
||||
}) => {
|
||||
const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
|
||||
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
||||
const handleBeginMigration = () => {
|
||||
handleAction({
|
||||
currentTarget: {
|
||||
value: "migrate_start"
|
||||
},
|
||||
source: "primary_button"
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
handleAction({
|
||||
currentTarget: {
|
||||
value: "migrate_close"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const {
|
||||
current
|
||||
} = ref;
|
||||
current === null || current === void 0 ? void 0 : current.addEventListener("MigrationWizard:BeginMigration", handleBeginMigration);
|
||||
current === null || current === void 0 ? void 0 : current.addEventListener("MigrationWizard:Close", handleClose);
|
||||
return () => {
|
||||
current === null || current === void 0 ? void 0 : current.removeEventListener("MigrationWizard:BeginMigration", handleBeginMigration);
|
||||
current === null || current === void 0 ? void 0 : current.removeEventListener("MigrationWizard:Close", handleClose);
|
||||
};
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("migration-wizard", {
|
||||
"auto-request-state": "",
|
||||
ref: ref
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("panel-list", null));
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 17 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "BASE_PARAMS": () => (/* binding */ BASE_PARAMS),
|
||||
@@ -1902,7 +1958,7 @@ function addUtmParams(url, utmTerm) {
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
/* 17 */
|
||||
/* 18 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
@@ -1913,7 +1969,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
||||
/* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17);
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@@ -2108,7 +2164,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
||||
/* harmony import */ var _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
|
||||
/* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17);
|
||||
/* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18);
|
||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|
||||
@@ -356,6 +356,14 @@ const MR_ABOUT_WELCOME_DEFAULT = {
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-import.svg') var(--mr-secondary-position) no-repeat var(--mr-screen-background-color)",
|
||||
progress_bar: true,
|
||||
migrate_start: {
|
||||
action: {},
|
||||
},
|
||||
migrate_close: {
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: {
|
||||
string_id: "mr2022-onboarding-secondary-skip-button-label",
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
export const EmbeddedMigrationWizard = ({ handleAction }) => {
|
||||
const ref = useRef();
|
||||
useEffect(() => {
|
||||
const handleBeginMigration = () => {
|
||||
handleAction({
|
||||
currentTarget: { value: "migrate_start" },
|
||||
source: "primary_button",
|
||||
});
|
||||
};
|
||||
const handleClose = () => {
|
||||
handleAction({ currentTarget: { value: "migrate_close" } });
|
||||
};
|
||||
const { current } = ref;
|
||||
current?.addEventListener(
|
||||
"MigrationWizard:BeginMigration",
|
||||
handleBeginMigration
|
||||
);
|
||||
current?.addEventListener("MigrationWizard:Close", handleClose);
|
||||
return () => {
|
||||
current?.removeEventListener(
|
||||
"MigrationWizard:BeginMigration",
|
||||
handleBeginMigration
|
||||
);
|
||||
current?.removeEventListener("MigrationWizard:Close", handleClose);
|
||||
};
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
return (
|
||||
<migration-wizard auto-request-state="" ref={ref}>
|
||||
<panel-list />
|
||||
</migration-wizard>
|
||||
);
|
||||
};
|
||||
@@ -338,6 +338,7 @@ export class WelcomeScreen extends React.PureComponent {
|
||||
let { props } = this;
|
||||
const value =
|
||||
event.currentTarget.value ?? event.currentTarget.getAttribute("value");
|
||||
const source = event.source || value;
|
||||
let targetContent =
|
||||
props.content[value] ||
|
||||
props.content.tiles ||
|
||||
@@ -347,13 +348,13 @@ export class WelcomeScreen extends React.PureComponent {
|
||||
return;
|
||||
}
|
||||
// Send telemetry before waiting on actions
|
||||
AboutWelcomeUtils.sendActionTelemetry(props.messageId, value, event.name);
|
||||
AboutWelcomeUtils.sendActionTelemetry(props.messageId, source, event.name);
|
||||
|
||||
// Send additional telemetry if a messaging surface like feature callout is
|
||||
// dismissed via the dismiss button. Other causes of dismissal will be
|
||||
// handled separately by the messaging surface's own code.
|
||||
if (value === "dismiss_button" && !event.name) {
|
||||
AboutWelcomeUtils.sendDismissTelemetry(props.messageId, value);
|
||||
AboutWelcomeUtils.sendDismissTelemetry(props.messageId, source);
|
||||
}
|
||||
|
||||
let { action } = targetContent;
|
||||
|
||||
@@ -18,6 +18,7 @@ import { CTAParagraph } from "./CTAParagraph";
|
||||
import { HeroImage } from "./HeroImage";
|
||||
import { OnboardingVideo } from "./OnboardingVideo";
|
||||
import { AdditionalCTA } from "./AdditionalCTA";
|
||||
import { EmbeddedMigrationWizard } from "./EmbeddedMigrationWizard";
|
||||
|
||||
export const MultiStageProtonScreen = props => {
|
||||
const { autoAdvance, handleAction, order } = props;
|
||||
@@ -227,9 +228,7 @@ export class ProtonScreen extends React.PureComponent {
|
||||
/>
|
||||
) : null}
|
||||
{content.tiles && content.tiles.type === "migration-wizard" ? (
|
||||
<migration-wizard auto-request-state="">
|
||||
<panel-list />
|
||||
</migration-wizard>
|
||||
<EmbeddedMigrationWizard handleAction={this.props.handleAction} />
|
||||
) : null}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -1166,8 +1166,15 @@ These record the telemetry metrics during the Firefox onboarding experience.
|
||||
"locale": "en-US",
|
||||
"experiments": {},
|
||||
"release_channel": "default",
|
||||
"addon_version": "20200330194034"
|
||||
"message_id": ["DEFAULT_ABOUTWELCOME" | "DEFAULT_ABOUTWELCOME_AW_GET_STARTED" | "DEFAULT_ABOUTWELCOME_SITES" | "DEFAULT_ABOUTWELCOME_AW_IMPORT_SETTINGS" | "DEFAULT_ABOUTWELCOME_AW_CHOOSE_THEME", "RTAMO_DEFAULT_WELCOME"],
|
||||
"addon_version": "20200330194034",
|
||||
"message_id": [
|
||||
| "DEFAULT_ABOUTWELCOME"
|
||||
| "DEFAULT_ABOUTWELCOME_AW_GET_STARTED"
|
||||
| "DEFAULT_ABOUTWELCOME_SITES"
|
||||
| "DEFAULT_ABOUTWELCOME_AW_IMPORT_SETTINGS"
|
||||
| "DEFAULT_ABOUTWELCOME_AW_CHOOSE_THEME"
|
||||
| "RTAMO_DEFAULT_WELCOME"
|
||||
],
|
||||
"event": "IMPRESSION",
|
||||
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
|
||||
"event_context": { "page": "about:welcome" },
|
||||
@@ -1192,8 +1199,13 @@ These record the telemetry metrics during the Firefox onboarding experience.
|
||||
"locale": "en-US",
|
||||
"experiments": {},
|
||||
"release_channel": "default",
|
||||
"addon_version": "20200330194034"
|
||||
"message_id": ["DEFAULT_ABOUTWELCOME_AW_GET_STARTED" | "DEFAULT_ABOUTWELCOME_AW_IMPORT_SETTINGS" | "DEFAULT_ABOUTWELCOME_AW_CHOOSE_THEME" | "RTAMO_DEFAULT_WELCOME"],
|
||||
"addon_version": "20200330194034",
|
||||
"message_id": [
|
||||
| "DEFAULT_ABOUTWELCOME_AW_GET_STARTED"
|
||||
| "DEFAULT_ABOUTWELCOME_AW_IMPORT_SETTINGS"
|
||||
| "DEFAULT_ABOUTWELCOME_AW_CHOOSE_THEME"
|
||||
| "RTAMO_DEFAULT_WELCOME"
|
||||
],
|
||||
"event": "CLICK_BUTTION",
|
||||
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
|
||||
"event_context": { "page": "about:welcome", "source": ["primary_button" | "secondary_button"] },
|
||||
@@ -1218,7 +1230,7 @@ These record the telemetry metrics during the Firefox onboarding experience.
|
||||
"locale": "en-US",
|
||||
"experiments": {},
|
||||
"release_channel": "default",
|
||||
"addon_version": "20200330194034"
|
||||
"addon_version": "20200330194034",
|
||||
"message_id": "RTAMO_DEFAULT_WELCOME",
|
||||
"event": "INSTALL",
|
||||
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
|
||||
@@ -1235,6 +1247,26 @@ These record the telemetry metrics during the Firefox onboarding experience.
|
||||
}
|
||||
```
|
||||
|
||||
### Onboarding embedded migration interactions
|
||||
|
||||
```js
|
||||
{
|
||||
"client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
|
||||
"version": "76.0a1",
|
||||
"locale": "en-US",
|
||||
"experiments": {},
|
||||
"release_channel": "default",
|
||||
"addon_version": "20200330194034",
|
||||
"message_id": "MR_WELCOME_DEFAULT_0_AW_IMPORT_SETTINGS_EMBEDDED",
|
||||
"event": "CLICK_BUTTION",
|
||||
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
|
||||
"event_context": {
|
||||
"page": "about:welcome",
|
||||
"source": ["primary_button" | "migrate_close"],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Onboarding session end ping
|
||||
|
||||
```js
|
||||
@@ -1244,12 +1276,19 @@ These record the telemetry metrics during the Firefox onboarding experience.
|
||||
"locale": "en-US",
|
||||
"experiments": {},
|
||||
"release_channel": "default",
|
||||
"addon_version": "20200330194034"
|
||||
"addon_version": "20200330194034",
|
||||
"message_id": "DEFAULT_ABOUTWELCOME",
|
||||
"event": "SESSION_END",
|
||||
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
|
||||
"event_context": { "page": "about:welcome", "reason":
|
||||
["welcome-window-closed" | "welcome-tab-closed" | "app-shut-down" | "address-bar-navigated"]},
|
||||
"event_context": {
|
||||
"page": "about:welcome",
|
||||
"reason": [
|
||||
| "welcome-window-closed"
|
||||
| "welcome-tab-closed"
|
||||
| "app-shut-down"
|
||||
| "address-bar-navigated"
|
||||
]
|
||||
},
|
||||
"attribution": {
|
||||
"source": "mozilla.org",
|
||||
"medium": "referral",
|
||||
|
||||
@@ -203,6 +203,14 @@ module.exports = function(config) {
|
||||
functions: 0,
|
||||
branches: 0,
|
||||
},
|
||||
"content-src/aboutwelcome/components/EmbeddedMigrationWizard.jsx": {
|
||||
// This file is covered by the mochitest: browser_aboutwelcome_multistage_mr.js
|
||||
// Can't be unit tested because it relies on the migration-wizard custom element
|
||||
statements: 0,
|
||||
lines: 0,
|
||||
functions: 0,
|
||||
branches: 0,
|
||||
},
|
||||
"content-src/aboutwelcome/**/*.jsx": {
|
||||
statements: 62,
|
||||
lines: 60,
|
||||
|
||||
@@ -10,6 +10,9 @@ const { AboutWelcomeTelemetry } = ChromeUtils.import(
|
||||
const { AWScreenUtils } = ChromeUtils.import(
|
||||
"resource://activity-stream/lib/AWScreenUtils.jsm"
|
||||
);
|
||||
const { InternalTestingProfileMigrator } = ChromeUtils.importESModule(
|
||||
"resource:///modules/InternalTestingProfileMigrator.sys.mjs"
|
||||
);
|
||||
|
||||
async function clickVisibleButton(browser, selector) {
|
||||
// eslint-disable-next-line no-shadow
|
||||
@@ -367,6 +370,37 @@ add_task(async function test_aboutwelcome_embedded_migration() {
|
||||
set: [["browser.migrate.internal-testing.enabled", true]],
|
||||
});
|
||||
|
||||
const sandbox = sinon.createSandbox();
|
||||
sandbox
|
||||
.stub(InternalTestingProfileMigrator.prototype, "getResources")
|
||||
.callsFake(() =>
|
||||
Promise.resolve([
|
||||
{
|
||||
type: MigrationUtils.resourceTypes.BOOKMARKS,
|
||||
migrate: () => {},
|
||||
},
|
||||
])
|
||||
);
|
||||
sandbox.stub(MigrationUtils, "_importQuantities").value({
|
||||
bookmarks: 123,
|
||||
history: 123,
|
||||
logins: 123,
|
||||
});
|
||||
const migrated = new Promise(resolve => {
|
||||
sandbox
|
||||
.stub(InternalTestingProfileMigrator.prototype, "migrate")
|
||||
.callsFake((aResourceTypes, aStartup, aProfile, aProgressCallback) => {
|
||||
aProgressCallback(MigrationUtils.resourceTypes.BOOKMARKS);
|
||||
Services.obs.notifyObservers(null, "Migration:Ended");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let telemetrySpy = sandbox.spy(
|
||||
AboutWelcomeTelemetry.prototype,
|
||||
"sendTelemetry"
|
||||
);
|
||||
|
||||
const TEST_CONTENT = [
|
||||
{
|
||||
id: "AW_IMPORT_SETTINGS_EMBEDDED",
|
||||
@@ -380,6 +414,12 @@ add_task(async function test_aboutwelcome_embedded_migration() {
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-import.svg') var(--mr-secondary-position) no-repeat var(--mr-screen-background-color)",
|
||||
progress_bar: true,
|
||||
migrate_start: {
|
||||
action: {},
|
||||
},
|
||||
migrate_close: {
|
||||
action: { navigate: true },
|
||||
},
|
||||
secondary_button: {
|
||||
label: {
|
||||
string_id: "mr2022-onboarding-secondary-skip-button-label",
|
||||
@@ -391,6 +431,31 @@ add_task(async function test_aboutwelcome_embedded_migration() {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "AW_STEP2",
|
||||
content: {
|
||||
position: "split",
|
||||
split_narrow_bkg_position: "-228px",
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-gratitude.svg') var(--mr-secondary-position) no-repeat, var(--mr-screen-background-color)",
|
||||
progress_bar: true,
|
||||
logo: {},
|
||||
title: {
|
||||
string_id: "mr2022-onboarding-gratitude-title",
|
||||
},
|
||||
subtitle: {
|
||||
string_id: "mr2022-onboarding-gratitude-subtitle",
|
||||
},
|
||||
primary_button: {
|
||||
label: {
|
||||
string_id: "mr2022-onboarding-gratitude-primary-button-label",
|
||||
},
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await setAboutWelcomeMultiStage(JSON.stringify(TEST_CONTENT)); // NB: calls SpecialPowers.pushPrefEnv
|
||||
@@ -410,68 +475,115 @@ add_task(async function test_aboutwelcome_embedded_migration() {
|
||||
|
||||
// Do a basic test to make sure that the <migration-wizard> is on the right
|
||||
// page and the <panel-list> can open.
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
const { MigrationWizardConstants } = ChromeUtils.importESModule(
|
||||
"chrome://browser/content/migration/migration-wizard-constants.mjs"
|
||||
);
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[`panel-item[key="${InternalTestingProfileMigrator.key}"]`],
|
||||
async menuitemSelector => {
|
||||
const { MigrationWizardConstants } = ChromeUtils.importESModule(
|
||||
"chrome://browser/content/migration/migration-wizard-constants.mjs"
|
||||
);
|
||||
|
||||
let wizard = content.document.querySelector("migration-wizard");
|
||||
let shadow = wizard.openOrClosedShadowRoot;
|
||||
let deck = shadow.querySelector("#wizard-deck");
|
||||
|
||||
// It's unlikely but possible that the deck might not yet be showing the
|
||||
// selection page yet, in which case we wait for that page to appear.
|
||||
if (deck.selectedViewName !== MigrationWizardConstants.PAGES.SELECTION) {
|
||||
await ContentTaskUtils.waitForMutationCondition(
|
||||
deck,
|
||||
{ attributeFilter: ["selected-view"] },
|
||||
() => {
|
||||
return (
|
||||
deck.getAttribute("selected-view") ===
|
||||
`page-${MigrationWizardConstants.PAGES.SELECTION}`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Assert.ok(true, "Selection page is being shown in the migration wizard.");
|
||||
|
||||
// Now let's make sure that the <panel-list> can appear.
|
||||
let panelList = wizard.querySelector("panel-list");
|
||||
Assert.ok(panelList, "Found the <panel-list>.");
|
||||
|
||||
// The "shown" event from the panel-list is coming from a lower level
|
||||
// of privilege than where we're executing this SpecialPowers.spawn
|
||||
// task. In order to properly listen for it, we have to ask
|
||||
// ContentTaskUtils.waitForEvent to listen for untrusted events.
|
||||
let shown = ContentTaskUtils.waitForEvent(
|
||||
panelList,
|
||||
"shown",
|
||||
false /* capture */,
|
||||
null /* checkFn */,
|
||||
true /* wantsUntrusted */
|
||||
);
|
||||
let selector = shadow.querySelector("#browser-profile-selector");
|
||||
selector.click();
|
||||
await shown;
|
||||
|
||||
let panelRect = panelList.getBoundingClientRect();
|
||||
let selectorRect = selector.getBoundingClientRect();
|
||||
|
||||
// Recalculate the <panel-list> rect top value relative to the top-left
|
||||
// of the selectorRect. We expect the <panel-list> to be tightly anchored
|
||||
// to the bottom of the <button>, so we expect this new value to be 0.
|
||||
let panelTopLeftRelativeToAnchorTopLeft =
|
||||
panelRect.top - selectorRect.top - selectorRect.height;
|
||||
Assert.equal(
|
||||
panelTopLeftRelativeToAnchorTopLeft,
|
||||
0,
|
||||
"Panel should be tightly anchored to the bottom of the button shadow node."
|
||||
);
|
||||
|
||||
let panelItem = wizard.querySelector(menuitemSelector);
|
||||
panelItem.click();
|
||||
|
||||
let importButton = shadow.querySelector("#import");
|
||||
importButton.click();
|
||||
}
|
||||
);
|
||||
|
||||
await migrated;
|
||||
Assert.ok(
|
||||
telemetrySpy.calledWithMatch({
|
||||
event: "CLICK_BUTTON",
|
||||
event_context: { source: "primary_button", page: "about:welcome" },
|
||||
message_id: sinon.match.string,
|
||||
}),
|
||||
"Should have sent telemetry for clicking the 'Import' button."
|
||||
);
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
let wizard = content.document.querySelector("migration-wizard");
|
||||
let shadow = wizard.openOrClosedShadowRoot;
|
||||
let deck = shadow.querySelector("#wizard-deck");
|
||||
|
||||
// It's unlikely but possible that the deck might not yet be showing the
|
||||
// selection page yet, in which case we wait for that page to appear.
|
||||
if (deck.selectedViewName !== MigrationWizardConstants.PAGES.SELECTION) {
|
||||
await ContentTaskUtils.waitForMutationCondition(
|
||||
deck,
|
||||
{ attributeFilter: ["selected-view"] },
|
||||
() => {
|
||||
return (
|
||||
deck.getAttribute("selected-view") ===
|
||||
`page-${MigrationWizardConstants.PAGES.SELECTION}`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Assert.ok(true, "Selection page is being shown in the migration wizard.");
|
||||
|
||||
// Now let's make sure that the <panel-list> can appear.
|
||||
let panelList = wizard.querySelector("panel-list");
|
||||
Assert.ok(panelList, "Found the <panel-list>.");
|
||||
|
||||
// The "shown" event from the panel-list is coming from a lower level
|
||||
// of privilege than where we're executing this SpecialPowers.spawn
|
||||
// task. In order to properly listen for it, we have to ask
|
||||
// ContentTaskUtils.waitForEvent to listen for untrusted events.
|
||||
let shown = ContentTaskUtils.waitForEvent(
|
||||
panelList,
|
||||
"shown",
|
||||
false /* capture */,
|
||||
null /* checkFn */,
|
||||
true /* wantsUntrusted */
|
||||
let continueButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .continue-button"
|
||||
);
|
||||
let selector = shadow.querySelector("#browser-profile-selector");
|
||||
selector.click();
|
||||
await shown;
|
||||
|
||||
let panelRect = panelList.getBoundingClientRect();
|
||||
let selectorRect = selector.getBoundingClientRect();
|
||||
|
||||
// Recalculate the <panel-list> rect top value relative to the top-left
|
||||
// of the selectorRect. We expect the <panel-list> to be tightly anchored
|
||||
// to the bottom of the <button>, so we expect this new value to be 0.
|
||||
let panelTopLeftRelativeToAnchorTopLeft =
|
||||
panelRect.top - selectorRect.top - selectorRect.height;
|
||||
Assert.equal(
|
||||
panelTopLeftRelativeToAnchorTopLeft,
|
||||
0,
|
||||
"Panel should be tightly anchored to the bottom of the button shadow node."
|
||||
continueButton.click();
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.querySelector("main.AW_STEP2"),
|
||||
"Waiting for step 2 to render"
|
||||
);
|
||||
});
|
||||
|
||||
Assert.ok(
|
||||
telemetrySpy.calledWithMatch({
|
||||
event: "CLICK_BUTTON",
|
||||
event_context: { source: "migrate_close", page: "about:welcome" },
|
||||
message_id: sinon.match.string,
|
||||
}),
|
||||
"Should have sent telemetry for clicking the 'Continue' button."
|
||||
);
|
||||
|
||||
// cleanup
|
||||
await SpecialPowers.popPrefEnv(); // for the InternalTestingProfileMigrator.
|
||||
await SpecialPowers.popPrefEnv(); // for setAboutWelcomeMultiStage
|
||||
await cleanup();
|
||||
sandbox.restore();
|
||||
let migrator = await MigrationUtils.getMigrator(
|
||||
InternalTestingProfileMigrator.key
|
||||
);
|
||||
migrator.flushResourceCache();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user