Bug 1314057 - Move worker actor and console tests to shared. r=loganfsmyth
authorDavid Walsh <dwalsh@mozilla.com>
Mon, 08 Oct 2018 20:23:46 -0500
changeset 499024 e7efb5d6d6fdac850042ee5a289e84b124ca1b6a
parent 499023 e3373dae68a52f5960579442ac0782f497717312
child 499025 d0e3cbf73f04bd02cb9e5ef1b4a0c79123d7ae42
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersloganfsmyth
bugs1314057
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1314057 - Move worker actor and console tests to shared. r=loganfsmyth
devtools/client/debugger/test/mochitest/browser2.ini
devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js
devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attachThread.js
devtools/client/debugger/test/mochitest/browser_dbg_worker-console-01.js
devtools/client/debugger/test/mochitest/browser_dbg_worker-console-02.js
devtools/client/debugger/test/mochitest/browser_dbg_worker-console-03.js
devtools/client/debugger/test/mochitest/browser_dbg_worker-console-04.js
devtools/client/shared/test/browser.ini
devtools/client/shared/test/browser_dbg_WorkerTargetActor.attach.js
devtools/client/shared/test/browser_dbg_worker-console-01.js
devtools/client/shared/test/browser_dbg_worker-console-02.js
devtools/client/shared/test/browser_dbg_worker-console-03.js
devtools/client/shared/test/browser_dbg_worker-console-04.js
devtools/client/shared/test/code_WorkerTargetActor.attach-worker1.js
devtools/client/shared/test/code_WorkerTargetActor.attach-worker2.js
devtools/client/shared/test/code_WorkerTargetActor.attachThread-worker.js
devtools/client/shared/test/code_frame-script.js
devtools/client/shared/test/doc_WorkerTargetActor.attach-tab1.html
devtools/client/shared/test/doc_WorkerTargetActor.attach-tab2.html
devtools/client/shared/test/doc_WorkerTargetActor.attachThread-tab.html
devtools/client/shared/test/helper_workers.js
--- a/devtools/client/debugger/test/mochitest/browser2.ini
+++ b/devtools/client/debugger/test/mochitest/browser2.ini
@@ -154,28 +154,16 @@ skip-if = (os == "linux" && debug && bit
 [browser_dbg_sources-bookmarklet.js]
 uses-unsafe-cpows = true
 skip-if = e10s && debug
 [browser_dbg_split-console-paused-reload.js]
 skip-if = true # Bug 1288348 - previously e10s && debug
 [browser_dbg_terminate-on-tab-close.js]
 uses-unsafe-cpows = true
 skip-if = e10s && debug
-[browser_dbg_worker-console-01.js]
-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_worker-source-map.js]
 uses-unsafe-cpows = true
 skip-if = e10s && debug
 [browser_dbg_worker-window.js]
 skip-if = (e10s && debug) || true # Bug 1486974
-[browser_dbg_WorkerTargetActor.attach.js]
-skip-if = e10s && debug
-[browser_dbg_WorkerTargetActor.attachThread.js]
-skip-if = e10s && debug
 [browser_dbg_split-console-keypress.js]
 uses-unsafe-cpows = true
 skip-if = (debug || os == "linux") # Bug 1214439
deleted file mode 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attachThread.js
+++ /dev/null
@@ -1,100 +0,0 @@
-var TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
-var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
-
-function test() {
-  Task.spawn(function* () {
-    DebuggerServer.init();
-    DebuggerServer.registerAllActors();
-
-    let client1 = new DebuggerClient(DebuggerServer.connectPipe());
-    yield connect(client1);
-    let client2 = new DebuggerClient(DebuggerServer.connectPipe());
-    yield connect(client2);
-
-    let tab = yield addTab(TAB_URL);
-    let { tabs: tabs1 } = yield listTabs(client1);
-    let [, tabClient1] = yield attachTarget(client1, findTab(tabs1, TAB_URL));
-    let { tabs: tabs2 } = yield listTabs(client2);
-    let [, tabClient2] = yield attachTarget(client2, findTab(tabs2, TAB_URL));
-
-    yield listWorkers(tabClient1);
-    yield listWorkers(tabClient2);
-    yield createWorkerInTab(tab, WORKER_URL);
-    let { workers: workers1 } = yield listWorkers(tabClient1);
-    let [, workerClient1] = yield attachWorker(tabClient1,
-                                               findWorker(workers1, WORKER_URL));
-    let { workers: workers2 } = yield listWorkers(tabClient2);
-    let [, workerClient2] = yield attachWorker(tabClient2,
-                                               findWorker(workers2, WORKER_URL));
-
-    let location = { line: 5 };
-
-    let [, threadClient1] = yield attachThread(workerClient1);
-    let sources1 = yield getSources(threadClient1);
-    let sourceClient1 = threadClient1.source(findSource(sources1,
-                                                        EXAMPLE_URL + WORKER_URL));
-    let [, breakpointClient1] = yield setBreakpoint(sourceClient1, location);
-    yield resume(threadClient1);
-
-    let [, threadClient2] = yield attachThread(workerClient2);
-    let sources2 = yield getSources(threadClient2);
-    let sourceClient2 = threadClient2.source(findSource(sources2,
-                                                        EXAMPLE_URL + WORKER_URL));
-    let [, breakpointClient2] = yield setBreakpoint(sourceClient2, location);
-    yield resume(threadClient2);
-
-    let packet = yield source(sourceClient1);
-    let text = (yield new Promise(function (resolve) {
-      let request = new XMLHttpRequest();
-      request.open("GET", EXAMPLE_URL + WORKER_URL, true);
-      request.send();
-      request.onload = function () {
-        resolve(request.responseText);
-      };
-    }));
-    is(packet.source, text);
-
-    postMessageToWorkerInTab(tab, WORKER_URL, "ping");
-    yield Promise.all([
-      waitForPause(threadClient1).then((packet) => {
-        is(packet.type, "paused");
-        let why = packet.why;
-        is(why.type, "breakpoint");
-        is(why.actors.length, 1);
-        is(why.actors[0], breakpointClient1.actor);
-        let frame = packet.frame;
-        let where = frame.where;
-        is(where.source.actor, sourceClient1.actor);
-        is(where.line, location.line);
-        let variables = frame.environment.bindings.variables;
-        is(variables.a.value, 1);
-        is(variables.b.value.type, "undefined");
-        is(variables.c.value.type, "undefined");
-        return resume(threadClient1);
-      }),
-      waitForPause(threadClient2).then((packet) => {
-        is(packet.type, "paused");
-        let why = packet.why;
-        is(why.type, "breakpoint");
-        is(why.actors.length, 1);
-        is(why.actors[0], breakpointClient2.actor);
-        let frame = packet.frame;
-        let where = frame.where;
-        is(where.source.actor, sourceClient2.actor);
-        is(where.line, location.line);
-        let variables = frame.environment.bindings.variables;
-        is(variables.a.value, 1);
-        is(variables.b.value.type, "undefined");
-        is(variables.c.value.type, "undefined");
-        return resume(threadClient2);
-      }),
-    ]);
-
-    terminateWorkerInTab(tab, WORKER_URL);
-    yield waitForWorkerClose(workerClient1);
-    yield waitForWorkerClose(workerClient2);
-    yield close(client1);
-    yield close(client2);
-    finish();
-  });
-}
--- a/devtools/client/shared/test/browser.ini
+++ b/devtools/client/shared/test/browser.ini
@@ -1,15 +1,19 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 support-files =
   addon1.xpi
   addon2.xpi
   browser_devices.json
+  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_filter-editor-01.html
   doc_html_tooltip-02.xul
   doc_html_tooltip-03.xul
   doc_html_tooltip-04.xul
@@ -27,22 +31,26 @@ support-files =
   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
