Bug 1373453 Part 1 Move repeated webextension startup check to AddonTestUtils draft
authorAndrew Swan <aswan@mozilla.com>
Thu, 15 Jun 2017 16:33:28 -0700
changeset 595748 e3691c9a7f1d4b72a0806c1ad1b4db2f34dce045
parent 594852 ac2d0008d149be9bd183dd1fb3a127997bf3f14e
child 595749 3c4dac752d02d26cb3cd01de75986cf6d82dfee4
push id64443
push useraswan@mozilla.com
push dateFri, 16 Jun 2017 20:50:33 +0000
bugs1373453
milestone56.0a1
Bug 1373453 Part 1 Move repeated webextension startup check to AddonTestUtils MozReview-Commit-ID: 5uhi7VSbZNi
toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_reload.js
toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
--- a/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
@@ -1,28 +1,15 @@
 "use strict";
 
 /* globals browser */
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 
-function promiseAddonStartup() {
-  const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 add_task(async function setup() {
   await ExtensionTestUtils.startAddonManager();
 });
 
 add_task(async function test_experiments_api() {
   let apiAddonFile = Extension.generateZipFile({
     "install.rdf": `<?xml version="1.0" encoding="UTF-8"?>
       <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
@@ -143,26 +130,25 @@ add_task(async function test_experiments
   let apiAddon = await AddonManager.installTemporaryAddon(apiAddonFile);
 
   let {ExtensionAPIs} = Cu.import("resource://gre/modules/ExtensionAPI.jsm", {});
   ok(ExtensionAPIs.apis.has("meh"), "Should have meh API.");
 
 
   // Install boring WebExtension add-on.
   let boringAddon = await AddonManager.installTemporaryAddon(boringAddonFile);
-  await promiseAddonStartup();
-
+  await AddonTestUtils.promiseWebExtensionStartup();
 
   // Install interesting WebExtension add-on.
   let promise = new Promise(resolve => {
     resolveHello = resolve;
   });
 
   let addon = await AddonManager.installTemporaryAddon(addonFile);
-  await promiseAddonStartup();
+  await AddonTestUtils.promiseWebExtensionStartup();
 
   let hello = await promise;
   equal(hello, "Here I am", "Should get hello from add-on");
 
   // Cleanup.
   apiAddon.uninstall();
 
   boringAddon.userDisabled = true;
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -23,16 +23,20 @@ Cu.import("resource://gre/modules/NetUti
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const {EventEmitter} = Cu.import("resource://gre/modules/EventEmitter.jsm", {});
 const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "Extension",
                                   "resource://gre/modules/Extension.jsm");
+XPCOMUtils.defineLazyGetter(this, "Management", () => {
+  let {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
+  return Management;
+});
 
 XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
                                    "@mozilla.org/addons/addon-manager-startup;1",
                                    "amIAddonManagerStartup");
 XPCOMUtils.defineLazyServiceGetter(this, "rdfService",
                                    "@mozilla.org/rdf/rdf-service;1", "nsIRDFService");
 XPCOMUtils.defineLazyServiceGetter(this, "uuidGen",
                                    "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
@@ -1237,16 +1241,36 @@ var AddonTestUtils = {
       Services.console.logStringMessage(DONE);
       await awaitListener;
 
       return {messages, result};
     } finally {
       Services.console.unregisterListener(listener);
     }
   },
+
+  /**
+   * Helper to wait for a webextension to completely start
+   *
+   * @param {string} [id]
+   *        An optional extension id to look for.
+   *
+   * @returns {Promise<Extension>}
+   *           A promise that resolves with the extension, once it is started.
+   */
+  promiseWebExtensionStartup(id) {
+    return new Promise(resolve => {
+      Management.on("startup", function listener(event, extension) {
+        if (!id || extension.id == id) {
+          Management.off("ready", listener);
+          resolve(extension);
+        }
+      });
+    });
+  },
 };
 
 for (let [key, val] of Object.entries(AddonTestUtils)) {
   if (typeof val == "function")
     AddonTestUtils[key] = val.bind(AddonTestUtils);
 }
 
 EventEmitter.decorate(AddonTestUtils);
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -81,16 +81,17 @@ const {
   promiseConsoleOutput,
   promiseFindAddonUpdates,
   promiseInstallAllFiles,
   promiseInstallFile,
   promiseRestartManager,
   promiseSetExtensionModifiedTime,
   promiseShutdownManager,
   promiseStartupManager,
+  promiseWebExtensionStartup,
   promiseWriteProxyFileToDir,
   registerDirectory,
   setExtensionModifiedTime,
   writeFilesToZip
 } = AddonTestUtils;
 
 function manuallyInstall(...args) {
   return AddonTestUtils.awaitPromise(
@@ -1061,29 +1062,16 @@ function completeAllInstalls(aInstalls, 
 function installAllFiles(aFiles, aCallback, aIgnoreIncompatible) {
   promiseInstallAllFiles(aFiles, aIgnoreIncompatible).then(aCallback);
 }
 
 const EXTENSIONS_DB = "extensions.json";
 var gExtensionsJSON = gProfD.clone();
 gExtensionsJSON.append(EXTENSIONS_DB);
 
-function promiseWebExtensionStartup() {
-  const {Management} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("ready", listener);
-      resolve(extension);
-    };
-
-    Management.on("ready", listener);
-  });
-}
-
 function promiseInstallWebExtension(aData) {
   let addonFile = createTempWebExtensionFile(aData);
 
   return promiseInstallAllFiles([addonFile]).then(installs => {
     Services.obs.notifyObservers(addonFile, "flush-cache-entry");
     // Since themes are disabled by default, it won't start up.
     if (aData.manifest.theme)
       return installs[0].addon;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_reload.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_reload.js
@@ -16,29 +16,16 @@ const manifestSample = {
   bootstrap: true,
   targetApplications: [{
     id: "xpcshell@tests.mozilla.org",
     minVersion: "1",
     maxVersion: "1"
   }],
 };
 
-const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 async function installAddon(fixtureName, addonID) {
   await promiseInstallAllFiles([do_get_addon(fixtureName)]);
   return promiseAddonByID(addonID);
 }
 
 async function tearDownAddon(addon) {
   addon.uninstall();
   await promiseShutdownManager();
@@ -80,17 +67,17 @@ add_task(async function test_reloading_a
         resolve();
       },
     }
     AddonManager.addAddonListener(listener);
   });
 
   await Promise.all([
     addon.reload(),
-    promiseAddonStartup(),
+    promiseWebExtensionStartup(),
   ]);
   await onReload;
 
   // Make sure reload() doesn't trigger uninstall events.
   equal(receivedOnUninstalled, false, "reload should not trigger onUninstalled");
   equal(receivedOnUninstalling, false, "reload should not trigger onUninstalling");
 
   // Make sure reload() triggers install events, like an upgrade.
@@ -114,17 +101,17 @@ add_task(async function test_can_reload_
     onEnabled: (aAddon) => {
       do_check_true(disabledCalled);
       enabledCalled = true
     }
   })
 
   await Promise.all([
     addon.reload(),
-    promiseAddonStartup(),
+    promiseWebExtensionStartup(),
   ]);
 
   do_check_true(disabledCalled);
   do_check_true(enabledCalled);
 
   notEqual(addon, null);
   equal(addon.appDisabled, false);
   equal(addon.userDisabled, false);
@@ -147,17 +134,17 @@ add_task(async function test_reload_to_i
       gecko: {
         id: addonId,
       }
     },
   };
 
   let addonDir = await promiseWriteWebManifestForExtension(manifest, tempdir, "invalid_version");
   await AddonManager.installTemporaryAddon(addonDir);
-  await promiseAddonStartup();
+  await promiseWebExtensionStartup();
 
   let addon = await promiseAddonByID(addonId);
   notEqual(addon, null);
   equal(addon.id, addonId);
   equal(addon.version, "1.0");
   equal(addon.appDisabled, false);
   equal(addon.userDisabled, false);
   addonDir.remove(true);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
@@ -13,29 +13,16 @@ const sampleRDFManifest = {
     maxVersion: "1"
   }],
   name: "Test Bootstrap 1 (temporary)",
 };
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 startupManager();
 
-const {Management} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 BootstrapMonitor.init();
 
 // Partial list of bootstrap reasons from XPIProvider.jsm
 const BOOTSTRAP_REASONS = {
   ADDON_INSTALL: 5,
   ADDON_UPGRADE: 7,
   ADDON_DOWNGRADE: 8,
 };
@@ -260,17 +247,17 @@ add_task(async function() {
             id: ID
           }
         }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     // temporary add-on is installed and started
     do_check_neq(addon, null);
     do_check_eq(addon.version, "4.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
@@ -290,17 +277,17 @@ add_task(async function() {
             id: ID
           }
         }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     // temporary add-on is installed and started
     do_check_neq(addon, null);
     do_check_eq(addon.version, "5.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
@@ -322,17 +309,17 @@ add_task(async function() {
           }
         },
         theme: { images: { headerURL: "example.png" } }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     do_check_neq(addon, null);
     do_check_eq(addon.version, "6.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
     do_check_false(addon.appDisabled);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
@@ -6,35 +6,22 @@ const ID = "webextension1@tests.mozilla.
 
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 profileDir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 startupManager();
 
-const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 async function testSimpleIconsetParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let uri = do_get_addon_root_uri(profileDir, ID);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   function check_icons(addon_copy) {
@@ -58,33 +45,33 @@ async function testSimpleIconsetParsing(
     equal(AddonManager.getPreferredIconURL(addon, 128), uri + "icon64.png");
   }
 
   check_icons(addon);
 
   // check if icons are persisted through a restart
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   check_icons(addon);
 
   addon.uninstall();
 }
 
 async function testRetinaIconsetParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   let uri = do_get_addon_root_uri(profileDir, ID);
 
   // AddonManager displays larger icons for higher pixel density
@@ -103,17 +90,17 @@ async function testRetinaIconsetParsing(
   addon.uninstall();
 }
 
 async function testNoIconsParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   deepEqual(addon.icons, {});
 
   equal(addon.iconURL, null);