Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
"use strict";
const { AddonSettings } = ChromeUtils.importESModule(
"resource://gre/modules/addons/AddonSettings.sys.mjs"
);
// This test checks whether the theme experiments work
add_task(async function test_experiment_static_theme() {
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
theme: {
colors: {
some_color_property: "#ff00ff",
},
images: {
some_image_property: "background.jpg",
},
properties: {
some_random_property: "no-repeat",
},
},
theme_experiment: {
colors: {
some_color_property: "--some-color-property",
},
images: {
some_image_property: "--some-image-property",
},
properties: {
some_random_property: "--some-random-property",
},
},
},
});
const root = window.document.documentElement;
is(
root.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
root.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
root.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
await extension.startup();
const testExperimentApplied = rootEl => {
if (AddonSettings.EXPERIMENTS_ENABLED) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
} else {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
};
info("Testing that current window updated with the experiment applied");
testExperimentApplied(root);
info("Testing that new window initialized with the experiment applied");
const newWindow = await BrowserTestUtils.openNewBrowserWindow();
const newWindowRoot = newWindow.document.documentElement;
testExperimentApplied(newWindowRoot);
await extension.unload();
info("Testing that both windows unapplied the experiment");
for (const rootEl of [root, newWindowRoot]) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
await BrowserTestUtils.closeWindow(newWindow);
});
add_task(async function test_experiment_dynamic_theme() {
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
permissions: ["theme"],
theme_experiment: {
colors: {
some_color_property: "--some-color-property",
},
images: {
some_image_property: "--some-image-property",
},
properties: {
some_random_property: "--some-random-property",
},
},
},
background() {
const theme = {
colors: {
some_color_property: "#ff00ff",
},
images: {
some_image_property: "background.jpg",
},
properties: {
some_random_property: "no-repeat",
},
};
browser.test.onMessage.addListener(msg => {
if (msg === "update-theme") {
browser.theme.update(theme).then(() => {
browser.test.sendMessage("theme-updated");
});
} else {
browser.theme.reset().then(() => {
browser.test.sendMessage("theme-reset");
});
}
});
},
});
await extension.startup();
const root = window.document.documentElement;
is(
root.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
root.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
root.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
extension.sendMessage("update-theme");
await extension.awaitMessage("theme-updated");
const testExperimentApplied = rootEl => {
if (AddonSettings.EXPERIMENTS_ENABLED) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
} else {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
};
testExperimentApplied(root);
const newWindow = await BrowserTestUtils.openNewBrowserWindow();
const newWindowRoot = newWindow.document.documentElement;
testExperimentApplied(newWindowRoot);
extension.sendMessage("reset-theme");
await extension.awaitMessage("theme-reset");
for (const rootEl of [root, newWindowRoot]) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
extension.sendMessage("update-theme");
await extension.awaitMessage("theme-updated");
testExperimentApplied(root);
testExperimentApplied(newWindowRoot);
await extension.unload();
for (const rootEl of [root, newWindowRoot]) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
await BrowserTestUtils.closeWindow(newWindow);
});
add_task(async function test_experiment_stylesheet() {
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
theme: {
colors: {
menu_button_background: "#ff00ff",
},
},
theme_experiment: {
stylesheet: "experiment.css",
colors: {
menu_button_background: "--menu-button-background",
},
},
},
files: {
"experiment.css": `#PanelUI-menu-button {
background-color: var(--menu-button-background);
fill: white;
}`,
},
});
const root = window.document.documentElement;
const menuButton = document.getElementById("PanelUI-menu-button");
const computedStyle = window.getComputedStyle(menuButton);
const expectedColor = hexToCSS("#ff00ff");
const expectedFill = hexToCSS("#ffffff");
is(
root.style.getPropertyValue("--menu-button-background"),
"",
"Variable should be unset"
);
isnot(
computedStyle.backgroundColor,
expectedColor,
"Menu button should not have custom background"
);
isnot(
computedStyle.fill,
expectedFill,
"Menu button should not have stylesheet fill"
);
await extension.startup();
if (AddonSettings.EXPERIMENTS_ENABLED) {
// Wait for stylesheet load.
await BrowserTestUtils.waitForCondition(
() => computedStyle.fill === expectedFill
);
is(
root.style.getPropertyValue("--menu-button-background"),
expectedColor,
"Variable should be parsed and set."
);
is(
computedStyle.backgroundColor,
expectedColor,
"Menu button should be have correct background"
);
is(
computedStyle.fill,
expectedFill,
"Menu button should be have correct fill"
);
} else {
is(
root.style.getPropertyValue("--menu-button-background"),
"",
"Variable should be unset"
);
isnot(
computedStyle.backgroundColor,
expectedColor,
"Menu button should not have custom background"
);
isnot(
computedStyle.fill,
expectedFill,
"Menu button should not have stylesheet fill"
);
}
await extension.unload();
is(
root.style.getPropertyValue("--menu-button-background"),
"",
"Variable should be unset"
);
isnot(
computedStyle.backgroundColor,
expectedColor,
"Menu button should not have custom background"
);
isnot(
computedStyle.fill,
expectedFill,
"Menu button should not have stylesheet fill"
);
});
// This test checks whether the theme experiments are allowed for non privileged
// theme installed non-temporarily if AddonSettings.EXPERIMENTS_ENABLED is true.
add_task(async function test_experiment_installed_non_temporarily() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.experiments.enabled", true]],
});
if (!AddonSettings.EXPERIMENTS_ENABLED) {
info(
"Skipping test case on build where AddonSettings.EXPERIMENTS_ENABLED is false"
);
return;
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
theme: {
colors: {
some_color_property: "#ff00ff",
},
},
theme_experiment: {
colors: {
some_color_property: "--some-color-property",
},
},
},
});
const root = window.document.documentElement;
is(
root.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
await extension.startup();
is(
root.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
await extension.unload();
await SpecialPowers.popPrefEnv();
});