зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1808574 - [devtools] Migrate old worker test to about:debugging test. r=jdescottes
This will help remove a few callsites still spawning toolboxes for regular workers. Only service workers and chrome/parent process workers can be debugged independantly, in a dedicated toolbox. That, only from about:debugging, by opening a toolbox in a tab. Differential Revision: https://phabricator.services.mozilla.com/D165977
This commit is contained in:
Родитель
6ca7c21da2
Коммит
714cfde67b
|
@ -122,6 +122,8 @@ support-files =
|
||||||
[browser_aboutdebugging_runtime_usbclient_closed.js]
|
[browser_aboutdebugging_runtime_usbclient_closed.js]
|
||||||
[browser_aboutdebugging_select_network_runtime.js]
|
[browser_aboutdebugging_select_network_runtime.js]
|
||||||
[browser_aboutdebugging_select_page_with_serviceworker.js]
|
[browser_aboutdebugging_select_page_with_serviceworker.js]
|
||||||
|
[browser_aboutdebugging_serviceworker_console.js]
|
||||||
|
https_first_disabled = true
|
||||||
[browser_aboutdebugging_serviceworker_fetch_flag.js]
|
[browser_aboutdebugging_serviceworker_fetch_flag.js]
|
||||||
https_first_disabled = true
|
https_first_disabled = true
|
||||||
skip-if =
|
skip-if =
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* import-globals-from helper-serviceworker.js */
|
||||||
|
Services.scriptloader.loadSubScript(
|
||||||
|
CHROME_URL_ROOT + "helper-serviceworker.js",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
/* import-globals-from ../../../debugger/test/mochitest/shared-head.js */
|
||||||
|
Services.scriptloader.loadSubScript(
|
||||||
|
"chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/shared-head.js",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
const SW_TAB_URL = URL_ROOT + "resources/service-workers/controlled-sw.html";
|
||||||
|
const SW_URL = URL_ROOT + "resources/service-workers/controlled-sw.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test various simple debugging operation against service workers debugged through about:debugging.
|
||||||
|
*/
|
||||||
|
add_task(async function() {
|
||||||
|
await enableServiceWorkerDebugging();
|
||||||
|
|
||||||
|
const { document, tab, window } = await openAboutDebugging({
|
||||||
|
enableWorkerUpdates: true,
|
||||||
|
});
|
||||||
|
await selectThisFirefoxPage(document, window.AboutDebugging.store);
|
||||||
|
|
||||||
|
// Open a tab that registers a basic service worker.
|
||||||
|
const swTab = await addTab(SW_TAB_URL);
|
||||||
|
|
||||||
|
// Wait for the registration to make sure service worker has been started, and that we
|
||||||
|
// are not just reading STOPPED as the initial state.
|
||||||
|
await waitForRegistration(swTab);
|
||||||
|
|
||||||
|
info("Open a toolbox to debug the worker");
|
||||||
|
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
|
||||||
|
document,
|
||||||
|
tab,
|
||||||
|
window,
|
||||||
|
SW_URL
|
||||||
|
);
|
||||||
|
|
||||||
|
const toolbox = getToolbox(devtoolsWindow);
|
||||||
|
|
||||||
|
info("Assert the default tools displayed in worker toolboxes");
|
||||||
|
const toolTabs = toolbox.doc.querySelectorAll(".devtools-tab");
|
||||||
|
const activeTools = [...toolTabs].map(toolTab =>
|
||||||
|
toolTab.getAttribute("data-id")
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
activeTools.join(","),
|
||||||
|
"webconsole,jsdebugger",
|
||||||
|
"Correct set of tools supported by worker"
|
||||||
|
);
|
||||||
|
|
||||||
|
const webconsole = await toolbox.selectTool("webconsole");
|
||||||
|
const { hud } = webconsole;
|
||||||
|
|
||||||
|
info("Evaluate location in the console");
|
||||||
|
await executeAndWaitForMessage(hud, "this.location.toString()", SW_URL);
|
||||||
|
ok(true, "Got the location logged in the console");
|
||||||
|
|
||||||
|
info(
|
||||||
|
"Evaluate Date and RegExp to ensure their formater also work from worker threads"
|
||||||
|
);
|
||||||
|
await executeAndWaitForMessage(
|
||||||
|
hud,
|
||||||
|
"new Date(2013, 3, 1)",
|
||||||
|
"Mon Apr 01 2013 00:00:00"
|
||||||
|
);
|
||||||
|
ok(true, "Date object has expected text content");
|
||||||
|
await executeAndWaitForMessage(hud, "new RegExp('.*')", "/.*/");
|
||||||
|
ok(true, "RegExp has expected text content");
|
||||||
|
|
||||||
|
await toolbox.selectTool("jsdebugger");
|
||||||
|
const dbg = createDebuggerContext(toolbox);
|
||||||
|
const {
|
||||||
|
selectors: { getIsWaitingOnBreak, getCurrentThread },
|
||||||
|
} = dbg;
|
||||||
|
|
||||||
|
info("Wait for next interupt in the worker thread");
|
||||||
|
await clickElement(dbg, "pause");
|
||||||
|
await waitForState(dbg, state => getIsWaitingOnBreak(getCurrentThread()));
|
||||||
|
|
||||||
|
info("Trigger some code in the worker and wait for pause");
|
||||||
|
await SpecialPowers.spawn(swTab.linkedBrowser, [], async function() {
|
||||||
|
content.wrappedJSObject.installServiceWorker();
|
||||||
|
});
|
||||||
|
await waitForPaused(dbg);
|
||||||
|
ok(true, "successfully paused");
|
||||||
|
|
||||||
|
info(
|
||||||
|
"Evaluate some variable only visible if we execute in the breakpoint frame"
|
||||||
|
);
|
||||||
|
await executeAndWaitForMessage(hud, "event.data", "install-service-worker");
|
||||||
|
|
||||||
|
info("Resume execution");
|
||||||
|
await resume(dbg);
|
||||||
|
|
||||||
|
info("Test pausing from console evaluation");
|
||||||
|
hud.ui.wrapper.dispatchEvaluateExpression("debugger; 42");
|
||||||
|
await waitForPaused(dbg);
|
||||||
|
ok(true, "successfully paused");
|
||||||
|
info("Immediately resume");
|
||||||
|
await resume(dbg);
|
||||||
|
await waitFor(() => findMessagesByType(hud, "42", ".result"));
|
||||||
|
ok("The paused console evaluation resumed and logged its magic number");
|
||||||
|
|
||||||
|
info("Destroy the toolbox");
|
||||||
|
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
|
||||||
|
|
||||||
|
info("Unregister service worker");
|
||||||
|
await unregisterServiceWorker(swTab);
|
||||||
|
|
||||||
|
info("Wait until the service worker disappears from about:debugging");
|
||||||
|
await waitUntil(() => !findDebugTargetByText(SW_URL, document));
|
||||||
|
|
||||||
|
info("Remove tabs");
|
||||||
|
await removeTab(swTab);
|
||||||
|
await removeTab(tab);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function executeAndWaitForMessage(hud, evaluationString, expectedResult) {
|
||||||
|
hud.ui.wrapper.dispatchEvaluateExpression();
|
||||||
|
await waitFor(() => findMessagesByType(hud, expectedResult, ".result"));
|
||||||
|
}
|
|
@ -43,7 +43,6 @@ support-files =
|
||||||
helper_color_data.js
|
helper_color_data.js
|
||||||
helper_html_tooltip.js
|
helper_html_tooltip.js
|
||||||
helper_inplace_editor.js
|
helper_inplace_editor.js
|
||||||
helper_workers.js
|
|
||||||
highlighter-test-actor.js
|
highlighter-test-actor.js
|
||||||
leakhunt.js
|
leakhunt.js
|
||||||
shared-head.js
|
shared-head.js
|
||||||
|
@ -206,11 +205,3 @@ skip-if = debug
|
||||||
skip-if = debug
|
skip-if = debug
|
||||||
[browser_dbg_target-scoped-actor-01.js]
|
[browser_dbg_target-scoped-actor-01.js]
|
||||||
[browser_dbg_target-scoped-actor-02.js]
|
[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 = debug
|
|
||||||
[browser_dbg_worker-console-03.js]
|
|
||||||
skip-if = debug # bug 1334683
|
|
||||||
[browser_dbg_worker-console-04.js]
|
|
||||||
skip-if = debug
|
|
||||||
|
|
|
@ -9,13 +9,6 @@ registerCleanupFunction(() => {
|
||||||
Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
|
Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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_listworkers-tab.html";
|
var TAB_URL = EXAMPLE_URL + "doc_listworkers-tab.html";
|
||||||
var WORKER1_URL = "code_listworkers-worker1.js";
|
var WORKER1_URL = "code_listworkers-worker1.js";
|
||||||
var WORKER2_URL = "code_listworkers-worker2.js";
|
var WORKER2_URL = "code_listworkers-worker2.js";
|
||||||
|
@ -27,38 +20,42 @@ add_task(async function test() {
|
||||||
let { workers } = await listWorkers(target);
|
let { workers } = await listWorkers(target);
|
||||||
is(workers.length, 0);
|
is(workers.length, 0);
|
||||||
|
|
||||||
executeSoon(() => {
|
let onWorkerListChanged = waitForWorkerListChanged(target);
|
||||||
evalInTab(tab, "var worker1 = new Worker('" + WORKER1_URL + "');");
|
await SpecialPowers.spawn(tab.linkedBrowser, [WORKER1_URL], workerUrl => {
|
||||||
|
content.worker1 = new content.Worker(workerUrl);
|
||||||
});
|
});
|
||||||
await waitForWorkerListChanged(target);
|
await onWorkerListChanged;
|
||||||
|
|
||||||
({ workers } = await listWorkers(target));
|
({ workers } = await listWorkers(target));
|
||||||
is(workers.length, 1);
|
is(workers.length, 1);
|
||||||
is(workers[0].url, WORKER1_URL);
|
is(workers[0].url, WORKER1_URL);
|
||||||
|
|
||||||
executeSoon(() => {
|
onWorkerListChanged = waitForWorkerListChanged(target);
|
||||||
evalInTab(tab, "var worker2 = new Worker('" + WORKER2_URL + "');");
|
await SpecialPowers.spawn(tab.linkedBrowser, [WORKER2_URL], workerUrl => {
|
||||||
|
content.worker2 = new content.Worker(workerUrl);
|
||||||
});
|
});
|
||||||
await waitForWorkerListChanged(target);
|
await onWorkerListChanged;
|
||||||
|
|
||||||
({ workers } = await listWorkers(target));
|
({ workers } = await listWorkers(target));
|
||||||
is(workers.length, 2);
|
is(workers.length, 2);
|
||||||
is(workers[0].url, WORKER1_URL);
|
is(workers[0].url, WORKER1_URL);
|
||||||
is(workers[1].url, WORKER2_URL);
|
is(workers[1].url, WORKER2_URL);
|
||||||
|
|
||||||
executeSoon(() => {
|
onWorkerListChanged = waitForWorkerListChanged(target);
|
||||||
evalInTab(tab, "worker1.terminate()");
|
await SpecialPowers.spawn(tab.linkedBrowser, [WORKER2_URL], workerUrl => {
|
||||||
|
content.worker1.terminate();
|
||||||
});
|
});
|
||||||
await waitForWorkerListChanged(target);
|
await onWorkerListChanged;
|
||||||
|
|
||||||
({ workers } = await listWorkers(target));
|
({ workers } = await listWorkers(target));
|
||||||
is(workers.length, 1);
|
is(workers.length, 1);
|
||||||
is(workers[0].url, WORKER2_URL);
|
is(workers[0].url, WORKER2_URL);
|
||||||
|
|
||||||
executeSoon(() => {
|
onWorkerListChanged = waitForWorkerListChanged(target);
|
||||||
evalInTab(tab, "worker2.terminate()");
|
await SpecialPowers.spawn(tab.linkedBrowser, [WORKER2_URL], workerUrl => {
|
||||||
|
content.worker2.terminate();
|
||||||
});
|
});
|
||||||
await waitForWorkerListChanged(target);
|
await onWorkerListChanged;
|
||||||
|
|
||||||
({ workers } = await listWorkers(target));
|
({ workers } = await listWorkers(target));
|
||||||
is(workers.length, 0);
|
is(workers.length, 0);
|
||||||
|
@ -66,3 +63,13 @@ add_task(async function test() {
|
||||||
await target.destroy();
|
await target.destroy();
|
||||||
finish();
|
finish();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function listWorkers(targetFront) {
|
||||||
|
info("Listing workers.");
|
||||||
|
return targetFront.listWorkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForWorkerListChanged(targetFront) {
|
||||||
|
info("Waiting for worker list to change.");
|
||||||
|
return targetFront.once("workerListChanged");
|
||||||
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* 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() {
|
|
||||||
const {
|
|
||||||
client,
|
|
||||||
tab,
|
|
||||||
workerDescriptorFront,
|
|
||||||
toolbox,
|
|
||||||
} = await initWorkerDebugger(TAB_URL, WORKER_URL);
|
|
||||||
|
|
||||||
const hud = await getSplitConsole(toolbox);
|
|
||||||
await executeAndWaitForMessage(hud, "this.location.toString()", WORKER_URL);
|
|
||||||
ok(true, "Evaluating the global's location works");
|
|
||||||
|
|
||||||
terminateWorkerInTab(tab, WORKER_URL);
|
|
||||||
await waitForWorkerClose(workerDescriptorFront);
|
|
||||||
await toolbox.destroy();
|
|
||||||
await close(client);
|
|
||||||
await removeTab(tab);
|
|
||||||
});
|
|
|
@ -1,70 +0,0 @@
|
||||||
/* 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() {
|
|
||||||
const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
|
|
||||||
const { client, tab, workerDescriptorFront, toolbox } = dbg;
|
|
||||||
const {
|
|
||||||
selectors: { getIsWaitingOnBreak, getCurrentThread },
|
|
||||||
} = dbg;
|
|
||||||
|
|
||||||
await waitForSourcesInSourceTree(dbg, [WORKER_URL]);
|
|
||||||
|
|
||||||
// Execute some basic math to make sure evaluations are working.
|
|
||||||
const hud = await getSplitConsole(toolbox);
|
|
||||||
await executeAndWaitForMessage(hud, "10000+1", "10001");
|
|
||||||
ok(true, "Text for message appeared correct");
|
|
||||||
|
|
||||||
await clickElement(dbg, "pause");
|
|
||||||
await waitForState(dbg, state => getIsWaitingOnBreak(getCurrentThread()));
|
|
||||||
|
|
||||||
info("Posting message to worker, then waiting for a pause");
|
|
||||||
postMessageToWorkerInTab(tab, WORKER_URL, "ping");
|
|
||||||
|
|
||||||
await waitForPaused(dbg);
|
|
||||||
|
|
||||||
const command1 = executeAndWaitForMessage(hud, "10000+2", "10002");
|
|
||||||
const command2 = executeAndWaitForMessage(hud, "10000+3", "10003");
|
|
||||||
// throw an error
|
|
||||||
const command3 = executeAndWaitForMessage(
|
|
||||||
hud,
|
|
||||||
"foobar",
|
|
||||||
"ReferenceError: foobar is not defined",
|
|
||||||
"error"
|
|
||||||
);
|
|
||||||
|
|
||||||
info("Trying to get the result of command1");
|
|
||||||
let executed = await command1;
|
|
||||||
ok(executed, "command1 executed successfully");
|
|
||||||
|
|
||||||
info("Trying to get the result of command2");
|
|
||||||
executed = await command2;
|
|
||||||
ok(executed, "command2 executed successfully");
|
|
||||||
|
|
||||||
info("Trying to get the result of command3");
|
|
||||||
executed = await command3;
|
|
||||||
ok(executed, "command3 executed successfully");
|
|
||||||
|
|
||||||
await resume(dbg);
|
|
||||||
|
|
||||||
terminateWorkerInTab(tab, WORKER_URL);
|
|
||||||
await waitForWorkerClose(workerDescriptorFront);
|
|
||||||
await toolbox.destroy();
|
|
||||||
await close(client);
|
|
||||||
await removeTab(tab);
|
|
||||||
});
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* 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() {
|
|
||||||
const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
|
|
||||||
const { client, tab, workerDescriptorFront, toolbox } = dbg;
|
|
||||||
|
|
||||||
const console = await getSplitConsole(toolbox);
|
|
||||||
let executed = await executeAndWaitForMessage(console, "10000+1", "10001");
|
|
||||||
ok(executed, "Text for message appeared correct");
|
|
||||||
|
|
||||||
await clickElement(dbg, "pause");
|
|
||||||
|
|
||||||
const pausedExecution = executeAndWaitForMessage(console, "10000+2", "10002");
|
|
||||||
|
|
||||||
info("Executed a command with 'break on next' active, waiting for pause");
|
|
||||||
await waitForPaused(dbg);
|
|
||||||
|
|
||||||
executed = await executeAndWaitForMessage(console, "10000+3", "10003");
|
|
||||||
ok(executed, "Text for message appeared correct");
|
|
||||||
|
|
||||||
info("Waiting for a resume");
|
|
||||||
await clickElement(dbg, "resume");
|
|
||||||
|
|
||||||
executed = await pausedExecution;
|
|
||||||
ok(executed, "Text for message appeared correct");
|
|
||||||
|
|
||||||
terminateWorkerInTab(tab, WORKER_URL);
|
|
||||||
await waitForWorkerClose(workerDescriptorFront);
|
|
||||||
await toolbox.destroy();
|
|
||||||
await close(client);
|
|
||||||
await removeTab(tab);
|
|
||||||
});
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* 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.
|
|
||||||
PromiseTestUtils.allowMatchingRejectionsGlobally(/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() {
|
|
||||||
const {
|
|
||||||
client,
|
|
||||||
tab,
|
|
||||||
workerDescriptorFront,
|
|
||||||
toolbox,
|
|
||||||
} = await initWorkerDebugger(TAB_URL, WORKER_URL);
|
|
||||||
|
|
||||||
info("Check Date objects can be used in the console");
|
|
||||||
const console = await getSplitConsole(toolbox);
|
|
||||||
let executed = await executeAndWaitForMessage(
|
|
||||||
console,
|
|
||||||
"new Date(2013, 3, 1)",
|
|
||||||
"Mon Apr 01 2013 00:00:00"
|
|
||||||
);
|
|
||||||
ok(executed, "Date object has expected text content");
|
|
||||||
|
|
||||||
info("Check RegExp objects can be used in the console");
|
|
||||||
executed = await executeAndWaitForMessage(
|
|
||||||
console,
|
|
||||||
"new RegExp('.*')",
|
|
||||||
"/.*/"
|
|
||||||
);
|
|
||||||
ok(executed, "Text for message appeared correct");
|
|
||||||
|
|
||||||
terminateWorkerInTab(tab, WORKER_URL);
|
|
||||||
await waitForWorkerClose(workerDescriptorFront);
|
|
||||||
await toolbox.destroy();
|
|
||||||
await close(client);
|
|
||||||
await removeTab(tab);
|
|
||||||
});
|
|
|
@ -1,250 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
|
|
||||||
|
|
||||||
// Assume that head.js was ran and imported shared-head.js
|
|
||||||
/* import-globals-from shared-head.js */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/* import-globals-from ../../debugger/test/mochitest/shared-head.js */
|
|
||||||
Services.scriptloader.loadSubScript(
|
|
||||||
"chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/shared-head.js",
|
|
||||||
this
|
|
||||||
);
|
|
||||||
|
|
||||||
var {
|
|
||||||
DevToolsServer,
|
|
||||||
} = require("resource://devtools/server/devtools-server.js");
|
|
||||||
var {
|
|
||||||
DevToolsClient,
|
|
||||||
} = require("resource://devtools/client/devtools-client.js");
|
|
||||||
var { Toolbox } = require("resource://devtools/client/framework/toolbox.js");
|
|
||||||
|
|
||||||
function createWorkerInTab(tab, url) {
|
|
||||||
info("Creating worker with url '" + url + "' in tab.");
|
|
||||||
|
|
||||||
return SpecialPowers.spawn(tab.linkedBrowser, [url], urlChild => {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const worker = new content.Worker(urlChild);
|
|
||||||
worker.addEventListener(
|
|
||||||
"message",
|
|
||||||
function() {
|
|
||||||
if (!content.workers) {
|
|
||||||
content.workers = [];
|
|
||||||
}
|
|
||||||
content.workers[urlChild] = worker;
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function terminateWorkerInTab(tab, url) {
|
|
||||||
info("Terminating worker with url '" + url + "' in tab.");
|
|
||||||
|
|
||||||
return SpecialPowers.spawn(tab.linkedBrowser, [url], urlChild => {
|
|
||||||
content.workers[urlChild].terminate();
|
|
||||||
delete content.workers[urlChild];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function postMessageToWorkerInTab(tab, url, message) {
|
|
||||||
info("Posting message to worker with url '" + url + "' in tab.");
|
|
||||||
|
|
||||||
return SpecialPowers.spawn(
|
|
||||||
tab.linkedBrowser,
|
|
||||||
[url, message],
|
|
||||||
(urlChild, messageChild) => {
|
|
||||||
return new Promise(function(resolve) {
|
|
||||||
const worker = content.workers[urlChild];
|
|
||||||
worker.postMessage(messageChild);
|
|
||||||
worker.addEventListener(
|
|
||||||
"message",
|
|
||||||
function() {
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function evalInTab(tab, string) {
|
|
||||||
info("Evalling string in tab.");
|
|
||||||
|
|
||||||
return SpecialPowers.spawn(tab.linkedBrowser, [string], stringChild => {
|
|
||||||
return content.eval(stringChild);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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.mainRoot.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 listWorkers(targetFront) {
|
|
||||||
info("Listing workers.");
|
|
||||||
return targetFront.listWorkers();
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitForWorkerListChanged(targetFront) {
|
|
||||||
info("Waiting for worker list to change.");
|
|
||||||
return targetFront.once("workerListChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function waitForWorkerClose(workerDescriptorFront) {
|
|
||||||
info("Waiting for worker to close.");
|
|
||||||
await workerDescriptorFront.once("descriptor-destroyed");
|
|
||||||
info("Worker did close.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a promise with a reference to webconsole, opening the split
|
|
||||||
// console if necessary. This cleans up the split console pref so
|
|
||||||
// it won't pollute other tests.
|
|
||||||
async function getSplitConsole(toolbox, win) {
|
|
||||||
if (!win) {
|
|
||||||
win = toolbox.win;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toolbox.splitConsole) {
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
|
|
||||||
}
|
|
||||||
|
|
||||||
await toolbox.getPanelWhenReady("webconsole");
|
|
||||||
ok(toolbox.splitConsole, "Split console is shown.");
|
|
||||||
return toolbox.getPanel("webconsole");
|
|
||||||
}
|
|
||||||
|
|
||||||
function executeAndWaitForMessage(
|
|
||||||
webconsole,
|
|
||||||
expression,
|
|
||||||
expectedTextContent,
|
|
||||||
className = "result"
|
|
||||||
) {
|
|
||||||
const { ui } = webconsole.hud;
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const onNewMessages = messages => {
|
|
||||||
for (const message of messages) {
|
|
||||||
if (
|
|
||||||
message.node.classList.contains(className) &&
|
|
||||||
message.node.textContent.includes(expectedTextContent)
|
|
||||||
) {
|
|
||||||
ui.off("new-messages", onNewMessages);
|
|
||||||
resolve(message.node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ui.on("new-messages", onNewMessages);
|
|
||||||
ui.wrapper.dispatchEvaluateExpression(expression);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function initWorkerDebugger(TAB_URL, WORKER_URL) {
|
|
||||||
const tab = await addTab(TAB_URL);
|
|
||||||
|
|
||||||
await createWorkerInTab(tab, WORKER_URL);
|
|
||||||
|
|
||||||
const commands = await CommandsFactory.forLocalTabWorker(tab, WORKER_URL);
|
|
||||||
const workerDescriptorFront = commands.descriptorFront;
|
|
||||||
const target = workerDescriptorFront.parentFront;
|
|
||||||
const client = commands.client;
|
|
||||||
|
|
||||||
const toolbox = await gDevTools.showToolbox(commands, {
|
|
||||||
toolId: "jsdebugger",
|
|
||||||
hostType: Toolbox.HostType.WINDOW,
|
|
||||||
});
|
|
||||||
|
|
||||||
const debuggerPanel = toolbox.getCurrentPanel();
|
|
||||||
|
|
||||||
const gDebugger = debuggerPanel.panelWin;
|
|
||||||
|
|
||||||
const context = createDebuggerContext(toolbox);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...context,
|
|
||||||
client,
|
|
||||||
tab,
|
|
||||||
target,
|
|
||||||
workerDescriptorFront,
|
|
||||||
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);
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const targetWindow = win || window;
|
|
||||||
const targetBrowser = targetWindow.gBrowser;
|
|
||||||
|
|
||||||
targetWindow.focus();
|
|
||||||
const tab = (targetBrowser.selectedTab = BrowserTestUtils.addTab(
|
|
||||||
targetBrowser,
|
|
||||||
url
|
|
||||||
));
|
|
||||||
const linkedBrowser = tab.linkedBrowser;
|
|
||||||
|
|
||||||
BrowserTestUtils.browserLoaded(linkedBrowser).then(function() {
|
|
||||||
info("Tab added and finished loading: " + url);
|
|
||||||
resolve(tab);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.removeTab = function removeTab(tab, win) {
|
|
||||||
info("Removing tab.");
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const targetWindow = win || window;
|
|
||||||
const targetBrowser = targetWindow.gBrowser;
|
|
||||||
const tabContainer = targetBrowser.tabContainer;
|
|
||||||
|
|
||||||
tabContainer.addEventListener(
|
|
||||||
"TabClose",
|
|
||||||
function() {
|
|
||||||
info("Tab removed and finished closing.");
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
targetBrowser.removeTab(tab);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function pushPrefs(...aPrefs) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
SpecialPowers.pushPrefEnv({ set: aPrefs }, resolve);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function popPrefs() {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
SpecialPowers.popPrefEnv(resolve);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -127,30 +127,6 @@ exports.CommandsFactory = {
|
||||||
return commands;
|
return commands;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Create commands for a worker in a local tab.
|
|
||||||
*
|
|
||||||
* @param {Tab} tab: The local tab into which the worker runs.
|
|
||||||
* @param {String} workerUrl: The URL of the worker to debug.
|
|
||||||
* @returns {Object} Commands
|
|
||||||
*/
|
|
||||||
async forLocalTabWorker(tab, workerUrl) {
|
|
||||||
// For now, the root actor doesn't support instantiating a worker descriptor
|
|
||||||
// for a worker running in a content process (it supports only for parent process workers).
|
|
||||||
// So that we have to first instantiate a commands for the related tab.
|
|
||||||
// Then we can fetch the worker descriptor via the top level target front.
|
|
||||||
const tabCommands = await this.forTab(tab);
|
|
||||||
await tabCommands.targetCommand.startListening();
|
|
||||||
const {
|
|
||||||
workers,
|
|
||||||
} = await tabCommands.targetCommand.targetFront.listWorkers();
|
|
||||||
|
|
||||||
const workerDescriptor = workers.find(worker => worker.url == workerUrl);
|
|
||||||
|
|
||||||
const commands = await createCommandsDictionary(workerDescriptor);
|
|
||||||
return commands;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create commands for a Web Extension.
|
* Create commands for a Web Extension.
|
||||||
*
|
*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче