Bug 1500986 - Migrate old event-listener and worker debugger tests r=jdescottes
authorDavid Walsh <dwalsh@mozilla.com>
Tue, 23 Oct 2018 20:39:19 -0500
changeset 491325 ca3eb80797aa25c80a673fb397e7df1a25c9a775
parent 491324 9e5694d74ffb6dba5066173561310fb0ca7f258e
child 491326 9c5d6ad21391c871733e2cb4aeb5840a7833e112
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjdescottes
bugs1500986
milestone65.0a1
Bug 1500986 - Migrate old event-listener and worker debugger tests r=jdescottes
.eslintignore
devtools/client/debugger/test/mochitest/browser.ini
devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
devtools/client/debugger/test/mochitest/browser_dbg_listworkers.js
devtools/client/debugger/test/mochitest/browser_dbg_worker-window.js
devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attachThread-worker.js
devtools/client/debugger/test/mochitest/code_listworkers-worker1.js
devtools/client/debugger/test/mochitest/code_listworkers-worker2.js
devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attachThread-tab.html
devtools/client/debugger/test/mochitest/doc_event-listeners-01.html
devtools/client/debugger/test/mochitest/doc_event-listeners-03.html
devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html
devtools/client/debugger/test/mochitest/doc_listworkers-tab.html
devtools/client/debugger/test/mochitest/doc_native-event-handler.html
devtools/client/shared/test/browser.ini
devtools/client/shared/test/browser_dbg_debugger-statement.js
devtools/client/shared/test/browser_dbg_event-listeners-01.js
devtools/client/shared/test/browser_dbg_event-listeners-02.js
devtools/client/shared/test/browser_dbg_event-listeners-03.js
devtools/client/shared/test/browser_dbg_listworkers.js
devtools/client/shared/test/browser_dbg_worker-window.js
devtools/client/shared/test/code_listworkers-worker1.js
devtools/client/shared/test/code_listworkers-worker2.js
devtools/client/shared/test/doc_event-listeners-01.html
devtools/client/shared/test/doc_event-listeners-03.html
devtools/client/shared/test/doc_inline-debugger-statement.html
devtools/client/shared/test/doc_listworkers-tab.html
devtools/client/shared/test/doc_native-event-handler.html
devtools/client/shared/test/helper_workers.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -93,16 +93,18 @@ browser/extensions/mortar/**
 # Generated data files
 browser/extensions/formautofill/phonenumberutils/PhoneNumberMetaData.jsm
 
 # devtools/ exclusions
 devtools/client/inspector/markup/test/doc_markup_events_*.html
 devtools/client/inspector/rules/test/doc_media_queries.html
 devtools/client/performance/components/test/test_jit_optimizations_01.html
 devtools/client/responsive.html/test/browser/touch.html
+devtools/client/shared/test/*.html
+devtools/client/shared/test/code_*.js
 devtools/client/shared/components/test/mochitest/*.html
 !devtools/client/shared/components/test/mochitest/test_stack-trace.html
 devtools/client/storage/test/*.html
 !devtools/client/storage/test/storage-cookies.html
 !devtools/client/storage/test/storage-overflow.html
 !devtools/client/storage/test/storage-search.html
 !devtools/client/storage/test/storage-unsecured-iframe.html
 !devtools/client/storage/test/storage-unsecured-iframe-usercontextid.html
--- a/devtools/client/debugger/test/mochitest/browser.ini
+++ b/devtools/client/debugger/test/mochitest/browser.ini
@@ -2,53 +2,33 @@
 # to facilitate better chunking; see bug 1294489.
 
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 skip-if = (os == 'linux' && debug && bits == 32)
 support-files =
   addon4.xpi
-  code_listworkers-worker1.js
-  code_listworkers-worker2.js
-  code_WorkerTargetActor.attachThread-worker.js
-  doc_event-listeners-01.html
-  doc_event-listeners-03.html
-  doc_inline-debugger-statement.html
-  doc_listworkers-tab.html
-  doc_native-event-handler.html
   doc_promise-get-allocation-stack.html
   doc_promise-get-fulfillment-stack.html
   doc_promise-get-rejection-stack.html
   doc_terminate-on-tab-close.html
-  doc_WorkerTargetActor.attachThread-tab.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_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
-[browser_dbg_listworkers.js]
 [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
 skip-if = true
 [browser_dbg_promises-rejection-stack.js]
 uses-unsafe-cpows = true
 skip-if = true
 [browser_dbg_terminate-on-tab-close.js]
 uses-unsafe-cpows = true
-skip-if = true
-[browser_dbg_worker-window.js]
-skip-if = (e10s && debug) || true # Bug 1486974
\ No newline at end of file
+skip-if = true
\ No newline at end of file
deleted file mode 100644
--- a/devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attachThread-worker.js
+++ /dev/null
@@ -1,16 +0,0 @@
-"use strict";
-
-function f() {
-  var a = 1;
-  var b = 2;
-  var c = 3;
-}
-
-self.onmessage = function (event) {
-  if (event.data == "ping") {
-    f();
-    postMessage("pong");
-  }
-};
-
-postMessage("load");
deleted file mode 100644
--- a/devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attachThread-tab.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8"/>
-  </head>
-  <body>
-  </body>
-</html>
--- a/devtools/client/shared/test/browser.ini
+++ b/devtools/client/shared/test/browser.ini
@@ -1,38 +1,45 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 support-files =
   addon1.xpi
   addon2.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
   doc_cubic-bezier-02.html
   doc_empty-tab-01.html
   doc_empty-tab-02.html
+  doc_event-listeners-01.html
+  doc_event-listeners-03.html
   doc_filter-editor-01.html
   doc_html_tooltip-02.xul
   doc_html_tooltip-03.xul
   doc_html_tooltip-04.xul
   doc_html_tooltip-05.xul
   doc_html_tooltip.xul
   doc_html_tooltip_arrow-01.xul
   doc_html_tooltip_arrow-02.xul
   doc_html_tooltip_doorhanger-01.xul
   doc_html_tooltip_doorhanger-02.xul
   doc_html_tooltip_hover.xul
   doc_html_tooltip_rtl.xul
+  doc_inline-debugger-statement.html
   doc_inplace-editor_autocomplete_offset.xul
   doc_layoutHelpers-getBoxQuads.html
   doc_layoutHelpers.html
+  doc_listworkers-tab.html
+  doc_native-event-handler.html
   doc_options-view.xul
   doc_script-switching-01.html
   doc_script-switching-02.html
   doc_spectrum.html
   doc_tableWidget_basic.html
   doc_tableWidget_keyboard_interaction.xul
   doc_tableWidget_mouse_interaction.xul
   doc_templater_basic.html
@@ -62,18 +69,27 @@ 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_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
 [browser_dbg_globalactor.js]
 skip-if = e10s
+[browser_dbg_listworkers.js]
 [browser_filter-editor-01.js]
 [browser_filter-editor-02.js]
 [browser_filter-editor-03.js]
 [browser_filter-editor-04.js]
 [browser_filter-editor-05.js]
 [browser_filter-editor-06.js]
 [browser_filter-editor-07.js]
 [browser_filter-editor-08.js]
@@ -241,8 +257,10 @@ skip-if = true # bug 1368569
 [browser_dbg_worker-console-02.js]
 skip-if = e10s && debug
 [browser_dbg_worker-console-03.js]
 skip-if = debug # bug 1334683
 [browser_dbg_worker-console-04.js]
 skip-if = e10s && debug
 [browser_dbg_WorkerTargetActor.attach.js]
 skip-if = e10s && debug
+[browser_dbg_worker-window.js]
+skip-if = (e10s && debug) || true # Bug 1486974
\ No newline at end of file
rename from devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
rename to devtools/client/shared/test/browser_dbg_debugger-statement.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
+++ b/devtools/client/shared/test/browser_dbg_debugger-statement.js
@@ -1,51 +1,62 @@
 /* -*- 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";
+
 /**
  * Tests the behavior of the debugger statement.
  */
 
