Bug 1283622 - add Devtools test addons as Temporary Addons. r?ochameau draft
authorLuca Greco <lgreco@mozilla.com>
Wed, 06 Jul 2016 18:41:58 +0200
changeset 385005 194f16704754542a8469175566aaae52b80c1433
parent 384195 3db27bf874fa9e5057b7bcb96f325699bb7f1688
child 524812 9823914a7875822829c6f0d48aec23255f149fb2
push id22387
push userluca.greco@alcacoop.it
push dateThu, 07 Jul 2016 12:59:30 +0000
reviewersochameau
bugs1283622
milestone50.0a1
Bug 1283622 - add Devtools test addons as Temporary Addons. r?ochameau MozReview-Commit-ID: 1plXeerEAJp
devtools/client/debugger/test/mochitest/browser.ini
devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
devtools/client/debugger/test/mochitest/browser_dbg_addon-modules-unpacked.js
devtools/client/debugger/test/mochitest/browser_dbg_addon-modules.js
devtools/client/debugger/test/mochitest/browser_dbg_addon-panels.js
devtools/client/debugger/test/mochitest/browser_dbg_addon-sources.js
devtools/client/debugger/test/mochitest/browser_dbg_addon-workers-dbg-enabled.js
devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js
devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
devtools/client/debugger/test/mochitest/browser_dbg_sources-webext-contentscript.js
devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
devtools/client/debugger/test/mochitest/head.js
--- a/devtools/client/debugger/test/mochitest/browser.ini
+++ b/devtools/client/debugger/test/mochitest/browser.ini
@@ -4,16 +4,17 @@ subsuite = devtools
 skip-if = (os == 'linux' && debug && bits == 32)
 support-files =
   addon1.xpi
   addon2.xpi
   addon3.xpi
   addon4.xpi
   addon5.xpi
   addon-webext-contentscript.xpi
+  addon-source/browser_dbg_addon5
   code_binary_search.coffee
   code_binary_search.js
   code_binary_search.map
   code_blackboxing_blackboxme.js
   code_blackboxing_one.js
   code_blackboxing_three.js
   code_blackboxing_two.js
   code_blackboxing_unblackbox.min.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js
@@ -1,33 +1,34 @@
 /* -*- 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/ */
 
 // Test that the we can see console messages from the add-on
 
