Bug 1302702 - ExtensionParent DebugUtils xpcshell test unit. r=kmag
☠☠ backed out by d30987357f75 ☠ ☠
authorLuca Greco <lgreco@mozilla.com>
Tue, 11 Apr 2017 05:13:13 +0200
changeset 406904 d4ebca627094a76823a037acec723b921bd65952
parent 406903 5c8ee04870565b471702ecce95e64d06413ca600
child 406905 9b16857ca48d5057aba8240b41546e8592e990bb
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1302702
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1302702 - ExtensionParent DebugUtils xpcshell test unit. r=kmag MozReview-Commit-ID: 2wbZfQiktho
toolkit/components/extensions/test/xpcshell/test_ext_debugging_utils.js
toolkit/components/extensions/test/xpcshell/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_debugging_utils.js
@@ -0,0 +1,231 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+Cu.import("resource://gre/modules/ExtensionParent.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
+
+add_task(async function testExtensionDebuggingUtilsCleanup() {
+  const extension = ExtensionTestUtils.loadExtension({
+    background() {
+      browser.test.sendMessage("background.ready");
+    },
+  });
+
+  const expectedEmptyDebugUtils = {
+    hiddenXULWindow: null,
+    cacheSize: 0,
+  };
+
+  let {
+    hiddenXULWindow,
+    debugBrowserPromises,
+  } = ExtensionParent.DebugUtils;
+
+  deepEqual({hiddenXULWindow, cacheSize: debugBrowserPromises.size},
+            expectedEmptyDebugUtils,
+            "No ExtensionDebugUtils resources has been allocated yet");
+
+  await extension.startup();
+
+  await extension.awaitMessage("background.ready");
+
+  hiddenXULWindow = ExtensionParent.DebugUtils.hiddenXULWindow;
+  deepEqual({hiddenXULWindow, cacheSize: debugBrowserPromises.size},
+            expectedEmptyDebugUtils,
+            "No debugging resources has been yet allocated once the extension is running");
+
+  const fakeAddonActor = {
+    addonId: extension.id,
+  };
+
+  const anotherAddonActor = {
+    addonId: extension.id,
+  };
+
+  const waitFirstBrowser = ExtensionParent.DebugUtils.getExtensionProcessBrowser(fakeAddonActor);
+  const waitSecondBrowser = ExtensionParent.DebugUtils.getExtensionProcessBrowser(anotherAddonActor);
+
+  const addonDebugBrowser = await waitFirstBrowser;
+  equal(addonDebugBrowser.isRemoteBrowser, extension.extension.remote,
+       "The addon debugging browser has the expected remote type");
+
+  equal((await waitSecondBrowser), addonDebugBrowser,
+        "Two addon debugging actors related to the same addon get the same browser element ");
+
+  equal(debugBrowserPromises.size, 1, "The expected resources has been allocated");
+
+  const nonExistentAddonActor = {
+    addonId: "non-existent-addon@test",
+  };
+
+  const waitRejection = ExtensionParent.DebugUtils.getExtensionProcessBrowser(nonExistentAddonActor);
+
+  Assert.rejects(waitRejection, /Extension not found/,
+                "Reject with the expected message for non existent addons");
+
+  equal(debugBrowserPromises.size, 1, "No additional debugging resources has been allocated");
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(fakeAddonActor);
+
+  equal(debugBrowserPromises.size, 1,
+        "The addon debugging browser is cached until all the related actors have released it");
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(anotherAddonActor);
+
+  hiddenXULWindow = ExtensionParent.DebugUtils.hiddenXULWindow;
+
+  deepEqual({hiddenXULWindow, cacheSize: debugBrowserPromises.size},
+            expectedEmptyDebugUtils,
+            "All the allocated debugging resources has been cleared");
+
+  await extension.unload();
+});
+
+add_task(async function testExtensionDebuggingUtilsAddonReloaded() {
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "test-reloaded@test.mozilla.com",
+        },
+      },
+    },
+    background() {
+      browser.test.sendMessage("background.ready");
+    },
+  });
+
+  await extension.startup();
+  await extension.awaitMessage("background.ready");
+
+  let fakeAddonActor = {
+    addonId: extension.id,
+  };
+
+  const addonDebugBrowser = await ExtensionParent.DebugUtils
+                                                 .getExtensionProcessBrowser(fakeAddonActor);
+  equal(addonDebugBrowser.isRemoteBrowser, extension.extension.remote,
+        "The addon debugging browser has the expected remote type");
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 1,
+        "Got the expected number of requested debug browsers");
+
+  const {chromeDocument} = ExtensionParent.DebugUtils.hiddenXULWindow;
+
+  ok(addonDebugBrowser.parentElement === chromeDocument.documentElement,
+     "The addon debugging browser is part of the hiddenXULWindow chromeDocument");
+
+  await extension.unload();
+
+  // Install an extension with the same id to recreate for the DebugUtils
+  // conditions similar to an addon reloaded while the Addon Debugger is opened.
+  extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "test-reloaded@test.mozilla.com",
+        },
+      },
+    },
+    background() {
+      browser.test.sendMessage("background.ready");
+    },
+  });
+
+  await extension.startup();
+  await extension.awaitMessage("background.ready");
+
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 1,
+        "Got the expected number of requested debug browsers");
+
+  const newAddonDebugBrowser = await ExtensionParent.DebugUtils
+                                                    .getExtensionProcessBrowser(fakeAddonActor);
+
+  equal(addonDebugBrowser, newAddonDebugBrowser,
+           "The existent debugging browser has been reused");
+
+  equal(newAddonDebugBrowser.isRemoteBrowser, extension.extension.remote,
+        "The addon debugging browser has the expected remote type");
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(fakeAddonActor);
+
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 0,
+        "All the addon debugging browsers has been released");
+
+  await extension.unload();
+});
+
+add_task(async function testExtensionDebuggingUtilsWithMultipleAddons() {
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "test-addon-1@test.mozilla.com",
+        },
+      },
+    },
+    background() {
+      browser.test.sendMessage("background.ready");
+    },
+  });
+  let anotherExtension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "test-addon-2@test.mozilla.com",
+        },
+      },
+    },
+    background() {
+      browser.test.sendMessage("background.ready");
+    },
+  });
+
+  await extension.startup();
+  await extension.awaitMessage("background.ready");
+
+  await anotherExtension.startup();
+  await anotherExtension.awaitMessage("background.ready");
+
+  const fakeAddonActor = {
+    addonId: extension.id,
+  };
+
+  const anotherFakeAddonActor = {
+    addonId: anotherExtension.id,
+  };
+
+  const {DebugUtils} = ExtensionParent;
+  const debugBrowser = await DebugUtils.getExtensionProcessBrowser(fakeAddonActor);
+  const anotherDebugBrowser = await DebugUtils.getExtensionProcessBrowser(anotherFakeAddonActor);
+
+  const chromeDocument = DebugUtils.hiddenXULWindow.chromeDocument;
+
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 2,
+        "Got the expected number of debug browsers requested");
+  ok(debugBrowser.parentElement === chromeDocument.documentElement,
+     "The first debug browser is part of the hiddenXUL chromeDocument");
+  ok(anotherDebugBrowser.parentElement === chromeDocument.documentElement,
+     "The second debug browser is part of the hiddenXUL chromeDocument");
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(fakeAddonActor);
+
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 1,
+        "Got the expected number of debug browsers requested");
+
+  ok(anotherDebugBrowser.parentElement === chromeDocument.documentElement,
+     "The second debug browser is still part of the hiddenXUL chromeDocument");
+
+  ok(debugBrowser.parentElement == null,
+     "The first debug browser has been removed from the hiddenXUL chromeDocument");
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(anotherFakeAddonActor);
+
+  ok(anotherDebugBrowser.parentElement == null,
+     "The second debug browser has been removed from the hiddenXUL chromeDocument");
+  equal(ExtensionParent.DebugUtils.debugBrowserPromises.size, 0,
+        "All the addon debugging browsers has been released");
+
+  await extension.unload();
+  await anotherExtension.unload();
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -23,16 +23,17 @@ skip-if = os == "android" # Android does
 [test_ext_background_private_browsing.js]
 [test_ext_background_runtime_connect_params.js]
 [test_ext_background_sub_windows.js]
 [test_ext_background_window_properties.js]
 skip-if = os == "android"
 [test_ext_contexts.js]
 [test_ext_contextual_identities.js]
 skip-if = os == "android" # Containers are not exposed to android.
+[test_ext_debugging_utils.js]
 [test_ext_downloads.js]
 [test_ext_downloads_download.js]
 skip-if = os == "android"
 [test_ext_downloads_misc.js]
 skip-if = os == "android" || (os=='linux' && bits==32) # linux32: bug 1324870
 [test_ext_downloads_search.js]
 skip-if = os == "android"
 [test_ext_experiments.js]