Bug 1451513 Part 3: Make loading the mochitest extension more robust draft
authorAndrew Swan <aswan@mozilla.com>
Mon, 30 Jul 2018 17:03:27 -0700
changeset 824479 cddee0df896fc640596a41b42e0edd0f37add0a5
parent 824478 3870a63d96c0b2d73ccc468393c75e17b884383f
push id117928
push useraswan@mozilla.com
push dateTue, 31 Jul 2018 01:07:02 +0000
bugs1451513
milestone63.0a1
Bug 1451513 Part 3: Make loading the mochitest extension more robust A couple of changes to ensure that the mochitest harness doesn't try to start executing changes before the mochitest extension is loaded: 1. Fix the marionette driver to wait for an installed extension to be started before returning from Addon:install 2. Wait for extension API onStartup() handlers to finish before considering a webextension started. MozReview-Commit-ID: 8YEdNn6s5qh
testing/marionette/addon.js
toolkit/components/extensions/Extension.jsm
--- a/testing/marionette/addon.js
+++ b/testing/marionette/addon.js
@@ -18,48 +18,26 @@ const ERRORS = {
   [-3]: "ERROR_CORRUPT_FILE: The file appears to be corrupt.",
   [-4]: "ERROR_FILE_ACCESS: There was an error accessing the filesystem.",
   [-5]: "ERROR_SIGNEDSTATE_REQUIRED: The addon must be signed and isn't.",
 };
 
 async function installAddon(file) {
   let install = await AddonManager.getInstallForFile(file);
 
-  return new Promise(resolve => {
-    if (install.error) {
-      throw new UnknownError(ERRORS[install.error]);
-    }
-
-    let addonId = install.addon.id;
-
-    let success = install => {
-      if (install.addon.id === addonId) {
-        install.removeListener(listener);
-        resolve(install.addon);
-      }
-    };
+  if (install.error) {
+    throw new UnknownError(ERRORS[install.error]);
+  }
 
-    let fail = install => {
-      if (install.addon.id === addonId) {
-        install.removeListener(listener);
-        throw new UnknownError(ERRORS[install.error]);
-      }
-    };
-
-    let listener = {
-      onDownloadCancelled: fail,
-      onDownloadFailed: fail,
-      onInstallCancelled: fail,
-      onInstallFailed: fail,
-      onInstallEnded: success,
-    };
-
-    install.addListener(listener);
-    install.install();
-  });
+  try {
+    let addon = await install.install();
+    return addon;
+  } catch (ex) {
+    throw new UnknownError(ERRORS[install.error]);
+  }
 }
 
 /** Installs addons by path and uninstalls by ID. */
 class Addon {
   /**
    * Install a Firefox addon.
    *
    * If the addon is restartless, it can be used right away.  Otherwise a
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1773,19 +1773,21 @@ class Extension extends ExtensionData {
 
       this.updatePermissions(this.startupReason);
 
       // The "startup" Management event sent on the extension instance itself
       // is emitted just before the Management "startup" event,
       // and it is used to run code that needs to be executed before
       // any of the "startup" listeners.
       this.emit("startup", this);
-      Management.emit("startup", this);
 
-      await this.runManifest(this.manifest);
+      await Promise.all([
+        Management.emit("startup", this),
+        this.runManifest(this.manifest),
+      ]);
 
       Management.emit("ready", this);
       this.emit("ready");
       TelemetryStopwatch.finish("WEBEXT_EXTENSION_STARTUP_MS", this);
     } catch (errors) {
       for (let e of [].concat(errors)) {
         dump(`Extension error: ${e.message || e} ${e.filename || e.fileName}:${e.lineNumber} :: ${e.stack || new Error().stack}\n`);
         Cu.reportError(e);