browser_theme_switching.js (3714B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const THEME_PREF = "devtools.theme"; 7 8 add_task(async function () { 9 await pushPref(THEME_PREF, "light"); 10 await pushPref("devtools.high-contrast-mode-support", true); 11 // force HCM 12 await pushPref("browser.display.document_color_use", 2); 13 await pushPref("ui.useAccessibilityTheme", 1); 14 15 // For some reason, mochitest spawn a very special default tab, 16 // whose WindowGlobal is still the initial about:blank document. 17 // This seems to be specific to mochitest, this doesn't reproduce 18 // in regular firefox run. Even having about:blank as home page, 19 // force loading another final about:blank document (which isn't the initial one) 20 // 21 // To workaround this, force opening a dedicated test tab 22 const tab = await addTab("data:text/html;charset=utf-8,Test page"); 23 24 const toolbox = await gDevTools.showToolboxForTab(tab); 25 const doc = toolbox.doc; 26 const root = doc.documentElement; 27 28 const platform = root.getAttribute("platform"); 29 const expectedPlatform = getPlatform(); 30 is(platform, expectedPlatform, ":root[platform] is correct"); 31 checkTheme(root, { 32 theme: "light", 33 className: "theme-light", 34 forcedColorsActive: false, 35 }); 36 37 await switchTheme(root, "dark"); 38 checkTheme(root, { 39 theme: "dark", 40 className: "theme-dark", 41 forcedColorsActive: false, 42 }); 43 44 // When setting theme to "auto", we rely on Services.appinfo.chromeColorSchemeIsDark. 45 const isDark = Services.appinfo.chromeColorSchemeIsDark; 46 await switchTheme(root, "auto", isDark ? "dark" : "light"); 47 checkTheme(root, { 48 theme: isDark ? "dark" : "light", 49 className: isDark ? "theme-dark" : "theme-light", 50 forcedColorsActive: true, 51 }); 52 53 info( 54 "Check that disabling HCM will remove the forced-colors-active attribute" 55 ); 56 await pushPref("browser.display.document_color_use", 0); 57 await pushPref("ui.useAccessibilityTheme", 0); 58 checkTheme(root, { 59 theme: isDark ? "dark" : "light", 60 className: isDark ? "theme-dark" : "theme-light", 61 forcedColorsActive: false, 62 }); 63 64 await toolbox.destroy(); 65 }); 66 67 function switchTheme(root, themePrefValue, appliedTheme = themePrefValue) { 68 const ac = new AbortController(); 69 const onThemeSwitched = new Promise(res => 70 gDevTools.on( 71 "theme-switched", 72 (win, newTheme) => { 73 if (win === root.ownerGlobal && newTheme === appliedTheme) { 74 res(); 75 ac.abort(); 76 } 77 }, 78 { signal: ac.signal } 79 ) 80 ); 81 pushPref(THEME_PREF, themePrefValue); 82 return onThemeSwitched; 83 } 84 85 function checkTheme(root, { theme, className, forcedColorsActive }) { 86 const themePrefValue = Services.prefs.getCharPref(THEME_PREF); 87 ok( 88 root.classList.contains(className), 89 `:root has ${className} class for ${themePrefValue} theme (${root.className})` 90 ); 91 92 is( 93 root.hasAttribute("forced-colors-active"), 94 forcedColorsActive, 95 `high contrast mode is ${ 96 !forcedColorsActive ? "not " : "" 97 }supported in ${themePrefValue} theme` 98 ); 99 100 const sheetsInDOM = Array.from( 101 root.ownerDocument.querySelectorAll("link[rel='stylesheet']"), 102 l => l.href 103 ); 104 105 const sheetsFromTheme = gDevTools.getThemeDefinition(theme).stylesheets; 106 info("Checking for existence of " + sheetsInDOM.length + " sheets"); 107 for (const themeSheet of sheetsFromTheme) { 108 ok( 109 sheetsInDOM.some(s => s.includes(themeSheet)), 110 "There is a stylesheet for " + themeSheet 111 ); 112 } 113 } 114 115 function getPlatform() { 116 const { OS } = Services.appinfo; 117 if (OS == "WINNT") { 118 return "win"; 119 } else if (OS == "Darwin") { 120 return "mac"; 121 } 122 return "linux"; 123 }