-const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
+// Import helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
+
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+
+const TAB_URL = TEST_URI_ROOT + "doc_inline-debugger-statement.html";
 
 var gClient;
 var gTab;
 
 function test() {
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
 
-  let transport = DebuggerServer.connectPipe();
+  const transport = DebuggerServer.connectPipe();
   gClient = new DebuggerClient(transport);
   gClient.connect().then(([aType, aTraits]) => {
     is(aType, "browser",
       "Root actor should identify itself as a browser.");
 
     addTab(TAB_URL)
-      .then((aTab) => {
-        gTab = aTab;
+      .then(tab => {
+        gTab = tab;
         return attachTargetActorForUrl(gClient, TAB_URL);
       })
       .then(testEarlyDebuggerStatement)
       .then(testDebuggerStatement)
       .then(() => gClient.close())
       .then(finish)
-      .catch(aError => {
-        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      .catch(error => {
+        ok(false, "Got an error: " + error.message + "\n" + error.stack);
       });
   });
 }
 
 function testEarlyDebuggerStatement([aGrip, aResponse]) {
-  let deferred = promise.defer();
+  const deferred = getDeferredPromise().defer();
 
-  let onPaused = function (aEvent, aPacket) {
+  const onPaused = function(event, packet) {
     ok(false, "Pause shouldn't be called before we've attached!");
     deferred.reject();
   };
 
   gClient.addListener("paused", onPaused);
 
   // This should continue without nesting an event loop and calling
   // the onPaused hook, because we haven't attached yet.
@@ -60,26 +71,26 @@ function testEarlyDebuggerStatement([aGr
       deferred.resolve([aGrip, aResponse]);
     });
   });
 
   return deferred.promise;
 }
 
 function testDebuggerStatement([aGrip, aResponse]) {
-  let deferred = promise.defer();
+  const deferred = getDeferredPromise().defer();
 
-  gClient.addListener("paused", (aEvent, aPacket) => {
+  gClient.addListener("paused", (event, packet) => {
     gClient.request({ to: aResponse.threadActor, type: "resume" }, () => {
       ok(true, "The pause handler was triggered on a debugger statement.");
       deferred.resolve();
     });
   });
 
   // Reach around the debugging protocol and execute the debugger statement.
   callInTab(gTab, "runDebuggerStatement");
 
   return deferred.promise;
 }
 
-registerCleanupFunction(function () {
+registerCleanupFunction(function() {
   gClient = null;
 });
rename from devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
rename to devtools/client/shared/test/browser_dbg_event-listeners-01.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
+++ b/devtools/client/shared/test/browser_dbg_event-listeners-01.js
@@ -1,99 +1,111 @@
 /* -*- 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";
+
 /**
  * Tests that the eventListeners request works.
  */
 
-const TAB_URL = EXAMPLE_URL + "doc_event-listeners-01.html";
+// Import helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
+
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+
+const TAB_URL = TEST_URI_ROOT + "doc_event-listeners-01.html";
 
 add_task(async function() {
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
 
-  let transport = DebuggerServer.connectPipe();
-  let client = new DebuggerClient(transport);
-  let [type, traits] = await client.connect();
+  const transport = DebuggerServer.connectPipe();
+  const client = new DebuggerClient(transport);
+  const [type] = await client.connect();
 
   Assert.equal(type, "browser",
     "Root actor should identify itself as a browser.");
 
-  let tab = await addTab(TAB_URL);
-  let threadClient = await attachThreadActorForUrl(client, TAB_URL);
+  const tab = await addTab(TAB_URL);
+  const threadClient = await attachThreadActorForUrl(client, TAB_URL);
   await pauseDebuggee(tab, client, threadClient);
   await testEventListeners(client, threadClient);
 
   await client.close();
 });
 
-function pauseDebuggee(aTab, aClient, aThreadClient) {
-  let deferred = promise.defer();
+function pauseDebuggee(tab, client, threadClient) {
+  const deferred = getDeferredPromise().defer();
 
-  aClient.addOneTimeListener("paused", (aEvent, aPacket) => {
-    is(aPacket.type, "paused",
+  client.addOneTimeListener("paused", (event, packet) => {
+    is(packet.type, "paused",
       "We should now be paused.");
-    is(aPacket.why.type, "debuggerStatement",
+    is(packet.why.type, "debuggerStatement",
       "The debugger statement was hit.");
 
-    deferred.resolve(aThreadClient);
+    deferred.resolve(threadClient);
   });
 
-  generateMouseClickInTab(aTab, "content.document.querySelector('button')");
+  generateMouseClickInTab(tab, "content.document.querySelector('button')");
 
   return deferred.promise;
 }
 
-async function testEventListeners(aClient, aThreadClient) {
-  let packet = await aThreadClient.eventListeners();
+async function testEventListeners(client, threadClient) {
+  const packet = await threadClient.eventListeners();
 
   if (packet.error) {
-    let msg = "Error getting event listeners: " + packet.message;
+    const msg = "Error getting event listeners: " + packet.message;
     Assert.ok(false, msg);
     return;
   }
 
   is(packet.listeners.length, 3, "Found all event listeners.");
 
-  let listeners = await promise.all(packet.listeners.map(listener => {
-    const lDeferred = promise.defer();
-    aThreadClient.pauseGrip(listener.function).getDefinitionSite(aResponse => {
-      if (aResponse.error) {
-        const msg = "Error getting function definition site: " + aResponse.message;
+  const listeners = await getDeferredPromise().all(packet.listeners.map(listener => {
+    const lDeferred = getDeferredPromise().defer();
+    threadClient.pauseGrip(listener.function).getDefinitionSite(response => {
+      if (response.error) {
+        const msg = "Error getting function definition site: " + response.message;
         ok(false, msg);
         lDeferred.reject(msg);
         return;
       }
-      listener.function.url = aResponse.source.url;
+      listener.function.url = response.source.url;
       lDeferred.resolve(listener);
     });
     return lDeferred.promise;
   }));
 
-  let types = [];
+  const types = [];
 
-  for (let l of listeners) {
+  for (const l of listeners) {
     info("Listener for the " + l.type + " event.");
-    let node = l.node;
+    const node = l.node;
     ok(node, "There is a node property.");
     ok(node.object, "There is a node object property.");
     if (node.selector != "window") {
-      let nodeCount =
-        await ContentTask.spawn(gBrowser.selectedBrowser, node.selector, async (selector) => {
-          return content.document.querySelectorAll(selector).length;
-        });
+      const nodeCount =
+        await ContentTask.spawn(gBrowser.selectedBrowser, node.selector,
+          async (selector) => {
+            return content.document.querySelectorAll(selector).length;
+          });
       Assert.equal(nodeCount, 1, "The node property is a unique CSS selector.");
     } else {
       Assert.ok(true, "The node property is a unique CSS selector.");
     }
 
-    let func = l.function;
+    const func = l.function;
     ok(func, "There is a function property.");
     is(func.type, "object", "The function form is of type 'object'.");
     is(func.class, "Function", "The function form is of class 'Function'.");
 
     // The onchange handler is an inline string that doesn't have
     // a URL because it's basically eval'ed
     if (l.type !== "change") {
       is(func.url, TAB_URL, "The function url is correct.");
@@ -123,10 +135,10 @@ async function testEventListeners(aClien
         "'isEventHandler' property has the right value.");
     }
   }
 
   Assert.ok(types.includes("click"), "Found the click handler.");
   Assert.ok(types.includes("change"), "Found the change handler.");
   Assert.ok(types.includes("keyup"), "Found the keyup handler.");
 
-  await aThreadClient.resume();
+  await threadClient.resume();
 }
rename from devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
rename to devtools/client/shared/test/browser_dbg_event-listeners-02.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
+++ b/devtools/client/shared/test/browser_dbg_event-listeners-02.js
@@ -1,111 +1,122 @@
 /* -*- 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";
+
 /**
  * Tests that the eventListeners request works when bound functions are used as
  * event listeners.
  */
 
-const TAB_URL = EXAMPLE_URL + "doc_event-listeners-03.html";
+// Import helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
 
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+
+const TAB_URL = TEST_URI_ROOT + "doc_event-listeners-03.html";
 
 add_task(async function() {
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
 
-  let transport = DebuggerServer.connectPipe();
-  let client = new DebuggerClient(transport);
-  let [type, traits] = await client.connect();
+  const transport = DebuggerServer.connectPipe();
+  const client = new DebuggerClient(transport);
+  const [type] = await client.connect();
 
   Assert.equal(type, "browser",
     "Root actor should identify itself as a browser.");
 
-  let tab = await addTab(TAB_URL);
-  let threadClient = await attachThreadActorForUrl(client, TAB_URL);
+  const tab = await addTab(TAB_URL);
+  const threadClient = await attachThreadActorForUrl(client, TAB_URL);
   await pauseDebuggee(tab, client, threadClient);
   await testEventListeners(client, threadClient);
   await client.close();
 });
 
-function pauseDebuggee(aTab, aClient, aThreadClient) {
-  let deferred = promise.defer();
+function pauseDebuggee(tab, client, threadClient) {
+  const deferred = getDeferredPromise().defer();
 
-  aClient.addOneTimeListener("paused", (aEvent, aPacket) => {
-    is(aPacket.type, "paused",
+  client.addOneTimeListener("paused", (event, packet) => {
+    is(packet.type, "paused",
       "We should now be paused.");
-    is(aPacket.why.type, "debuggerStatement",
+    is(packet.why.type, "debuggerStatement",
       "The debugger statement was hit.");
 
-    deferred.resolve(aThreadClient);
+    deferred.resolve(threadClient);
   });
 
-  generateMouseClickInTab(aTab, "content.document.querySelector('button')");
+  generateMouseClickInTab(tab, "content.document.querySelector('button')");
 
   return deferred.promise;
 }
 
-async function testEventListeners(aClient, aThreadClient) {
-  let packet = await aThreadClient.eventListeners();
+async function testEventListeners(client, threadClient) {
+  const packet = await threadClient.eventListeners();
 
   if (packet.error) {
-    let msg = "Error getting event listeners: " + aPacket.message;
+    const msg = "Error getting event listeners: " + packet.message;
     ok(false, msg);
     return;
   }
 
   is(packet.listeners.length, 3,
     "Found all event listeners.");
 
-  let listeners = await promise.all(packet.listeners.map(listener => {
-    const lDeferred = promise.defer();
-    aThreadClient.pauseGrip(listener.function).getDefinitionSite(aResponse => {
-      if (aResponse.error) {
-        const msg = "Error getting function definition site: " + aResponse.message;
+  const listeners = await getDeferredPromise().all(packet.listeners.map(listener => {
+    const lDeferred = getDeferredPromise().defer();
+    threadClient.pauseGrip(listener.function).getDefinitionSite(response => {
+      if (response.error) {
+        const msg = "Error getting function definition site: " + response.message;
         ok(false, msg);
         lDeferred.reject(msg);
         return;
       }
-      listener.function.url = aResponse.source.url;
+      listener.function.url = response.source.url;
       lDeferred.resolve(listener);
     });
     return lDeferred.promise;
   }));
 
   Assert.equal(listeners.length, 3, "Found three event listeners.");
 
-  for (let l of listeners) {
-    let node = l.node;
+  for (const l of listeners) {
+    const node = l.node;
     ok(node, "There is a node property.");
     ok(node.object, "There is a node object property.");
 
     if (node.selector != "window") {
-      let nodeCount =
-        await ContentTask.spawn(gBrowser.selectedBrowser, node.selector, async (selector) => {
-          return content.document.querySelectorAll(selector).length;
-        });
+      const nodeCount =
+        await ContentTask.spawn(gBrowser.selectedBrowser, node.selector,
+          async (selector) => {
+            return content.document.querySelectorAll(selector).length;
+          });
       Assert.equal(nodeCount, 1, "The node property is a unique CSS selector.");
     } else {
       Assert.ok(true, "The node property is a unique CSS selector.");
     }
 
-    let func = l.function;
+    const func = l.function;
     ok(func, "There is a function property.");
     is(func.type, "object", "The function form is of type 'object'.");
     is(func.class, "Function", "The function form is of class 'Function'.");
     is(func.url, TAB_URL, "The function url is correct.");
 
     is(l.type, "click", "This is a click event listener.");
     is(l.allowsUntrusted, true,
       "'allowsUntrusted' property has the right value.");
     is(l.inSystemEventGroup, false,
       "'inSystemEventGroup' property has the right value.");
     is(l.isEventHandler, false,
       "'isEventHandler' property has the right value.");
     is(l.capturing, false,
       "Capturing property has the right value.");
   }
 
-  await aThreadClient.resume();
+  await threadClient.resume();
 }
rename from devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
rename to devtools/client/shared/test/browser_dbg_event-listeners-03.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
+++ b/devtools/client/shared/test/browser_dbg_event-listeners-03.js
@@ -1,81 +1,92 @@
 /* -*- 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";
+
 /**
  * Tests that the eventListeners request works when there are event handlers
  * that the debugger cannot unwrap.
  */
 
-const TAB_URL = EXAMPLE_URL + "doc_native-event-handler.html";
+// Import helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
+
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+
+const TAB_URL = TEST_URI_ROOT + "doc_native-event-handler.html";
 
 var gClient;
 var gTab;
 
 function test() {
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
 
-  let transport = DebuggerServer.connectPipe();
+  const transport = DebuggerServer.connectPipe();
   gClient = new DebuggerClient(transport);
   gClient.connect().then(([aType, aTraits]) => {
     is(aType, "browser",
       "Root actor should identify itself as a browser.");
 
     addTab(TAB_URL)
-      .then((aTab) => {
-        gTab = aTab;
+      .then((tab) => {
+        gTab = tab;
         return attachThreadActorForUrl(gClient, TAB_URL);
       })
       .then(pauseDebuggee)
       .then(testEventListeners)
       .then(() => gClient.close())
       .then(finish)
-      .catch(aError => {
-        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      .catch(error => {
+        ok(false, "Got an error: " + error.message + "\n" + error.stack);
       });
   });
 }
 
-function pauseDebuggee(aThreadClient) {
-  let deferred = promise.defer();
+function pauseDebuggee(threadClient) {
+  const deferred = getDeferredPromise().defer();
 
-  gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
-    is(aPacket.type, "paused",
+  gClient.addOneTimeListener("paused", (event, packet) => {
+    is(packet.type, "paused",
       "We should now be paused.");
-    is(aPacket.why.type, "debuggerStatement",
+    is(packet.why.type, "debuggerStatement",
       "The debugger statement was hit.");
 
-    deferred.resolve(aThreadClient);
+    deferred.resolve(threadClient);
   });
 
   generateMouseClickInTab(gTab, "content.document.querySelector('button')");
 
   return deferred.promise;
 }
 
-function testEventListeners(aThreadClient) {
-  let deferred = promise.defer();
+function testEventListeners(threadClient) {
+  const deferred = getDeferredPromise().defer();
 
-  aThreadClient.eventListeners(aPacket => {
-    if (aPacket.error) {
-      let msg = "Error getting event listeners: " + aPacket.message;
+  threadClient.eventListeners(packet => {
+    if (packet.error) {
+      const msg = "Error getting event listeners: " + packet.message;
       ok(false, msg);
       deferred.reject(msg);
       return;
     }
 
     // There are 2 event listeners in the page: button.onclick, window.onload.
     // The video element controls listeners are skipped — they cannot be
     // unwrapped but they shouldn't cause us to throw either.
-    is(aPacket.listeners.length, 2, "Found all event listeners.");
-    aThreadClient.resume(deferred.resolve);
+    is(packet.listeners.length, 2, "Found all event listeners.");
+    threadClient.resume(deferred.resolve);
   });
 
   return deferred.promise;
 }
 
-registerCleanupFunction(function () {
+registerCleanupFunction(function() {
   gClient = null;
 });
rename from devtools/client/debugger/test/mochitest/browser_dbg_listworkers.js
rename to devtools/client/shared/test/browser_dbg_listworkers.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_listworkers.js
+++ b/devtools/client/shared/test/browser_dbg_listworkers.js
@@ -1,59 +1,73 @@
+/* -*- 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 helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
+
+var { DebuggerServer } = require("devtools/server/main");
+var { DebuggerClient } = require("devtools/shared/client/debugger-client");
+
 var TAB_URL = EXAMPLE_URL + "doc_listworkers-tab.html";
 var WORKER1_URL = "code_listworkers-worker1.js";
 var WORKER2_URL = "code_listworkers-worker2.js";
 
-function test() {
-  Task.spawn(function* () {
-    DebuggerServer.init();
-    DebuggerServer.registerAllActors();
+add_task(async function test() {
+  DebuggerServer.init();
+  DebuggerServer.registerAllActors();
 
-    let client = new DebuggerClient(DebuggerServer.connectPipe());
-    yield connect(client);
+  const client = new DebuggerClient(DebuggerServer.connectPipe());
+  await connect(client);
 
-    let tab = yield addTab(TAB_URL);
-    let { tabs } = yield listTabs(client);
-    let [, targetFront] = yield attachTarget(client, findTab(tabs, TAB_URL));
+  const tab = await addTab(TAB_URL);
+  const { tabs } = await listTabs(client);
+  const [, targetFront] = await attachTarget(client, findTab(tabs, TAB_URL));
 
-    let { workers } = yield listWorkers(targetFront);
-    is(workers.length, 0);
+  let { workers } = await listWorkers(targetFront);
+  is(workers.length, 0);
 
-    executeSoon(() => {
-      evalInTab(tab, "var worker1 = new Worker('" + WORKER1_URL + "');");
-    });
-    yield waitForWorkerListChanged(targetFront);
+  executeSoon(() => {
+    evalInTab(tab, "var worker1 = new Worker('" + WORKER1_URL + "');");
+  });
+  await waitForWorkerListChanged(targetFront);
 
-    ({ workers } = yield listWorkers(targetFront));
-    is(workers.length, 1);
-    is(workers[0].url, WORKER1_URL);
+  ({ workers } = await listWorkers(targetFront));
+  is(workers.length, 1);
+  is(workers[0].url, WORKER1_URL);
 
-    executeSoon(() => {
-      evalInTab(tab, "var worker2 = new Worker('" + WORKER2_URL + "');");
-    });
-    yield waitForWorkerListChanged(targetFront);
+  executeSoon(() => {
+    evalInTab(tab, "var worker2 = new Worker('" + WORKER2_URL + "');");
+  });
+  await waitForWorkerListChanged(targetFront);
 
-    ({ workers } = yield listWorkers(targetFront));
-    is(workers.length, 2);
-    is(workers[0].url, WORKER1_URL);
-    is(workers[1].url, WORKER2_URL);
+  ({ workers } = await listWorkers(targetFront));
+  is(workers.length, 2);
+  is(workers[0].url, WORKER1_URL);
+  is(workers[1].url, WORKER2_URL);
 
-    executeSoon(() => {
-      evalInTab(tab, "worker1.terminate()");
-    });
-    yield waitForWorkerListChanged(targetFront);
+  executeSoon(() => {
+    evalInTab(tab, "worker1.terminate()");
+  });
+  await waitForWorkerListChanged(targetFront);
 
-    ({ workers } = yield listWorkers(targetFront));
-    is(workers.length, 1);
-    is(workers[0].url, WORKER2_URL);
+  ({ workers } = await listWorkers(targetFront));
+  is(workers.length, 1);
+  is(workers[0].url, WORKER2_URL);
 
-    executeSoon(() => {
-      evalInTab(tab, "worker2.terminate()");
-    });
-    yield waitForWorkerListChanged(targetFront);
+  executeSoon(() => {
+    evalInTab(tab, "worker2.terminate()");
+  });
+  await waitForWorkerListChanged(targetFront);
 
-    ({ workers } = yield listWorkers(targetFront));
-    is(workers.length, 0);
+  ({ workers } = await listWorkers(targetFront));
+  is(workers.length, 0);
 
-    yield close(client);
-    finish();
-  });
-}
+  await close(client);
+  finish();
+});
rename from devtools/client/debugger/test/mochitest/browser_dbg_worker-window.js
rename to devtools/client/shared/test/browser_dbg_worker-window.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_worker-window.js
+++ b/devtools/client/shared/test/browser_dbg_worker-window.js
@@ -1,60 +1,66 @@
 // Check to make sure that a worker can be attached to a toolbox
 // directly, and that the toolbox has expected properties.
 
 "use strict";
 
+// Import helpers for the workers
+/* import-globals-from helper_workers.js */
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
+  this);
+
 // The following "connectionClosed" rejection should not be left uncaught. This
 // test has been whitelisted until the issue is fixed.
 ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", this);
 PromiseTestUtils.expectUncaughtRejection(/[object Object]/);
 
-var TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
-var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
+const TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
+const WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
 
 add_task(async function() {
   await pushPrefs(["devtools.scratchpad.enabled", true]);
 
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
 
-  let client = new DebuggerClient(DebuggerServer.connectPipe());
+  const client = new DebuggerClient(DebuggerServer.connectPipe());
   await connect(client);
 
-  let tab = await addTab(TAB_URL);
-  let { tabs } = await listTabs(client);
-  let [, targetFront] = await attachTarget(client, findTab(tabs, TAB_URL));
+  const tab = await addTab(TAB_URL);
+  const { tabs } = await listTabs(client);
+  const [, targetFront] = await attachTarget(client, findTab(tabs, TAB_URL));
 
   await listWorkers(targetFront);
   await createWorkerInTab(tab, WORKER_URL);
 
-  let { workers } = await listWorkers(targetFront);
-  let [, workerTargetFront] = await attachWorker(targetFront,
+  const { workers } = await listWorkers(targetFront);
+  const [, workerTargetFront] = await attachWorker(targetFront,
                                              findWorker(workers, WORKER_URL));
 
-  let toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
+  const toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
                                             "jsdebugger",
                                             Toolbox.HostType.WINDOW);
 
   is(toolbox.hostType, "window", "correct host");
 
   await new Promise(done => {
     toolbox.win.parent.addEventListener("message", function onmessage(event) {
       if (event.data.name == "set-host-title") {
         toolbox.win.parent.removeEventListener("message", onmessage);
         done();
       }
     });
   });
   ok(toolbox.win.parent.document.title.includes(WORKER_URL),
      "worker URL in host title");
 
-  let toolTabs = toolbox.doc.querySelectorAll(".devtools-tab");
-  let activeTools = [...toolTabs].map(tab=>tab.getAttribute("data-id"));
+  const toolTabs = toolbox.doc.querySelectorAll(".devtools-tab");
+  const activeTools = [...toolTabs].map(toolTab => toolTab.getAttribute("data-id"));
 
   is(activeTools.join(","), "webconsole,jsdebugger,scratchpad",
     "Correct set of tools supported by worker");
 
   terminateWorkerInTab(tab, WORKER_URL);
   await waitForWorkerClose(workerTargetFront);
   await close(client);
 
rename from devtools/client/debugger/test/mochitest/code_listworkers-worker1.js
rename to devtools/client/shared/test/code_listworkers-worker1.js
--- a/devtools/client/debugger/test/mochitest/code_listworkers-worker1.js
+++ b/devtools/client/shared/test/code_listworkers-worker1.js
@@ -1,3 +1,3 @@
 "use strict";
 
-self.onmessage = function () {};
+self.onmessage = function() {};
rename from devtools/client/debugger/test/mochitest/code_listworkers-worker2.js
rename to devtools/client/shared/test/code_listworkers-worker2.js
--- a/devtools/client/debugger/test/mochitest/code_listworkers-worker2.js
+++ b/devtools/client/shared/test/code_listworkers-worker2.js
@@ -1,3 +1,3 @@
 "use strict";
 
-self.onmessage = function () {};
+self.onmessage = function() {};
rename from devtools/client/debugger/test/mochitest/doc_event-listeners-01.html
rename to devtools/client/shared/test/doc_event-listeners-01.html
--- a/devtools/client/debugger/test/mochitest/doc_event-listeners-01.html
+++ b/devtools/client/shared/test/doc_event-listeners-01.html
@@ -7,36 +7,38 @@
     <title>Debugger test page</title>
   </head>
 
   <body>
     <button>Click me!</button>
     <input type="text" onchange="changeHandler()">
 
     <script type="text/javascript">
-      window.addEventListener("load", function () {
+      "use strict";
+
+      window.addEventListener("load", function() {
         function initialSetup(event) {
           debugger;
-          var button = document.querySelector("button");
+          const button = document.querySelector("button");
           button.onclick = clickHandler;
         }
         function clickHandler(event) {
           window.foobar = "clickHandler";
         }
         function changeHandler(event) {
           window.foobar = "changeHandler";
         }
         function keyupHandler(event) {
           window.foobar = "keyupHandler";
         }
 
-        var button = document.querySelector("button");
+        const button = document.querySelector("button");
         button.onclick = initialSetup;
 
-        var input = document.querySelector("input");
+        const input = document.querySelector("input");
         input.addEventListener("keyup", keyupHandler, true);
 
         window.changeHandler = changeHandler;
       }, {once: true});
     </script>
   </body>
 
 </html>
rename from devtools/client/debugger/test/mochitest/doc_event-listeners-03.html
rename to devtools/client/shared/test/doc_event-listeners-03.html
--- a/devtools/client/debugger/test/mochitest/doc_event-listeners-03.html
+++ b/devtools/client/shared/test/doc_event-listeners-03.html
@@ -9,54 +9,56 @@
 
   <body>
     <button id="initialSetup">initialSetup</button>
     <button id="clicker">clicker</button>
     <button id="handleEventClick">handleEventClick</button>
     <button id="boundHandleEventClick">boundHandleEventClick</button>
 
     <script type="text/javascript">
-      window.addEventListener("load", function () {
+      "use strict";
+
+      window.addEventListener("load", function() {
         function initialSetup(event) {
-          var button = document.getElementById("initialSetup");
+          const button = document.getElementById("initialSetup");
           button.removeEventListener("click", initialSetup);
           debugger;
         }
 
         function clicker(event) {
           window.foobar = "clicker";
         }
 
         function handleEventClick() {
-          var button = document.getElementById("handleEventClick");
+          const button = document.getElementById("handleEventClick");
           // Create a long prototype chain to test for weird edge cases.
           button.addEventListener("click", Object.create(Object.create(this)));
         }
 
         handleEventClick.prototype.handleEvent = function() {
           window.foobar = "handleEventClick";
         };
 
         function boundHandleEventClick() {
-          var button = document.getElementById("boundHandleEventClick");
+          const button = document.getElementById("boundHandleEventClick");
           this.handleEvent = this.handleEvent.bind(this);
           button.addEventListener("click", this);
         }
 
         boundHandleEventClick.prototype.handleEvent = function() {
           window.foobar = "boundHandleEventClick";
         };
 
-        var button = document.getElementById("clicker");
+        const button = document.getElementById("clicker");
         // Bind more than once to test for weird edge cases.
-        var boundClicker = clicker.bind(this).bind(this).bind(this);
+        const boundClicker = clicker.bind(this).bind(this).bind(this);
         button.addEventListener("click", boundClicker);
 
         new handleEventClick();
         new boundHandleEventClick();
 
-        var initButton = document.getElementById("initialSetup");
+        const initButton = document.getElementById("initialSetup");
         initButton.addEventListener("click", initialSetup);
       }, {once: true});
     </script>
   </body>
 
 </html>
rename from devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html
rename to devtools/client/shared/test/doc_inline-debugger-statement.html
--- a/devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html
+++ b/devtools/client/shared/test/doc_inline-debugger-statement.html
@@ -7,15 +7,16 @@
     <meta charset="utf-8"/>
     <title>Debugger test page</title>
   </head>
 
   <body>
     <button>Click me!</button>
 
     <script type="text/javascript">
+      "use strict";
       function runDebuggerStatement() {
         debugger;
       }
     </script>
   </body>
 
 </html>
rename from devtools/client/debugger/test/mochitest/doc_listworkers-tab.html
rename to devtools/client/shared/test/doc_listworkers-tab.html
rename from devtools/client/debugger/test/mochitest/doc_native-event-handler.html
rename to devtools/client/shared/test/doc_native-event-handler.html
--- a/devtools/client/debugger/test/mochitest/doc_native-event-handler.html
+++ b/devtools/client/shared/test/doc_native-event-handler.html
@@ -1,16 +1,18 @@
 <!-- Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/ -->
 <!doctype html>
 <html lang="en">
   <head>
     <meta charset="utf-8">
     <title>A video element with native event handlers</title>
     <script type="text/javascript">
+      "use strict";
+
       function initialSetup(event) {
         debugger;
       }
 
       window.addEventListener("load", function() {});
     </script>
   </head>
   <body>
--- a/devtools/client/shared/test/helper_workers.js
+++ b/devtools/client/shared/test/helper_workers.js
@@ -63,16 +63,34 @@ function terminateWorkerInTab(tab, url) 
 }
 
 function postMessageToWorkerInTab(tab, url, message) {
   info("Posting message to worker with url '" + url + "' in tab.");
 
   return jsonrpc(tab, "postMessageToWorker", [url, message]);
 }
 
+function generateMouseClickInTab(tab, path) {
+  info("Generating mouse click in tab.");
+
+  return jsonrpc(tab, "generateMouseClick", [path]);
+}
+
+function evalInTab(tab, string) {
+  info("Evalling string in tab.");
+
+  return jsonrpc(tab, "_eval", [string]);
+}
+
+function callInTab(tab, name) {
+  info("Calling function with name '" + name + "' in tab.");
+
+  return jsonrpc(tab, "call", [name, Array.prototype.slice.call(arguments, 2)]);
+}
+
 function connect(client) {
   info("Connecting client.");
   return client.connect();
 }
 
 function close(client) {
   info("Waiting for client to close.\n");
   return client.close();
@@ -113,16 +131,21 @@ function findWorker(workers, url) {
   return null;
 }
 
 function attachWorker(targetFront, worker) {
   info("Attaching to worker with url '" + worker.url + "'.");
   return targetFront.attachWorker(worker.actor);
 }
 
+function waitForWorkerListChanged(targetFront) {
+  info("Waiting for worker list to change.");
+  return targetFront.once("workerListChanged");
+}
+
 function attachThread(workerTargetFront, options) {
   info("Attaching to thread.");
   return workerTargetFront.attachThread(options);
 }
 
 async function waitForWorkerClose(workerTargetFront) {
   info("Waiting for worker to close.");
   await workerTargetFront.once("close");
@@ -216,8 +239,44 @@ this.removeTab = function removeTab(tab,
   tabContainer.addEventListener("TabClose", function() {
     info("Tab removed and finished closing.");
     deferred.resolve();
   }, {once: true});
 
   targetBrowser.removeTab(tab);
   return deferred.promise;
 };
+
+async function attachTargetActorForUrl(client, url) {
+  const grip = await getTargetActorForUrl(client, url);
+  const [ response, front ] = await client.attachTarget(grip.actor);
+  return [grip, response, front];
+}
+
+async function attachThreadActorForUrl(client, url) {
+  const [, response] = await attachTargetActorForUrl(client, url);
+  const [, threadClient] = await client.attachThread(response.threadActor);
+  await threadClient.resume();
+  return threadClient;
+}
+
+function getTargetActorForUrl(client, url) {
+  const deferred = getDeferredPromise().defer();
+
+  client.listTabs().then(response => {
+    const targetActor = response.tabs.filter(grip => grip.url == url).pop();
+    deferred.resolve(targetActor);
+  });
+
+  return deferred.promise;
+}
+
+function pushPrefs(...aPrefs) {
+  const deferred = getDeferredPromise().defer();
+  SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve);
+  return deferred.promise;
+}
+
+function popPrefs() {
+  const deferred = getDeferredPromise().defer();
+  SpecialPowers.popPrefEnv(deferred.resolve);
+  return deferred.promise;
+}