summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js')
-rw-r--r--toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js116
1 files changed, 116 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js b/toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js
new file mode 100644
index 0000000000..09ded0bcc1
--- /dev/null
+++ b/toolkit/components/extensions/test/browser/browser_ext_process_crash_handling.js
@@ -0,0 +1,116 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { AddonTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/AddonTestUtils.sys.mjs"
+);
+
+const { ExtensionProcessCrashObserver, Management } =
+ ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs");
+
+AddonTestUtils.initMochitest(this);
+
+add_task(async function test_ExtensionProcessCrashObserver() {
+ let mv2Extension = ExtensionTestUtils.loadExtension({
+ useAddonManager: "temporary",
+ manifest: {
+ manifest_version: 2,
+ },
+ background() {
+ browser.test.sendMessage("background_running");
+ },
+ });
+
+ await mv2Extension.startup();
+ await mv2Extension.awaitMessage("background_running");
+
+ let { currentProcessChildID, lastCrashedProcessChildID } =
+ ExtensionProcessCrashObserver;
+
+ Assert.notEqual(
+ currentProcessChildID,
+ undefined,
+ "Expect ExtensionProcessCrashObserver.currentProcessChildID to be set"
+ );
+
+ Assert.equal(
+ ChromeUtils.getAllDOMProcesses().find(
+ pp => pp.childID == currentProcessChildID
+ )?.remoteType,
+ "extension",
+ "Expect a child process with remoteType extension to be found for the process childID set"
+ );
+
+ Assert.notEqual(
+ lastCrashedProcessChildID,
+ currentProcessChildID,
+ "Expect lastCrashedProcessChildID to not be set to the same value that currentProcessChildID is set"
+ );
+
+ let mv3Extension = ExtensionTestUtils.loadExtension({
+ useAddonManager: "temporary",
+ manifest: {
+ manifest_version: 3,
+ },
+ background() {
+ browser.test.sendMessage("background_running");
+ },
+ });
+
+ const waitForExtensionBrowserInserted = () =>
+ new Promise(resolve => {
+ const listener = (_eventName, browser) => {
+ if (!browser.getAttribute("webextension-view-type") === "background") {
+ return;
+ }
+ Management.off("extension-browser-inserted", listener);
+ resolve(browser);
+ };
+ Management.on("extension-browser-inserted", listener);
+ });
+
+ const waitForExtensionProcessCrashNotified = () =>
+ new Promise(resolve => {
+ Management.once("extension-process-crash", (_evt, data) => resolve(data));
+ });
+
+ const promiseBackgroundBrowser = waitForExtensionBrowserInserted();
+
+ const promiseExtensionProcessCrashNotified =
+ waitForExtensionProcessCrashNotified();
+
+ await mv3Extension.startup();
+ await mv3Extension.awaitMessage("background_running");
+ const bgPageBrowser = await promiseBackgroundBrowser;
+
+ info("Force extension process crash");
+ // NOTE: shouldShowTabCrashPage option needs to be set to false
+ // to make sure crashFrame method resolves without waiting for a
+ // tab crash page (which is not going to be shown for a background
+ // page browser element).
+ await BrowserTestUtils.crashFrame(
+ bgPageBrowser,
+ /* shouldShowTabCrashPage */ false
+ );
+
+ info("Verify ExtensionProcessCrashObserver after extension process crash");
+ Assert.equal(
+ ExtensionProcessCrashObserver.lastCrashedProcessChildID,
+ currentProcessChildID,
+ "Expect ExtensionProcessCrashObserver.lastCrashedProcessChildID to be set to the expected childID"
+ );
+
+ info("Expect the same childID to have been notified as a Management event");
+ Assert.deepEqual(
+ await promiseExtensionProcessCrashNotified,
+ { childID: currentProcessChildID },
+ "Got the expected childID notified as part of the extension-process-crash Management event"
+ );
+
+ info("Wait for mv3 extension shutdown");
+ await mv3Extension.unload();
+ info("Wait for mv2 extension shutdown");
+ await mv2Extension.unload();
+});