+  doc_WorkerTargetActor.attach-tab1.html
+  doc_WorkerTargetActor.attach-tab2.html
+  doc_WorkerTargetActor.attachThread-tab.html
   dummy.html
   frame-script-utils.js
   head.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
   test-actor-registry.js
   test-actor.js
   testactors.js
   !/devtools/client/responsive.html/test/browser/devices.json
@@ -220,9 +228,19 @@ tags = addons
 [browser_dbg_listtabs-02.js]
 skip-if = true # Never worked for remote frames, needs a mock DebuggerServerConnection
 [browser_dbg_listtabs-03.js]
 skip-if = e10s && debug
 [browser_dbg_multiple-windows.js]
 [browser_dbg_navigation.js]
 skip-if = e10s && debug
 [browser_dbg_target-scoped-actor-01.js]
-[browser_dbg_target-scoped-actor-02.js]
\ No newline at end of file
+[browser_dbg_target-scoped-actor-02.js]
+[browser_dbg_worker-console-01.js]
+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
\ No newline at end of file
rename from devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js
rename to devtools/client/shared/test/browser_dbg_WorkerTargetActor.attach.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js
+++ b/devtools/client/shared/test/browser_dbg_WorkerTargetActor.attach.js
@@ -1,29 +1,45 @@
+/* -*- 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";
+
+// Check to make sure that a worker can be attached to a toolbox
+// and that the console works.
+
+// 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 MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
 
 var TAB1_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attach-tab1.html";
 var TAB2_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attach-tab2.html";
 var WORKER1_URL = "code_WorkerTargetActor.attach-worker1.js";
 var WORKER2_URL = "code_WorkerTargetActor.attach-worker2.js";
 
 function test() {
   Task.spawn(function* () {
-    let oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
+    const oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
     SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
 
     DebuggerServer.init();
     DebuggerServer.registerAllActors();
 
-    let client = new DebuggerClient(DebuggerServer.connectPipe());
+    const client = new DebuggerClient(DebuggerServer.connectPipe());
     yield connect(client);
 
-    let tab = yield addTab(TAB1_URL);
-    let { tabs } = yield listTabs(client);
-    let [, tabClient] = yield attachTarget(client, findTab(tabs, TAB1_URL));
+    const tab = yield addTab(TAB1_URL);
+    const { tabs } = yield listTabs(client);
+    const [, tabClient] = yield attachTarget(client, findTab(tabs, TAB1_URL));
     yield listWorkers(tabClient);
 
     // If a page still has pending network requests, it will not be moved into
     // the bfcache. Consequently, we cannot use waitForWorkerListChanged here,
     // because the worker is not guaranteed to have finished loading when it is
     // registered. Instead, we have to wait for the promise returned by
     // createWorker in the tab to be resolved.
     yield createWorkerInTab(tab, WORKER1_URL);
@@ -35,17 +51,17 @@ function test() {
     executeSoon(() => {
       BrowserTestUtils.loadURI(tab.linkedBrowser, TAB2_URL);
     });
     yield waitForWorkerClose(workerClient1);
     is(workerClient1.isClosed, true, "worker in tab 1 should be closed");
 
     yield createWorkerInTab(tab, WORKER2_URL);
     ({ workers } = yield listWorkers(tabClient));
-    let [, workerClient2] = yield attachWorker(tabClient,
+    const [, workerClient2] = yield attachWorker(tabClient,
                                                findWorker(workers, WORKER2_URL));
     is(workerClient2.isClosed, false, "worker in tab 2 should not be closed");
 
     executeSoon(() => {
       tab.linkedBrowser.goBack();
     });
     yield waitForWorkerClose(workerClient2);
     is(workerClient2.isClosed, true, "worker in tab 2 should be closed");
rename from devtools/client/debugger/test/mochitest/browser_dbg_worker-console-01.js
rename to devtools/client/shared/test/browser_dbg_worker-console-01.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_worker-console-01.js
+++ b/devtools/client/shared/test/browser_dbg_worker-console-01.js
@@ -1,20 +1,33 @@
+/* -*- 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";
+
 // Check to make sure that a worker can be attached to a toolbox
 // and that the console works.
 
+// 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 TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
 var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
 
 add_task(async function testNormalExecution() {
-  let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
+  const {client, tab, workerClient, toolbox} =
     await initWorkerDebugger(TAB_URL, WORKER_URL);
 
-  let jsterm = await getSplitConsole(toolbox);
-  let executed = await jsterm.execute("this.location.toString()");
+  const jsterm = await getSplitConsole(toolbox);
+  const executed = await jsterm.execute("this.location.toString()");
   ok(executed.textContent.includes(WORKER_URL),
       "Evaluating the global's location works");
 
   terminateWorkerInTab(tab, WORKER_URL);
   await waitForWorkerClose(workerClient);
   await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
   await close(client);
   await removeTab(tab);
rename from devtools/client/debugger/test/mochitest/browser_dbg_worker-console-02.js
rename to devtools/client/shared/test/browser_dbg_worker-console-02.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_worker-console-02.js
+++ b/devtools/client/shared/test/browser_dbg_worker-console-02.js
@@ -1,58 +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";
+
 // Check to make sure that a worker can be attached to a toolbox
 // and that the console works.
 
+// 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 TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
 var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
 
 add_task(async function testWhilePaused() {
-  let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
-    await initWorkerDebugger(TAB_URL, WORKER_URL);
-
-  let gTarget = gDebugger.gTarget;
-  let gResumeButton = gDebugger.document.getElementById("resume");
-  let gResumeKey = gDebugger.document.getElementById("resumeKey");
+  const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
+  const {client, tab, workerClient, toolbox} = dbg;
 
   // Execute some basic math to make sure evaluations are working.
-  let jsterm = await getSplitConsole(toolbox);
+  const jsterm = await getSplitConsole(toolbox);
   let executed = await jsterm.execute("10000+1");
   ok(executed.textContent.includes("10001"), "Text for message appeared correct");
 
-  // Pause the worker by waiting for next execution and then sending a message to
-  // it from the main thread.
-  let oncePaused = gTarget.once("thread-paused");
-  EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
-  once(gDebugger.gClient, "willInterrupt").then(() => {
+  await clickElement(dbg, "pause");
+  once(dbg.client, "willInterrupt").then(() => {
     info("Posting message to worker, then waiting for a pause");
     postMessageToWorkerInTab(tab, WORKER_URL, "ping");
   });
-  await oncePaused;
+  await waitForPaused(dbg);
 
-  let command1 = jsterm.execute("10000+2");
-  let command2 = jsterm.execute("10000+3");
-  let command3 = jsterm.execute("foobar"); // throw an error
+  const command1 = jsterm.execute("10000+2");
+  const command2 = jsterm.execute("10000+3");
+  const command3 = jsterm.execute("foobar"); // throw an error
 
   info("Trying to get the result of command1");
   executed = await command1;
   ok(executed.textContent.includes("10002"),
       "command1 executed successfully");
 
   info("Trying to get the result of command2");
   executed = await command2;
   ok(executed.textContent.includes("10003"),
       "command2 executed successfully");
 
   info("Trying to get the result of command3");
   executed = await command3;
   ok(executed.textContent.includes("ReferenceError: foobar is not defined"),
      "command3 executed successfully");
 
-  let onceResumed = gTarget.once("thread-resumed");
-  EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
-  await onceResumed;
+  await resume(dbg);
 
   terminateWorkerInTab(tab, WORKER_URL);
   await waitForWorkerClose(workerClient);
   await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
   await close(client);
   await removeTab(tab);
 });
rename from devtools/client/debugger/test/mochitest/browser_dbg_worker-console-03.js
rename to devtools/client/shared/test/browser_dbg_worker-console-03.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_worker-console-03.js
+++ b/devtools/client/shared/test/browser_dbg_worker-console-03.js
@@ -1,43 +1,50 @@
+/* -*- 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";
+
 // Check to make sure that a worker can be attached to a toolbox
 // and that the console works.
 
+// 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 TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
 var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
 
 // Test to see if creating the pause from the console works.
 add_task(async function testPausedByConsole() {
-  let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
-    await initWorkerDebugger(TAB_URL, WORKER_URL);
+  const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
+  const {client, tab, workerClient, toolbox} = dbg;
 
-  let gTarget = gDebugger.gTarget;
-  let gResumeButton = gDebugger.document.getElementById("resume");
-  let gResumeKey = gDebugger.document.getElementById("resumeKey");
-
-  let jsterm = await getSplitConsole(toolbox);
+  const jsterm = await getSplitConsole(toolbox);
   let executed = await jsterm.execute("10000+1");
   ok(executed.textContent.includes("10001"),
       "Text for message appeared correct");
 
-  let oncePaused = gTarget.once("thread-paused");
-  EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
-  let pausedExecution = jsterm.execute("10000+2");
+  await clickElement(dbg, "pause");
+
+  const pausedExecution = jsterm.execute("10000+2");
 
   info("Executed a command with 'break on next' active, waiting for pause");
-  await oncePaused;
+  await waitForPaused(dbg);
 
   executed = await jsterm.execute("10000+3");
   ok(executed.textContent.includes("10003"),
       "Text for message appeared correct");
 
   info("Waiting for a resume");
-  let onceResumed = gTarget.once("thread-resumed");
-  EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
-  await onceResumed;
+  await clickElement(dbg, "resume");
 
   executed = await pausedExecution;
   ok(executed.textContent.includes("10002"),
       "Text for message appeared correct");
 
   terminateWorkerInTab(tab, WORKER_URL);
   await waitForWorkerClose(workerClient);
   await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
rename from devtools/client/debugger/test/mochitest/browser_dbg_worker-console-04.js
rename to devtools/client/shared/test/browser_dbg_worker-console-04.js
--- a/devtools/client/debugger/test/mochitest/browser_dbg_worker-console-04.js
+++ b/devtools/client/shared/test/browser_dbg_worker-console-04.js
@@ -1,26 +1,42 @@
+/* -*- 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";
+
+// Check to make sure that a worker can be attached to a toolbox
+// and that the console works.
+
+// 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);
+
 // Check that the date and regexp previewers work in the console of a worker debugger.
 
 "use strict";
 
 // There are shutdown issues for which multiple rejections are left uncaught.
 // See bug 1018184 for resolving these issues.
 const { PromiseTestUtils } = scopedCuImport("resource://testing-common/PromiseTestUtils.jsm");
 PromiseTestUtils.whitelistRejectionsGlobally(/connection just closed/);
 
 const TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
 const WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
 
 add_task(async function testPausedByConsole() {
-  let {client, tab, workerClient, toolbox} =
+  const {client, tab, workerClient, toolbox} =
     await initWorkerDebugger(TAB_URL, WORKER_URL);
 
   info("Check Date objects can be used in the console");
-  let jsterm = await getSplitConsole(toolbox);
+  const jsterm = await getSplitConsole(toolbox);
   let executed = await jsterm.execute("new Date(0)");
   ok(executed.textContent.includes("1970-01-01T00:00:00.000Z"),
       "Text for message appeared correct");
 
   info("Check RegExp objects can be used in the console");
   executed = await jsterm.execute("new RegExp('.*')");
   ok(executed.textContent.includes("/.*/"),
       "Text for message appeared correct");
