Bug 1500986 - Migrate addon test from old debugger to shared r=jdescottes
authorDavid Walsh <dwalsh@mozilla.com>
Wed, 24 Oct 2018 15:13:17 -0500
changeset 491326 9c5d6ad21391c871733e2cb4aeb5840a7833e112
parent 491325 ca3eb80797aa25c80a673fb397e7df1a25c9a775
child 491327 b304191da6b7922375b78f6b3ea27245833a2ab6
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjdescottes
bugs1500986
milestone65.0a1
Bug 1500986 - Migrate addon test from old debugger to shared r=jdescottes
devtools/client/debugger/test/mochitest/addon4.xpi
devtools/client/debugger/test/mochitest/browser.ini
devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
devtools/client/debugger/test/mochitest/head.js
devtools/client/shared/test/addon4.xpi
devtools/client/shared/test/browser.ini
devtools/client/shared/test/browser_dbg_addon-console.js
devtools/client/shared/test/browser_dbg_listaddons.js
devtools/client/shared/test/helper_addons.js
devtools/client/shared/test/helper_workers.js
--- a/devtools/client/debugger/test/mochitest/browser.ini
+++ b/devtools/client/debugger/test/mochitest/browser.ini
@@ -1,27 +1,20 @@
-# Tests in this directory are split into two manifests (this and browser2.ini)
-# to facilitate better chunking; see bug 1294489.
-
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 skip-if = (os == 'linux' && debug && bits == 32)
 support-files =
-  addon4.xpi
   doc_promise-get-allocation-stack.html
   doc_promise-get-fulfillment-stack.html
   doc_promise-get-rejection-stack.html
   doc_terminate-on-tab-close.html
   head.js
   !/devtools/client/shared/test/shared-head.js
   !/devtools/client/shared/test/telemetry-test-helpers.js
-[browser_dbg_addon-console.js]
-skip-if = (e10s && debug || os == 'win' || verify) || true # bug 1005274
-tags = addons
 [browser_dbg_promises-allocation-stack.js]
 uses-unsafe-cpows = true
 skip-if = true
 [browser_dbg_promises-chrome-allocation-stack.js]
 uses-unsafe-cpows = true
 skip-if = true # Bug 1177730
 [browser_dbg_promises-fulfillment-stack.js]
 uses-unsafe-cpows = true
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -586,167 +586,16 @@ let initDebugger = Task.async(function*(
       }
     }
     yield onCaretUpdated;
   }
 
   return [tab, debuggerPanel, window];
 });
 
