summaryrefslogtreecommitdiffstats
path: root/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js')
-rw-r--r--devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js
new file mode 100644
index 0000000000..c205ecbfe3
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js
@@ -0,0 +1,246 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+/* import-globals-from helper-addons.js */
+Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
+
+// There are shutdown issues for which multiple rejections are left uncaught.
+// See bug 1018184 for resolving these issues.
+const { PromiseTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/PromiseTestUtils.sys.mjs"
+);
+PromiseTestUtils.allowMatchingRejectionsGlobally(/File closed/);
+
+// Avoid test timeouts that can occur while waiting for the "addon-console-works" message.
+requestLongerTimeout(2);
+
+const ADDON_ID = "test-devtools-webextension@mozilla.org";
+const ADDON_NAME = "test-devtools-webextension";
+
+/**
+ * This test file ensures that the webextension addon developer toolbox:
+ * - has a frame list menu and the noautohide toolbar toggle button, and they
+ * can be used to switch the current target to the extension popup page.
+ */
+add_task(async function testWebExtensionsToolboxWebConsole() {
+ await enableExtensionDebugging();
+
+ // Bug 1686922: Disable the error count button to avoid intermittent failures.
+ await pushPref("devtools.command-button-errorcount.enabled", false);
+
+ is(
+ Services.prefs.getBoolPref("ui.popup.disable_autohide"),
+ false,
+ "disable_autohide should be initially false"
+ );
+
+ const {
+ document,
+ tab,
+ window: aboutDebuggingWindow,
+ } = await openAboutDebugging();
+ await selectThisFirefoxPage(
+ document,
+ aboutDebuggingWindow.AboutDebugging.store
+ );
+
+ const extension = await installTestAddon(document);
+
+ const onBackgroundFunctionCalled = waitForExtensionTestMessage(
+ extension,
+ "onBackgroundFunctionCalled"
+ );
+ const onPopupPageFunctionCalled = waitForExtensionTestMessage(
+ extension,
+ "onPopupPageFunctionCalled"
+ );
+
+ info("Open a toolbox to debug the addon");
+ const { devtoolsWindow } = await openAboutDevtoolsToolbox(
+ document,
+ tab,
+ aboutDebuggingWindow,
+ ADDON_NAME
+ );
+
+ const toolbox = getToolbox(devtoolsWindow);
+ const webconsole = await toolbox.selectTool("webconsole");
+
+ info("Clicking the menu button to disable autohide");
+ await disablePopupAutohide(toolbox);
+
+ info("Check that console messages are evaluated in the background context");
+ const consoleWrapper = webconsole.hud.ui.wrapper;
+ consoleWrapper.dispatchEvaluateExpression("backgroundFunction()");
+ await onBackgroundFunctionCalled;
+
+ clickOnAddonWidget(ADDON_ID);
+
+ info("Wait until the frames list button is displayed");
+ const btn = await waitFor(() =>
+ toolbox.doc.getElementById("command-button-frames")
+ );
+
+ info("Clicking the frame list button");
+ btn.click();
+
+ const menuList = toolbox.doc.getElementById("toolbox-frame-menu");
+ const frames = Array.from(menuList.querySelectorAll(".command"));
+ is(frames.length, 2, "Has the expected number of frames");
+
+ const popupFrameBtn = frames
+ .filter(frame => {
+ return frame.querySelector(".label").textContent.endsWith("popup.html");
+ })
+ .pop();
+
+ ok(popupFrameBtn, "Extension Popup frame found in the listed frames");
+
+ info(
+ "Click on the extension popup frame and wait for a `dom-complete` resource"
+ );
+ const { onDomCompleteResource } =
+ await waitForNextTopLevelDomCompleteResource(toolbox.commands);
+ popupFrameBtn.click();
+ await onDomCompleteResource;
+
+ info("Execute `popupPageFunction()`");
+ consoleWrapper.dispatchEvaluateExpression("popupPageFunction()");
+
+ const args = await onPopupPageFunctionCalled;
+ ok(true, "Received console message from the popup page function as expected");
+ is(args[0], "onPopupPageFunctionCalled", "Got the expected console message");
+ is(
+ args[1] && args[1].name,
+ ADDON_NAME,
+ "Got the expected manifest from WebExtension API"
+ );
+
+ await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, aboutDebuggingWindow);
+
+ is(
+ Services.prefs.getBoolPref("ui.popup.disable_autohide"),
+ false,
+ "disable_autohide should be reset to false when the toolbox is closed"
+ );
+
+ await removeTemporaryExtension(ADDON_NAME, document);
+ await removeTab(tab);
+});
+
+/**
+ * Helper to wait for a specific message on an Extension instance.
+ */
+function waitForExtensionTestMessage(extension, expectedMessage) {
+ return new Promise(done => {
+ extension.on("test-message", function testLogListener(evt, ...args) {
+ const [message] = args;
+
+ if (message !== expectedMessage) {
+ return;
+ }
+
+ extension.off("test-message", testLogListener);
+ done(args);
+ });
+ });
+}
+
+/**
+ * Install the addon used for this test.
+ * Returns a Promise that resolve the Extension instance that was just
+ * installed.
+ */
+async function installTestAddon(doc) {
+ // Start watching for the extension on the Extension Management before we
+ // install it.
+ const onExtensionReady = waitForExtension(ADDON_NAME);
+
+ // Install the extension.
+ await installTemporaryExtensionFromXPI(
+ {
+ background() {
+ const { browser } = this;
+ window.backgroundFunction = function () {
+ browser.test.sendMessage("onBackgroundFunctionCalled");
+ };
+ },
+ extraProperties: {
+ browser_action: {
+ default_title: "WebExtension Popup Debugging",
+ default_popup: "popup.html",
+ },
+ },
+ files: {
+ "popup.html": `<!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <script src="popup.js"></script>
+ </head>
+ <body>
+ Background Page Body Test Content
+ </body>
+ </html>
+ `,
+ "popup.js": function () {
+ const { browser } = this;
+ window.popupPageFunction = function () {
+ browser.test.sendMessage(
+ "onPopupPageFunctionCalled",
+ browser.runtime.getManifest()
+ );
+ };
+ },
+ },
+ id: ADDON_ID,
+ name: ADDON_NAME,
+ },
+ doc
+ );
+
+ // The onExtensionReady promise will resolve the extension instance.
+ return onExtensionReady;
+}
+
+/**
+ * Helper to retrieve the Extension instance.
+ */
+async function waitForExtension(addonName) {
+ const { Management } = ChromeUtils.importESModule(
+ "resource://gre/modules/Extension.sys.mjs"
+ );
+
+ return new Promise(resolve => {
+ Management.on("startup", function listener(event, extension) {
+ if (extension.name != addonName) {
+ return;
+ }
+
+ Management.off("startup", listener);
+ resolve(extension);
+ });
+ });
+}
+
+/**
+ * Disables the popup autohide feature, which is mandatory to debug webextension
+ * popups.
+ */
+function disablePopupAutohide(toolbox) {
+ return new Promise(resolve => {
+ toolbox.doc.addEventListener(
+ "popupshown",
+ () => {
+ const menuItem = toolbox.doc.getElementById(
+ "toolbox-meatball-menu-noautohide"
+ );
+ menuItem.click();
+ resolve();
+ },
+ { once: true }
+ );
+ toolbox.doc.getElementById("toolbox-meatball-menu-button").click();
+ });
+}