copy from devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker1.js
copy to devtools/client/shared/test/code_WorkerTargetActor.attach-worker1.js
--- a/devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker1.js
+++ b/devtools/client/shared/test/code_WorkerTargetActor.attach-worker1.js
@@ -1,5 +1,5 @@
 "use strict";
 
-self.onmessage = function () {};
+self.onmessage = function() {};
 
 postMessage("load");
copy from devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker2.js
copy to devtools/client/shared/test/code_WorkerTargetActor.attach-worker2.js
--- a/devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker2.js
+++ b/devtools/client/shared/test/code_WorkerTargetActor.attach-worker2.js
@@ -1,5 +1,5 @@
 "use strict";
 
-self.onmessage = function () {};
+self.onmessage = function() {};
 
 postMessage("load");
copy from devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attachThread-worker.js
copy to devtools/client/shared/test/code_WorkerTargetActor.attachThread-worker.js
--- a/devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attachThread-worker.js
+++ b/devtools/client/shared/test/code_WorkerTargetActor.attachThread-worker.js
@@ -1,16 +1,18 @@
 "use strict";
 
 function f() {
-  var a = 1;
-  var b = 2;
-  var c = 3;
+  const a = 1;
+  const b = 2;
+  const c = 3;
+
+  return [a, b, c];
 }
 