-// Creates an add-on debugger for a given add-on. The returned AddonDebugger
-// object must be destroyed before finishing the test
-function initAddonDebugger(aAddonId) {
-  let addonDebugger = new AddonDebugger();
-  return addonDebugger.init(aAddonId).then(() => addonDebugger);
-}
-
-function AddonDebugger() {
-  this._onMessage = this._onMessage.bind(this);
-  this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
-  EventEmitter.decorate(this);
-}
-
-AddonDebugger.prototype = {
-  init: Task.async(function* (aAddonId) {
-    info("Initializing an addon debugger panel.");
-
-    DebuggerServer.init();
-    DebuggerServer.registerAllActors();
-    DebuggerServer.allowChromeProcess = true;
-
-    this.frame = document.createElement("iframe");
-    this.frame.setAttribute("height", 400);
-    document.documentElement.appendChild(this.frame);
-    window.addEventListener("message", this._onMessage);
-
-    let transport = DebuggerServer.connectPipe();
-    this.client = new DebuggerClient(transport);
-
-    yield this.client.connect();
-
-    let addonTargetActor = yield getAddonActorForId(this.client, aAddonId);
-
-    let targetOptions = {
-      form: addonTargetActor,
-      client: this.client,
-      chrome: true,
-    };
-
-    let toolboxOptions = {
-      customIframe: this.frame
-    };
-
-    this.target = yield TargetFactory.forRemoteTab(targetOptions);
-    let toolbox = yield gDevTools.showToolbox(this.target, "jsdebugger", Toolbox.HostType.CUSTOM, toolboxOptions);
-
-    info("Addon debugger panel shown successfully.");
-
-    this.debuggerPanel = toolbox.getCurrentPanel();
-    yield waitForSourceShown(this.debuggerPanel, "");
-
-    prepareDebugger(this.debuggerPanel);
-    yield this._attachConsole();
-  }),
-
-  destroy: Task.async(function* () {
-    yield this.client.close();
-    yield this.debuggerPanel._toolbox.destroy();
-    this.frame.remove();
-    window.removeEventListener("message", this._onMessage);
-  }),
-
-  _attachConsole: function () {
-    let deferred = promise.defer();
-    this.client.attachConsole(this.target.form.consoleActor, ["ConsoleAPI"])
-      .then(([aResponse, aWebConsoleClient]) => {
-        this.webConsole = aWebConsoleClient;
-        this.client.addListener("consoleAPICall", this._onConsoleAPICall);
-        deferred.resolve();
-      }, e => {
-        deferred.reject(e);
-      });
-    return deferred.promise;
-  },
-
-  _onConsoleAPICall: function (aType, aPacket) {
-    if (aPacket.from != this.webConsole.actor)
-      return;
-    this.emit("console", aPacket.message);
-  },
-
-  /**
-   * Returns a list of the groups and sources in the UI. The returned array
-   * contains objects for each group with properties name and sources. The
-   * sources property contains an array with objects for each source for that
-   * group with properties label and url.
-   */
-  getSourceGroups: Task.async(function* () {
-    let debuggerWin = this.debuggerPanel.panelWin;
-    let sources = yield getSources(debuggerWin.gThreadClient);
-    ok(sources.length, "retrieved sources");
-
-    // groups will be the return value, groupmap and the maps we put in it will
-    // be used as quick lookups to add the url information in below
-    let groups = [];
-    let groupmap = new Map();
-
-    let uigroups = this.debuggerPanel.panelWin.document.querySelectorAll(".side-menu-widget-group");
-    for (let g of uigroups) {
-      let name = g.querySelector(".side-menu-widget-group-title .name").value;
-      let group = {
-        name: name,
-        sources: []
-      };
-      groups.push(group);
-      let labelmap = new Map();
-      groupmap.set(name, labelmap);
-
-      for (let l of g.querySelectorAll(".dbg-source-item")) {
-        let source = {
-          label: l.value,
-          url: null
-        };
-
-        labelmap.set(l.value, source);
-        group.sources.push(source);
-      }
-    }
-
-    for (let source of sources) {
-      let { label, group } = debuggerWin.DebuggerView.Sources.getItemByValue(source.actor).attachment;
-
-      if (!groupmap.has(group)) {
-        ok(false, "Saw a source group not in the UI: " + group);
-        continue;
-      }
-
-      if (!groupmap.get(group).has(label)) {
-        ok(false, "Saw a source label not in the UI: " + label);
-        continue;
-      }
-
-      groupmap.get(group).get(label).url = source.url.split(" -> ").pop();
-    }
-
-    return groups;
-  }),
-
-  _onMessage: function(event) {
-    if (!event.data) {
-      return;
-    }
-    const msg = event.data;
-    switch (msg.name) {
-      case "toolbox-title":
-        this.title = msg.data.value;
-        break;
-    }
-  }
-};
-
 function initChromeDebugger(aOnClose) {
   info("Initializing a chrome debugger process.");
 
   let deferred = promise.defer();
 
   // Wait for the toolbox process to start...
   BrowserToolboxProcess.init(aOnClose, aProcess => {
     info("Browser toolbox process started successfully.");
rename from devtools/client/debugger/test/mochitest/addon4.xpi
rename to devtools/client/shared/test/addon4.xpi
--- a/devtools/client/shared/test/browser.ini
+++ b/devtools/client/shared/test/browser.ini
@@ -1,14 +1,15 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 support-files =
   addon1.xpi
   addon2.xpi
+  addon4.xpi
   browser_devices.json
   code_listworkers-worker1.js
   code_listworkers-worker2.js
   code_WorkerTargetActor.attach-worker1.js
   code_WorkerTargetActor.attach-worker2.js
   code_WorkerTargetActor.attachThread-worker.js
   code_frame-script.js
   doc_cubic-bezier-01.html
@@ -44,16 +45,17 @@ support-files =
   doc_tableWidget_mouse_interaction.xul
   doc_templater_basic.html
   doc_WorkerTargetActor.attach-tab1.html
   doc_WorkerTargetActor.attach-tab2.html
   doc_WorkerTargetActor.attachThread-tab.html
   dummy.html
   frame-script-utils.js
   head.js
+  helper_addons.js
   helper_color_data.js
   helper_html_tooltip.js
   helper_inplace_editor.js
   helper_workers.js
   leakhunt.js
   shared-head.js
   shared-redux-head.js
   telemetry-test-helpers.js
@@ -69,16 +71,19 @@ support-files =
 [browser_css_color.js]
 [browser_cubic-bezier-01.js]
 [browser_cubic-bezier-02.js]
 [browser_cubic-bezier-03.js]
 [browser_cubic-bezier-04.js]
 [browser_cubic-bezier-05.js]
 [browser_cubic-bezier-06.js]
 [browser_cubic-bezier-07.js]
+[browser_dbg_addon-console.js]
+skip-if = (e10s && debug || os == 'win' || verify)
+tags = addons
 [browser_dbg_debugger-statement.js]
 skip-if = e10s && debug
 [browser_dbg_event-listeners-01.js]
 skip-if = e10s && debug
 [browser_dbg_event-listeners-02.js]
 skip-if = e10s && debug
 [browser_dbg_event-listeners-03.js]
 skip-if = e10s && debug
rename from devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
rename to devtools/client/shared/test/browser_dbg_addon-console.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
+++ b/devtools/client/shared/test/browser_dbg_addon-console.js
@@ -1,47 +1,151 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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://mochitests/content/browser/devtools/client/shared/test/helper_addons.js",
+  this);
+
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+var { Toolbox } = require("devtools/client/framework/toolbox");
+var { Task } = require("devtools/shared/task");
+
 // Test that the we can see console messages from the add-on
 
 const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
 const ADDON_PATH = "addon4.xpi";
 
 function getCachedMessages(webConsole) {
-  let deferred = promise.defer();
-  webConsole.getCachedMessages(["ConsoleAPI"], (aResponse) => {
-    if (aResponse.error) {
-      deferred.reject(aResponse.error);
+  const deferred = getDeferredPromise().defer();
+  webConsole.getCachedMessages(["ConsoleAPI"], response => {
+    if (response.error) {
+      deferred.reject(response.error);
       return;
     }
-    deferred.resolve(aResponse.messages);
+    deferred.resolve(response.messages);
   });
   return deferred.promise;
 }
 
-function test() {
-  Task.spawn(function* () {
-    let addon = yield addTemporaryAddon(ADDON_PATH);
-    let addonDebugger = yield initAddonDebugger(ADDON_ID);
+// Creates an add-on debugger for a given add-on. The returned AddonDebugger
+// object must be destroyed before finishing the test
+function initAddonDebugger(addonId) {
+  const addonDebugger = new AddonDebugger();
+  return addonDebugger.init(addonId).then(() => addonDebugger);
+}
+
+function AddonDebugger() {
+  this._onMessage = this._onMessage.bind(this);
+  this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
+  EventEmitter.decorate(this);
+}
+
+AddonDebugger.prototype = {
+  init: Task.async(function* (addonId) {
+    info("Initializing an addon debugger panel.");
+
+    DebuggerServer.init();
+    DebuggerServer.registerAllActors();
+    DebuggerServer.allowChromeProcess = true;
+
+    this.frame = document.createElement("iframe");
+    this.frame.setAttribute("height", 400);
+    document.documentElement.appendChild(this.frame);
+    window.addEventListener("message", this._onMessage);
+
+    const transport = DebuggerServer.connectPipe();
+    this.client = new DebuggerClient(transport);
 
-    let webConsole = addonDebugger.webConsole;
-    let messages = yield getCachedMessages(webConsole);
-    is(messages.length, 1, "Should be one cached message");
-    is(messages[0].arguments[0].type, "object", "Should have logged an object");
-    is(messages[0].arguments[0].preview.ownProperties.msg.value, "Hello from the test add-on", "Should have got the right message");
+    yield this.client.connect();
+
+    const addonTargetActor = yield getAddonActorForId(this.client, addonId);
+
+    const targetOptions = {
+      form: addonTargetActor,
+      client: this.client,
+      chrome: true,
+    };
+
+    const toolboxOptions = {
+      customIframe: this.frame,
+    };
 
-    let consolePromise = addonDebugger.once("console");
+    this.target = yield TargetFactory.forRemoteTab(targetOptions);
+    const toolbox = yield gDevTools.showToolbox(
+      this.target, "jsdebugger", Toolbox.HostType.CUSTOM, toolboxOptions);
+
+    info("Addon debugger panel shown successfully.");
+
+    this.debuggerPanel = toolbox.getCurrentPanel();
+    yield this._attachConsole();
+  }),
+
+  destroy: Task.async(function* () {
+    yield this.client.close();
+    this.frame.remove();
+    window.removeEventListener("message", this._onMessage);
+  }),
 
-    console.log("Bad message");
-    Services.obs.notifyObservers(null, "addon-test-ping");
+  _attachConsole: function() {
+    const deferred = getDeferredPromise().defer();
+    this.client.attachConsole(this.target.form.consoleActor, ["ConsoleAPI"])
+      .then(([aResponse, aWebConsoleClient]) => {
+        this.webConsole = aWebConsoleClient;
+        this.client.addListener("consoleAPICall", this._onConsoleAPICall);
+        deferred.resolve();
+      }, e => {
+        deferred.reject(e);
+      });
+    return deferred.promise;
+  },
+
+  _onConsoleAPICall: function(type, packet) {
+    if (packet.from != this.webConsole.actor) {
+      return;
+    }
+    this.emit("console", packet.message);
+  },
 
-    let messageGrip = yield consolePromise;
-    is(messageGrip.arguments[0].type, "object", "Should have logged an object");
-    is(messageGrip.arguments[0].preview.ownProperties.msg.value, "Hello again", "Should have got the right message");
+  _onMessage: function(event) {
+    if (!event.data) {
+      return;
+    }
+    const msg = event.data;
+    switch (msg.name) {
+      case "toolbox-title":
+        this.title = msg.data.value;
+        break;
+    }
+  },
+};
+
+add_task(async function test() {
+  const addon = await addTemporaryAddon(ADDON_PATH);
+  const addonDebugger = await initAddonDebugger(ADDON_ID);
 
-    yield addonDebugger.destroy();
-    yield removeAddon(addon);
-    finish();
-  });
-}
+  const webConsole = addonDebugger.webConsole;
+  const messages = await getCachedMessages(webConsole);
+  is(messages.length, 1, "Should be one cached message");
+  is(messages[0].arguments[0].type, "object", "Should have logged an object");
+  is(messages[0].arguments[0].preview.ownProperties.msg.value,
+    "Hello from the test add-on", "Should have got the right message");
+
+  const consolePromise = addonDebugger.once("console");
+
+  console.log("Bad message");
+  Services.obs.notifyObservers(null, "addon-test-ping");
+
+  const messageGrip = await consolePromise;
+  is(messageGrip.arguments[0].type, "object", "Should have logged an object");
+  is(messageGrip.arguments[0].preview.ownProperties.msg.value,
+    "Hello again", "Should have got the right message");
+
+  await addonDebugger.destroy();
+  await removeAddon(addon);
+  finish();
+});
--- a/devtools/client/shared/test/browser_dbg_listaddons.js
+++ b/devtools/client/shared/test/browser_dbg_listaddons.js
@@ -1,25 +1,23 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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://mochitests/content/browser/devtools/client/shared/test/helper_addons.js",
+  this);
+
 var { DebuggerServer } = require("devtools/server/main");
 var { DebuggerClient } = require("devtools/shared/client/debugger-client");
 
-const chromeRegistry =
-  Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
-const DEBUGGER_CHROME_URL = "chrome://mochitests/content/browser/devtools/client/shared/test/";
-const DEBUGGER_CHROME_URI = Services.io.newURI(DEBUGGER_CHROME_URL);
-
-var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
-
 /**
  * Make sure the listAddons request works as specified.
  */
 const ADDON1_ID = "jid1-oBAwBoE5rSecNg@jetpack";
 const ADDON1_PATH = "addon1.xpi";
 const ADDON2_ID = "jid1-qjtzNGV8xw5h2A@jetpack";
 const ADDON2_PATH = "addon2.xpi";
 
@@ -113,53 +111,8 @@ function testRemoveSecondAddon() {
 }
 
 registerCleanupFunction(function() {
   gAddon1 = null;
   gAddon1Actor = null;
   gAddon2 = null;
   gClient = null;
 });
-
-function getAddonURIFromPath(path) {
-  const chromeURI = Services.io.newURI(path, null, DEBUGGER_CHROME_URI);
-  return chromeRegistry.convertChromeURL(chromeURI).QueryInterface(Ci.nsIFileURL);
-}
-
-function addTemporaryAddon(path) {
-  const addonFile = getAddonURIFromPath(path).file;
-  info("Installing addon: " + addonFile.path);
-
-  return AddonManager.installTemporaryAddon(addonFile);
-}
-
-function getAddonActorForId(client, addonId) {
-  info("Get addon actor for ID: " + addonId);
-  const deferred = promise.defer();
-
-  client.listAddons().then(response => {
-    const addonTargetActor = response.addons.filter(grip => grip.id == addonId).pop();
-    info("got addon actor for ID: " + addonId);
-    deferred.resolve(addonTargetActor);
-  });
-
-  return deferred.promise;
-}
-
-function removeAddon(addon) {
-  info("Removing addon.");
-
-  const deferred = promise.defer();
-
-  const listener = {
-    onUninstalled: function(uninstalledAddon) {
-      if (uninstalledAddon != addon) {
-        return;
-      }
-      AddonManager.removeAddonListener(listener);
-      deferred.resolve();
-    },
-  };
-  AddonManager.addAddonListener(listener);
-  addon.uninstall();
-
-  return deferred.promise;
-}
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/test/helper_addons.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
+
+"use strict";
+
+const chromeRegistry =
+  Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
+const DEBUGGER_CHROME_URL = "chrome://mochitests/content/browser/devtools/client/shared/test/";
+const DEBUGGER_CHROME_URI = Services.io.newURI(DEBUGGER_CHROME_URL);
+
+const EventEmitter = require("devtools/shared/event-emitter");
+
+var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
+
+/**
+ * Returns a thenable promise
+ * @return {Promise}
+ */
+function getDeferredPromise() {
+  // Override promise with deprecated-sync-thenables
+  const promise = require("devtools/shared/deprecated-sync-thenables");
+  return promise;
+}
+
+function getAddonURIFromPath(path) {
+  const chromeURI = Services.io.newURI(path, null, DEBUGGER_CHROME_URI);
+  return chromeRegistry.convertChromeURL(chromeURI).QueryInterface(Ci.nsIFileURL);
+}
+
+function addTemporaryAddon(path) {
+  const addonFile = getAddonURIFromPath(path).file;
+  info("Installing addon: " + addonFile.path);
+
+  return AddonManager.installTemporaryAddon(addonFile);
+}
+
+function getAddonActorForId(client, addonId) {
+  info("Get addon actor for ID: " + addonId);
+  const deferred = getDeferredPromise().defer();
+
+  client.listAddons().then(response => {
+    const addonTargetActor = response.addons.filter(grip => grip.id == addonId).pop();
+    info("got addon actor for ID: " + addonId);
+    deferred.resolve(addonTargetActor);
+  });
+
+  return deferred.promise;
+}
+
+function removeAddon(addon) {
+  info("Removing addon.");
+
+  const deferred = getDeferredPromise().defer();
+
+  const listener = {
+    onUninstalled: function(uninstalledAddon) {
+      if (uninstalledAddon != addon) {
+        return;
+      }
+      AddonManager.removeAddonListener(listener);
+      deferred.resolve();
+    },
+  };
+  AddonManager.addAddonListener(listener);
+  addon.uninstall();
+
+  return deferred.promise;
+}
--- a/devtools/client/shared/test/helper_workers.js
+++ b/devtools/client/shared/test/helper_workers.js
@@ -7,23 +7,26 @@
 /* import-globals-from ../../debugger/new/test/mochitest/helpers.js */
 /* import-globals-from ../../debugger/new/test/mochitest/helpers/context.js */
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/debugger/new/test/mochitest/helpers.js",
   this);
 
 var { DebuggerServer } = require("devtools/server/main");
 var { DebuggerClient } = require("devtools/shared/client/debugger-client");
-
 var { Toolbox } = require("devtools/client/framework/toolbox");
 
 const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js";
 
 var nextId = 0;
 
+/**
+ * Returns a thenable promise
+ * @return {Promise}
+ */
 function getDeferredPromise() {
   // Override promise with deprecated-sync-thenables
   const promise = require("devtools/shared/deprecated-sync-thenables");
   return promise;
 }
 
 function jsonrpc(tab, method, params) {
   return new Promise(function(resolve, reject) {