summaryrefslogtreecommitdiffstats
path: root/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js')
-rw-r--r--devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js200
1 files changed, 200 insertions, 0 deletions
diff --git a/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js
new file mode 100644
index 0000000000..1b43808fa2
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_eventpage_terminate_on_idle.js
@@ -0,0 +1,200 @@
+/* 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);
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.eventPages.enabled", true]],
+ });
+});
+
+// Test that an extension event page isn't terminated on idle when a DevTools
+// Toolbox is attached to the extension.
+add_task(
+ async function test_eventpage_no_idle_shutdown_with_toolbox_attached() {
+ const { document, tab, window } = await openAboutDebugging();
+ await selectThisFirefoxPage(document, window.AboutDebugging.store);
+
+ const EXTENSION_ID = "test-devtools-eventpage@mozilla.org";
+ const EXTENSION_NAME = "Temporary EventPage-based web extension";
+
+ const promiseBackgroundLoaded =
+ promiseBackgroundContextLoaded(EXTENSION_ID);
+
+ let waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+
+ // Install the extension using an event page (non persistent background page).
+ await installTemporaryExtensionFromXPI(
+ {
+ id: EXTENSION_ID,
+ name: EXTENSION_NAME,
+ // The extension is expected to have a non persistent background script.
+ extraProperties: {
+ background: {
+ scripts: ["bgpage.js"],
+ persistent: false,
+ },
+ },
+ files: {
+ "bgpage.js": function () {
+ // Emit a dump when the script is loaded to make it easier
+ // to investigate intermittents.
+ dump(`Background script loaded: ${window.location}\n`);
+ },
+ },
+ },
+ document
+ );
+
+ const target = findDebugTargetByText(EXTENSION_NAME, document);
+ ok(
+ !!target,
+ "The EventPage-based extension is installed with the expected name"
+ );
+
+ info("Wait for the test extension background script to be loaded");
+ await promiseBackgroundLoaded;
+
+ info("Wait for the test extension background script status update");
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "running",
+ });
+
+ waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+ await triggerExtensionEventPageIdleTimeout(EXTENSION_ID);
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "stopped",
+ });
+
+ info(
+ "Respawn the extension background script on new WebExtension API event"
+ );
+ waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+ await wakeupExtensionEventPage(EXTENSION_ID);
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "running",
+ });
+
+ info("Open a DevTools toolbox on the target extension");
+ const { devtoolsWindow } = await openAboutDevtoolsToolbox(
+ document,
+ tab,
+ window,
+ EXTENSION_NAME
+ );
+
+ info(
+ "Verify event page terminated on terminate button clicked while the DevTools toolbox is open"
+ );
+ const terminateButton = target.querySelector(
+ ".qa-temporary-extension-terminate-bgscript-button"
+ );
+ ok(
+ !!terminateButton,
+ `${EXTENSION_NAME} is expected to have a terminate button`
+ );
+
+ info(`Click on the terminate button for ${EXTENSION_NAME}`);
+ const promiseBackgroundUnloaded =
+ promiseBackgroundContextUnloaded(EXTENSION_ID);
+ const waitForTerminateSuccess = waitForDispatch(
+ window.AboutDebugging.store,
+ "TERMINATE_EXTENSION_BGSCRIPT_SUCCESS"
+ );
+ waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+ terminateButton.click();
+ await waitForTerminateSuccess;
+
+ info("Wait for the extension background script to be unloaded");
+ await promiseBackgroundUnloaded;
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "stopped",
+ targetElement: target,
+ });
+
+ info(
+ "Verify event page isn't terminated on idle while the DevTools toolbox is open"
+ );
+
+ // Make sure the event page is running again.
+ waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+ await wakeupExtensionEventPage(EXTENSION_ID);
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "running",
+ targetElement: target,
+ });
+
+ const waitForBGSuspendIgnored =
+ promiseTerminateBackgroundScriptIgnored(EXTENSION_ID);
+ waitForBGStatusUpdate = promiseBackgroundStatusUpdate(window);
+ await triggerExtensionEventPageIdleTimeout(EXTENSION_ID);
+ await Promise.race([waitForBGStatusUpdate, waitForBGSuspendIgnored]);
+
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "running",
+ // After opening the toolbox there will be an additional target listed
+ // for the devtools toolbox tab, its card includes the extension name
+ // and so while the toolbox is open we should make sure to look for
+ // the background status inside the extension target card instead of
+ // the one associated to the devtools toolbox tab.
+ targetElement: target,
+ });
+
+ info(
+ "Wait for warning message expected to be logged for the event page not terminated on idle"
+ );
+ const toolbox = getToolbox(devtoolsWindow);
+ const webconsole = await toolbox.selectTool("webconsole");
+ const { hud } = webconsole;
+ const expectedWarning =
+ "Background event page was not terminated on idle because a DevTools toolbox is attached to the extension.";
+ let consoleElements;
+ await waitUntil(() => {
+ consoleElements = findMessagesByType(hud, expectedWarning, ".warn");
+ return !!consoleElements.length;
+ });
+
+ const locationElement = consoleElements[0].querySelector(
+ ".frame-link-filename"
+ );
+ ok(
+ locationElement.textContent.endsWith("_generated_background_page.html"),
+ "The warning message is associated to the event page url"
+ );
+
+ info(
+ "Verify event page is terminated on idle after closing the DevTools toolbox"
+ );
+
+ await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
+ await triggerExtensionEventPageIdleTimeout(EXTENSION_ID);
+ await waitForBGStatusUpdate;
+ await assertBackgroundStatus(EXTENSION_NAME, {
+ document,
+ expectedStatus: "stopped",
+ });
+
+ // Uninstall the test extensions.
+ info("Unload extension and remove about:debugging tab");
+ await AddonManager.getAddonByID(EXTENSION_ID).then(addon =>
+ addon.uninstall()
+ );
+ info("Wait until the debug targets with test extensions disappears");
+ await waitUntil(() => !findDebugTargetByText(EXTENSION_NAME, document));
+ await removeTab(tab);
+ }
+);