summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/resource/tests/browser_resources_thread_states.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/resource/tests/browser_resources_thread_states.js')
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_thread_states.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/devtools/shared/commands/resource/tests/browser_resources_thread_states.js b/devtools/shared/commands/resource/tests/browser_resources_thread_states.js
index f915bb14d0..f9d49e227a 100644
--- a/devtools/shared/commands/resource/tests/browser_resources_thread_states.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_thread_states.js
@@ -30,6 +30,9 @@ add_task(async function () {
// Check debugger statement for (remote) iframes
await checkDebuggerStatementInIframes();
+
+ // Check the behavior of THREAD_STATE against a multiprocess usecase
+ await testMultiprocessThreadState();
});
async function checkBreakpointBeforeWatchResources() {
@@ -507,6 +510,85 @@ async function checkDebuggerStatementInIframes() {
await client.close();
}
+async function testMultiprocessThreadState() {
+ // Ensure debugging the content processes and the tab
+ await pushPref("devtools.browsertoolbox.scope", "everything");
+
+ const { client, resourceCommand, targetCommand } =
+ await initMultiProcessResourceCommand();
+
+ info("Call watchResources");
+ const availableResources = [];
+ await resourceCommand.watchResources([resourceCommand.TYPES.SOURCE], {
+ onAvailable() {},
+ });
+ await resourceCommand.watchResources([resourceCommand.TYPES.THREAD_STATE], {
+ onAvailable: resources => availableResources.push(...resources),
+ });
+
+ is(
+ availableResources.length,
+ 0,
+ "Got no THREAD_STATE when calling watchResources"
+ );
+
+ const tab = await addTab(BREAKPOINT_TEST_URL);
+
+ info("Run the 'debugger' statement");
+ // Note that we do not wait for the resolution of spawn as it will be paused
+ const onResumed = ContentTask.spawn(tab.linkedBrowser, null, () => {
+ content.window.wrappedJSObject.runDebuggerStatement();
+ });
+
+ await waitFor(
+ () => availableResources.length == 1,
+ "Got the THREAD_STATE related to the debugger statement"
+ );
+ const threadState = availableResources.pop();
+ ok(threadState.targetFront.targetType, "process");
+ ok(threadState.targetFront.threadFront.state, "paused");
+
+ assertPausedResource(threadState, {
+ state: "paused",
+ why: {
+ type: "debuggerStatement",
+ },
+ frame: {
+ type: "call",
+ asyncCause: null,
+ state: "on-stack",
+ // this: object actor's form referring to `this` variable
+ displayName: "runDebuggerStatement",
+ // arguments: []
+ where: {
+ line: 17,
+ column: 6,
+ },
+ },
+ });
+
+ await threadState.targetFront.threadFront.resume();
+
+ await waitFor(
+ () => availableResources.length == 1,
+ "Wait until we receive the resumed event"
+ );
+
+ const resumed = availableResources.pop();
+
+ assertResumedResource(resumed);
+
+ // This is an important check, which verify that no unexpected pause happens.
+ // We might spawn a Thread Actor for the WindowGlobal target, which might pause the thread a second time,
+ // whereas we only expect the ContentProcess target actor to pause on all JS files of the related content process.
+ info("Wait for the content page thread to resume its execution");
+ await onResumed;
+ is(availableResources.length, 0, "There should be no other pause");
+
+ targetCommand.destroy();
+ await client.close();
+}
+
async function assertPausedResource(resource, expected) {
is(
resource.resourceType,