-self.onmessage = function (event) {
+self.onmessage = function(event) {
   if (event.data == "ping") {
     f();
     postMessage("pong");
   }
 };
 
 postMessage("load");
copy from devtools/client/debugger/test/mochitest/code_frame-script.js
copy to devtools/client/shared/test/code_frame-script.js
--- a/devtools/client/debugger/test/mochitest/code_frame-script.js
+++ b/devtools/client/shared/test/code_frame-script.js
@@ -1,102 +1,105 @@
+/* eslint-disable */
 "use strict";
 
 const { loadSubScript } = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                           getService(Ci.mozIJSSubScriptLoader);
 
 // Set up a dummy environment so that EventUtils works. We need to be careful to
 // pass a window object into each EventUtils method we call rather than having
 // it rely on the |window| global.
-let EventUtils = {};
+const EventUtils = {};
 EventUtils.window = content;
 EventUtils.parent = EventUtils.window;
 EventUtils._EU_Ci = Ci;
 EventUtils._EU_Cc = Cc;
 EventUtils.navigator = content.navigator;
 EventUtils.KeyboardEvent = content.KeyboardEvent;
 loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
 
 dump("Frame script loaded.\n");
 
 var workers = {};
 
-this.call = function (name, args) {
+this.call = function(name, args) {
   dump("Calling function with name " + name + ".\n");
 
   dump("args " + JSON.stringify(args) + "\n");
-  return XPCNativeWrapper.unwrap(content)[name].apply(undefined, Cu.cloneInto(args, content));
+  return XPCNativeWrapper
+    .unwrap(content)[name]
+    .apply(undefined, Cu.cloneInto(args, content));
 };
 
-this._eval = function (string) {
+this._eval = function(string) {
   dump("Evalling string.\n");
 
   return content.eval(string);
 };
 
-this.generateMouseClick = function (path) {
+this.generateMouseClick = function(path) {
   dump("Generating mouse click.\n");
 
-  let target = eval(path);
+  const target = eval(path);
   EventUtils.synthesizeMouseAtCenter(target, {},
                                      target.ownerDocument.defaultView);
 };
 
-this.createWorker = function (url) {
+this.createWorker = function(url) {
   dump("Creating worker with url '" + url + "'.\n");
 
-  return new Promise(function (resolve, reject) {
-    let worker = new content.Worker(url);
-    worker.addEventListener("message", function () {
+  return new Promise(function(resolve, reject) {
+    const worker = new content.Worker(url);
+    worker.addEventListener("message", function() {
       workers[url] = worker;
       resolve();
     }, {once: true});
   });
 };
 
-this.terminateWorker = function (url) {
+this.terminateWorker = function(url) {
   dump("Terminating worker with url '" + url + "'.\n");
 
   workers[url].terminate();
   delete workers[url];
 };
 
-this.postMessageToWorker = function (url, message) {
+this.postMessageToWorker = function(url, message) {
   dump("Posting message to worker with url '" + url + "'.\n");
 
-  return new Promise(function (resolve) {
-    let worker = workers[url];
+  return new Promise(function(resolve) {
+    const worker = workers[url];
     worker.postMessage(message);
-    worker.addEventListener("message", function () {
+    worker.addEventListener("message", function() {
       resolve();
     }, {once: true});
   });
 };
 
-addMessageListener("jsonrpc", function ({ data: { method, params, id } }) {
+addMessageListener("jsonrpc", function({ data: { method, params, id } }) {
   method = this[method];
-  Promise.resolve().then(function () {
+  Promise.resolve().then(function() {
     return method.apply(undefined, params);
-  }).then(function (result) {
+  }).then(function(result) {
     sendAsyncMessage("jsonrpc", {
       result: result,
       error: null,
       id: id
     });
-  }, function (error) {
+  }, function(error) {
     sendAsyncMessage("jsonrpc", {
       result: null,
       error: error.message.toString(),
       id: id
     });
   });
 });
 
-addMessageListener("test:postMessageToWorker", function (message) {
+addMessageListener("test:postMessageToWorker", function(message) {
   dump("Posting message '" + message.data.message + "' to worker with url '" +
        message.data.url + "'.\n");
 
   let worker = workers[message.data.url];
   worker.postMessage(message.data.message);
-  worker.addEventListener("message", function () {
+  worker.addEventListener("message", function() {
     sendAsyncMessage("test:postMessageToWorker");
   }, {once: true});
 });
copy from devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attach-tab1.html
copy to devtools/client/shared/test/doc_WorkerTargetActor.attach-tab1.html
copy from devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attach-tab2.html
copy to devtools/client/shared/test/doc_WorkerTargetActor.attach-tab2.html
copy from devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attachThread-tab.html
copy to devtools/client/shared/test/doc_WorkerTargetActor.attachThread-tab.html
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/test/helper_workers.js
@@ -0,0 +1,227 @@
+/* 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";
+
+/* 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;
+
+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) {
+    const currentId = nextId++;
+    const messageManager = tab.linkedBrowser.messageManager;
+    messageManager.sendAsyncMessage("jsonrpc", {
+      method: method,
+      params: params,
+      id: currentId
+    });
+    messageManager.addMessageListener("jsonrpc", function listener(res) {
+      const { data: { result, error, id } } = res;
+      if (id !== currentId) {
+        return;
+      }
+
+      messageManager.removeMessageListener("jsonrpc", listener);
+      if (error != null) {
+        reject(error);
+      }
+
+      resolve(result);
+    });
+  });
+}
+
+function createWorkerInTab(tab, url) {
+  info("Creating worker with url '" + url + "' in tab.");
+
+  return jsonrpc(tab, "createWorker", [url]);
+}
+
+function terminateWorkerInTab(tab, url) {
+  info("Terminating worker with url '" + url + "' in tab.");
+
+  return jsonrpc(tab, "terminateWorker", [url]);
+}
+
+function postMessageToWorkerInTab(tab, url, message) {
+  info("Posting message to worker with url '" + url + "' in tab.");
+
+  return jsonrpc(tab, "postMessageToWorker", [url, message]);
+}
+
+function connect(client) {
+  info("Connecting client.");
+  return client.connect();
+}
+
+function close(client) {
+  info("Waiting for client to close.\n");
+  return client.close();
+}
+
+function listTabs(client) {
+  info("Listing tabs.");
+  return client.listTabs();
+}
+
+function findTab(tabs, url) {
+  info("Finding tab with url '" + url + "'.");
+  for (const tab of tabs) {
+    if (tab.url === url) {
+      return tab;
+    }
+  }
+  return null;
+}
+
+function attachTarget(client, tab) {
+  info("Attaching to tab with url '" + tab.url + "'.");
+  return client.attachTarget(tab.actor);
+}
+
+function listWorkers(tabClient) {
+  info("Listing workers.");
+  return tabClient.listWorkers();
+}
+
+function findWorker(workers, url) {
+  info("Finding worker with url '" + url + "'.");
+  for (const worker of workers) {
+    if (worker.url === url) {
+      return worker;
+    }
+  }
+  return null;
+}
+
+function attachWorker(tabClient, worker) {
+  info("Attaching to worker with url '" + worker.url + "'.");
+  return tabClient.attachWorker(worker.actor);
+}
+
+function attachThread(workerClient, options) {
+  info("Attaching to thread.");
+  return workerClient.attachThread(options);
+}
+
+function waitForWorkerClose(workerClient) {
+  info("Waiting for worker to close.");
+  return new Promise(function(resolve) {
+    workerClient.addOneTimeListener("close", function() {
+      info("Worker did close.");
+      resolve();
+    });
+  });
+}
+
+// Return a promise with a reference to jsterm, opening the split
+// console if necessary.  This cleans up the split console pref so
+// it won't pollute other tests.
+function getSplitConsole(toolbox, win) {
+  if (!win) {
+    win = toolbox.win;
+  }
+
+  if (!toolbox.splitConsole) {
+    EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
+  }
+
+  return new Promise(resolve => {
+    toolbox.getPanelWhenReady("webconsole").then(() => {
+      ok(toolbox.splitConsole, "Split console is shown.");
+      const jsterm = toolbox.getPanel("webconsole").hud.jsterm;
+      resolve(jsterm);
+    });
+  });
+}
+
+async function initWorkerDebugger(TAB_URL, WORKER_URL) {
+  DebuggerServer.init();
+  DebuggerServer.registerAllActors();
+
+  const client = new DebuggerClient(DebuggerServer.connectPipe());
+  await connect(client);
+
+  const tab = await addTab(TAB_URL);
+  const { tabs } = await listTabs(client);
+  const [, tabClient] = await attachTarget(client, findTab(tabs, TAB_URL));
+
+  await createWorkerInTab(tab, WORKER_URL);
+
+  const { workers } = await listWorkers(tabClient);
+  const [, workerClient] = await attachWorker(tabClient,
+                                             findWorker(workers, WORKER_URL));
+
+  const toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
+                                            "jsdebugger",
+                                            Toolbox.HostType.WINDOW);
+
+  const debuggerPanel = toolbox.getCurrentPanel();
+
+  const gDebugger = debuggerPanel.panelWin;
+
+  const context = createDebuggerContext(toolbox);
+
+  return { ...context, client, tab, tabClient, workerClient, toolbox, gDebugger};
+}
+
+// Override addTab/removeTab as defined by shared-head, since these have
+// an extra window parameter and add a frame script
+this.addTab = function addTab(url, win) {
+  info("Adding tab: " + url);
+
+  const deferred = getDeferredPromise().defer();
+  const targetWindow = win || window;
+  const targetBrowser = targetWindow.gBrowser;
+
+  targetWindow.focus();
+  const tab = targetBrowser.selectedTab = BrowserTestUtils.addTab(targetBrowser, url);
+  const linkedBrowser = tab.linkedBrowser;
+
+  info("Loading frame script with url " + FRAME_SCRIPT_URL + ".");
+  linkedBrowser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
+
+  BrowserTestUtils.browserLoaded(linkedBrowser)
+    .then(function() {
+      info("Tab added and finished loading: " + url);
+      deferred.resolve(tab);
+    });
+
+  return deferred.promise;
+};
+
+this.removeTab = function removeTab(tab, win) {
+  info("Removing tab.");
+
+  const deferred = getDeferredPromise().defer();
+  const targetWindow = win || window;
+  const targetBrowser = targetWindow.gBrowser;
+  const tabContainer = targetBrowser.tabContainer;
+
+  tabContainer.addEventListener("TabClose", function() {
+    info("Tab removed and finished closing.");
+    deferred.resolve();
+  }, {once: true});
+
+  targetBrowser.removeTab(tab);
+  return deferred.promise;
+};