forked from mirrors/gecko-dev
Bug 1863400 - Part 7: Move about:welcome Karma unit tests to browser/components/aboutwelcome folder. r=pdahiya
Depends on D193121 Differential Revision: https://phabricator.services.mozilla.com/D193122
This commit is contained in:
parent
b443310b40
commit
8f2ec8be56
23 changed files with 1339 additions and 60 deletions
|
|
@ -22,7 +22,8 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||||
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm",
|
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm",
|
||||||
AboutWelcomeDefaults:
|
AboutWelcomeDefaults:
|
||||||
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeDefaults.jsm",
|
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeDefaults.jsm",
|
||||||
AWScreenUtils: "resource://activity-stream/lib/AWScreenUtils.jsm",
|
AWScreenUtils:
|
||||||
|
"resource://activity-stream/aboutwelcome/lib/AWScreenUtils.jsm",
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(lazy, "log", () => {
|
XPCOMUtils.defineLazyGetter(lazy, "log", () => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Localized } from "./MSLocalized";
|
import { Localized } from "./MSLocalized";
|
||||||
import { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
|
import { AboutWelcomeUtils } from "../lib/aboutwelcome-utils";
|
||||||
const MS_STRING_PROP = "string_id";
|
const MS_STRING_PROP = "string_id";
|
||||||
|
|
||||||
export const HelpText = props => {
|
export const HelpText = props => {
|
||||||
|
|
|
||||||
243
browser/components/aboutwelcome/karma.mc.config.js
Normal file
243
browser/components/aboutwelcome/karma.mc.config.js
Normal file
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* 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 path = require("path");
|
||||||
|
const webpack = require("webpack");
|
||||||
|
const { ResourceUriPlugin } = require("../newtab/tools/resourceUriPlugin");
|
||||||
|
|
||||||
|
const PATHS = {
|
||||||
|
// Where is the entry point for the unit tests?
|
||||||
|
testEntryFile: path.resolve(__dirname, "./tests/unit/unit-entry.js"),
|
||||||
|
|
||||||
|
// A glob-style pattern matching all unit tests
|
||||||
|
testFilesPattern: "./tests/unit/unit-entry.js",
|
||||||
|
|
||||||
|
// The base directory of all source files (used for path resolution in webpack importing)
|
||||||
|
moduleResolveDirectory: __dirname,
|
||||||
|
newtabResolveDirectory: "../newtab",
|
||||||
|
|
||||||
|
// a RegEx matching all Cu.import statements of local files
|
||||||
|
resourcePathRegEx: /^resource:\/\/activity-stream\//,
|
||||||
|
|
||||||
|
coverageReportingPath: "logs/coverage/",
|
||||||
|
};
|
||||||
|
|
||||||
|
// When tweaking here, be sure to review the docs about the execution ordering
|
||||||
|
// semantics of the preprocessors array, as they are somewhat odd.
|
||||||
|
const preprocessors = {};
|
||||||
|
preprocessors[PATHS.testFilesPattern] = [
|
||||||
|
"webpack", // require("karma-webpack")
|
||||||
|
"sourcemap", // require("karma-sourcemap-loader")
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
const isTDD = config.tdd;
|
||||||
|
const browsers = isTDD ? ["Firefox"] : ["FirefoxHeadless"]; // require("karma-firefox-launcher")
|
||||||
|
config.set({
|
||||||
|
singleRun: !isTDD,
|
||||||
|
browsers,
|
||||||
|
customLaunchers: {
|
||||||
|
FirefoxHeadless: {
|
||||||
|
base: "Firefox",
|
||||||
|
flags: ["--headless"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
frameworks: [
|
||||||
|
"chai", // require("chai") require("karma-chai")
|
||||||
|
"mocha", // require("mocha") require("karma-mocha")
|
||||||
|
"sinon", // require("sinon") require("karma-sinon")
|
||||||
|
],
|
||||||
|
reporters: [
|
||||||
|
"coverage-istanbul", // require("karma-coverage")
|
||||||
|
"mocha", // require("karma-mocha-reporter")
|
||||||
|
|
||||||
|
// for bin/try-runner.js to parse the output easily
|
||||||
|
"json", // require("karma-json-reporter")
|
||||||
|
],
|
||||||
|
jsonReporter: {
|
||||||
|
// So this doesn't get interleaved with other karma output
|
||||||
|
stdout: false,
|
||||||
|
outputFile: path.join("logs", "karma-run-results.json"),
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
reports: ["lcov", "text-summary"], // for some reason "lcov" reallys means "lcov" and "html"
|
||||||
|
"report-config": {
|
||||||
|
// so the full m-c path gets printed; needed for https://coverage.moz.tools/ integration
|
||||||
|
lcov: {
|
||||||
|
projectRoot: "../../..",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dir: PATHS.coverageReportingPath,
|
||||||
|
// This will make karma fail if coverage reporting is less than the minimums here
|
||||||
|
thresholds: !isTDD && {
|
||||||
|
each: {
|
||||||
|
statements: 100,
|
||||||
|
lines: 100,
|
||||||
|
functions: 100,
|
||||||
|
branches: 66,
|
||||||
|
overrides: {
|
||||||
|
"modules/*.jsm": {
|
||||||
|
statements: 0,
|
||||||
|
lines: 0,
|
||||||
|
functions: 0,
|
||||||
|
branches: 0,
|
||||||
|
},
|
||||||
|
"content-src/lib/aboutwelcome-utils.js": {
|
||||||
|
statements: 50,
|
||||||
|
lines: 50,
|
||||||
|
functions: 50,
|
||||||
|
branches: 0,
|
||||||
|
},
|
||||||
|
"content-src/components/LanguageSwitcher.jsx": {
|
||||||
|
// This file is covered by the mochitest: browser_aboutwelcome_multistage_languageSwitcher.js
|
||||||
|
statements: 0,
|
||||||
|
lines: 0,
|
||||||
|
functions: 0,
|
||||||
|
branches: 0,
|
||||||
|
},
|
||||||
|
"content-src/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/components/AddonsPicker.jsx": {
|
||||||
|
// This file is covered by the mochitest: browser_aboutwelcome_multistage_addonspicker.js
|
||||||
|
statements: 0,
|
||||||
|
lines: 0,
|
||||||
|
functions: 0,
|
||||||
|
branches: 0,
|
||||||
|
},
|
||||||
|
"content-src/**/*.jsx": {
|
||||||
|
statements: 62,
|
||||||
|
lines: 60,
|
||||||
|
functions: 50,
|
||||||
|
branches: 50,
|
||||||
|
},
|
||||||
|
"content-src/components/**/*.jsx": {
|
||||||
|
statements: 51.1,
|
||||||
|
lines: 52.38,
|
||||||
|
functions: 31.2,
|
||||||
|
branches: 31.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
files: [PATHS.testEntryFile],
|
||||||
|
preprocessors,
|
||||||
|
webpack: {
|
||||||
|
mode: "none",
|
||||||
|
devtool: "inline-source-map",
|
||||||
|
// This loader allows us to override required files in tests
|
||||||
|
resolveLoader: {
|
||||||
|
alias: {
|
||||||
|
inject: path.join(__dirname, "../newtab/loaders/inject-loader"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// This resolve config allows us to import with paths relative to the root directory, e.g. "lib/ActivityStream.jsm"
|
||||||
|
resolve: {
|
||||||
|
extensions: [".js", ".jsx"],
|
||||||
|
modules: [
|
||||||
|
PATHS.moduleResolveDirectory,
|
||||||
|
"node_modules",
|
||||||
|
PATHS.newtabResolveDirectory,
|
||||||
|
],
|
||||||
|
fallback: {
|
||||||
|
stream: require.resolve("stream-browserify"),
|
||||||
|
buffer: require.resolve("buffer"),
|
||||||
|
},
|
||||||
|
alias: {
|
||||||
|
newtab: path.join(__dirname, "../newtab"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// The ResourceUriPlugin handles translating resource URIs in import
|
||||||
|
// statements in .mjs files, in a similar way to what
|
||||||
|
// babel-jsm-to-commonjs does for jsm files.
|
||||||
|
new ResourceUriPlugin({
|
||||||
|
resourcePathRegEx: PATHS.resourcePathRegEx,
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
"process.env.NODE_ENV": JSON.stringify("development"),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
externals: {
|
||||||
|
// enzyme needs these for backwards compatibility with 0.13.
|
||||||
|
// see https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md#using-enzyme-with-webpack
|
||||||
|
"react/addons": true,
|
||||||
|
"react/lib/ReactContext": true,
|
||||||
|
"react/lib/ExecutionEnvironment": true,
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
// This rule rewrites importing/exporting in .jsm files to be compatible with esmodules
|
||||||
|
{
|
||||||
|
test: /\.jsm$/,
|
||||||
|
exclude: [/node_modules/],
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "babel-loader", // require("babel-core")
|
||||||
|
options: {
|
||||||
|
plugins: [
|
||||||
|
// Converts .jsm files into common-js modules
|
||||||
|
[
|
||||||
|
"../newtab/tools/babel-jsm-to-commonjs.js",
|
||||||
|
{
|
||||||
|
basePath: PATHS.resourcePathRegEx,
|
||||||
|
removeOtherImports: true,
|
||||||
|
replace: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
|
"@babel/plugin-proposal-class-properties",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: [/node_modules\/(?!@fluent\/).*/, /tests/],
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
// This is a workaround for bug 1787278. It can be removed once
|
||||||
|
// that bug is fixed.
|
||||||
|
plugins: ["@babel/plugin-proposal-optional-chaining"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.jsx$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
presets: ["@babel/preset-react"],
|
||||||
|
plugins: [
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.md$/,
|
||||||
|
use: "raw-loader",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enforce: "post",
|
||||||
|
test: /\.js[mx]?$/,
|
||||||
|
loader: "@jsdevtools/coverage-istanbul-loader",
|
||||||
|
options: { esModules: true },
|
||||||
|
include: [path.resolve("content-src"), path.resolve("modules")],
|
||||||
|
exclude: [path.resolve("tests"), path.resolve("../newtab")],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Silences some overly-verbose logging of individual module builds
|
||||||
|
webpackMiddleware: { noInfo: true },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -30,6 +30,7 @@ const AWScreenUtils = {
|
||||||
/**
|
/**
|
||||||
* Given a JEXL expression, returns the evaluation of the expression or returns
|
* Given a JEXL expression, returns the evaluation of the expression or returns
|
||||||
* true if the expression did not evaluate successfully
|
* true if the expression did not evaluate successfully
|
||||||
|
*
|
||||||
* @param {string} targeting - The JEXL expression that will be evaluated
|
* @param {string} targeting - The JEXL expression that will be evaluated
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
|
|
@ -21,7 +21,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||||
AWScreenUtils: "resource://activity-stream/lib/AWScreenUtils.jsm",
|
AWScreenUtils:
|
||||||
|
"resource://activity-stream/aboutwelcome/lib/AWScreenUtils.jsm",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Message to be updated based on finalized MR designs
|
// Message to be updated based on finalized MR designs
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,31 @@
|
||||||
"redux": "4.1.2"
|
"redux": "4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/plugin-proposal-class-properties": "7.16.0",
|
||||||
"@babel/plugin-proposal-optional-chaining": "7.16.0",
|
"@babel/plugin-proposal-optional-chaining": "7.16.0",
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator": "7.16.0",
|
||||||
"@babel/preset-react": "7.16.0",
|
"@babel/preset-react": "7.16.0",
|
||||||
|
"@jsdevtools/coverage-istanbul-loader": "^3.0.5",
|
||||||
"babel-loader": "8.2.3",
|
"babel-loader": "8.2.3",
|
||||||
|
"babel-plugin-jsm-to-esmodules": "0.6.0",
|
||||||
|
"chai": "4.3.4",
|
||||||
|
"chai-json-schema": "1.5.1",
|
||||||
|
"enzyme": "3.11.0",
|
||||||
|
"enzyme-adapter-react-16": "1.15.6",
|
||||||
|
"karma": "6.3.8",
|
||||||
|
"karma-chai": "0.1.0",
|
||||||
|
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||||
|
"karma-firefox-launcher": "2.1.2",
|
||||||
|
"karma-json-reporter": "1.2.1",
|
||||||
|
"karma-mocha": "2.0.1",
|
||||||
|
"karma-mocha-reporter": "2.2.5",
|
||||||
|
"karma-sinon": "1.0.5",
|
||||||
|
"karma-sourcemap-loader": "0.3.8",
|
||||||
|
"karma-webpack": "5.0.0",
|
||||||
"npm-run-all": "4.1.5",
|
"npm-run-all": "4.1.5",
|
||||||
"sass": "1.43.4",
|
"sass": "1.43.4",
|
||||||
"sinon": "12.0.1",
|
"sinon": "12.0.1",
|
||||||
|
"stream-browserify": "3.0.0",
|
||||||
"webpack": "5.56.0",
|
"webpack": "5.56.0",
|
||||||
"webpack-cli": "4.9.1",
|
"webpack-cli": "4.9.1",
|
||||||
"yamscripts": "0.1.0"
|
"yamscripts": "0.1.0"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const { AboutWelcomeTelemetry } = ChromeUtils.import(
|
||||||
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm"
|
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm"
|
||||||
);
|
);
|
||||||
const { AWScreenUtils } = ChromeUtils.import(
|
const { AWScreenUtils } = ChromeUtils.import(
|
||||||
"resource://activity-stream/lib/AWScreenUtils.jsm"
|
"resource://activity-stream/aboutwelcome/lib/AWScreenUtils.jsm"
|
||||||
);
|
);
|
||||||
const { InternalTestingProfileMigrator } = ChromeUtils.importESModule(
|
const { InternalTestingProfileMigrator } = ChromeUtils.importESModule(
|
||||||
"resource:///modules/InternalTestingProfileMigrator.sys.mjs"
|
"resource:///modules/InternalTestingProfileMigrator.sys.mjs"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const { getAddonAndLocalAPIsMocker } = ChromeUtils.importESModule(
|
||||||
);
|
);
|
||||||
|
|
||||||
const { AWScreenUtils } = ChromeUtils.import(
|
const { AWScreenUtils } = ChromeUtils.import(
|
||||||
"resource://activity-stream/lib/AWScreenUtils.jsm"
|
"resource://activity-stream/aboutwelcome/lib/AWScreenUtils.jsm"
|
||||||
);
|
);
|
||||||
|
|
||||||
const sandbox = sinon.createSandbox();
|
const sandbox = sinon.createSandbox();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const { AboutWelcomeTelemetry } = ChromeUtils.import(
|
||||||
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm"
|
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm"
|
||||||
);
|
);
|
||||||
const { AWScreenUtils } = ChromeUtils.import(
|
const { AWScreenUtils } = ChromeUtils.import(
|
||||||
"resource://activity-stream/lib/AWScreenUtils.jsm"
|
"resource://activity-stream/aboutwelcome/lib/AWScreenUtils.jsm"
|
||||||
);
|
);
|
||||||
const { InternalTestingProfileMigrator } = ChromeUtils.importESModule(
|
const { InternalTestingProfileMigrator } = ChromeUtils.importESModule(
|
||||||
"resource:///modules/InternalTestingProfileMigrator.sys.mjs"
|
"resource:///modules/InternalTestingProfileMigrator.sys.mjs"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { AWScreenUtils } from "lib/AWScreenUtils.jsm";
|
import { AWScreenUtils } from "modules/AWScreenUtils.jsm";
|
||||||
import { GlobalOverrider } from "test/unit/utils";
|
import { GlobalOverrider } from "newtab/test/unit/utils";
|
||||||
import { ASRouter } from "lib/ASRouter.jsm";
|
import { ASRouter } from "newtab/lib/ASRouter.jsm";
|
||||||
|
|
||||||
describe("AWScreenUtils", () => {
|
describe("AWScreenUtils", () => {
|
||||||
let sandbox;
|
let sandbox;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
import { CTAParagraph } from "content-src/aboutwelcome/components/CTAParagraph";
|
import { CTAParagraph } from "content-src/components/CTAParagraph";
|
||||||
|
|
||||||
describe("CTAParagraph component", () => {
|
describe("CTAParagraph component", () => {
|
||||||
let sandbox;
|
let sandbox;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { HelpText } from "content-src/aboutwelcome/components/HelpText";
|
import { HelpText } from "content-src/components/HelpText";
|
||||||
import { Localized } from "content-src/aboutwelcome/components/MSLocalized";
|
import { Localized } from "content-src/components/MSLocalized";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
import { HeroImage } from "content-src/aboutwelcome/components/HeroImage";
|
import { HeroImage } from "content-src/components/HeroImage";
|
||||||
|
|
||||||
describe("HeroImage component", () => {
|
describe("HeroImage component", () => {
|
||||||
const imageUrl = "https://example.com";
|
const imageUrl = "https://example.com";
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import { LinkParagraph } from "../../../content-src/aboutwelcome/components/LinkParagraph";
|
import { LinkParagraph } from "content-src/components/LinkParagraph";
|
||||||
|
|
||||||
describe("LinkParagraph component", () => {
|
describe("LinkParagraph component", () => {
|
||||||
let sandbox;
|
let sandbox;
|
||||||
328
browser/components/aboutwelcome/tests/unit/MRColorways.test.jsx
Normal file
328
browser/components/aboutwelcome/tests/unit/MRColorways.test.jsx
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
import React from "react";
|
||||||
|
import { shallow } from "enzyme";
|
||||||
|
import {
|
||||||
|
Colorways,
|
||||||
|
computeColorWay,
|
||||||
|
ColorwayDescription,
|
||||||
|
computeVariationIndex,
|
||||||
|
} from "content-src/components/MRColorways";
|
||||||
|
import { WelcomeScreen } from "content-src/components/MultiStageAboutWelcome";
|
||||||
|
|
||||||
|
describe("Multistage AboutWelcome module", () => {
|
||||||
|
let sandbox;
|
||||||
|
let COLORWAY_SCREEN_PROPS;
|
||||||
|
beforeEach(() => {
|
||||||
|
sandbox = sinon.createSandbox();
|
||||||
|
COLORWAY_SCREEN_PROPS = {
|
||||||
|
id: "test-colorway-screen",
|
||||||
|
totalNumberofScreens: 1,
|
||||||
|
content: {
|
||||||
|
subtitle: "test subtitle",
|
||||||
|
tiles: {
|
||||||
|
type: "colorway",
|
||||||
|
action: {
|
||||||
|
theme: "<event>",
|
||||||
|
},
|
||||||
|
defaultVariationIndex: 0,
|
||||||
|
systemVariations: ["automatic", "light"],
|
||||||
|
variations: ["soft", "bold"],
|
||||||
|
colorways: [
|
||||||
|
{
|
||||||
|
id: "default",
|
||||||
|
label: "Default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "abstract",
|
||||||
|
label: "Abstract",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
primary_button: {
|
||||||
|
action: {},
|
||||||
|
label: "test button",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
messageId: "test-mr-colorway-screen",
|
||||||
|
activeTheme: "automatic",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("MRColorway component", () => {
|
||||||
|
it("should render WelcomeScreen", () => {
|
||||||
|
const wrapper = shallow(<WelcomeScreen {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
|
||||||
|
assert.ok(wrapper.exists());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should use default when activeTheme is not set", () => {
|
||||||
|
const wrapper = shallow(<Colorways {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
wrapper.setProps({ activeTheme: null });
|
||||||
|
|
||||||
|
const colorwaysOptionIcons = wrapper.find(
|
||||||
|
".tiles-theme-section .theme .icon"
|
||||||
|
);
|
||||||
|
assert.strictEqual(colorwaysOptionIcons.length, 2);
|
||||||
|
|
||||||
|
// Default automatic theme is selected by default
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.first().prop("className").includes("selected"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.first().prop("className").includes("default"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should use default when activeTheme is alpenglow", () => {
|
||||||
|
const wrapper = shallow(<Colorways {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
wrapper.setProps({ activeTheme: "alpenglow" });
|
||||||
|
|
||||||
|
const colorwaysOptionIcons = wrapper.find(
|
||||||
|
".tiles-theme-section .theme .icon"
|
||||||
|
);
|
||||||
|
assert.strictEqual(colorwaysOptionIcons.length, 2);
|
||||||
|
|
||||||
|
// Default automatic theme is selected when unsupported in colorway alpenglow theme is active
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.first().prop("className").includes("selected"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.first().prop("className").includes("default"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render colorways options", () => {
|
||||||
|
const wrapper = shallow(<Colorways {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
|
||||||
|
const colorwaysOptions = wrapper.find(
|
||||||
|
".tiles-theme-section .theme input[name='theme']"
|
||||||
|
);
|
||||||
|
|
||||||
|
const colorwaysOptionIcons = wrapper.find(
|
||||||
|
".tiles-theme-section .theme .icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
const colorwaysLabels = wrapper.find(
|
||||||
|
".tiles-theme-section .theme span.sr-only"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(colorwaysOptions.length, 2);
|
||||||
|
assert.strictEqual(colorwaysOptionIcons.length, 2);
|
||||||
|
assert.strictEqual(colorwaysLabels.length, 2);
|
||||||
|
|
||||||
|
// First colorway option
|
||||||
|
// Default theme radio option is selected by default
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.first().prop("className").includes("selected"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
//Colorway should be using id property
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptions.first().prop("data-colorway"),
|
||||||
|
"default"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Second colorway option
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptionIcons.last().prop("className").includes("selected"),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
//Colorway should be using id property
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptions.last().prop("data-colorway"),
|
||||||
|
"abstract"
|
||||||
|
);
|
||||||
|
|
||||||
|
//Colorway should be labelled for screen readers (parent label is for tooltip only, and does not describe the Colorway)
|
||||||
|
assert.strictEqual(
|
||||||
|
colorwaysOptions.last().prop("aria-labelledby"),
|
||||||
|
"abstract-label"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle colorway clicks", () => {
|
||||||
|
sandbox.stub(React, "useEffect").callsFake((fn, vals) => {
|
||||||
|
if (vals === undefined) {
|
||||||
|
fn();
|
||||||
|
} else if (vals[0] === "in") {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleAction = sandbox.stub();
|
||||||
|
const wrapper = shallow(
|
||||||
|
<Colorways handleAction={handleAction} {...COLORWAY_SCREEN_PROPS} />
|
||||||
|
);
|
||||||
|
const colorwaysOptions = wrapper.find(
|
||||||
|
".tiles-theme-section .theme input[name='theme']"
|
||||||
|
);
|
||||||
|
|
||||||
|
let props = wrapper.find(ColorwayDescription).props();
|
||||||
|
assert.propertyVal(props.colorway, "label", "Default");
|
||||||
|
|
||||||
|
const option = colorwaysOptions.last();
|
||||||
|
assert.propertyVal(option.props(), "value", "abstract-soft");
|
||||||
|
colorwaysOptions.last().simulate("click");
|
||||||
|
assert.calledOnce(handleAction);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render colorway description", () => {
|
||||||
|
const wrapper = shallow(<Colorways {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
|
||||||
|
let descriptionsWrapper = wrapper.find(ColorwayDescription);
|
||||||
|
assert.ok(descriptionsWrapper.exists());
|
||||||
|
|
||||||
|
let props = descriptionsWrapper.props();
|
||||||
|
|
||||||
|
// Colorway description should display Default theme desc by default
|
||||||
|
assert.strictEqual(props.colorway.label, "Default");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ColorwayDescription should display active colorway desc", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
colorway: {
|
||||||
|
label: "Activist",
|
||||||
|
description: "Test Activist",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const descWrapper = shallow(
|
||||||
|
<ColorwayDescription {...TEST_COLORWAY_PROPS} />
|
||||||
|
);
|
||||||
|
assert.ok(descWrapper.exists());
|
||||||
|
const descText = descWrapper.find(".colorway-text");
|
||||||
|
assert.equal(
|
||||||
|
descText.props()["data-l10n-args"].includes("Activist"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should computeColorWayId for default active theme", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
...COLORWAY_SCREEN_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const colorwayId = computeColorWay(
|
||||||
|
TEST_COLORWAY_PROPS.activeTheme,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.systemVariations
|
||||||
|
);
|
||||||
|
assert.strictEqual(colorwayId, "default");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should computeColorWayId for non-default active theme", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
...COLORWAY_SCREEN_PROPS,
|
||||||
|
activeTheme: "abstract-soft",
|
||||||
|
};
|
||||||
|
|
||||||
|
const colorwayId = computeColorWay(
|
||||||
|
TEST_COLORWAY_PROPS.activeTheme,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.systemVariations
|
||||||
|
);
|
||||||
|
assert.strictEqual(colorwayId, "abstract");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should computeVariationIndex for default active theme", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
...COLORWAY_SCREEN_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const variationIndex = computeVariationIndex(
|
||||||
|
TEST_COLORWAY_PROPS.activeTheme,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.systemVariations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.variations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.defaultVariationIndex
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
variationIndex,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.defaultVariationIndex
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should computeVariationIndex for active theme", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
...COLORWAY_SCREEN_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const variationIndex = computeVariationIndex(
|
||||||
|
"light",
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.systemVariations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.variations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.defaultVariationIndex
|
||||||
|
);
|
||||||
|
assert.strictEqual(variationIndex, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should computeVariationIndex for colorway theme", () => {
|
||||||
|
let TEST_COLORWAY_PROPS = {
|
||||||
|
...COLORWAY_SCREEN_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const variationIndex = computeVariationIndex(
|
||||||
|
"abstract-bold",
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.systemVariations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.variations,
|
||||||
|
TEST_COLORWAY_PROPS.content.tiles.defaultVariationIndex
|
||||||
|
);
|
||||||
|
assert.strictEqual(variationIndex, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("random colorways", () => {
|
||||||
|
let test;
|
||||||
|
beforeEach(() => {
|
||||||
|
COLORWAY_SCREEN_PROPS.handleAction = sandbox.stub();
|
||||||
|
sandbox.stub(window, "matchMedia");
|
||||||
|
// eslint-disable-next-line max-nested-callbacks
|
||||||
|
sandbox.stub(React, "useEffect").callsFake((fn, vals) => {
|
||||||
|
if (vals?.length === 0) {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test = () => {
|
||||||
|
shallow(<Colorways {...COLORWAY_SCREEN_PROPS} />);
|
||||||
|
return COLORWAY_SCREEN_PROPS.handleAction.firstCall.firstArg
|
||||||
|
.currentTarget;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should select a random colorway", () => {
|
||||||
|
const { value } = test();
|
||||||
|
|
||||||
|
assert.strictEqual(value, "abstract-soft");
|
||||||
|
assert.calledThrice(React.useEffect);
|
||||||
|
assert.notCalled(window.matchMedia);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should select a random soft colorway when not dark", () => {
|
||||||
|
window.matchMedia.returns({ matches: false });
|
||||||
|
COLORWAY_SCREEN_PROPS.content.tiles.darkVariation = 1;
|
||||||
|
|
||||||
|
const { value } = test();
|
||||||
|
|
||||||
|
assert.strictEqual(value, "abstract-soft");
|
||||||
|
assert.calledThrice(React.useEffect);
|
||||||
|
assert.calledOnce(window.matchMedia);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should select a random bold colorway when dark", () => {
|
||||||
|
window.matchMedia.returns({ matches: true });
|
||||||
|
COLORWAY_SCREEN_PROPS.content.tiles.darkVariation = 1;
|
||||||
|
|
||||||
|
const { value } = test();
|
||||||
|
|
||||||
|
assert.strictEqual(value, "abstract-bold");
|
||||||
|
assert.calledThrice(React.useEffect);
|
||||||
|
assert.calledOnce(window.matchMedia);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Localized } from "content-src/aboutwelcome/components/MSLocalized";
|
import { Localized } from "content-src/components/MSLocalized";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow, mount } from "enzyme";
|
import { shallow, mount } from "enzyme";
|
||||||
import { GlobalOverrider } from "test/unit/utils";
|
import { GlobalOverrider } from "newtab/test/unit/utils";
|
||||||
import { MobileDownloads } from "content-src/aboutwelcome/components/MobileDownloads";
|
import { MobileDownloads } from "content-src/components/MobileDownloads";
|
||||||
|
|
||||||
describe("Multistage AboutWelcome MobileDownloads module", () => {
|
describe("Multistage AboutWelcome MobileDownloads module", () => {
|
||||||
let globals;
|
let globals;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import { MultiSelect } from "content-src/aboutwelcome/components/MultiSelect";
|
import { MultiSelect } from "content-src/components/MultiSelect";
|
||||||
|
|
||||||
describe("Multistage AboutWelcome module", () => {
|
describe("Multistage AboutWelcome module", () => {
|
||||||
let sandbox;
|
let sandbox;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { AboutWelcomeDefaults } from "aboutwelcome/lib/AboutWelcomeDefaults.jsm";
|
import { AboutWelcomeDefaults } from "modules/AboutWelcomeDefaults.jsm";
|
||||||
import { MultiStageProtonScreen } from "content-src/aboutwelcome/components/MultiStageProtonScreen";
|
import { MultiStageProtonScreen } from "content-src/components/MultiStageProtonScreen";
|
||||||
import { AWScreenUtils } from "lib/AWScreenUtils.jsm";
|
import { AWScreenUtils } from "modules/AWScreenUtils.jsm";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import { GlobalOverrider } from "test/unit/utils";
|
import { GlobalOverrider } from "newtab/test/unit/utils";
|
||||||
import {
|
import {
|
||||||
MultiStageAboutWelcome,
|
MultiStageAboutWelcome,
|
||||||
SecondaryCTA,
|
SecondaryCTA,
|
||||||
StepsIndicator,
|
StepsIndicator,
|
||||||
ProgressBar,
|
ProgressBar,
|
||||||
WelcomeScreen,
|
WelcomeScreen,
|
||||||
} from "content-src/aboutwelcome/components/MultiStageAboutWelcome";
|
} from "content-src/components/MultiStageAboutWelcome";
|
||||||
import { Themes } from "content-src/aboutwelcome/components/Themes";
|
import { Themes } from "content-src/components/Themes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { shallow, mount } from "enzyme";
|
import { shallow, mount } from "enzyme";
|
||||||
import { AboutWelcomeDefaults } from "aboutwelcome/lib/AboutWelcomeDefaults.jsm";
|
import { AboutWelcomeDefaults } from "modules/AboutWelcomeDefaults.jsm";
|
||||||
import { AboutWelcomeUtils } from "content-src/lib/aboutwelcome-utils";
|
import { AboutWelcomeUtils } from "content-src/lib/aboutwelcome-utils";
|
||||||
|
|
||||||
describe("MultiStageAboutWelcome module", () => {
|
describe("MultiStageAboutWelcome module", () => {
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import { OnboardingVideo } from "content-src/aboutwelcome/components/OnboardingVideo";
|
import { OnboardingVideo } from "content-src/components/OnboardingVideo";
|
||||||
|
|
||||||
describe("OnboardingVideo component", () => {
|
describe("OnboardingVideo component", () => {
|
||||||
let sandbox;
|
let sandbox;
|
||||||
720
browser/components/aboutwelcome/tests/unit/unit-entry.js
Normal file
720
browser/components/aboutwelcome/tests/unit/unit-entry.js
Normal file
|
|
@ -0,0 +1,720 @@
|
||||||
|
import {
|
||||||
|
EventEmitter,
|
||||||
|
FakePrefs,
|
||||||
|
FakensIPrefService,
|
||||||
|
GlobalOverrider,
|
||||||
|
FakeConsoleAPI,
|
||||||
|
FakeLogger,
|
||||||
|
} from "newtab/test/unit/utils";
|
||||||
|
import Adapter from "enzyme-adapter-react-16";
|
||||||
|
import { chaiAssertions } from "newtab/test/schemas/pings";
|
||||||
|
import chaiJsonSchema from "chai-json-schema";
|
||||||
|
import enzyme from "enzyme";
|
||||||
|
import FxMSCommonSchema from "newtab/content-src/asrouter/schemas/FxMSCommon.schema.json";
|
||||||
|
|
||||||
|
enzyme.configure({ adapter: new Adapter() });
|
||||||
|
|
||||||
|
// Cause React warnings to make tests that trigger them fail
|
||||||
|
const origConsoleError = console.error;
|
||||||
|
console.error = function (msg, ...args) {
|
||||||
|
origConsoleError.apply(console, [msg, ...args]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
/(Invalid prop|Failed prop type|Check the render method|React Intl)/.test(
|
||||||
|
msg
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const req = require.context(".", true, /\.test\.jsx?$/);
|
||||||
|
const files = req.keys();
|
||||||
|
|
||||||
|
// This exposes sinon assertions to chai.assert
|
||||||
|
sinon.assert.expose(assert, { prefix: "" });
|
||||||
|
|
||||||
|
chai.use(chaiAssertions);
|
||||||
|
chai.use(chaiJsonSchema);
|
||||||
|
chai.tv4.addSchema("file:///FxMSCommon.schema.json", FxMSCommonSchema);
|
||||||
|
|
||||||
|
const overrider = new GlobalOverrider();
|
||||||
|
|
||||||
|
const RemoteSettings = name => ({
|
||||||
|
get: () => {
|
||||||
|
if (name === "attachment") {
|
||||||
|
return Promise.resolve([{ attachment: {} }]);
|
||||||
|
}
|
||||||
|
return Promise.resolve([]);
|
||||||
|
},
|
||||||
|
on: () => {},
|
||||||
|
off: () => {},
|
||||||
|
});
|
||||||
|
RemoteSettings.pollChanges = () => {};
|
||||||
|
|
||||||
|
class JSWindowActorParent {
|
||||||
|
sendAsyncMessage(name, data) {
|
||||||
|
return { name, data };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JSWindowActorChild {
|
||||||
|
sendAsyncMessage(name, data) {
|
||||||
|
return { name, data };
|
||||||
|
}
|
||||||
|
|
||||||
|
sendQuery(name, data) {
|
||||||
|
return Promise.resolve({ name, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentWindow() {
|
||||||
|
return {
|
||||||
|
Promise,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect plain object passed to lazy getter APIs, and set its prototype to
|
||||||
|
// global object, and return the global object for further modification.
|
||||||
|
// Returns the object if it's not plain object.
|
||||||
|
//
|
||||||
|
// This is a workaround to make the existing testharness and testcase keep
|
||||||
|
// working even after lazy getters are moved to plain `lazy` object.
|
||||||
|
const cachedPlainObject = new Set();
|
||||||
|
function updateGlobalOrObject(object) {
|
||||||
|
// Given this function modifies the prototype, and the following
|
||||||
|
// condition doesn't meet on the second call, cache the result.
|
||||||
|
if (cachedPlainObject.has(object)) {
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.getPrototypeOf(object).constructor.name !== "Object") {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedPlainObject.add(object);
|
||||||
|
Object.setPrototypeOf(object, global);
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TEST_GLOBAL = {
|
||||||
|
JSWindowActorParent,
|
||||||
|
JSWindowActorChild,
|
||||||
|
AboutReaderParent: {
|
||||||
|
addMessageListener: (messageName, listener) => {},
|
||||||
|
removeMessageListener: (messageName, listener) => {},
|
||||||
|
},
|
||||||
|
AboutWelcomeTelemetry: class {
|
||||||
|
submitGleanPingForPing() {}
|
||||||
|
},
|
||||||
|
AddonManager: {
|
||||||
|
getActiveAddons() {
|
||||||
|
return Promise.resolve({ addons: [], fullData: false });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AppConstants: {
|
||||||
|
MOZILLA_OFFICIAL: true,
|
||||||
|
MOZ_APP_VERSION: "69.0a1",
|
||||||
|
isChinaRepack() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
isPlatformAndVersionAtMost() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
platform: "win",
|
||||||
|
},
|
||||||
|
ASRouterPreferences: {
|
||||||
|
console: new FakeConsoleAPI({
|
||||||
|
maxLogLevel: "off", // set this to "debug" or "all" to get more ASRouter logging in tests
|
||||||
|
prefix: "ASRouter",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
AWScreenUtils: {
|
||||||
|
evaluateTargetingAndRemoveScreens() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
async removeScreens() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
evaluateScreenTargeting() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
BrowserUtils: {
|
||||||
|
sendToDeviceEmailsSupported() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdateUtils: { getUpdateChannel() {} },
|
||||||
|
BasePromiseWorker: class {
|
||||||
|
constructor() {
|
||||||
|
this.ExceptionHandlers = [];
|
||||||
|
}
|
||||||
|
post() {}
|
||||||
|
},
|
||||||
|
browserSearchRegion: "US",
|
||||||
|
BrowserWindowTracker: { getTopWindow() {} },
|
||||||
|
ChromeUtils: {
|
||||||
|
defineModuleGetter: updateGlobalOrObject,
|
||||||
|
defineESModuleGetters: updateGlobalOrObject,
|
||||||
|
generateQI() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
import() {
|
||||||
|
return global;
|
||||||
|
},
|
||||||
|
importESModule() {
|
||||||
|
return global;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ClientEnvironment: {
|
||||||
|
get userId() {
|
||||||
|
return "foo123";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Components: {
|
||||||
|
Constructor(classId) {
|
||||||
|
switch (classId) {
|
||||||
|
case "@mozilla.org/referrer-info;1":
|
||||||
|
return function (referrerPolicy, sendReferrer, originalReferrer) {
|
||||||
|
this.referrerPolicy = referrerPolicy;
|
||||||
|
this.sendReferrer = sendReferrer;
|
||||||
|
this.originalReferrer = originalReferrer;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return function () {};
|
||||||
|
},
|
||||||
|
isSuccessCode: () => true,
|
||||||
|
},
|
||||||
|
ConsoleAPI: FakeConsoleAPI,
|
||||||
|
// NB: These are functions/constructors
|
||||||
|
// eslint-disable-next-line object-shorthand
|
||||||
|
ContentSearchUIController: function () {},
|
||||||
|
// eslint-disable-next-line object-shorthand
|
||||||
|
ContentSearchHandoffUIController: function () {},
|
||||||
|
Cc: {
|
||||||
|
"@mozilla.org/browser/nav-bookmarks-service;1": {
|
||||||
|
addObserver() {},
|
||||||
|
getService() {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
removeObserver() {},
|
||||||
|
SOURCES: {},
|
||||||
|
TYPE_BOOKMARK: {},
|
||||||
|
},
|
||||||
|
"@mozilla.org/browser/nav-history-service;1": {
|
||||||
|
addObserver() {},
|
||||||
|
executeQuery() {},
|
||||||
|
getNewQuery() {},
|
||||||
|
getNewQueryOptions() {},
|
||||||
|
getService() {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
insert() {},
|
||||||
|
markPageAsTyped() {},
|
||||||
|
removeObserver() {},
|
||||||
|
},
|
||||||
|
"@mozilla.org/io/string-input-stream;1": {
|
||||||
|
createInstance() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"@mozilla.org/security/hash;1": {
|
||||||
|
createInstance() {
|
||||||
|
return {
|
||||||
|
init() {},
|
||||||
|
updateFromStream() {},
|
||||||
|
finish() {
|
||||||
|
return "0";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
||||||
|
"@mozilla.org/widget/useridleservice;1": {
|
||||||
|
getService() {
|
||||||
|
return {
|
||||||
|
idleTime: 0,
|
||||||
|
addIdleObserver() {},
|
||||||
|
removeIdleObserver() {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"@mozilla.org/streamConverters;1": {
|
||||||
|
getService() {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"@mozilla.org/network/stream-loader;1": {
|
||||||
|
createInstance() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Ci: {
|
||||||
|
nsICryptoHash: {},
|
||||||
|
nsIReferrerInfo: { UNSAFE_URL: 5 },
|
||||||
|
nsITimer: { TYPE_ONE_SHOT: 1 },
|
||||||
|
nsIWebProgressListener: { LOCATION_CHANGE_SAME_DOCUMENT: 1 },
|
||||||
|
nsIDOMWindow: Object,
|
||||||
|
nsITrackingDBService: {
|
||||||
|
TRACKERS_ID: 1,
|
||||||
|
TRACKING_COOKIES_ID: 2,
|
||||||
|
CRYPTOMINERS_ID: 3,
|
||||||
|
FINGERPRINTERS_ID: 4,
|
||||||
|
SOCIAL_ID: 5,
|
||||||
|
},
|
||||||
|
nsICookieBannerService: {
|
||||||
|
MODE_DISABLED: 0,
|
||||||
|
MODE_REJECT: 1,
|
||||||
|
MODE_REJECT_OR_ACCEPT: 2,
|
||||||
|
MODE_UNSET: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Cu: {
|
||||||
|
importGlobalProperties() {},
|
||||||
|
now: () => window.performance.now(),
|
||||||
|
cloneInto: o => JSON.parse(JSON.stringify(o)),
|
||||||
|
},
|
||||||
|
console: {
|
||||||
|
...console,
|
||||||
|
error() {},
|
||||||
|
},
|
||||||
|
dump() {},
|
||||||
|
EveryWindow: {
|
||||||
|
registerCallback: (id, init, uninit) => {},
|
||||||
|
unregisterCallback: id => {},
|
||||||
|
},
|
||||||
|
setTimeout: window.setTimeout.bind(window),
|
||||||
|
clearTimeout: window.clearTimeout.bind(window),
|
||||||
|
fetch() {},
|
||||||
|
// eslint-disable-next-line object-shorthand
|
||||||
|
Image: function () {}, // NB: This is a function/constructor
|
||||||
|
IOUtils: {
|
||||||
|
writeJSON() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
readJSON() {
|
||||||
|
return Promise.resolve({});
|
||||||
|
},
|
||||||
|
read() {
|
||||||
|
return Promise.resolve(new Uint8Array());
|
||||||
|
},
|
||||||
|
makeDirectory() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
write() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
exists() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
stat() {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewTabUtils: {
|
||||||
|
activityStreamProvider: {
|
||||||
|
getTopFrecentSites: () => [],
|
||||||
|
executePlacesQuery: async (sql, options) => ({ sql, options }),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OS: {
|
||||||
|
File: {
|
||||||
|
writeAtomic() {},
|
||||||
|
makeDir() {},
|
||||||
|
stat() {},
|
||||||
|
Error: {},
|
||||||
|
read() {},
|
||||||
|
exists() {},
|
||||||
|
remove() {},
|
||||||
|
removeEmptyDir() {},
|
||||||
|
},
|
||||||
|
Path: {
|
||||||
|
join() {
|
||||||
|
return "/";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Constants: {
|
||||||
|
Path: {
|
||||||
|
localProfileDir: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PathUtils: {
|
||||||
|
join(...parts) {
|
||||||
|
return parts[parts.length - 1];
|
||||||
|
},
|
||||||
|
joinRelative(...parts) {
|
||||||
|
return parts[parts.length - 1];
|
||||||
|
},
|
||||||
|
getProfileDir() {
|
||||||
|
return Promise.resolve("/");
|
||||||
|
},
|
||||||
|
getLocalProfileDir() {
|
||||||
|
return Promise.resolve("/");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PlacesUtils: {
|
||||||
|
get bookmarks() {
|
||||||
|
return TEST_GLOBAL.Cc["@mozilla.org/browser/nav-bookmarks-service;1"];
|
||||||
|
},
|
||||||
|
get history() {
|
||||||
|
return TEST_GLOBAL.Cc["@mozilla.org/browser/nav-history-service;1"];
|
||||||
|
},
|
||||||
|
observers: {
|
||||||
|
addListener() {},
|
||||||
|
removeListener() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Preferences: FakePrefs,
|
||||||
|
PrivateBrowsingUtils: {
|
||||||
|
isBrowserPrivate: () => false,
|
||||||
|
isWindowPrivate: () => false,
|
||||||
|
permanentPrivateBrowsing: false,
|
||||||
|
},
|
||||||
|
DownloadsViewUI: {
|
||||||
|
getDisplayName: () => "filename.ext",
|
||||||
|
getSizeWithUnits: () => "1.5 MB",
|
||||||
|
},
|
||||||
|
FileUtils: {
|
||||||
|
// eslint-disable-next-line object-shorthand
|
||||||
|
File: function () {}, // NB: This is a function/constructor
|
||||||
|
},
|
||||||
|
Region: {
|
||||||
|
home: "US",
|
||||||
|
REGION_TOPIC: "browser-region-updated",
|
||||||
|
},
|
||||||
|
Services: {
|
||||||
|
dirsvc: {
|
||||||
|
get: () => ({ parent: { parent: { path: "appPath" } } }),
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
set: () => undefined,
|
||||||
|
},
|
||||||
|
locale: {
|
||||||
|
get appLocaleAsBCP47() {
|
||||||
|
return "en-US";
|
||||||
|
},
|
||||||
|
negotiateLanguages() {},
|
||||||
|
},
|
||||||
|
urlFormatter: { formatURL: str => str, formatURLPref: str => str },
|
||||||
|
mm: {
|
||||||
|
addMessageListener: (msg, cb) => this.receiveMessage(),
|
||||||
|
removeMessageListener() {},
|
||||||
|
},
|
||||||
|
obs: {
|
||||||
|
addObserver() {},
|
||||||
|
removeObserver() {},
|
||||||
|
notifyObservers() {},
|
||||||
|
},
|
||||||
|
telemetry: {
|
||||||
|
setEventRecordingEnabled: () => {},
|
||||||
|
recordEvent: eventDetails => {},
|
||||||
|
scalarSet: () => {},
|
||||||
|
keyedScalarAdd: () => {},
|
||||||
|
},
|
||||||
|
uuid: {
|
||||||
|
generateUUID() {
|
||||||
|
return "{foo-123-foo}";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
console: { logStringMessage: () => {} },
|
||||||
|
prefs: new FakensIPrefService(),
|
||||||
|
tm: {
|
||||||
|
dispatchToMainThread: cb => cb(),
|
||||||
|
idleDispatchToMainThread: cb => cb(),
|
||||||
|
},
|
||||||
|
eTLD: {
|
||||||
|
getBaseDomain({ spec }) {
|
||||||
|
return spec.match(/\/([^/]+)/)[1];
|
||||||
|
},
|
||||||
|
getBaseDomainFromHost(host) {
|
||||||
|
return host.match(/.*?(\w+\.\w+)$/)[1];
|
||||||
|
},
|
||||||
|
getPublicSuffix() {},
|
||||||
|
},
|
||||||
|
io: {
|
||||||
|
newURI: spec => ({
|
||||||
|
mutate: () => ({
|
||||||
|
setRef: ref => ({
|
||||||
|
finalize: () => ({
|
||||||
|
ref,
|
||||||
|
spec,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
spec,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
init() {
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
getVisibleEngines: () =>
|
||||||
|
Promise.resolve([{ identifier: "google" }, { identifier: "bing" }]),
|
||||||
|
defaultEngine: {
|
||||||
|
identifier: "google",
|
||||||
|
searchForm:
|
||||||
|
"https://www.google.com/search?q=&ie=utf-8&oe=utf-8&client=firefox-b",
|
||||||
|
aliases: ["@google"],
|
||||||
|
},
|
||||||
|
defaultPrivateEngine: {
|
||||||
|
identifier: "bing",
|
||||||
|
searchForm: "https://www.bing.com",
|
||||||
|
aliases: ["@bing"],
|
||||||
|
},
|
||||||
|
getEngineByAlias: async () => null,
|
||||||
|
},
|
||||||
|
scriptSecurityManager: {
|
||||||
|
createNullPrincipal() {},
|
||||||
|
getSystemPrincipal() {},
|
||||||
|
},
|
||||||
|
wm: {
|
||||||
|
getMostRecentWindow: () => window,
|
||||||
|
getMostRecentBrowserWindow: () => window,
|
||||||
|
getEnumerator: () => [],
|
||||||
|
},
|
||||||
|
ww: { registerNotification() {}, unregisterNotification() {} },
|
||||||
|
appinfo: { appBuildID: "20180710100040", version: "69.0a1" },
|
||||||
|
scriptloader: { loadSubScript: () => {} },
|
||||||
|
startup: {
|
||||||
|
getStartupInfo() {
|
||||||
|
return {
|
||||||
|
process: {
|
||||||
|
getTime() {
|
||||||
|
return 1588010448000;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
XPCOMUtils: {
|
||||||
|
defineLazyGetter(object, name, f) {
|
||||||
|
updateGlobalOrObject(object)[name] = f();
|
||||||
|
},
|
||||||
|
defineLazyGlobalGetters: updateGlobalOrObject,
|
||||||
|
defineLazyModuleGetters: updateGlobalOrObject,
|
||||||
|
defineLazyServiceGetter: updateGlobalOrObject,
|
||||||
|
defineLazyServiceGetters: updateGlobalOrObject,
|
||||||
|
defineLazyPreferenceGetter(object, name) {
|
||||||
|
updateGlobalOrObject(object)[name] = "";
|
||||||
|
},
|
||||||
|
generateQI() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EventEmitter,
|
||||||
|
ShellService: {
|
||||||
|
doesAppNeedPin: () => false,
|
||||||
|
isDefaultBrowser: () => true,
|
||||||
|
},
|
||||||
|
FilterExpressions: {
|
||||||
|
eval() {
|
||||||
|
return Promise.resolve(false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RemoteSettings,
|
||||||
|
Localization: class {
|
||||||
|
async formatMessages(stringsIds) {
|
||||||
|
return Promise.resolve(
|
||||||
|
stringsIds.map(({ id, args }) => ({ value: { string_id: id, args } }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
async formatValue(stringId) {
|
||||||
|
return Promise.resolve(stringId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FxAccountsConfig: {
|
||||||
|
promiseConnectAccountURI(id) {
|
||||||
|
return Promise.resolve(id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FX_MONITOR_OAUTH_CLIENT_ID: "fake_client_id",
|
||||||
|
ExperimentAPI: {
|
||||||
|
getExperiment() {},
|
||||||
|
getExperimentMetaData() {},
|
||||||
|
getRolloutMetaData() {},
|
||||||
|
},
|
||||||
|
NimbusFeatures: {
|
||||||
|
glean: {
|
||||||
|
getVariable() {},
|
||||||
|
},
|
||||||
|
newtab: {
|
||||||
|
getVariable() {},
|
||||||
|
getAllVariables() {},
|
||||||
|
onUpdate() {},
|
||||||
|
offUpdate() {},
|
||||||
|
},
|
||||||
|
pocketNewtab: {
|
||||||
|
getVariable() {},
|
||||||
|
getAllVariables() {},
|
||||||
|
onUpdate() {},
|
||||||
|
offUpdate() {},
|
||||||
|
},
|
||||||
|
cookieBannerHandling: {
|
||||||
|
getVariable() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TelemetryEnvironment: {
|
||||||
|
setExperimentActive() {},
|
||||||
|
currentEnvironment: {
|
||||||
|
profile: {
|
||||||
|
creationDate: 16587,
|
||||||
|
},
|
||||||
|
settings: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TelemetryStopwatch: {
|
||||||
|
start: () => {},
|
||||||
|
finish: () => {},
|
||||||
|
},
|
||||||
|
Sampling: {
|
||||||
|
ratioSample(seed, ratios) {
|
||||||
|
return Promise.resolve(0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
BrowserHandler: {
|
||||||
|
get kiosk() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TelemetrySession: {
|
||||||
|
getMetadata(reason) {
|
||||||
|
return {
|
||||||
|
reason,
|
||||||
|
sessionId: "fake_session_id",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PageThumbs: {
|
||||||
|
addExpirationFilter() {},
|
||||||
|
removeExpirationFilter() {},
|
||||||
|
},
|
||||||
|
Logger: FakeLogger,
|
||||||
|
getFxAccountsSingleton() {},
|
||||||
|
AboutNewTab: {},
|
||||||
|
Glean: {
|
||||||
|
newtab: {
|
||||||
|
opened: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
locale: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
newtabCategory: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
homepageCategory: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
blockedSponsors: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
sovAllocation: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newtabSearch: {
|
||||||
|
enabled: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pocket: {
|
||||||
|
enabled: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
impression: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
isSignedIn: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
sponsoredStoriesEnabled: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
click: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
save: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
topicClick: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
topsites: {
|
||||||
|
enabled: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
sponsoredEnabled: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
impression: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
click: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
rows: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
showPrivacyClick: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
dismiss: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
prefChanged: {
|
||||||
|
record() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
topSites: {
|
||||||
|
pingType: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
tileId: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
reportingUrl: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
advertiser: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
contextId: {
|
||||||
|
set() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
GleanPings: {
|
||||||
|
newtab: {
|
||||||
|
submit() {},
|
||||||
|
},
|
||||||
|
topSites: {
|
||||||
|
submit() {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Utils: {
|
||||||
|
SERVER_URL: "bogus://foo",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
overrider.set(TEST_GLOBAL);
|
||||||
|
|
||||||
|
describe("activity-stream", () => {
|
||||||
|
after(() => overrider.restore());
|
||||||
|
files.forEach(file => req(file));
|
||||||
|
});
|
||||||
|
|
@ -206,46 +206,12 @@ module.exports = function (config) {
|
||||||
functions: 0,
|
functions: 0,
|
||||||
branches: 0,
|
branches: 0,
|
||||||
},
|
},
|
||||||
"content-src/lib/aboutwelcome-utils.js": {
|
|
||||||
statements: 50,
|
|
||||||
lines: 50,
|
|
||||||
functions: 50,
|
|
||||||
branches: 0,
|
|
||||||
},
|
|
||||||
"content-src/lib/link-menu-options.js": {
|
"content-src/lib/link-menu-options.js": {
|
||||||
statements: 96,
|
statements: 96,
|
||||||
lines: 96,
|
lines: 96,
|
||||||
functions: 96,
|
functions: 96,
|
||||||
branches: 70,
|
branches: 70,
|
||||||
},
|
},
|
||||||
"content-src/aboutwelcome/components/LanguageSwitcher.jsx": {
|
|
||||||
// This file is covered by the mochitest: browser_aboutwelcome_multistage_languageSwitcher.js
|
|
||||||
statements: 0,
|
|
||||||
lines: 0,
|
|
||||||
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/components/AddonsPicker.jsx": {
|
|
||||||
// This file is covered by the mochitest: browser_aboutwelcome_multistage_addonspicker.js
|
|
||||||
statements: 0,
|
|
||||||
lines: 0,
|
|
||||||
functions: 0,
|
|
||||||
branches: 0,
|
|
||||||
},
|
|
||||||
"content-src/aboutwelcome/**/*.jsx": {
|
|
||||||
statements: 62,
|
|
||||||
lines: 60,
|
|
||||||
functions: 50,
|
|
||||||
branches: 50,
|
|
||||||
},
|
|
||||||
"content-src/components/**/*.jsx": {
|
"content-src/components/**/*.jsx": {
|
||||||
statements: 51.1,
|
statements: 51.1,
|
||||||
lines: 52.38,
|
lines: 52.38,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue