summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands')
-rw-r--r--devtools/shared/commands/object/object-command.js22
-rw-r--r--devtools/shared/commands/resource/legacy-listeners/thread-states.js2
-rw-r--r--devtools/shared/commands/resource/resource-command.js10
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_css_changes.js2
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_css_registered_properties.js2
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_network_events.js2
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js2
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_thread_states.js82
-rw-r--r--devtools/shared/commands/resource/tests/sse_frontend.html2
-rw-r--r--devtools/shared/commands/resource/tests/sse_frontend_iframe.html2
-rw-r--r--devtools/shared/commands/resource/tests/test_service_worker.js2
-rw-r--r--devtools/shared/commands/script/tests/browser_script_command_execute_basic.js53
-rw-r--r--devtools/shared/commands/target/actions/targets.js2
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_bfcache.js2
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_frames.js2
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_processes.js2
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_scope_flag.js19
-rw-r--r--devtools/shared/commands/target/tests/test_service_worker.js2
-rw-r--r--devtools/shared/commands/thread-configuration/thread-configuration-command.js2
-rw-r--r--devtools/shared/commands/tracer/tracer-command.js2
20 files changed, 178 insertions, 38 deletions
diff --git a/devtools/shared/commands/object/object-command.js b/devtools/shared/commands/object/object-command.js
index 0396b6167a..5812f31148 100644
--- a/devtools/shared/commands/object/object-command.js
+++ b/devtools/shared/commands/object/object-command.js
@@ -21,10 +21,6 @@ class ObjectCommand {
* List of fronts for the object to release.
*/
async releaseObjects(frontsToRelease) {
- // @backward-compat { version 123 } A new Objects Manager front has a new "releaseActors" method.
- // Only supportsReleaseActors=true codepath can be kept once 123 is the release channel.
- const { supportsReleaseActors } = this.#commands.client.mainRoot.traits;
-
// First group all object fronts per target
const actorsPerTarget = new Map();
const promises = [];
@@ -40,20 +36,14 @@ class ObjectCommand {
actorIDsToRemove = [];
actorsPerTarget.set(targetFront, actorIDsToRemove);
}
- if (supportsReleaseActors) {
- actorIDsToRemove.push(frontToRelease.actorID);
- frontToRelease.destroy();
- } else {
- promises.push(frontToRelease.release());
- }
+ actorIDsToRemove.push(frontToRelease.actorID);
+ frontToRelease.destroy();
}
- if (supportsReleaseActors) {
- // Then release all fronts by bulk per target
- for (const [targetFront, actorIDs] of actorsPerTarget) {
- const objectsManagerFront = await targetFront.getFront("objects-manager");
- promises.push(objectsManagerFront.releaseObjects(actorIDs));
- }
+ // Then release all fronts by bulk per target
+ for (const [targetFront, actorIDs] of actorsPerTarget) {
+ const objectsManagerFront = await targetFront.getFront("objects-manager");
+ promises.push(objectsManagerFront.releaseObjects(actorIDs));
}
await Promise.all(promises);
diff --git a/devtools/shared/commands/resource/legacy-listeners/thread-states.js b/devtools/shared/commands/resource/legacy-listeners/thread-states.js
index 42c922072a..b24bdfa8cc 100644
--- a/devtools/shared/commands/resource/legacy-listeners/thread-states.js
+++ b/devtools/shared/commands/resource/legacy-listeners/thread-states.js
@@ -56,7 +56,7 @@ module.exports = async function ({ targetCommand, targetFront, onAvailable }) {
};
threadFront.on("paused", onPausedPacket);
- threadFront.on("resumed", packet => {
+ threadFront.on("resumed", () => {
// NOTE: the client suppresses resumed events while interrupted
// to prevent unintentional behavior.
// see [client docs](devtools/client/debugger/src/client/README.md#interrupted) for more information.
diff --git a/devtools/shared/commands/resource/resource-command.js b/devtools/shared/commands/resource/resource-command.js
index c45dc6a584..5b34bf4442 100644
--- a/devtools/shared/commands/resource/resource-command.js
+++ b/devtools/shared/commands/resource/resource-command.js
@@ -826,7 +826,7 @@ class ResourceCommand {
* Called everytime a resource is destroyed in the remote target.
* See _onResourceAvailable for the argument description.
*/
- async _onResourceDestroyed({ targetFront, watcherFront }, resources) {
+ async _onResourceDestroyed({ targetFront }, resources) {
for (const resource of resources) {
const { resourceType, resourceId } = resource;
this._cache.delete(cacheKey(resourceType, resourceId));
@@ -923,7 +923,7 @@ class ResourceCommand {
return null;
}
- _onWillNavigate(targetFront) {
+ _onWillNavigate() {
// Special case for toolboxes debugging a document,
// purge the cache entirely when we start navigating to a new document.
// Other toolboxes and additional target for remote iframes or content process
@@ -1243,11 +1243,7 @@ const WORKER_RESOURCE_TYPES = [
// Each section added here should eventually be removed once the equivalent server
// code is implement in Firefox, in its release channel.
const LegacyListeners = {
- async [ResourceCommand.TYPES.DOCUMENT_EVENT]({
- targetCommand,
- targetFront,
- onAvailable,
- }) {
+ async [ResourceCommand.TYPES.DOCUMENT_EVENT]({ targetFront, onAvailable }) {
// DocumentEventsListener of webconsole handles only top level document.
if (!targetFront.isTopLevel) {
return;
diff --git a/devtools/shared/commands/resource/tests/browser_resources_css_changes.js b/devtools/shared/commands/resource/tests/browser_resources_css_changes.js
index 22b11a8186..e116dbceb8 100644
--- a/devtools/shared/commands/resource/tests/browser_resources_css_changes.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_css_changes.js
@@ -132,7 +132,7 @@ async function setProperty(rule, index, property, value) {
await modifications.apply();
}
-async function renameProperty(rule, index, oldName, newName, value) {
+async function renameProperty(rule, index, oldName, newName) {
const modifications = rule.startModifyingProperties({ isKnown: true });
modifications.renameProperty(index, oldName, newName);
await modifications.apply();
diff --git a/devtools/shared/commands/resource/tests/browser_resources_css_registered_properties.js b/devtools/shared/commands/resource/tests/browser_resources_css_registered_properties.js
index 1429b55167..b39d4419b1 100644
--- a/devtools/shared/commands/resource/tests/browser_resources_css_registered_properties.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_css_registered_properties.js
@@ -74,7 +74,7 @@ add_task(async function () {
onAvailable,
});
await waitFor(() => targets.length === 2);
- const [topLevelTarget, iframeTarget] = targets.sort((a, b) =>
+ const [topLevelTarget, iframeTarget] = targets.sort((a, _) =>
a.isTopLevel ? -1 : 1
);
diff --git a/devtools/shared/commands/resource/tests/browser_resources_network_events.js b/devtools/shared/commands/resource/tests/browser_resources_network_events.js
index da355fd023..dd8211b478 100644
--- a/devtools/shared/commands/resource/tests/browser_resources_network_events.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_network_events.js
@@ -128,7 +128,7 @@ add_task(async function testCanceledRequest() {
// from the parent process is much more reliable.
const observer = {
QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
- observe(subject, topic, data) {
+ observe(subject) {
subject = subject.QueryInterface(Ci.nsIHttpChannel);
if (subject.URI.spec == requestUrl) {
subject.cancel(Cr.NS_BINDING_ABORTED);
diff --git a/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js b/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
index 557d14380a..c319e3b9e2 100644
--- a/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
@@ -29,7 +29,7 @@ add_task(async function () {
// Empty onAvailable callback for CSS MESSAGES, we only want to check that
// the second resource we watch correctly provides existing resources.
- const onCssMessageAvailable = resources => {};
+ const onCssMessageAvailable = () => {};
// First call to watchResources.
// We do not await on `watchPromise1` here, in order to simulate simultaneous
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,
diff --git a/devtools/shared/commands/resource/tests/sse_frontend.html b/devtools/shared/commands/resource/tests/sse_frontend.html
index 3bdddbc5bc..359aad2215 100644
--- a/devtools/shared/commands/resource/tests/sse_frontend.html
+++ b/devtools/shared/commands/resource/tests/sse_frontend.html
@@ -18,7 +18,7 @@
function openConnection() {
return new Promise(resolve => {
const es = new EventSource("sse_backend.sjs");
- es.onmessage = function (e) {
+ es.onmessage = function () {
es.close();
resolve();
};
diff --git a/devtools/shared/commands/resource/tests/sse_frontend_iframe.html b/devtools/shared/commands/resource/tests/sse_frontend_iframe.html
index 477dca013d..1fe894cccc 100644
--- a/devtools/shared/commands/resource/tests/sse_frontend_iframe.html
+++ b/devtools/shared/commands/resource/tests/sse_frontend_iframe.html
@@ -18,7 +18,7 @@
function openConnection() {
return new Promise(resolve => {
const es = new EventSource("sse_backend.sjs");
- es.onmessage = function (e) {
+ es.onmessage = function () {
es.close();
resolve();
};
diff --git a/devtools/shared/commands/resource/tests/test_service_worker.js b/devtools/shared/commands/resource/tests/test_service_worker.js
index aabc3fda0f..0ed8942239 100644
--- a/devtools/shared/commands/resource/tests/test_service_worker.js
+++ b/devtools/shared/commands/resource/tests/test_service_worker.js
@@ -6,6 +6,6 @@
// We don't need any computation in the worker,
// but at least register a fetch listener so that
// we force instantiating the SW when loading the page.
-self.onfetch = function (event) {
+self.onfetch = function () {
// do nothing.
};
diff --git a/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js b/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js
index e63f55a338..f5efa6ac30 100644
--- a/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js
+++ b/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js
@@ -75,6 +75,11 @@ add_task(async () => {
function testFunc() {}
var testLocale = new Intl.Locale("de-latn-de-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn");
+
+ var testFormData = new FormData();
+ var testHeaders = new Headers();
+ var testURLSearchParams = new URLSearchParams();
+ var testReadableStream = new ReadableStream();
</script>
<body id="body1" class="class2"><h1>Body text</h1></body>
</html>`);
@@ -97,6 +102,7 @@ add_task(async () => {
await doEagerEvalESGetters(commands);
await doEagerEvalDOMGetters(commands);
await doEagerEvalOtherNativeGetters(commands);
+ await doEagerEvalDOMMethods(commands);
await doEagerEvalAsyncFunctions(commands);
await commands.destroy();
@@ -1001,6 +1007,53 @@ async function doEagerEvalOtherNativeGetters(commands) {
}
}
+async function doEagerEvalDOMMethods(commands) {
+ // The following "values" methods share single native function with different
+ // JitInfo, while ReadableStream's "values" isn't side-effect free.
+
+ const testDataAllowed = [
+ [`testFormData.values().constructor.name`, "Object"],
+ [`testHeaders.values().constructor.name`, "Object"],
+ [`testURLSearchParams.values().constructor.name`, "Object"],
+ ];
+
+ for (const [code, expectedResult] of testDataAllowed) {
+ const response = await commands.scriptCommand.execute(code, {
+ eager: true,
+ });
+ checkObject(
+ response,
+ {
+ input: code,
+ result: expectedResult,
+ },
+ code
+ );
+
+ ok(!response.exception, "no eval exception");
+ ok(!response.helperResult, "no helper result");
+ }
+
+ const testDataDisallowed = ["testReadableStream.values()"];
+
+ for (const code of testDataDisallowed) {
+ const response = await commands.scriptCommand.execute(code, {
+ eager: true,
+ });
+ checkObject(
+ response,
+ {
+ input: code,
+ result: { type: "undefined" },
+ },
+ code
+ );
+
+ ok(!response.exception, "no eval exception");
+ ok(!response.helperResult, "no helper result");
+ }
+}
+
async function doEagerEvalAsyncFunctions(commands) {
// [code, expectedResult]
const testData = [["typeof testAsync()", "object"]];
diff --git a/devtools/shared/commands/target/actions/targets.js b/devtools/shared/commands/target/actions/targets.js
index 577e5fedd3..8acd411866 100644
--- a/devtools/shared/commands/target/actions/targets.js
+++ b/devtools/shared/commands/target/actions/targets.js
@@ -16,7 +16,7 @@ function unregisterTarget(targetFront) {
* @param {String} targetActorID: The actorID of the target we want to select.
*/
function selectTarget(targetActorID) {
- return function ({ dispatch, getState }) {
+ return function ({ dispatch }) {
dispatch({ type: "SELECT_TARGET", targetActorID });
};
}
diff --git a/devtools/shared/commands/target/tests/browser_target_command_bfcache.js b/devtools/shared/commands/target/tests/browser_target_command_bfcache.js
index 598e9c550b..c5ce76848e 100644
--- a/devtools/shared/commands/target/tests/browser_target_command_bfcache.js
+++ b/devtools/shared/commands/target/tests/browser_target_command_bfcache.js
@@ -236,7 +236,7 @@ async function testTopLevelNavigations(bfcacheInParent) {
await commands.destroy();
}
-async function testTopLevelNavigationsOnDocumentWithIframe(bfcacheInParent) {
+async function testTopLevelNavigationsOnDocumentWithIframe() {
info(" # Test TOP LEVEL navigations on document with iframe");
// Create a TargetCommand for a given test tab
const tab =
diff --git a/devtools/shared/commands/target/tests/browser_target_command_frames.js b/devtools/shared/commands/target/tests/browser_target_command_frames.js
index 6aa0655b64..5f4e633d11 100644
--- a/devtools/shared/commands/target/tests/browser_target_command_frames.js
+++ b/devtools/shared/commands/target/tests/browser_target_command_frames.js
@@ -366,7 +366,7 @@ async function testBrowserFrames() {
await commands.destroy();
}
-async function testTabFrames(mainRoot) {
+async function testTabFrames() {
info("Test TargetCommand against frames via a tab target");
// Create a TargetCommand for a given test tab
diff --git a/devtools/shared/commands/target/tests/browser_target_command_processes.js b/devtools/shared/commands/target/tests/browser_target_command_processes.js
index d4f57ae036..9b55b34027 100644
--- a/devtools/shared/commands/target/tests/browser_target_command_processes.js
+++ b/devtools/shared/commands/target/tests/browser_target_command_processes.js
@@ -178,11 +178,13 @@ async function testProcesses(targetCommand, target) {
onAvailable: onAvailable2,
});
});
+ info("open new tab in new process");
const tab1 = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: TEST_URL,
forceNewProcess: true,
});
+ info("wait for process target to be created");
const createdTarget = await onProcessCreated;
// For some reason, creating a new tab purges processes created from previous tests
// so it is not reasonable to assert the size of `targets` as it may be lower than expected.
diff --git a/devtools/shared/commands/target/tests/browser_target_command_scope_flag.js b/devtools/shared/commands/target/tests/browser_target_command_scope_flag.js
index 65d9e9a622..0ceaaf39ee 100644
--- a/devtools/shared/commands/target/tests/browser_target_command_scope_flag.js
+++ b/devtools/shared/commands/target/tests/browser_target_command_scope_flag.js
@@ -52,6 +52,25 @@ add_task(async function () {
forceNewProcess: true,
});
+ // Verify that only PROCESS and top target have their thread actor attached.
+ // We especially care about having the FRAME targets to not be attached,
+ // otherwise we would have two thread actor debugging the same thread
+ // with the PROCESS target already debugging all FRAME documents.
+ for (const target of targets) {
+ const threadFront = await target.getFront("thread");
+ const isAttached = await threadFront.isAttached();
+ if (target.targetType == TYPES.PROCESS) {
+ ok(isAttached, "All process targets are attached");
+ } else if (target.isTopLevel) {
+ ok(isAttached, "The top level target is attached");
+ } else {
+ ok(
+ !isAttached,
+ "The frame targets should not be attached in multiprocess mode"
+ );
+ }
+ }
+
const newTabProcessID =
gBrowser.selectedTab.linkedBrowser.browsingContext.currentWindowGlobal
.osPid;
diff --git a/devtools/shared/commands/target/tests/test_service_worker.js b/devtools/shared/commands/target/tests/test_service_worker.js
index aabc3fda0f..0ed8942239 100644
--- a/devtools/shared/commands/target/tests/test_service_worker.js
+++ b/devtools/shared/commands/target/tests/test_service_worker.js
@@ -6,6 +6,6 @@
// We don't need any computation in the worker,
// but at least register a fetch listener so that
// we force instantiating the SW when loading the page.
-self.onfetch = function (event) {
+self.onfetch = function () {
// do nothing.
};
diff --git a/devtools/shared/commands/thread-configuration/thread-configuration-command.js b/devtools/shared/commands/thread-configuration/thread-configuration-command.js
index 0db1c2a285..8896cb17bc 100644
--- a/devtools/shared/commands/thread-configuration/thread-configuration-command.js
+++ b/devtools/shared/commands/thread-configuration/thread-configuration-command.js
@@ -32,7 +32,7 @@ class ThreadConfigurationCommand {
// the thread configuration actor.
const filteredConfiguration = Object.fromEntries(
Object.entries(configuration).filter(
- ([key, value]) => !["breakpoints", "eventBreakpoints"].includes(key)
+ ([key]) => !["breakpoints", "eventBreakpoints"].includes(key)
)
);
diff --git a/devtools/shared/commands/tracer/tracer-command.js b/devtools/shared/commands/tracer/tracer-command.js
index f512c15d9e..80c461a199 100644
--- a/devtools/shared/commands/tracer/tracer-command.js
+++ b/devtools/shared/commands/tracer/tracer-command.js
@@ -6,13 +6,11 @@
class TracerCommand {
constructor({ commands }) {
- this.#targetCommand = commands.targetCommand;
this.#targetConfigurationCommand = commands.targetConfigurationCommand;
this.#resourceCommand = commands.resourceCommand;
}
#resourceCommand;
- #targetCommand;
#targetConfigurationCommand;
#isTracing = false;