summaryrefslogtreecommitdiffstats
path: root/browser/tools/mozscreenshots/mozscreenshots/extension/configurations
diff options
context:
space:
mode:
Diffstat (limited to 'browser/tools/mozscreenshots/mozscreenshots/extension/configurations')
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/AppMenu.sys.mjs77
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.sys.mjs97
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/ControlCenter.sys.mjs320
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/CustomizeMode.sys.mjs72
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.sys.mjs74
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/LightweightThemes.sys.mjs51
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/PermissionPrompts.sys.mjs168
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.sys.mjs183
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.sys.mjs219
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/TabsInTitlebar.sys.mjs28
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Toolbars.sys.mjs54
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/UIDensities.sys.mjs42
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/configurations/WindowSize.sys.mjs68
13 files changed, 1453 insertions, 0 deletions
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/AppMenu.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/AppMenu.sys.mjs
new file mode 100644
index 0000000000..8309eab623
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/AppMenu.sys.mjs
@@ -0,0 +1,77 @@
+/* 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 { BrowserTestUtils } from "resource://testing-common/BrowserTestUtils.sys.mjs";
+
+export var AppMenu = {
+ init(libDir) {},
+
+ configurations: {
+ appMenuMainView: {
+ selectors: ["#appMenu-popup"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await reopenAppMenu(browserWindow);
+ },
+ },
+
+ appMenuHistorySubview: {
+ selectors: ["#appMenu-popup"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await reopenAppMenu(browserWindow);
+
+ browserWindow.document.getElementById("appMenu-library-button").click();
+ let view = browserWindow.document.getElementById("appMenu-libraryView");
+ let promiseViewShown = BrowserTestUtils.waitForEvent(view, "ViewShown");
+ await promiseViewShown;
+ },
+
+ verifyConfig: verifyConfigHelper,
+ },
+
+ appMenuHelpSubview: {
+ selectors: ["#appMenu-popup"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await reopenAppMenu(browserWindow);
+
+ browserWindow.document.getElementById("appMenu-help-button2").click();
+ let view = browserWindow.document.getElementById("PanelUI-helpView");
+ let promiseViewShown = BrowserTestUtils.waitForEvent(view, "ViewShown");
+ await promiseViewShown;
+ },
+
+ verifyConfig: verifyConfigHelper,
+ },
+ },
+};
+
+async function reopenAppMenu(browserWindow) {
+ browserWindow.PanelUI.hide();
+ let promiseViewShown = BrowserTestUtils.waitForEvent(
+ browserWindow.PanelUI.panel,
+ "ViewShown"
+ );
+ browserWindow.PanelUI.show();
+ await promiseViewShown;
+}
+
+function verifyConfigHelper() {
+ if (isCustomizing()) {
+ return "navigator:browser has the customizing attribute";
+ }
+ return undefined;
+}
+
+function isCustomizing() {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ if (browserWindow.document.documentElement.hasAttribute("customizing")) {
+ return true;
+ }
+ return false;
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.sys.mjs
new file mode 100644
index 0000000000..2bc12d9012
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.sys.mjs
@@ -0,0 +1,97 @@
+/* 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 { CustomizableUI } from "resource:///modules/CustomizableUI.sys.mjs";
+
+export var Buttons = {
+ init(libDir) {
+ createWidget();
+ },
+
+ configurations: {
+ navBarButtons: {
+ selectors: ["#nav-bar"],
+ applyConfig: async () => {
+ CustomizableUI.addWidgetToArea(
+ "screenshot-widget",
+ CustomizableUI.AREA_NAVBAR
+ );
+ },
+ },
+
+ tabsToolbarButtons: {
+ selectors: ["#TabsToolbar"],
+ applyConfig: async () => {
+ CustomizableUI.addWidgetToArea(
+ "screenshot-widget",
+ CustomizableUI.AREA_TABSTRIP
+ );
+ },
+ },
+
+ menuPanelButtons: {
+ selectors: ["#widget-overflow"],
+ applyConfig: async () => {
+ CustomizableUI.addWidgetToArea(
+ "screenshot-widget",
+ CustomizableUI.AREA_FIXED_OVERFLOW_PANEL
+ );
+ },
+
+ async verifyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ if (browserWindow.PanelUI.panel.state == "closed") {
+ return "The button isn't shown when the panel isn't open.";
+ }
+ return undefined;
+ },
+ },
+
+ custPaletteButtons: {
+ selectors: ["#customization-palette"],
+ applyConfig: async () => {
+ CustomizableUI.removeWidgetFromArea("screenshot-widget");
+ },
+
+ async verifyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ if (
+ browserWindow.document.documentElement.getAttribute("customizing") !=
+ "true"
+ ) {
+ return "The button isn't shown when we're not in customize mode.";
+ }
+ return undefined;
+ },
+ },
+ },
+};
+
+function createWidget() {
+ let id = "screenshot-widget";
+ let spec = {
+ id,
+ label: "My Button",
+ removable: true,
+ tooltiptext: "",
+ type: "button",
+ };
+ CustomizableUI.createWidget(spec);
+
+ // Append a <style> for the image
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let st = browserWindow.document.createElementNS(
+ "http://www.w3.org/1999/xhtml",
+ "style"
+ );
+ let styles =
+ "" +
+ "#screenshot-widget > .toolbarbutton-icon {" +
+ " list-style-image: url(chrome://browser/skin/thumb-down.svg);" +
+ "}";
+ st.appendChild(browserWindow.document.createTextNode(styles));
+ browserWindow.document.documentElement.appendChild(st);
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/ControlCenter.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/ControlCenter.sys.mjs
new file mode 100644
index 0000000000..2ada0e831c
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/ControlCenter.sys.mjs
@@ -0,0 +1,320 @@
+/* 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 { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
+import { BrowserTestUtils } from "resource://testing-common/BrowserTestUtils.sys.mjs";
+import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+import { UrlClassifierTestUtils } from "resource://testing-common/UrlClassifierTestUtils.sys.mjs";
+
+import { SitePermissions } from "resource:///modules/SitePermissions.sys.mjs";
+
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+const CC_SELECTORS = ["#identity-popup", "#urlbar-input-container"];
+const PP_SELECTORS = ["#protections-popup", "#urlbar-input-container"];
+
+const RESOURCE_PATH =
+ "browser/browser/tools/mozscreenshots/mozscreenshots/extension/mozscreenshots/browser/resources/lib/controlCenter";
+const HTTP_PAGE = "http://example.com/";
+const HTTPS_PAGE = "https://example.com/";
+const PERMISSIONS_PAGE = "https://test1.example.com/";
+const HTTP_PASSWORD_PAGE = `http://test2.example.org/${RESOURCE_PATH}/password.html`;
+const MIXED_CONTENT_URL = `https://example.com/${RESOURCE_PATH}/mixed.html`;
+const MIXED_ACTIVE_CONTENT_URL = `https://example.com/${RESOURCE_PATH}/mixed_active.html`;
+const MIXED_PASSIVE_CONTENT_URL = `https://example.com/${RESOURCE_PATH}/mixed_passive.html`;
+const TRACKING_PAGE = `http://tracking.example.org/${RESOURCE_PATH}/tracking.html`;
+
+export var ControlCenter = {
+ init(libDir) {},
+
+ configurations: {
+ about: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage("about:rights");
+ await openIdentityPopup();
+ },
+ },
+
+ localFile: {
+ // This selector is different so we can exclude the changing file: path
+ selectors: ["#identity-popup-security-button"],
+ async applyConfig() {
+ let channel = NetUtil.newChannel({
+ uri: "resource://mozscreenshots/lib/mozscreenshots.html",
+ loadUsingSystemPrincipal: true,
+ });
+ channel = channel.QueryInterface(Ci.nsIFileChannel);
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ BrowserTestUtils.loadURIString(
+ gBrowser.selectedBrowser,
+ channel.file.path
+ );
+ await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
+ await openIdentityPopup();
+ },
+ },
+
+ http: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTP_PAGE);
+ await openIdentityPopup();
+ },
+ },
+
+ httpSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTP_PAGE);
+ await openIdentityPopup(true);
+ },
+ },
+
+ https: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTPS_PAGE);
+ await openIdentityPopup();
+ },
+ },
+
+ httpsSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTPS_PAGE);
+ await openIdentityPopup(true);
+ },
+ },
+
+ singlePermission: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ PERMISSIONS_PAGE
+ );
+ SitePermissions.setForPrincipal(
+ principal,
+ "camera",
+ SitePermissions.ALLOW
+ );
+
+ await loadPage(PERMISSIONS_PAGE);
+ await openIdentityPopup();
+ },
+ },
+
+ allPermissions: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ // TODO: (Bug 1330601) Rewrite this to consider temporary (TAB) permission states.
+ // There are 2 possible non-default permission states, so we alternate between them.
+ let states = [SitePermissions.ALLOW, SitePermissions.BLOCK];
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ PERMISSIONS_PAGE
+ );
+ SitePermissions.listPermissions().forEach(function (permission, index) {
+ SitePermissions.setForPrincipal(
+ principal,
+ permission,
+ states[index % 2]
+ );
+ });
+
+ await loadPage(PERMISSIONS_PAGE);
+ await openIdentityPopup();
+ },
+ },
+
+ mixed: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_CONTENT_URL);
+ await openIdentityPopup();
+ },
+ },
+
+ mixedSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_CONTENT_URL);
+ await openIdentityPopup(true);
+ },
+ },
+
+ mixedPassive: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_PASSIVE_CONTENT_URL);
+ await openIdentityPopup();
+ },
+ },
+
+ mixedPassiveSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_PASSIVE_CONTENT_URL);
+ await openIdentityPopup(true);
+ },
+ },
+
+ mixedActive: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_ACTIVE_CONTENT_URL);
+ await openIdentityPopup();
+ },
+ },
+
+ mixedActiveSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(MIXED_ACTIVE_CONTENT_URL);
+ await openIdentityPopup(true);
+ },
+ },
+
+ mixedActiveUnblocked: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ await loadPage(MIXED_ACTIVE_CONTENT_URL);
+ gBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
+ await BrowserTestUtils.browserLoaded(
+ gBrowser.selectedBrowser,
+ false,
+ MIXED_ACTIVE_CONTENT_URL
+ );
+ await openIdentityPopup();
+ },
+ },
+
+ mixedActiveUnblockedSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ await loadPage(MIXED_ACTIVE_CONTENT_URL);
+ gBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
+ await BrowserTestUtils.browserLoaded(
+ gBrowser.selectedBrowser,
+ false,
+ MIXED_ACTIVE_CONTENT_URL
+ );
+ await openIdentityPopup(true);
+ },
+ },
+
+ httpPassword: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTP_PASSWORD_PAGE);
+ await openIdentityPopup();
+ },
+ },
+
+ httpPasswordSubView: {
+ selectors: CC_SELECTORS,
+ async applyConfig() {
+ await loadPage(HTTP_PASSWORD_PAGE);
+ await openIdentityPopup(true);
+ },
+ },
+
+ trackingProtectionNoElements: {
+ selectors: PP_SELECTORS,
+ async applyConfig() {
+ Services.prefs.setBoolPref("privacy.trackingprotection.enabled", true);
+
+ await loadPage(HTTP_PAGE);
+ await openProtectionsPopup();
+ },
+ },
+
+ trackingProtectionEnabled: {
+ selectors: PP_SELECTORS,
+ async applyConfig() {
+ Services.prefs.setBoolPref("privacy.trackingprotection.enabled", true);
+ await UrlClassifierTestUtils.addTestTrackers();
+
+ await loadPage(TRACKING_PAGE);
+ await openProtectionsPopup();
+ },
+ },
+
+ trackingProtectionDisabled: {
+ selectors: PP_SELECTORS,
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ Services.prefs.setBoolPref("privacy.trackingprotection.enabled", true);
+ await UrlClassifierTestUtils.addTestTrackers();
+
+ await loadPage(TRACKING_PAGE);
+
+ // unblock the page
+ let loaded = BrowserTestUtils.browserLoaded(
+ gBrowser.selectedBrowser,
+ false,
+ TRACKING_PAGE
+ );
+ gBrowser.ownerGlobal.gProtectionsHandler.disableForCurrentPage();
+ await loaded;
+ await openProtectionsPopup();
+ },
+ },
+ },
+};
+
+async function loadPage(url) {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, url);
+ await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, url);
+}
+
+async function openIdentityPopup(expand) {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ let { gIdentityHandler } = gBrowser.ownerGlobal;
+ // Ensure the popup is available, if it's never been opened.
+ gIdentityHandler._initializePopup();
+ gIdentityHandler._identityPopup.hidePopup();
+ // Disable the popup shadow on OSX until we have figured out bug 1425253.
+ if (AppConstants.platform == "macosx") {
+ gIdentityHandler._identityPopup.classList.add("no-shadow");
+ }
+ gIdentityHandler._identityIconBox.click();
+ if (expand) {
+ // give some time for opening to avoid weird style issues
+ await new Promise(c => setTimeout(c, 500));
+ gIdentityHandler._identityPopup
+ .querySelector("#identity-popup-security-button")
+ .click();
+ }
+}
+
+async function openProtectionsPopup() {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ let { gProtectionsHandler } = gBrowser.ownerGlobal;
+ // Force initializing the popup; we can't add classes otherwise.
+ gProtectionsHandler._initializePopup();
+ gProtectionsHandler._protectionsPopup.hidePopup();
+ // Disable the popup shadow on OSX until we have figured out bug 1425253.
+ if (AppConstants.platform == "macosx") {
+ gProtectionsHandler._protectionsPopup.classList.add("no-shadow");
+ }
+ gProtectionsHandler.showProtectionsPopup();
+ // Wait for any animation.
+ await new Promise(_ => setTimeout(_, 500));
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/CustomizeMode.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/CustomizeMode.sys.mjs
new file mode 100644
index 0000000000..a5a1b65b69
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/CustomizeMode.sys.mjs
@@ -0,0 +1,72 @@
+/* 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 { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+
+export var CustomizeMode = {
+ init(libDir) {},
+
+ configurations: {
+ notCustomizing: {
+ selectors: ["#navigator-toolbox"],
+ applyConfig() {
+ return new Promise(resolve => {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ if (
+ !browserWindow.document.documentElement.hasAttribute("customizing")
+ ) {
+ resolve("notCustomizing: already not customizing");
+ return;
+ }
+ function onCustomizationEnds() {
+ browserWindow.gNavToolbox.removeEventListener(
+ "aftercustomization",
+ onCustomizationEnds
+ );
+ // Wait for final changes
+ setTimeout(
+ () => resolve("notCustomizing: onCustomizationEnds"),
+ 500
+ );
+ }
+ browserWindow.gNavToolbox.addEventListener(
+ "aftercustomization",
+ onCustomizationEnds
+ );
+ browserWindow.gCustomizeMode.exit();
+ });
+ },
+ },
+
+ customizing: {
+ selectors: ["#navigator-toolbox", "#customization-container"],
+ applyConfig() {
+ return new Promise(resolve => {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ if (
+ browserWindow.document.documentElement.hasAttribute("customizing")
+ ) {
+ resolve("customizing: already customizing");
+ return;
+ }
+ function onCustomizing() {
+ browserWindow.gNavToolbox.removeEventListener(
+ "customizationready",
+ onCustomizing
+ );
+ // Wait for final changes
+ setTimeout(() => resolve("customizing: onCustomizing"), 500);
+ }
+ browserWindow.gNavToolbox.addEventListener(
+ "customizationready",
+ onCustomizing
+ );
+ browserWindow.gCustomizeMode.enter();
+ });
+ },
+ },
+ },
+};
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.sys.mjs
new file mode 100644
index 0000000000..addef011c0
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.sys.mjs
@@ -0,0 +1,74 @@
+/* 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 { require } from "resource://devtools/shared/loader/Loader.sys.mjs";
+
+const { gDevTools } = require("devtools/client/framework/devtools");
+
+import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+
+async function showToolboxForSelectedTab(toolId, hostType) {
+ const browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ const tab = browserWindow.gBrowser.selectedTab;
+ return gDevTools.showToolboxForTab(tab, { toolId, hostType });
+}
+
+function selectToolbox(toolbox) {
+ return toolbox.win.document.querySelector("#toolbox-container");
+}
+
+export var DevTools = {
+ init(libDir) {
+ let panels = [
+ "options",
+ "webconsole",
+ "jsdebugger",
+ "styleeditor",
+ "performance",
+ "netmonitor",
+ ];
+
+ panels.forEach(panel => {
+ this.configurations[panel] = {};
+ this.configurations[panel].applyConfig = async function () {
+ Services.prefs.setIntPref("devtools.toolbox.footer.height", 800);
+ let toolbox = await showToolboxForSelectedTab(panel, "bottom");
+ this.selectors = [selectToolbox.bind(null, toolbox)];
+ await new Promise(resolve => setTimeout(resolve, 500));
+ };
+ });
+ },
+
+ configurations: {
+ bottomToolbox: {
+ async applyConfig() {
+ Services.prefs.clearUserPref("devtools.toolbox.footer.height");
+ let toolbox = await showToolboxForSelectedTab("inspector", "bottom");
+ this.selectors = [selectToolbox.bind(null, toolbox)];
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ },
+ },
+ sideToolbox: {
+ async applyConfig() {
+ let toolbox = await showToolboxForSelectedTab("inspector", "right");
+ this.selectors = [selectToolbox.bind(null, toolbox)];
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ },
+ async verifyConfig() {
+ return "Panel sizes are regularly inconsistent";
+ },
+ },
+ undockedToolbox: {
+ windowType: "devtools:toolbox",
+ async applyConfig() {
+ let toolbox = await showToolboxForSelectedTab("inspector", "window");
+ this.selectors = [selectToolbox.bind(null, toolbox)];
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ },
+ async verifyConfig() {
+ return "Panel sizes are regularly inconsistent";
+ },
+ },
+ },
+};
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/LightweightThemes.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/LightweightThemes.sys.mjs
new file mode 100644
index 0000000000..91c3349ec7
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/LightweightThemes.sys.mjs
@@ -0,0 +1,51 @@
+/* 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 { AddonManager } from "resource://gre/modules/AddonManager.sys.mjs";
+
+export var LightweightThemes = {
+ init(libDir) {},
+
+ configurations: {
+ noLWT: {
+ selectors: [],
+ async applyConfig() {
+ let addon = await AddonManager.getAddonByID(
+ "default-theme@mozilla.org"
+ );
+ await addon.enable();
+ },
+ },
+
+ compactLight: {
+ selectors: [],
+ async applyConfig() {
+ let addon = await AddonManager.getAddonByID(
+ "firefox-compact-light@mozilla.org"
+ );
+ await addon.enable();
+ },
+ },
+
+ compactDark: {
+ selectors: [],
+ async applyConfig() {
+ let addon = await AddonManager.getAddonByID(
+ "firefox-compact-dark@mozilla.org"
+ );
+ await addon.enable();
+ },
+ },
+
+ alpenGlow: {
+ selectors: [],
+ async applyConfig() {
+ let addon = await AddonManager.getAddonByID(
+ "firefox-alpenglow@mozilla.org"
+ );
+ await addon.enable();
+ },
+ },
+ },
+};
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/PermissionPrompts.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/PermissionPrompts.sys.mjs
new file mode 100644
index 0000000000..de12c69e81
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/PermissionPrompts.sys.mjs
@@ -0,0 +1,168 @@
+/* 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/. */
+
+// Various parts here are run in the content process.
+/* global content */
+
+import { BrowserTestUtils } from "resource://testing-common/BrowserTestUtils.sys.mjs";
+
+const URL =
+ "https://test1.example.com/browser/browser/tools/mozscreenshots/mozscreenshots/extension/mozscreenshots/browser/resources/lib/permissionPrompts.html";
+let lastTab = null;
+
+export var PermissionPrompts = {
+ init(libDir) {
+ Services.prefs.setBoolPref("media.navigator.permission.fake", true);
+ Services.prefs.setBoolPref("extensions.install.requireBuiltInCerts", false);
+ Services.prefs.setBoolPref("signon.rememberSignons", true);
+ },
+
+ configurations: {
+ shareDevices: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#webRTC-shareDevices");
+ },
+ },
+
+ shareMicrophone: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#webRTC-shareMicrophone");
+ },
+ },
+
+ shareVideoAndMicrophone: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#webRTC-shareDevices2");
+ },
+ },
+
+ shareScreen: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#webRTC-shareScreen");
+ },
+ },
+
+ geo: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#geo");
+ },
+ },
+
+ persistentStorage: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#persistent-storage");
+ },
+ },
+
+ loginCapture: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ // we need to emulate user input in the form for the save-password prompt to be shown
+ await clickOn("#login-capture", function beforeContentFn() {
+ const { E10SUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/E10SUtils.sys.mjs"
+ );
+ E10SUtils.wrapHandlingUserInput(content, true, function () {
+ let element = content.document.querySelector(
+ "input[type=password]"
+ );
+ element.setUserInput("123456");
+ });
+ });
+ },
+ },
+
+ notifications: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ await closeLastTab();
+ await clickOn("#web-notifications");
+ },
+ },
+
+ addons: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ Services.prefs.setBoolPref("xpinstall.whitelist.required", true);
+
+ await closeLastTab();
+ await clickOn("#addons");
+ },
+ },
+
+ addonsNoWhitelist: {
+ selectors: ["#notification-popup", "#identity-box"],
+ async applyConfig() {
+ Services.prefs.setBoolPref("xpinstall.whitelist.required", false);
+
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let notification = browserWindow.document.getElementById(
+ "addon-webext-permissions-notification"
+ );
+
+ await closeLastTab();
+ await clickOn("#addons");
+
+ // We want to skip the progress-notification, so we wait for
+ // the install-confirmation screen to be "not hidden" = shown.
+ return BrowserTestUtils.waitForCondition(
+ () => !notification.hidden,
+ "addon install confirmation did not show",
+ 200
+ ).catch(msg => {
+ return Promise.resolve({ todo: msg });
+ });
+ },
+ },
+ },
+};
+
+async function closeLastTab() {
+ if (!lastTab) {
+ return;
+ }
+ BrowserTestUtils.removeTab(lastTab);
+ lastTab = null;
+}
+
+async function clickOn(selector, beforeContentFn) {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+
+ // Save the tab so we can close it later.
+ lastTab = await BrowserTestUtils.openNewForegroundTab(
+ browserWindow.gBrowser,
+ URL
+ );
+
+ let { SpecialPowers } = lastTab.ownerGlobal;
+ if (beforeContentFn) {
+ await SpecialPowers.spawn(lastTab.linkedBrowser, [], beforeContentFn);
+ }
+
+ await SpecialPowers.spawn(lastTab.linkedBrowser, [selector], arg => {
+ /* eslint-env mozilla/chrome-script */
+ let element = content.document.querySelector(arg);
+ return EventUtils.synthesizeClick(element);
+ });
+
+ // Wait for the popup to actually be shown before making the screenshot
+ await BrowserTestUtils.waitForEvent(
+ browserWindow.PopupNotifications.panel,
+ "popupshown"
+ );
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.sys.mjs
new file mode 100644
index 0000000000..77026523ba
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.sys.mjs
@@ -0,0 +1,183 @@
+/* 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/. */
+
+// Various parts here are run in the content process.
+/* global content */
+
+import { TestUtils } from "resource://testing-common/TestUtils.sys.mjs";
+
+export var Preferences = {
+ init(libDir) {
+ let panes = [
+ ["paneGeneral"],
+ ["paneGeneral", browsingGroup],
+ ["paneGeneral", connectionDialog],
+ ["paneSearch"],
+ ["panePrivacy"],
+ ["panePrivacy", cacheGroup],
+ ["panePrivacy", clearRecentHistoryDialog],
+ ["panePrivacy", certManager],
+ ["panePrivacy", deviceManager],
+ ["panePrivacy", DNTDialog],
+ ["paneSync"],
+ ];
+
+ for (let [primary, customFn] of panes) {
+ let configName = primary.replace(/^pane/, "prefs");
+ if (customFn) {
+ configName += "-" + customFn.name;
+ }
+ this.configurations[configName] = {};
+ this.configurations[configName].selectors = ["#browser"];
+ if (primary == "panePrivacy" && customFn) {
+ this.configurations[configName].applyConfig = async () => {
+ return { todo: `${configName} times out on the try server` };
+ };
+ } else {
+ this.configurations[configName].applyConfig = prefHelper.bind(
+ null,
+ primary,
+ customFn
+ );
+ }
+ }
+ },
+
+ configurations: {},
+};
+
+let prefHelper = async function (primary, customFn = null) {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let selectedBrowser = browserWindow.gBrowser.selectedBrowser;
+
+ // close any dialog that might still be open
+ await selectedBrowser.ownerGlobal.SpecialPowers.spawn(
+ selectedBrowser,
+ [],
+ async function () {
+ // Check that gSubDialog is defined on the content window
+ // and that there is an open dialog to close
+ if (!content.window.gSubDialog || !content.window.gSubDialog._topDialog) {
+ return;
+ }
+ content.window.gSubDialog.close();
+ }
+ );
+
+ let readyPromise = null;
+ if (selectedBrowser.currentURI.specIgnoringRef == "about:preferences") {
+ if (
+ selectedBrowser.currentURI.spec ==
+ "about:preferences#" + primary.replace(/^pane/, "")
+ ) {
+ // We're already on the correct pane.
+ readyPromise = Promise.resolve();
+ } else {
+ readyPromise = paintPromise(browserWindow);
+ }
+ } else {
+ readyPromise = TestUtils.topicObserved("sync-pane-loaded");
+ }
+
+ browserWindow.openPreferences(primary);
+
+ await readyPromise;
+
+ if (customFn) {
+ let customPaintPromise = paintPromise(browserWindow);
+ let result = await customFn(selectedBrowser);
+ await customPaintPromise;
+ return result;
+ }
+ return undefined;
+};
+
+function paintPromise(browserWindow) {
+ return new Promise(resolve => {
+ browserWindow.addEventListener(
+ "MozAfterPaint",
+ function () {
+ resolve();
+ },
+ { once: true }
+ );
+ });
+}
+
+async function browsingGroup(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("browsingGroup").scrollIntoView();
+ }
+ );
+}
+
+async function cacheGroup(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("cacheGroup").scrollIntoView();
+ }
+ );
+}
+
+async function DNTDialog(aBrowser) {
+ return aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ const button = content.document.getElementById("doNotTrackSettings");
+ if (!button) {
+ return {
+ todo: "The dialog may have exited before we could click the button",
+ };
+ }
+ button.click();
+ return undefined;
+ }
+ );
+}
+
+async function connectionDialog(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("connectionSettings").click();
+ }
+ );
+}
+
+async function clearRecentHistoryDialog(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("clearHistoryButton").click();
+ }
+ );
+}
+
+async function certManager(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("viewCertificatesButton").click();
+ }
+ );
+}
+
+async function deviceManager(aBrowser) {
+ await aBrowser.ownerGlobal.SpecialPowers.spawn(
+ aBrowser,
+ [],
+ async function () {
+ content.document.getElementById("viewSecurityDevicesButton").click();
+ }
+ );
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.sys.mjs
new file mode 100644
index 0000000000..85b134b8bc
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.sys.mjs
@@ -0,0 +1,219 @@
+/* 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 CUST_TAB = "chrome://browser/skin/customize.svg";
+const PREFS_TAB = "chrome://global/skin/icons/settings.svg";
+const DEFAULT_FAVICON_TAB = `data:text/html,<meta%20charset="utf-8"><title>No%20favicon</title>`;
+
+import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+import { TestUtils } from "resource://testing-common/TestUtils.sys.mjs";
+
+export var Tabs = {
+ init(libDir) {},
+
+ configurations: {
+ fiveTabs: {
+ selectors: ["#tabbrowser-tabs"],
+ async applyConfig() {
+ fiveTabsHelper();
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ hoverTab(browserWindow.gBrowser.tabs[3]);
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 3000);
+ });
+ await allTabTitlesDisplayed(browserWindow);
+ },
+ },
+
+ fourPinned: {
+ selectors: ["#tabbrowser-tabs"],
+ async applyConfig() {
+ fiveTabsHelper();
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let tab = browserWindow.gBrowser.addTab(PREFS_TAB, {
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ browserWindow.gBrowser.pinTab(tab);
+ tab = browserWindow.gBrowser.addTab(CUST_TAB, {
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ browserWindow.gBrowser.pinTab(tab);
+ tab = browserWindow.gBrowser.addTab("about:privatebrowsing", {
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ browserWindow.gBrowser.pinTab(tab);
+ tab = browserWindow.gBrowser.addTab("about:home", {
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ browserWindow.gBrowser.pinTab(tab);
+ browserWindow.gBrowser.selectTabAtIndex(5);
+ hoverTab(browserWindow.gBrowser.tabs[2]);
+ // also hover the new tab button
+ let newTabButton = browserWindow.gBrowser.tabContainer.newTabButton;
+ hoverTab(newTabButton);
+
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 3000);
+ });
+ await allTabTitlesDisplayed(browserWindow);
+ },
+ },
+
+ twoPinnedWithOverflow: {
+ selectors: ["#tabbrowser-tabs"],
+ async applyConfig() {
+ fiveTabsHelper();
+
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ browserWindow.gBrowser.loadTabs(
+ [
+ PREFS_TAB,
+ CUST_TAB,
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ ],
+ {
+ inBackground: true,
+ replace: true,
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ }
+ );
+ browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[1]);
+ browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[2]);
+ browserWindow.gBrowser.selectTabAtIndex(3);
+ hoverTab(browserWindow.gBrowser.tabs[5]);
+
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 3000);
+ });
+
+ // Make sure the tabstrip is scrolled all the way to the left.
+ browserWindow.gBrowser.tabContainer.arrowScrollbox.scrollByIndex(
+ -100,
+ true
+ );
+
+ await allTabTitlesDisplayed(browserWindow);
+ },
+ },
+ },
+};
+
+/* helpers */
+
+async function allTabTitlesDisplayed(browserWindow) {
+ let specToTitleMap = {
+ "about:home": "New Tab",
+ "about:newtab": "New Tab",
+ "about:addons": "Add-ons Manager",
+ "about:privatebrowsing": "about:privatebrowsing",
+ };
+ specToTitleMap[PREFS_TAB] = "global/skin/icons/settings.svg";
+ specToTitleMap[CUST_TAB] = "browser/skin/customize.svg";
+ specToTitleMap[DEFAULT_FAVICON_TAB] = "No favicon";
+
+ let tabTitlePromises = [];
+ for (let tab of browserWindow.gBrowser.tabs) {
+ function getSpec() {
+ return (
+ tab.linkedBrowser &&
+ tab.linkedBrowser.documentURI &&
+ tab.linkedBrowser.documentURI.spec
+ );
+ }
+ function tabTitleLoaded() {
+ let spec = getSpec();
+ return spec ? tab.label == specToTitleMap[spec] : false;
+ }
+ let promise = TestUtils.waitForCondition(
+ tabTitleLoaded,
+ `Tab (${getSpec()}) should be showing "${
+ specToTitleMap[getSpec()]
+ }". Got "${tab.label}"`
+ );
+ tabTitlePromises.push(promise);
+ }
+
+ return Promise.all(tabTitlePromises);
+}
+
+function fiveTabsHelper() {
+ // some with no favicon and some with. Selected tab in middle.
+ closeAllButOneTab("about:addons");
+
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ browserWindow.gBrowser.loadTabs(
+ [
+ "about:addons",
+ "about:home",
+ DEFAULT_FAVICON_TAB,
+ "about:newtab",
+ CUST_TAB,
+ ],
+ {
+ inBackground: true,
+ replace: true,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ }
+ );
+ browserWindow.gBrowser.selectTabAtIndex(1);
+}
+
+function closeAllButOneTab(url = "about:blank") {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ let gBrowser = browserWindow.gBrowser;
+ // Close all tabs except the last so we don't quit the browser.
+ while (gBrowser.tabs.length > 1) {
+ gBrowser.removeTab(gBrowser.selectedTab, { animate: false });
+ }
+ gBrowser.selectedBrowser.loadURI(Services.io.newURI(url), {
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ if (gBrowser.selectedTab.pinned) {
+ gBrowser.unpinTab(gBrowser.selectedTab);
+ }
+ let newTabButton = gBrowser.tabContainer.newTabButton;
+ hoverTab(newTabButton, false);
+}
+
+function hoverTab(tab, hover = true) {
+ if (hover) {
+ InspectorUtils.addPseudoClassLock(tab, ":hover");
+ } else {
+ InspectorUtils.clearPseudoClassLocks(tab);
+ }
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/TabsInTitlebar.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/TabsInTitlebar.sys.mjs
new file mode 100644
index 0000000000..bc5b12c219
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/TabsInTitlebar.sys.mjs
@@ -0,0 +1,28 @@
+/* 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 PREF_TABS_IN_TITLEBAR = "browser.tabs.inTitlebar";
+
+export var TabsInTitlebar = {
+ init(libDir) {},
+
+ configurations: {
+ tabsInTitlebar: {
+ selectors: ["#navigator-toolbox"],
+ async applyConfig() {
+ Services.prefs.setIntPref(PREF_TABS_IN_TITLEBAR, 1);
+ return undefined;
+ },
+ },
+
+ tabsOutsideTitlebar: {
+ selectors: ["#navigator-toolbox"].concat(
+ Services.appinfo.OS == "Linux" ? [] : ["#titlebar"]
+ ),
+ async applyConfig() {
+ Services.prefs.setIntPref(PREF_TABS_IN_TITLEBAR, 0);
+ },
+ },
+ },
+};
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Toolbars.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Toolbars.sys.mjs
new file mode 100644
index 0000000000..06b1159a5e
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Toolbars.sys.mjs
@@ -0,0 +1,54 @@
+/* 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/. */
+
+export var Toolbars = {
+ init(libDir) {},
+
+ configurations: {
+ onlyNavBar: {
+ selectors: ["#navigator-toolbox"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let personalToolbar =
+ browserWindow.document.getElementById("PersonalToolbar");
+ browserWindow.setToolbarVisibility(personalToolbar, false);
+ toggleMenubarIfNecessary(false);
+ },
+ },
+
+ allToolbars: {
+ selectors: ["#navigator-toolbox"],
+ async applyConfig() {
+ // Boookmarks and menubar
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ let personalToolbar =
+ browserWindow.document.getElementById("PersonalToolbar");
+ browserWindow.setToolbarVisibility(personalToolbar, true);
+ toggleMenubarIfNecessary(true);
+ },
+
+ async verifyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ if (browserWindow.fullScreen) {
+ return "The bookmark toolbar and menubar are not shown in fullscreen.";
+ }
+ return undefined;
+ },
+ },
+ },
+};
+
+// helpers
+
+function toggleMenubarIfNecessary(visible) {
+ let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ // The menubar is not shown on OS X or while in fullScreen
+ if (Services.appinfo.OS != "Darwin" /* && !browserWindow.fullScreen*/) {
+ let menubar = browserWindow.document.getElementById("toolbar-menubar");
+ browserWindow.setToolbarVisibility(menubar, visible);
+ }
+}
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/UIDensities.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/UIDensities.sys.mjs
new file mode 100644
index 0000000000..37cc123727
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/UIDensities.sys.mjs
@@ -0,0 +1,42 @@
+/* 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/. */
+
+export var UIDensities = {
+ init(libDir) {},
+
+ configurations: {
+ compactDensity: {
+ selectors: ["#navigator-toolbox", "#appMenu-popup", "#widget-overflow"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ browserWindow.gCustomizeMode.setUIDensity(
+ browserWindow.gUIDensity.MODE_COMPACT
+ );
+ },
+ },
+
+ normalDensity: {
+ selectors: ["#navigator-toolbox", "#appMenu-popup", "#widget-overflow"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ browserWindow.gCustomizeMode.setUIDensity(
+ browserWindow.gUIDensity.MODE_NORMAL
+ );
+ },
+ },
+
+ touchDensity: {
+ selectors: ["#navigator-toolbox", "#appMenu-popup", "#widget-overflow"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ browserWindow.gCustomizeMode.setUIDensity(
+ browserWindow.gUIDensity.MODE_TOUCH
+ );
+ },
+ },
+ },
+};
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/WindowSize.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/WindowSize.sys.mjs
new file mode 100644
index 0000000000..98a4e3ec00
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/WindowSize.sys.mjs
@@ -0,0 +1,68 @@
+/* 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 { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+import { BrowserTestUtils } from "resource://testing-common/BrowserTestUtils.sys.mjs";
+
+export var WindowSize = {
+ init(libDir) {
+ Services.prefs.setBoolPref("browser.fullscreen.autohide", false);
+ },
+
+ configurations: {
+ maximized: {
+ selectors: [":root"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await toggleFullScreen(browserWindow, false);
+
+ // Wait for the Lion fullscreen transition to end as there doesn't seem to be an event
+ // and trying to maximize while still leaving fullscreen doesn't work.
+ await new Promise((resolve, reject) => {
+ setTimeout(function waitToLeaveFS() {
+ browserWindow.maximize();
+ resolve();
+ }, 5000);
+ });
+ },
+ },
+
+ normal: {
+ selectors: [":root"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await toggleFullScreen(browserWindow, false);
+ browserWindow.restore();
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 5000);
+ });
+ },
+ },
+
+ fullScreen: {
+ selectors: [":root"],
+ async applyConfig() {
+ let browserWindow =
+ Services.wm.getMostRecentWindow("navigator:browser");
+ await toggleFullScreen(browserWindow, true);
+ // OS X Lion fullscreen transition takes a while
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 5000);
+ });
+ },
+ },
+ },
+};
+
+function toggleFullScreen(browserWindow, wantsFS) {
+ browserWindow.fullScreen = wantsFS;
+ return BrowserTestUtils.waitForCondition(() => {
+ return (
+ wantsFS ==
+ browserWindow.document.documentElement.hasAttribute("inFullscreen")
+ );
+ }, "waiting for @inFullscreen change");
+}