summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/target/tests/browser_target_command_browser_workers.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/target/tests/browser_target_command_browser_workers.js')
-rw-r--r--devtools/shared/commands/target/tests/browser_target_command_browser_workers.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/devtools/shared/commands/target/tests/browser_target_command_browser_workers.js b/devtools/shared/commands/target/tests/browser_target_command_browser_workers.js
new file mode 100644
index 0000000000..181cfa2614
--- /dev/null
+++ b/devtools/shared/commands/target/tests/browser_target_command_browser_workers.js
@@ -0,0 +1,246 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test the TargetCommand API around workers
+
+const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
+const WORKER_FILE = "test_worker.js";
+const CHROME_WORKER_URL = CHROME_URL_ROOT + WORKER_FILE;
+const SERVICE_WORKER_URL = URL_ROOT_SSL + "test_service_worker.js";
+
+add_task(async function () {
+ // Enabled fission's pref as the TargetCommand is almost disabled without it
+ await pushPref("devtools.browsertoolbox.scope", "everything");
+
+ // Disable the preloaded process as it creates processes intermittently
+ // which forces the emission of RDP requests we aren't correctly waiting for.
+ await pushPref("dom.ipc.processPrelaunch.enabled", false);
+
+ const tab = await addTab(FISSION_TEST_URL);
+
+ info("Test TargetCommand against workers via the parent process target");
+
+ // Instantiate a worker in the parent process
+ // eslint-disable-next-line no-unused-vars
+ const worker = new Worker(CHROME_WORKER_URL + "#simple-worker");
+ // eslint-disable-next-line no-unused-vars
+ const sharedWorker = new SharedWorker(CHROME_WORKER_URL + "#shared-worker");
+
+ const commands = await CommandsFactory.forMainProcess();
+ const targetCommand = commands.targetCommand;
+ const { TYPES } = targetCommand;
+ await targetCommand.startListening();
+
+ // Very naive sanity check against getAllTargets([workerType])
+ info("Check that getAllTargets returned the expected targets");
+ const workers = await targetCommand.getAllTargets([TYPES.WORKER]);
+ const hasWorker = workers.find(workerTarget => {
+ return workerTarget.url == CHROME_WORKER_URL + "#simple-worker";
+ });
+ ok(hasWorker, "retrieve the target for the worker");
+
+ const sharedWorkers = await targetCommand.getAllTargets([
+ TYPES.SHARED_WORKER,
+ ]);
+ const hasSharedWorker = sharedWorkers.find(workerTarget => {
+ return workerTarget.url == CHROME_WORKER_URL + "#shared-worker";
+ });
+ ok(hasSharedWorker, "retrieve the target for the shared worker");
+
+ const serviceWorkers = await targetCommand.getAllTargets([
+ TYPES.SERVICE_WORKER,
+ ]);
+ const hasServiceWorker = serviceWorkers.find(workerTarget => {
+ return workerTarget.url == SERVICE_WORKER_URL;
+ });
+ ok(hasServiceWorker, "retrieve the target for the service worker");
+
+ info(
+ "Check that calling getAllTargets again return the same target instances"
+ );
+ const workers2 = await targetCommand.getAllTargets([TYPES.WORKER]);
+ const sharedWorkers2 = await targetCommand.getAllTargets([
+ TYPES.SHARED_WORKER,
+ ]);
+ const serviceWorkers2 = await targetCommand.getAllTargets([
+ TYPES.SERVICE_WORKER,
+ ]);
+ is(workers2.length, workers.length, "retrieved the same number of workers");
+ is(
+ sharedWorkers2.length,
+ sharedWorkers.length,
+ "retrieved the same number of shared workers"
+ );
+ is(
+ serviceWorkers2.length,
+ serviceWorkers.length,
+ "retrieved the same number of service workers"
+ );
+
+ workers.sort(sortFronts);
+ workers2.sort(sortFronts);
+ sharedWorkers.sort(sortFronts);
+ sharedWorkers2.sort(sortFronts);
+ serviceWorkers.sort(sortFronts);
+ serviceWorkers2.sort(sortFronts);
+
+ for (let i = 0; i < workers.length; i++) {
+ is(workers[i], workers2[i], `worker ${i} targets are the same`);
+ }
+ for (let i = 0; i < sharedWorkers2.length; i++) {
+ is(
+ sharedWorkers[i],
+ sharedWorkers2[i],
+ `shared worker ${i} targets are the same`
+ );
+ }
+ for (let i = 0; i < serviceWorkers2.length; i++) {
+ is(
+ serviceWorkers[i],
+ serviceWorkers2[i],
+ `service worker ${i} targets are the same`
+ );
+ }
+
+ info(
+ "Check that watchTargets will call the create callback for all existing workers"
+ );
+ const targets = [];
+ const topLevelTarget = await commands.targetCommand.targetFront;
+ const onAvailable = async ({ targetFront }) => {
+ ok(
+ targetFront.targetType === TYPES.WORKER ||
+ targetFront.targetType === TYPES.SHARED_WORKER ||
+ targetFront.targetType === TYPES.SERVICE_WORKER,
+ "We are only notified about worker targets"
+ );
+ ok(
+ targetFront == topLevelTarget
+ ? targetFront.isTopLevel
+ : !targetFront.isTopLevel,
+ "isTopLevel property is correct"
+ );
+ targets.push(targetFront);
+ };
+ await targetCommand.watchTargets({
+ types: [TYPES.WORKER, TYPES.SHARED_WORKER, TYPES.SERVICE_WORKER],
+ onAvailable,
+ });
+ is(
+ targets.length,
+ workers.length + sharedWorkers.length + serviceWorkers.length,
+ "retrieved the same number of workers via watchTargets"
+ );
+
+ targets.sort(sortFronts);
+ const allWorkers = workers
+ .concat(sharedWorkers, serviceWorkers)
+ .sort(sortFronts);
+
+ for (let i = 0; i < allWorkers.length; i++) {
+ is(
+ allWorkers[i],
+ targets[i],
+ `worker ${i} targets are the same via watchTargets`
+ );
+ }
+
+ targetCommand.unwatchTargets({
+ types: [TYPES.WORKER, TYPES.SHARED_WORKER, TYPES.SERVICE_WORKER],
+ onAvailable,
+ });
+
+ // Create a new worker and see if the worker target is reported
+ const onWorkerCreated = new Promise(resolve => {
+ const onAvailable2 = async ({ targetFront }) => {
+ if (targets.includes(targetFront)) {
+ return;
+ }
+ targetCommand.unwatchTargets({
+ types: [TYPES.WORKER],
+ onAvailable: onAvailable2,
+ });
+ resolve(targetFront);
+ };
+ targetCommand.watchTargets({
+ types: [TYPES.WORKER],
+ onAvailable: onAvailable2,
+ });
+ });
+ // eslint-disable-next-line no-unused-vars
+ const worker2 = new Worker(CHROME_WORKER_URL + "#second");
+ info("Wait for the second worker to be created");
+ const workerTarget = await onWorkerCreated;
+
+ is(
+ workerTarget.url,
+ CHROME_WORKER_URL + "#second",
+ "This worker target is about the new worker"
+ );
+ is(
+ workerTarget.name,
+ "test_worker.js#second",
+ "The worker target has the expected name"
+ );
+
+ const workers3 = await targetCommand.getAllTargets([TYPES.WORKER]);
+ const hasWorker2 = workers3.find(
+ ({ url }) => url == `${CHROME_WORKER_URL}#second`
+ );
+ ok(hasWorker2, "retrieve the target for tab via getAllTargets");
+
+ info(
+ "Check that terminating the worker does trigger the onDestroyed callback"
+ );
+ const onWorkerDestroyed = new Promise(resolve => {
+ const emptyFn = () => {};
+ const onDestroyed = ({ targetFront }) => {
+ targetCommand.unwatchTargets({
+ types: [TYPES.WORKER],
+ onAvailable: emptyFn,
+ onDestroyed,
+ });
+ resolve(targetFront);
+ };
+
+ targetCommand.watchTargets({
+ types: [TYPES.WORKER],
+ onAvailable: emptyFn,
+ onDestroyed,
+ });
+ });
+ worker2.terminate();
+ const workerTargetFront = await onWorkerDestroyed;
+ ok(true, "onDestroyed was called when the worker was terminated");
+
+ workerTargetFront.isTopLevel;
+ ok(
+ true,
+ "isTopLevel can be called on the target front after onDestroyed was called"
+ );
+
+ workerTargetFront.name;
+ ok(
+ true,
+ "name can be accessed on the target front after onDestroyed was called"
+ );
+
+ targetCommand.destroy();
+
+ info("Unregister service workers so they don't appear in other tests.");
+ await unregisterAllServiceWorkers(commands.client);
+
+ await commands.destroy();
+
+ await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
+ // registrationPromise is set by the test page.
+ const registration = await content.wrappedJSObject.registrationPromise;
+ registration.unregister();
+ });
+});
+
+function sortFronts(f1, f2) {
+ return f1.actorID < f2.actorID;
+}