forked from mirrors/gecko-dev
422 lines
12 KiB
JavaScript
422 lines
12 KiB
JavaScript
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set sts=2 sw=2 et tw=80: */
|
|
"use strict";
|
|
|
|
/**
|
|
* Tests that we apply dark theme variants to PBM windows where applicable.
|
|
*/
|
|
|
|
const { BuiltInThemes } = ChromeUtils.importESModule(
|
|
"resource:///modules/BuiltInThemes.sys.mjs"
|
|
);
|
|
const { PromptTestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/PromptTestUtils.sys.mjs"
|
|
);
|
|
|
|
const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
|
|
const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
|
|
|
|
// This tests opens many chrome windows which is slow on debug builds.
|
|
requestLongerTimeout(2);
|
|
|
|
async function testIsDark(win, expectDark) {
|
|
let mql = win.matchMedia("(prefers-color-scheme: dark)");
|
|
if (mql.matches != expectDark) {
|
|
// The color scheme change might not have been processed yet, since that
|
|
// happens on a refresh driver tick.
|
|
await new Promise(r => mql.addEventListener("change", r, { once: true }));
|
|
}
|
|
is(
|
|
mql.matches,
|
|
expectDark,
|
|
`Window should${expectDark ? "" : " not"} be dark.`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test a window's theme color scheme.
|
|
*
|
|
* @param {*} options - Test options.
|
|
* @param {Window} options.win - Window object to test.
|
|
* @param {boolean} options.colorScheme - Whether expected chrome color scheme
|
|
* is dark (true) or light (false).
|
|
* @param {boolean} options.expectLWTAttributes - Whether the window should
|
|
* have the LWT attributes set matching the color scheme.
|
|
*/
|
|
async function testWindowColorScheme({ win, expectDark, expectLWTAttributes }) {
|
|
let docEl = win.document.documentElement;
|
|
|
|
await testIsDark(win, expectDark);
|
|
|
|
if (expectLWTAttributes) {
|
|
ok(docEl.hasAttribute("lwtheme"), "Window should have LWT attribute.");
|
|
is(
|
|
docEl.getAttribute("lwtheme-brighttext"),
|
|
expectDark ? "true" : null,
|
|
"LWT text color attribute should be set."
|
|
);
|
|
} else {
|
|
ok(!docEl.hasAttribute("lwtheme"), "Window should not have LWT attribute.");
|
|
ok(
|
|
!docEl.hasAttribute("lwtheme-brighttext"),
|
|
"LWT text color attribute should not be set."
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Match the prefers-color-scheme media query and return the results.
|
|
*
|
|
* @param {object} options
|
|
* @param {Window} options.win - If chrome=true, window to test, otherwise
|
|
* parent window of the content window to test.
|
|
* @param {boolean} options.chrome - If true the media queries will be matched
|
|
* against the supplied chrome window. Otherwise they will be matched against
|
|
* the content window.
|
|
* @returns {Promise<{light: boolean, dark: boolean}>} - Resolves with an
|
|
* object of the media query results.
|
|
*/
|
|
function getPrefersColorSchemeInfo({ win, chrome = false }) {
|
|
let fn = async windowObj => {
|
|
// If called in the parent, we use the supplied win object. Otherwise use
|
|
// the content window global.
|
|
let win = windowObj || content;
|
|
|
|
// LookAndFeel updates are async.
|
|
await new Promise(resolve => {
|
|
win.requestAnimationFrame(() => win.requestAnimationFrame(resolve));
|
|
});
|
|
return {
|
|
light: win.matchMedia("(prefers-color-scheme: light)").matches,
|
|
dark: win.matchMedia("(prefers-color-scheme: dark)").matches,
|
|
};
|
|
};
|
|
|
|
if (chrome) {
|
|
return fn(win);
|
|
}
|
|
|
|
return SpecialPowers.spawn(win.gBrowser.selectedBrowser, [], fn);
|
|
}
|
|
|
|
add_setup(async function () {
|
|
// Set system theme to light to ensure consistency across test machines.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["browser.theme.dark-private-windows", true],
|
|
["ui.systemUsesDarkTheme", 0],
|
|
],
|
|
});
|
|
// Ensure the built-in themes are initialized.
|
|
await BuiltInThemes.ensureBuiltInThemes();
|
|
|
|
// The previous test, browser_ext_themes_ntp_colors.js has side effects.
|
|
// Switch to a theme, then switch back to the default theme to reach a
|
|
// consistent themeData state. Without this, themeData in
|
|
// LightWeightConsumer#_update does not contain darkTheme data and PBM windows
|
|
// don't get themed correctly.
|
|
let lightTheme = await AddonManager.getAddonByID(LIGHT_THEME_ID);
|
|
await lightTheme.enable();
|
|
await lightTheme.disable();
|
|
});
|
|
|
|
// For the default theme with light color scheme, private browsing windows
|
|
// should be themed dark.
|
|
// The PBM window's content should not be themed dark.
|
|
add_task(async function test_default_theme_light() {
|
|
info("Normal browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: false,
|
|
expectLWTAttributes: false,
|
|
});
|
|
|
|
let windowB = await BrowserTestUtils.openNewBrowserWindow();
|
|
|
|
info("Additional normal browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: windowB,
|
|
expectDark: false,
|
|
expectLWTAttributes: false,
|
|
});
|
|
|
|
let pbmWindowA = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
|
|
info("Private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindowA,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
let prefersColorScheme = await getPrefersColorSchemeInfo({ win: pbmWindowA });
|
|
ok(
|
|
prefersColorScheme.light && !prefersColorScheme.dark,
|
|
"Content of dark themed PBM window should still be themed light"
|
|
);
|
|
|
|
let pbmWindowB = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
info("Additional private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindowB,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
await BrowserTestUtils.closeWindow(windowB);
|
|
await BrowserTestUtils.closeWindow(pbmWindowA);
|
|
await BrowserTestUtils.closeWindow(pbmWindowB);
|
|
});
|
|
|
|
// For the default theme with dark color scheme, normal and private browsing
|
|
// windows should be themed dark.
|
|
add_task(async function test_default_theme_dark() {
|
|
// Set the system theme to dark. The default theme will follow this color
|
|
// scheme.
|
|
await SpecialPowers.pushPrefEnv({ set: [["ui.systemUsesDarkTheme", 1]] });
|
|
|
|
info("Normal browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: true,
|
|
expectLWTAttributes: false,
|
|
});
|
|
|
|
let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
|
|
info("Private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: true,
|
|
expectLWTAttributes: false,
|
|
});
|
|
|
|
await BrowserTestUtils.closeWindow(pbmWindow);
|
|
|
|
await SpecialPowers.popPrefEnv();
|
|
});
|
|
|
|
// For the light theme both normal and private browsing windows should have a
|
|
// bright color scheme applied.
|
|
add_task(async function test_light_theme_builtin() {
|
|
let lightTheme = await AddonManager.getAddonByID(LIGHT_THEME_ID);
|
|
await lightTheme.enable();
|
|
|
|
info("Normal browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: false,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
info("Private browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: false,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
await BrowserTestUtils.closeWindow(pbmWindow);
|
|
await lightTheme.disable();
|
|
});
|
|
|
|
// For the dark theme both normal and private browsing should have a dark color
|
|
// scheme applied.
|
|
add_task(async function test_dark_theme_builtin() {
|
|
let darkTheme = await AddonManager.getAddonByID(DARK_THEME_ID);
|
|
await darkTheme.enable();
|
|
|
|
info("Normal browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
|
|
info("Private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
await BrowserTestUtils.closeWindow(pbmWindow);
|
|
await darkTheme.disable();
|
|
});
|
|
|
|
// When switching between default, light and dark theme the private browsing
|
|
// window color scheme should update accordingly.
|
|
add_task(async function test_theme_switch_updates_existing_pbm_win() {
|
|
let windowB = await BrowserTestUtils.openNewBrowserWindow();
|
|
let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: true,
|
|
});
|
|
|
|
info("Normal browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: false,
|
|
expectLWTAttributes: false,
|
|
});
|
|
|
|
info("Private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
info("Enabling light theme.");
|
|
let lightTheme = await AddonManager.getAddonByID(LIGHT_THEME_ID);
|
|
await lightTheme.enable();
|
|
|
|
info("Normal browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: false,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
info("Private browsing window should not be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: false,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
await lightTheme.disable();
|
|
|
|
info("Enabling dark theme.");
|
|
let darkTheme = await AddonManager.getAddonByID(DARK_THEME_ID);
|
|
await darkTheme.enable();
|
|
|
|
info("Normal browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: window,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
info("Private browsing window should be in dark mode.");
|
|
await testWindowColorScheme({
|
|
win: pbmWindow,
|
|
expectDark: true,
|
|
expectLWTAttributes: true,
|
|
});
|
|
|
|
await darkTheme.disable();
|
|
|
|
await BrowserTestUtils.closeWindow(windowB);
|
|
await BrowserTestUtils.closeWindow(pbmWindow);
|
|
});
|
|
|
|
// pageInfo windows should inherit the PBM window dark theme.
|
|
add_task(async function test_pbm_dark_page_info() {
|
|
for (let isPBM of [false, true]) {
|
|
let win = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: isPBM,
|
|
});
|
|
let windowTypeStr = isPBM ? "private" : "normal";
|
|
|
|
info(`Opening pageInfo from ${windowTypeStr} browsing.`);
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{ gBrowser: win.gBrowser, url: "https://example.com" },
|
|
async () => {
|
|
let pageInfo = win.BrowserCommands.pageInfo(null, "securityTab");
|
|
await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
|
|
|
|
let prefersColorScheme = await getPrefersColorSchemeInfo({
|
|
win: pageInfo,
|
|
chrome: true,
|
|
});
|
|
if (isPBM) {
|
|
ok(
|
|
!prefersColorScheme.light && prefersColorScheme.dark,
|
|
"pageInfo from private window should be themed dark."
|
|
);
|
|
} else {
|
|
ok(
|
|
prefersColorScheme.light && !prefersColorScheme.dark,
|
|
"pageInfo from normal window should be themed light."
|
|
);
|
|
}
|
|
|
|
pageInfo.close();
|
|
}
|
|
);
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
}
|
|
});
|
|
|
|
// Prompts should inherit the PBM window dark theme.
|
|
add_task(async function test_pbm_dark_prompts() {
|
|
const { MODAL_TYPE_TAB, MODAL_TYPE_CONTENT } = Services.prompt;
|
|
|
|
for (let isPBM of [false, true]) {
|
|
let win = await BrowserTestUtils.openNewBrowserWindow({
|
|
private: isPBM,
|
|
});
|
|
|
|
// TODO: Once Bug 1751953 has been fixed, we can also test MODAL_TYPE_WINDOW
|
|
// here.
|
|
for (let modalType of [MODAL_TYPE_TAB, MODAL_TYPE_CONTENT]) {
|
|
let windowTypeStr = isPBM ? "private" : "normal";
|
|
let modalTypeStr = modalType == MODAL_TYPE_TAB ? "tab" : "content";
|
|
|
|
info(`Opening ${modalTypeStr} prompt from ${windowTypeStr} browsing.`);
|
|
|
|
let openPromise = PromptTestUtils.waitForPrompt(
|
|
win.gBrowser.selectedBrowser,
|
|
{
|
|
modalType,
|
|
promptType: "alert",
|
|
}
|
|
);
|
|
let promptPromise = Services.prompt.asyncAlert(
|
|
win.gBrowser.selectedBrowser.browsingContext,
|
|
modalType,
|
|
"Hello",
|
|
"Hello, world!"
|
|
);
|
|
|
|
let dialog = await openPromise;
|
|
|
|
let prefersColorScheme = await getPrefersColorSchemeInfo({
|
|
win: dialog.ui.prompt,
|
|
chrome: true,
|
|
});
|
|
|
|
if (isPBM) {
|
|
ok(
|
|
!prefersColorScheme.light && prefersColorScheme.dark,
|
|
"Prompt from private window should be themed dark."
|
|
);
|
|
} else {
|
|
ok(
|
|
prefersColorScheme.light && !prefersColorScheme.dark,
|
|
"Prompt from normal window should be themed light."
|
|
);
|
|
}
|
|
|
|
await PromptTestUtils.handlePrompt(dialog);
|
|
await promptPromise;
|
|
}
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
}
|
|
});
|