Files
firefox/devtools/server/tests/xpcshell/test_xpcshell_debugging.js
T
Alexandre Poirot 26d9f9bb91 Bug 1713093 - [devtools] Remove TargetMixin.attachThread. r=devtools-reviewers,nchevobbe
This code was only used for workers targets, which weren't passing breakpoints
from the server side via "sessionData" concept.
Instead, we were still relying on the frontend to pass them and only after that
manually requesting the thread to resume its execution.

Now, there is still a notion of "attach" around the thread actor.
While all the targets are immediately instantiating their related thread actor,
the thread actor isn't active by default.
It becomes active as soon as:
* SOURCE or THREAD_STATE resource is watched
* breakpoints are set via session data (breakpoint list actor)
* thread configuration are set via session data (thread configuration actor)
I had to do one of these things in order to keep test from working.
In the production code, we do most of these things by default on the toolbox startup.
We could revise this behavior by:
* always attaching the thread actor, but it may start pausing unexpectedly in some tests.
* decouple sources from breakpoints within the thread actor, so that watching for sources doesn't necessarily "attach" the thread actor and activate breakpoints/debugger statements.
* have a new thread configuration to explicitly enable the thread actor pausing features.

I'm often using thread configuration to enable pausing in tests.
This required to improve xpcshell test helpers to be able to use Watcher/Commands.

About browser_target_command_bfcache.js, the DevTools code is now so quick that the
back/forward requests at done too quickly one after the other and fail actually moving to
the other document.

Differential Revision: https://phabricator.services.mozilla.com/D166321
2024-03-20 12:30:17 +00:00

97 lines
3.2 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test the xpcshell-test debug support. Ideally we should have this test
// next to the xpcshell support code, but that's tricky...
// HACK: ServiceWorkerManager requires the "profile-change-teardown" to cleanly
// shutdown, and setting _profileInitialized to `true` will trigger those
// notifications (see /testing/xpcshell/head.js).
// eslint-disable-next-line no-undef
_profileInitialized = true;
add_task(async function () {
const testFile = do_get_file("xpcshell_debugging_script.js");
// _setupDevToolsServer is from xpcshell-test's head.js
/* global _setupDevToolsServer */
let testInitialized = false;
const { DevToolsServer } = _setupDevToolsServer([testFile.path], () => {
testInitialized = true;
});
const transport = DevToolsServer.connectPipe();
const client = new DevToolsClient(transport);
await client.connect();
// Ensure that global actors are available. Just test the device actor.
const deviceFront = await client.mainRoot.getFront("device");
const desc = await deviceFront.getDescription();
equal(
desc.geckobuildid,
Services.appinfo.platformBuildID,
"device actor works"
);
// Even though we have no tabs, getMainProcess gives us the chrome debugger.
const commands = await CommandsFactory.forMainProcess({ client });
await commands.targetCommand.startListening();
// We have to pass at least one valid thread configuration in order to initialize
// the thread actor and make it pause on breakpoint/debugger statements.
await commands.threadConfigurationCommand.updateConfiguration({
skipBreakpoints: false,
});
const threadFront = await commands.targetCommand.targetFront.getFront(
"thread"
);
// Checks that the thread actor initializes immediately and that _setupDevToolsServer
// callback gets called.
ok(testInitialized);
const onPause = waitForPause(threadFront);
// Now load our test script,
// in another event loop so that the test can keep running!
Services.tm.dispatchToMainThread(() => {
load(testFile.path);
});
// and our "paused" listener should get hit.
info("Wait for first paused event");
const packet1 = await onPause;
equal(
packet1.why.type,
"breakpoint",
"yay - hit the breakpoint at the first line in our script"
);
// Resume again - next stop should be our "debugger" statement.
info("Wait for second pause event");
const packet2 = await resumeAndWaitForPause(threadFront);
equal(
packet2.why.type,
"debuggerStatement",
"yay - hit the 'debugger' statement in our script"
);
info("Dynamically add a breakpoint after the debugger statement");
const breakpointsFront = await commands.watcherFront.getBreakpointListActor();
await breakpointsFront.setBreakpoint(
{ sourceUrl: testFile.path, line: 11, column: 0 },
{}
);
// Resume again - next stop should be the new breakpoint.
info("Wait for third pause event");
const packet3 = await resumeAndWaitForPause(threadFront);
equal(
packet3.why.type,
"breakpoint",
"yay - hit the breakpoint added after starting the test"
);
finishClient(client);
});