-const ADDON_URL = EXAMPLE_URL + "addon4.xpi";
+const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
+const ADDON_URL = CHROME_URL + "addon4.xpi";
 
 function getCachedMessages(webConsole) {
   let deferred = promise.defer();
   webConsole.getCachedMessages(["ConsoleAPI"], (aResponse) => {
     if (aResponse.error) {
       deferred.reject(aResponse.error);
       return;
     }
     deferred.resolve(aResponse.messages);
   });
   return deferred.promise;
 }
 
 function test() {
   Task.spawn(function* () {
-    let addon = yield addAddon(ADDON_URL);
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
     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");
 
     let consolePromise = addonDebugger.once("console");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-modules-unpacked.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-modules-unpacked.js
@@ -1,36 +1,37 @@
 /* -*- 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/ */
 
 // Make sure the add-on actor can see loaded JS Modules from an add-on
 
-const ADDON_URL = EXAMPLE_URL + "addon5.xpi";
+const ADDON_ID = "browser_dbg_addon5@tests.mozilla.org";
+const ADDON_URL = CHROME_URL + "addon-source/browser_dbg_addon5";
 
 function test() {
   Task.spawn(function* () {
-    let addon = yield addAddon(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
     let tab1 = yield addTab("chrome://browser_dbg_addon5/content/test.xul");
 
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
-    is(addonDebugger.title, `Developer Tools - Test unpacked add-on with JS Modules - ${ADDON_URL}`,
+    is(addonDebugger.title, `Developer Tools - Test unpacked add-on with JS Modules - (null)`,
        "Saw the right toolbox title.");
 
     // Check the inital list of sources is correct
     let groups = yield addonDebugger.getSourceGroups();
     is(groups[0].name, "browser_dbg_addon5@tests.mozilla.org", "Add-on code should be the first group");
     is(groups[1].name, "chrome://global", "XUL code should be the second group");
     is(groups.length, 2, "Should be only two groups.");
 
     let sources = groups[0].sources;
     is(sources.length, 3, "Should be three sources");
-    ok(sources[0].url.endsWith("/browser_dbg_addon5@tests.mozilla.org/bootstrap.js"), "correct url for bootstrap code");
+    ok(sources[0].url.endsWith("/browser_dbg_addon5/bootstrap.js"), "correct url for bootstrap code");
     is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
     is(sources[1].url, "resource://browser_dbg_addon5/test.jsm", "correct url for addon code");
     is(sources[1].label, "test.jsm", "correct label for addon code");
     is(sources[2].url, "chrome://browser_dbg_addon5/content/testxul.js", "correct url for addon tab code");
     is(sources[2].label, "testxul.js", "correct label for addon tab code");
 
     // Load a new module and tab and check they appear in the list of sources
     Cu.import("resource://browser_dbg_addon5/test2.jsm", {});
@@ -38,17 +39,17 @@ function test() {
 
     groups = yield addonDebugger.getSourceGroups();
     is(groups[0].name, "browser_dbg_addon5@tests.mozilla.org", "Add-on code should be the first group");
     is(groups[1].name, "chrome://global", "XUL code should be the second group");
     is(groups.length, 2, "Should be only two groups.");
 
     sources = groups[0].sources;
     is(sources.length, 5, "Should be five sources");
-    ok(sources[0].url.endsWith("/browser_dbg_addon5@tests.mozilla.org/bootstrap.js"), "correct url for bootstrap code");
+    ok(sources[0].url.endsWith("/browser_dbg_addon5/bootstrap.js"), "correct url for bootstrap code");
     is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
     is(sources[1].url, "resource://browser_dbg_addon5/test.jsm", "correct url for addon code");
     is(sources[1].label, "test.jsm", "correct label for addon code");
     is(sources[2].url, "chrome://browser_dbg_addon5/content/testxul.js", "correct url for addon tab code");
     is(sources[2].label, "testxul.js", "correct label for addon tab code");
     is(sources[3].url, "resource://browser_dbg_addon5/test2.jsm", "correct url for addon code");
     is(sources[3].label, "test2.jsm", "correct label for addon code");
     is(sources[4].url, "chrome://browser_dbg_addon5/content/testxul2.js", "correct url for addon tab code");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-modules.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-modules.js
@@ -1,36 +1,37 @@
 /* -*- 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/ */
 
 // Make sure the add-on actor can see loaded JS Modules from an add-on
 
-const ADDON_URL = EXAMPLE_URL + "addon4.xpi";
+const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
+const ADDON_URL = CHROME_URL + "addon4.xpi";
 
 function test() {
   Task.spawn(function* () {
-    let addon = yield addAddon(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
     let tab1 = yield addTab("chrome://browser_dbg_addon4/content/test.xul");
 
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
-    is(addonDebugger.title, `Developer Tools - Test add-on with JS Modules - ${ADDON_URL}`,
+    is(addonDebugger.title, `Developer Tools - Test add-on with JS Modules - (null)`,
        "Saw the right toolbox title.");
 
     // Check the inital list of sources is correct
     let groups = yield addonDebugger.getSourceGroups();
     is(groups[0].name, "browser_dbg_addon4@tests.mozilla.org", "Add-on code should be the first group");
     is(groups[1].name, "chrome://global", "XUL code should be the second group");
     is(groups.length, 2, "Should be only two groups.");
 
     let sources = groups[0].sources;
     is(sources.length, 3, "Should be three sources");
-    ok(sources[0].url.endsWith("/browser_dbg_addon4@tests.mozilla.org.xpi!/bootstrap.js"), "correct url for bootstrap code");
+    ok(sources[0].url.endsWith("/addon4.xpi!/bootstrap.js"), "correct url for bootstrap code");
     is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
     is(sources[1].url, "resource://browser_dbg_addon4/test.jsm", "correct url for addon code");
     is(sources[1].label, "test.jsm", "correct label for addon code");
     is(sources[2].url, "chrome://browser_dbg_addon4/content/testxul.js", "correct url for addon tab code");
     is(sources[2].label, "testxul.js", "correct label for addon tab code");
 
     // Load a new module and tab and check they appear in the list of sources
     Cu.import("resource://browser_dbg_addon4/test2.jsm", {});
@@ -38,17 +39,17 @@ function test() {
 
     groups = yield addonDebugger.getSourceGroups();
     is(groups[0].name, "browser_dbg_addon4@tests.mozilla.org", "Add-on code should be the first group");
     is(groups[1].name, "chrome://global", "XUL code should be the second group");
     is(groups.length, 2, "Should be only two groups.");
 
     sources = groups[0].sources;
     is(sources.length, 5, "Should be five sources");
-    ok(sources[0].url.endsWith("/browser_dbg_addon4@tests.mozilla.org.xpi!/bootstrap.js"), "correct url for bootstrap code");
+    ok(sources[0].url.endsWith("/addon4.xpi!/bootstrap.js"), "correct url for bootstrap code");
     is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
     is(sources[1].url, "resource://browser_dbg_addon4/test.jsm", "correct url for addon code");
     is(sources[1].label, "test.jsm", "correct label for addon code");
     is(sources[2].url, "chrome://browser_dbg_addon4/content/testxul.js", "correct url for addon tab code");
     is(sources[2].label, "testxul.js", "correct label for addon tab code");
     is(sources[3].url, "resource://browser_dbg_addon4/test2.jsm", "correct url for addon code");
     is(sources[3].label, "test2.jsm", "correct label for addon code");
     is(sources[4].url, "chrome://browser_dbg_addon4/content/testxul2.js", "correct url for addon tab code");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-panels.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-panels.js
@@ -1,33 +1,34 @@
 /* -*- 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/ */
 
 // Ensure that only panels that are relevant to the addon debugger
 // display in the toolbox
 
-const ADDON_URL = EXAMPLE_URL + "addon3.xpi";
+const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
+const ADDON_URL = CHROME_URL + "addon3.xpi";
 
 var gAddon, gClient, gThreadClient, gDebugger, gSources;
 var PREFS = [
   ["devtools.canvasdebugger.enabled", true],
   ["devtools.shadereditor.enabled", true],
   ["devtools.performance.enabled", true],
   ["devtools.netmonitor.enabled", true],
   ["devtools.scratchpad.enabled", true]
 ];
 function test() {
   Task.spawn(function* () {
     // Store and enable all optional dev tools panels
     yield pushPrefs(...PREFS);
 
-    let addon = yield addAddon(ADDON_URL);
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
     // Check only valid tabs are shown
     let tabs = addonDebugger.frame.contentDocument.getElementById("toolbox-tabs").children;
     let expectedTabs = ["webconsole", "jsdebugger", "scratchpad"];
 
     is(tabs.length, expectedTabs.length, "displaying only " + expectedTabs.length + " tabs in addon debugger");
     Array.forEach(tabs, (tab, i) => {
       let toolName = expectedTabs[i];
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-sources.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-sources.js
@@ -1,36 +1,37 @@
 /* -*- 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/ */
 
 // Ensure that the sources listed when debugging an addon are either from the
 // addon itself, or the SDK, with proper groups and labels.
 
-const ADDON_URL = EXAMPLE_URL + "addon3.xpi";
+const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
+const ADDON_URL = CHROME_URL + "addon3.xpi";
 var gClient;
 
 function test() {
   Task.spawn(function* () {
-    let addon = yield addAddon(ADDON_URL);
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
-    is(addonDebugger.title, `Developer Tools - browser_dbg_addon3 - ${ADDON_URL}`,
+    is(addonDebugger.title, `Developer Tools - browser_dbg_addon3 - (null)`,
        "Saw the right toolbox title.");
 
     // Check the inital list of sources is correct
     let groups = yield addonDebugger.getSourceGroups();
     is(groups[0].name, "jid1-ami3akps3baaeg@jetpack", "Add-on code should be the first group");
     is(groups[1].name, "Add-on SDK", "Add-on SDK should be the second group");
     is(groups.length, 2, "Should be only two groups.");
 
     let sources = groups[0].sources;
     is(sources.length, 2, "Should be two sources");
-    ok(sources[0].url.endsWith("/jid1-ami3akps3baaeg@jetpack.xpi!/bootstrap.js"), "correct url for bootstrap code");
+    ok(sources[0].url.endsWith("/addon3.xpi!/bootstrap.js"), "correct url for bootstrap code");
     is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
     is(sources[1].url, "resource://jid1-ami3akps3baaeg-at-jetpack/browser_dbg_addon3/lib/main.js", "correct url for add-on code");
     is(sources[1].label, "resources/browser_dbg_addon3/lib/main.js", "correct label for add-on code");
 
     ok(groups[1].sources.length > 10, "SDK modules are listed");
 
     yield addonDebugger.destroy();
     yield removeAddon(addon);
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addon-workers-dbg-enabled.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addon-workers-dbg-enabled.js
@@ -3,32 +3,33 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Test that the Addon Debugger works when devtools.debugger.workers is enabled.
 // Workers controller cannot be used when debugging an Addon actor.
 
-const ADDON_URL = EXAMPLE_URL + "addon3.xpi";
+const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
+const ADDON_URL = CHROME_URL + "addon3.xpi";
 
 function test() {
   Task.spawn(function* () {
     info("Enable worker debugging.");
     yield new Promise(resolve => {
       SpecialPowers.pushPrefEnv({
         "set": [["devtools.debugger.workers", true]]
       }, resolve);
     });
 
-    let addon = yield addAddon(ADDON_URL);
-    let addonDebugger = yield initAddonDebugger(ADDON_URL);
+    let addon = yield addTemporaryAddon(ADDON_URL);
+    let addonDebugger = yield initAddonDebugger({ADDON_ID});
 
     is(addonDebugger.title,
-       `Developer Tools - browser_dbg_addon3 - ${ADDON_URL}`,
+       `Developer Tools - browser_dbg_addon3 - (null)`,
        "Saw the right toolbox title.");
 
     info("Check that groups and sources are displayed.");
     let groups = yield addonDebugger.getSourceGroups();
     is(groups.length, 2, "Should be only two groups.");
     let sources = groups[0].sources;
     is(sources.length, 2, "Should be two sources");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
@@ -1,16 +1,17 @@
 /* -*- 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/ */
 
 // Make sure we can attach to addon actors.
 
-const ADDON3_URL = EXAMPLE_URL + "addon3.xpi";
+const ADDON3_URL = CHROME_URL + "addon3.xpi";
+const ADDON3_ID = "jid1-ami3akps3baaeg@jetpack";
 const ADDON_MODULE_URL = "resource://jid1-ami3akps3baaeg-at-jetpack/browser_dbg_addon3/lib/main.js";
 
 var gAddon, gClient, gThreadClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
     DebuggerServer.addBrowserActors();
@@ -18,31 +19,31 @@ function test() {
 
   let transport = DebuggerServer.connectPipe();
   gClient = new DebuggerClient(transport);
   gClient.connect().then(([aType, aTraits]) => {
     is(aType, "browser",
       "Root actor should identify itself as a browser.");
 
     installAddon()
-      .then(attachAddonActorForUrl.bind(null, gClient, ADDON3_URL))
+      .then(attachAddonActorForId.bind(null, gClient, ADDON3_ID))
       .then(attachAddonThread)
       .then(testDebugger)
       .then(testSources)
       .then(closeConnection)
       .then(uninstallAddon)
       .then(finish)
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function installAddon() {
-  return addAddon(ADDON3_URL).then(aAddon => {
+  return addTemporaryAddon(ADDON3_URL).then(aAddon => {
     gAddon = aAddon;
   });
 }
 
 function attachAddonThread([aGrip, aResponse]) {
   info("attached addon actor for URL");
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js
@@ -2,17 +2,16 @@
 /* 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/ */
 
 /**
  * Check extension-added global actor API.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/";
 const ACTORS_URL = CHROME_URL + "testactors.js";
 
 function test() {
   let gClient;
 
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
     DebuggerServer.addBrowserActors();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
@@ -1,18 +1,20 @@
 /* -*- 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/ */
 
 /**
  * Make sure the listAddons request works as specified.
  */
-const ADDON1_URL = EXAMPLE_URL + "addon1.xpi";
-const ADDON2_URL = EXAMPLE_URL + "addon2.xpi";
+const ADDON1_ID = "jid1-oBAwBoE5rSecNg@jetpack";
+const ADDON1_URL = CHROME_URL + "addon1.xpi";
+const ADDON2_ID = "jid1-qjtzNGV8xw5h2A@jetpack";
+const ADDON2_URL = CHROME_URL + "addon2.xpi";
 
 var gAddon1, gAddon1Actor, gAddon2, gAddon2Actor, gClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
     DebuggerServer.addBrowserActors();
   }
@@ -37,69 +39,69 @@ function test() {
 }
 
 function testFirstAddon() {
   let addonListChanged = false;
   gClient.addOneTimeListener("addonListChanged", () => {
     addonListChanged = true;
   });
 
-  return addAddon(ADDON1_URL).then(aAddon => {
+  return addTemporaryAddon(ADDON1_URL).then(aAddon => {
     gAddon1 = aAddon;
 
-    return getAddonActorForUrl(gClient, ADDON1_URL).then(aGrip => {
+    return getAddonActorForId(gClient, ADDON1_ID).then(aGrip => {
       ok(!addonListChanged, "Should not yet be notified that list of addons changed.");
       ok(aGrip, "Should find an addon actor for addon1.");
       gAddon1Actor = aGrip.actor;
     });
   });
 }
 
 function testSecondAddon() {
   let addonListChanged = false;
   gClient.addOneTimeListener("addonListChanged", function () {
     addonListChanged = true;
   });
 
-  return addAddon(ADDON2_URL).then(aAddon => {
+  return addTemporaryAddon(ADDON2_URL).then(aAddon => {
     gAddon2 = aAddon;
 
-    return getAddonActorForUrl(gClient, ADDON1_URL).then(aFirstGrip => {
-      return getAddonActorForUrl(gClient, ADDON2_URL).then(aSecondGrip => {
+    return getAddonActorForId(gClient, ADDON1_ID).then(aFirstGrip => {
+      return getAddonActorForId(gClient, ADDON2_ID).then(aSecondGrip => {
         ok(addonListChanged, "Should be notified that list of addons changed.");
         is(aFirstGrip.actor, gAddon1Actor, "First addon's actor shouldn't have changed.");
         ok(aSecondGrip, "Should find a addon actor for the second addon.");
         gAddon2Actor = aSecondGrip.actor;
       });
     });
   });
 }
 
 function testRemoveFirstAddon() {
   let addonListChanged = false;
   gClient.addOneTimeListener("addonListChanged", function () {
     addonListChanged = true;
   });
 
-  removeAddon(gAddon1).then(() => {
-    return getAddonActorForUrl(gClient, ADDON1_URL).then(aGrip => {
+  return removeAddon(gAddon1).then(() => {
+    return getAddonActorForId(gClient, ADDON1_ID).then(aGrip => {
       ok(addonListChanged, "Should be notified that list of addons changed.");
       ok(!aGrip, "Shouldn't find a addon actor for the first addon anymore.");
     });
   });
 }
 
 function testRemoveSecondAddon() {
   let addonListChanged = false;
   gClient.addOneTimeListener("addonListChanged", function () {
     addonListChanged = true;
   });
 
-  removeAddon(gAddon2).then(() => {
-    return getAddonActorForUrl(gClient, ADDON2_URL).then(aGrip => {
+  return removeAddon(gAddon2).then(() => {
+    return getAddonActorForId(gClient, ADDON2_ID).then(aGrip => {
       ok(addonListChanged, "Should be notified that list of addons changed.");
       ok(!aGrip, "Shouldn't find a addon actor for the second addon anymore.");
     });
   });
 }
 
 function closeConnection() {
   let deferred = promise.defer();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_sources-webext-contentscript.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_sources-webext-contentscript.js
@@ -2,16 +2,17 @@
 /* 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/ */
 
 /**
  * Make sure eval scripts appear in the source list
  */
 
+const ADDON_URL = CHROME_URL + "addon-webext-contentscript.xpi";
 const TAB_URL = EXAMPLE_URL + "doc_script_webext_contentscript.html";
 
 let {getExtensionUUID} = Cu.import("resource://gre/modules/Extension.jsm", {});
 
 function test() {
   let gPanel, gDebugger;
   let gSources, gAddon;
 
@@ -25,17 +26,17 @@ function test() {
       yield closeDebuggerAndFinish(gPanel);
     } else {
       // If no debugger panel was opened, call finish directly.
       finish();
     }
   };
 
   return Task.spawn(function* () {
-    gAddon = yield addAddon(EXAMPLE_URL + "/addon-webext-contentscript.xpi");
+    gAddon = yield addTemporaryAddon(ADDON_URL);
     let uuid = getExtensionUUID(gAddon.id);
 
     let options = {
       source: `moz-extension://${uuid}/webext-content-script.js`,
       line: 1
     };
     [,, gPanel] = yield initDebugger(TAB_URL, options);
     gDebugger = gPanel.panelWin;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
@@ -2,17 +2,16 @@
 /* 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/ */
 
 /**
  * Check extension-added tab actor lifetimes.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/";
 const ACTORS_URL = CHROME_URL + "testactors.js";
 const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
 
 var gClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
@@ -2,17 +2,16 @@
 /* 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/ */
 
 /**
  * Check extension-added tab actor lifetimes.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/";
 const ACTORS_URL = CHROME_URL + "testactors.js";
 const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
 
 var gClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -16,21 +16,24 @@ Services.prefs.setBoolPref("devtools.deb
 
 var { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
 var { DebuggerServer } = require("devtools/server/main");
 var { DebuggerClient, ObjectClient } = require("devtools/shared/client/main");
 var { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
 var EventEmitter = require("devtools/shared/event-emitter");
 var { Toolbox } = require("devtools/client/framework/toolbox");
 
+const chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
+
 // Override promise with deprecated-sync-thenables
 promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
 
 const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/test/mochitest/";
 const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js";
+const CHROME_URL = "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/";
 
 registerCleanupFunction(function* () {
   info("finish() was called, cleaning up...");
   Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
 
   while (gBrowser && gBrowser.tabs && gBrowser.tabs.length > 1) {
     info("Destroying toolbox.");
     let target = TargetFactory.forTab(gBrowser.selectedTab);
@@ -106,19 +109,26 @@ this.removeTab = function removeTab(aTab
     info("Tab removed and finished closing.");
     deferred.resolve();
   }, false);
 
   targetBrowser.removeTab(aTab);
   return deferred.promise;
 };
 
+function addTemporaryAddon(aChromeURL) {
+  let aChromeURI = Services.io.newURI(aChromeURL, null, null);
+  let aFile = chromeRegistry.convertChromeURL(aChromeURI).QueryInterface(Ci.nsIFileURL).file;
+  info("Installing addon: " + aFile.path);
+
+  return AddonManager.installTemporaryAddon(aFile);
+}
+
 function addAddon(aUrl) {
   info("Installing addon: " + aUrl);
-
   let deferred = promise.defer();
 
   AddonManager.getInstallForURL(aUrl, aInstaller => {
     aInstaller.install();
     let listener = {
       onInstallEnded: function (aAddon, aAddonInstall) {
         aInstaller.removeListener(listener);
 
@@ -165,18 +175,33 @@ function getTabActorForUrl(aClient, aUrl
   return deferred.promise;
 }
 
 function getAddonActorForUrl(aClient, aUrl) {
   info("Get addon actor for URL: " + aUrl);
   let deferred = promise.defer();
 
   aClient.listAddons(aResponse => {
-    let addonActor = aResponse.addons.filter(aGrip => aGrip.url == aUrl).pop();
-    info("got addon actor for URL: " + addonActor.actor);
+    let addonActor = aResponse.addons.filter(aGrip => {
+      return aGrip.url == aUrl;
+    }).pop();
+    info("got addon actor for URL: " + aUrl);
+    deferred.resolve(addonActor);
+  });
+
+  return deferred.promise;
+}
+
+function getAddonActorForId(aClient, aAddonId) {
+  info("Get addon actor for ID: " + aAddonId);
+  let deferred = promise.defer();
+
+  aClient.listAddons(aResponse => {
+    let addonActor = aResponse.addons.filter(aGrip => aGrip.id == aAddonId).pop();
+    info("got addon actor for ID: " + aAddonId);
     deferred.resolve(addonActor);
   });
 
   return deferred.promise;
 }
 
 function attachTabActorForUrl(aClient, aUrl) {
   let deferred = promise.defer();
@@ -609,29 +634,29 @@ let initDebugger = Task.async(function*(
     yield onCaretUpdated;
   }
 
   return [tab, debuggee, 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(aUrl) {
+function initAddonDebugger(opts) {
   let addonDebugger = new AddonDebugger();
-  return addonDebugger.init(aUrl).then(() => addonDebugger);
+  return addonDebugger.init(opts).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* (aUrl) {
+  init: Task.async(function* ({ADDON_URL, ADDON_ID}) {
     info("Initializing an addon debugger panel.");
 
     if (!DebuggerServer.initialized) {
       DebuggerServer.init();
       DebuggerServer.addBrowserActors();
     }
     DebuggerServer.allowChromeProcess = true;
 
@@ -640,17 +665,23 @@ AddonDebugger.prototype = {
     document.documentElement.appendChild(this.frame);
     window.addEventListener("message", this._onMessage);
 
     let transport = DebuggerServer.connectPipe();
     this.client = new DebuggerClient(transport);
 
     yield this.client.connect();
 
-    let addonActor = yield getAddonActorForUrl(this.client, aUrl);
+    let addonActor;
+
+    if (ADDON_URL) {
+      addonActor = yield getAddonActorForUrl(this.client, ADDON_URL);
+    } else if (ADDON_ID) {
+      addonActor = yield getAddonActorForId(this.client, ADDON_ID);
+    }
 
     let targetOptions = {
       form: addonActor,
       client: this.client,
       chrome: true,
       isTabActor: false
     };
 
@@ -958,16 +989,28 @@ function attachAddonActorForUrl(aClient,
     aClient.attachAddon(aGrip.actor, aResponse => {
       deferred.resolve([aGrip, aResponse]);
     });
   });
 
   return deferred.promise;
 }
 
+function attachAddonActorForId(aClient, aAddonId) {
+  let deferred = promise.defer();
+
+  getAddonActorForId(aClient, aAddonId).then(aGrip => {
+    aClient.attachAddon(aGrip.actor, aResponse => {
+      deferred.resolve([aGrip, aResponse]);
+    });
+  });
+
+  return deferred.promise;
+}
+
 function doResume(aPanel) {
   const threadClient = aPanel.panelWin.gThreadClient;
   return threadClient.resume();
 }
 
 function doInterrupt(aPanel) {
   const threadClient = aPanel.panelWin.gThreadClient;
   return threadClient.interrupt();