summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js')
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js284
1 files changed, 284 insertions, 0 deletions
diff --git a/devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js b/devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js
new file mode 100644
index 0000000000..4ee5dd8b2f
--- /dev/null
+++ b/devtools/shared/commands/target/tests/browser_target_command_various_descriptors.js
@@ -0,0 +1,284 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test the TargetCommand API with all possible descriptors
+
+const TEST_URL = "https://example.org/document-builder.sjs?html=org";
+const SECOND_TEST_URL = "https://example.com/document-builder.sjs?html=org";
+const CHROME_WORKER_URL = CHROME_URL_ROOT + "test_worker.js";
+
+const DESCRIPTOR_TYPES = require("resource://devtools/client/fronts/descriptors/descriptor-types.js");
+
+add_task(async function () {
+ // Enabled fission prefs
+ await pushPref("devtools.browsertoolbox.scope", "everything");
+ // Disable the preloaded process as it gets created lazily and may interfere
+ // with process count assertions
+ await pushPref("dom.ipc.processPrelaunch.enabled", false);
+ // This preference helps destroying the content process when we close the tab
+ await pushPref("dom.ipc.keepProcessesAlive.web", 1);
+
+ await testLocalTab();
+ await testRemoteTab();
+ await testParentProcess();
+ await testWorker();
+ await testWebExtension();
+});
+
+async function testParentProcess() {
+ info("Test TargetCommand against parent process descriptor");
+
+ const commands = await CommandsFactory.forMainProcess();
+ const { descriptorFront } = commands;
+
+ is(
+ descriptorFront.descriptorType,
+ DESCRIPTOR_TYPES.PROCESS,
+ "The descriptor type is correct"
+ );
+ is(
+ descriptorFront.isParentProcessDescriptor,
+ true,
+ "Descriptor front isParentProcessDescriptor is correct"
+ );
+ is(
+ descriptorFront.isProcessDescriptor,
+ true,
+ "Descriptor front isProcessDescriptor is correct"
+ );
+
+ const targetCommand = commands.targetCommand;
+ await targetCommand.startListening();
+
+ const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
+ Assert.greater(
+ targets.length,
+ 1,
+ "We get many targets when debugging the parent process"
+ );
+ const targetFront = targets[0];
+ is(targetFront, targetCommand.targetFront, "The first is the top level one");
+ is(
+ targetFront.targetType,
+ targetCommand.TYPES.FRAME,
+ "the parent process target is of frame type, because it inherits from WindowGlobalTargetActor"
+ );
+ is(targetFront.isTopLevel, true, "This is flagged as top level");
+
+ targetCommand.destroy();
+ await waitForAllTargetsToBeAttached(targetCommand);
+
+ await commands.destroy();
+}
+
+async function testLocalTab() {
+ info("Test TargetCommand against local tab descriptor (via getTab({ tab }))");
+
+ const tab = await addTab(TEST_URL);
+ const commands = await CommandsFactory.forTab(tab);
+ const { descriptorFront } = commands;
+ is(
+ descriptorFront.descriptorType,
+ DESCRIPTOR_TYPES.TAB,
+ "The descriptor type is correct"
+ );
+ is(
+ descriptorFront.isTabDescriptor,
+ true,
+ "Descriptor front isTabDescriptor is correct"
+ );
+
+ const targetCommand = commands.targetCommand;
+ await targetCommand.startListening();
+
+ const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
+ is(targets.length, 1, "Got a unique target");
+ const targetFront = targets[0];
+ is(targetFront, targetCommand.targetFront, "The first is the top level one");
+ is(
+ targetFront.targetType,
+ targetCommand.TYPES.FRAME,
+ "the tab target is of frame type"
+ );
+ is(targetFront.isTopLevel, true, "This is flagged as top level");
+
+ targetCommand.destroy();
+
+ BrowserTestUtils.removeTab(tab);
+
+ await commands.destroy();
+}
+
+async function testRemoteTab() {
+ info(
+ "Test TargetCommand against remote tab descriptor (via getTab({ browserId }))"
+ );
+
+ const tab = await addTab(TEST_URL);
+ const commands = await CommandsFactory.forRemoteTab(
+ tab.linkedBrowser.browserId
+ );
+ const { descriptorFront } = commands;
+ is(
+ descriptorFront.descriptorType,
+ DESCRIPTOR_TYPES.TAB,
+ "The descriptor type is correct"
+ );
+ is(
+ descriptorFront.isTabDescriptor,
+ true,
+ "Descriptor front isTabDescriptor is correct"
+ );
+
+ const targetCommand = commands.targetCommand;
+ await targetCommand.startListening();
+
+ const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
+ is(targets.length, 1, "Got a unique target");
+ const targetFront = targets[0];
+ is(
+ targetFront,
+ targetCommand.targetFront,
+ "TargetCommand top target is the same as the first target"
+ );
+ is(
+ targetFront.targetType,
+ targetCommand.TYPES.FRAME,
+ "the tab target is of frame type"
+ );
+ is(targetFront.isTopLevel, true, "This is flagged as top level");
+
+ const browser = tab.linkedBrowser;
+ const onLoaded = BrowserTestUtils.browserLoaded(browser);
+ BrowserTestUtils.startLoadingURIString(browser, SECOND_TEST_URL);
+ await onLoaded;
+
+ info("Wait for the new target");
+ await waitFor(() => targetCommand.targetFront != targetFront);
+ isnot(
+ targetCommand.targetFront,
+ targetFront,
+ "The top level target changes on navigation"
+ );
+ ok(
+ !targetCommand.targetFront.isDestroyed(),
+ "The new target isn't destroyed"
+ );
+ ok(targetFront.isDestroyed(), "While the previous target is destroyed");
+
+ targetCommand.destroy();
+
+ BrowserTestUtils.removeTab(tab);
+
+ await commands.destroy();
+}
+
+async function testWebExtension() {
+ info("Test TargetCommand against webextension descriptor");
+
+ const extension = ExtensionTestUtils.loadExtension({
+ useAddonManager: "temporary",
+ manifest: {
+ name: "Sample extension",
+ },
+ });
+
+ await extension.startup();
+
+ const commands = await CommandsFactory.forAddon(extension.id);
+ const { descriptorFront } = commands;
+ is(
+ descriptorFront.descriptorType,
+ DESCRIPTOR_TYPES.EXTENSION,
+ "The descriptor type is correct"
+ );
+ is(
+ descriptorFront.isWebExtensionDescriptor,
+ true,
+ "Descriptor front isWebExtensionDescriptor is correct"
+ );
+
+ const targetCommand = commands.targetCommand;
+ await targetCommand.startListening();
+
+ const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
+ is(targets.length, 1, "Got a unique target");
+ const targetFront = targets[0];
+ is(targetFront, targetCommand.targetFront, "The first is the top level one");
+ is(
+ targetFront.targetType,
+ targetCommand.TYPES.FRAME,
+ "the web extension target is of frame type, because it inherits from WindowGlobalTargetActor"
+ );
+ is(targetFront.isTopLevel, true, "This is flagged as top level");
+
+ targetCommand.destroy();
+
+ await extension.unload();
+
+ await commands.destroy();
+}
+
+// CommandsFactory expect the worker id, which is computed from the nsIWorkerDebugger.id attribute
+function getNextWorkerDebuggerId() {
+ return new Promise(resolve => {
+ const wdm = Cc[
+ "@mozilla.org/dom/workers/workerdebuggermanager;1"
+ ].createInstance(Ci.nsIWorkerDebuggerManager);
+ const listener = {
+ onRegister(dbg) {
+ wdm.removeListener(listener);
+ resolve(dbg.id);
+ },
+ };
+ wdm.addListener(listener);
+ });
+}
+async function testWorker() {
+ info("Test TargetCommand against worker descriptor");
+
+ const workerUrl = CHROME_WORKER_URL + "#descriptor";
+ const onNextWorker = getNextWorkerDebuggerId();
+ const worker = new Worker(workerUrl);
+ const workerId = await onNextWorker;
+ ok(workerId, "Found the worker Debugger ID");
+
+ const commands = await CommandsFactory.forWorker(workerId);
+ const { descriptorFront } = commands;
+ is(
+ descriptorFront.descriptorType,
+ DESCRIPTOR_TYPES.WORKER,
+ "The descriptor type is correct"
+ );
+ is(
+ descriptorFront.isWorkerDescriptor,
+ true,
+ "Descriptor front isWorkerDescriptor is correct"
+ );
+
+ const targetCommand = commands.targetCommand;
+ await targetCommand.startListening();
+
+ const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
+ is(targets.length, 1, "Got a unique target");
+ const targetFront = targets[0];
+ is(targetFront, targetCommand.targetFront, "The first is the top level one");
+ is(
+ targetFront.targetType,
+ targetCommand.TYPES.WORKER,
+ "the worker target is of worker type"
+ );
+ is(targetFront.isTopLevel, true, "This is flagged as top level");
+
+ targetCommand.destroy();
+
+ // Calling CommandsFactory.forWorker, will call RootFront.getWorker
+ // which will spawn lots of worker legacy code, firing lots of requests,
+ // which may still be pending
+ await commands.waitForRequestsToSettle();
+
+ await commands.destroy();
+ worker.terminate();
+}