Bug 1691588 - [devtools] Rewrite browser_dbg_WorkerTargetActor.attach.js into a TargetCommand test. r=nchevobbe

This test was relying the BrowsingContextTargetActor.listWorkers, but this isn't fission compatible.
The target actor will be destroyed in case of top level target.
This starts to be failing with bfcache in parent, and will also fail with server side targets.

We should rather be testing TargetCommand's behavior instead of individual fronts.

The main STR being covered in this test which isn't covered yet is BF Cache navigation.

Differential Revision: https://phabricator.services.mozilla.com/D117164
This commit is contained in:
Alexandre Poirot 2021-07-23 09:01:55 +00:00
parent 8c7729a8a4
commit a4a5bf63c2
9 changed files with 142 additions and 133 deletions

View File

@ -6,8 +6,6 @@ support-files =
browser_devices.json
code_listworkers-worker1.js
code_listworkers-worker2.js
code_WorkerTargetActor.attach-worker1.js
code_WorkerTargetActor.attach-worker2.js
code_WorkerTargetActor.attachThread-worker.js
doc_cubic-bezier-01.html
doc_cubic-bezier-02.html
@ -41,8 +39,6 @@ support-files =
doc_tableWidget_keyboard_interaction.xhtml
doc_tableWidget_mouse_interaction.xhtml
doc_templater_basic.html
doc_WorkerTargetActor.attach-tab1.html
doc_WorkerTargetActor.attach-tab2.html
doc_WorkerTargetActor.attachThread-tab.html
dummy.html
head.js
@ -291,8 +287,5 @@ skip-if = e10s && debug
skip-if = debug # bug 1334683
[browser_dbg_worker-console-04.js]
skip-if = e10s && debug
[browser_dbg_WorkerTargetActor.attach.js]
fail-if = fission # Fails with Fission + session-history-in-parent (Bug 1669000)
skip-if = e10s && debug
[browser_dbg_worker-window.js]
skip-if = (e10s && debug) || true # Bug 1486974

View File

@ -1,83 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.
// Import helpers for the workers
/* import-globals-from helper_workers.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/helper_workers.js",
this
);
var MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
var TAB1_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attach-tab1.html";
var TAB2_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attach-tab2.html";
var WORKER1_URL = "code_WorkerTargetActor.attach-worker1.js";
var WORKER2_URL = "code_WorkerTargetActor.attach-worker2.js";
add_task(async function() {
const oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
const tab = await addTab(TAB1_URL);
const target = await createAndAttachTargetForTab(tab);
await listWorkers(target);
// If a page still has pending network requests, it will not be moved into
// the bfcache. Consequently, we cannot use waitForWorkerListChanged here,
// because the worker is not guaranteed to have finished loading when it is
// registered. Instead, we have to wait for the promise returned by
// createWorker in the tab to be resolved.
await createWorkerInTab(tab, WORKER1_URL);
let { workers } = await listWorkers(target);
let workerDescriptorFront1 = findWorker(workers, WORKER1_URL);
await workerDescriptorFront1.attach();
ok(
!workerDescriptorFront1.isDestroyed(),
"front for worker in tab 1 has been attached"
);
executeSoon(() => {
BrowserTestUtils.loadURI(tab.linkedBrowser, TAB2_URL);
});
await waitForWorkerClose(workerDescriptorFront1);
ok(
workerDescriptorFront1.isDestroyed(),
"front for worker in tab 1 has been closed"
);
await createWorkerInTab(tab, WORKER2_URL);
({ workers } = await listWorkers(target));
const workerDescriptorFront2 = findWorker(workers, WORKER2_URL);
await workerDescriptorFront2.attach();
ok(
!workerDescriptorFront2.isDestroyed(),
"front for worker in tab 2 has been attached"
);
executeSoon(() => {
tab.linkedBrowser.goBack();
});
await waitForWorkerClose(workerDescriptorFront2);
ok(
workerDescriptorFront2.isDestroyed(),
"front for worker in tab 2 has been closed"
);
({ workers } = await listWorkers(target));
workerDescriptorFront1 = findWorker(workers, WORKER1_URL);
await workerDescriptorFront1.attach();
ok(
!workerDescriptorFront1.isDestroyed(),
"front for worker in tab 1 has been attached"
);
await target.destroy();
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);
finish();
});

View File

@ -1,5 +0,0 @@
"use strict";
self.onmessage = function() {};
postMessage("load");

View File

@ -1,5 +0,0 @@
"use strict";
self.onmessage = function() {};
postMessage("load");

View File

@ -1,8 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
</head>
<body>
</body>
</html>

View File

@ -1,8 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
</head>
<body>
</body>
</html>

View File

@ -33,6 +33,8 @@ skip-if = fission
# their constructor.
[browser_target_list_switchToTarget.js]
[browser_target_list_tab_workers.js]
[browser_target_list_tab_workers_bfcache_navigation.js]
skip-if = debug # Bug 1721859
[browser_target_list_various_descriptors.js]
skip-if =
os == "linux" && bits == 64 && !debug #Bug 1701056

View File

@ -30,21 +30,15 @@ add_task(async function() {
// Create a TargetCommand for the tab
const commands = await CommandsFactory.forTab(tab);
await commands.targetCommand.startListening();
// Ensure attaching the target as BrowsingContextTargetActor.listWorkers
// assert that the target actor is attached.
// It isn't clear if this assertion is meaningful?
const target = commands.targetCommand.targetFront;
await target.attach();
const targetCommand = commands.targetCommand;
const { TYPES } = targetCommand;
// Workaround to allow listening for workers in the content toolbox
// without the fission preferences
targetCommand.listenForWorkers = true;
await targetCommand.startListening();
await commands.targetCommand.startListening();
const { TYPES } = targetCommand;
info("Check that getAllTargets only returns dedicated workers");
const workers = await targetCommand.getAllTargets([
@ -123,7 +117,7 @@ add_task(async function() {
});
});
await TestUtils.waitForCondition(
await waitFor(
() => targets.length === 4,
"Wait for the target list to notify us about the spawned worker"
);
@ -150,7 +144,7 @@ add_task(async function() {
content.spawnedWorker = null;
});
});
await TestUtils.waitForCondition(
await waitFor(
() =>
destroyedTargets.includes(mainPageSpawnedWorkerTarget) &&
destroyedTargets.includes(iframeSpawnedWorkerTarget),
@ -168,7 +162,7 @@ add_task(async function() {
const targetsCountBeforeReload = targets.length;
tab.linkedBrowser.reload();
await TestUtils.waitForCondition(() => {
await waitFor(() => {
return (
destroyedTargets.includes(mainPageWorkerTarget) &&
destroyedTargets.includes(iframeWorkerTarget)
@ -179,7 +173,7 @@ add_task(async function() {
"The target list notified us about all the expected workers being destroyed when reloading"
);
await TestUtils.waitForCondition(
await waitFor(
() => targets.length === targetsCountBeforeReload + 2,
"Wait for the target list to notify us about the new workers after reloading"
);
@ -210,7 +204,7 @@ add_task(async function() {
await SpecialPowers.spawn(tab.linkedBrowser, [], () => {
content.document.querySelector("iframe").remove();
});
await TestUtils.waitForCondition(() => {
await waitFor(() => {
return destroyedTargets.includes(iframeWorkerTargetAfterReload);
}, `Wait for the target list to notify us about the terminated workers when removing an iframe`);
@ -242,7 +236,7 @@ add_task(async function() {
// It's important to check the length of `targets` here to ensure we don't get unwanted
// worker targets.
await TestUtils.waitForCondition(
await waitFor(
() => targets.length === targetCount + 4,
"Wait for the target list to notify us about the workers in the new iframes"
);
@ -284,9 +278,9 @@ add_task(async function() {
"data:text/html,<meta charset=utf8>Away"
);
await TestUtils.waitForCondition(
await waitFor(
() => destroyedTargets.length === targets.length,
"Wait for all the targets to be reporeted as destroyed"
"Wait for all the targets to be reported as destroyed"
);
ok(

View File

@ -0,0 +1,129 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test WORKER targets when doing history navigations (BF Cache)
//
// Use a distinct file as this test currently hits a DEBUG assertion
// https://searchfox.org/mozilla-central/rev/352b525ab841278cd9b3098343f655ef85933544/dom/workers/WorkerPrivate.cpp#5218
// and so is running only on OPT builds.
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
const WORKER_FILE = "test_worker.js";
const WORKER_URL = URL_ROOT_SSL + WORKER_FILE;
const IFRAME_WORKER_URL = WORKER_FILE;
add_task(async function() {
// 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);
// The WorkerDebuggerManager#getWorkerDebuggerEnumerator method we're using to retrieve
// workers loops through _all_ the workers in the process, which means it goes over workers
// from other tabs as well. Here we add a few tabs that are not going to be used in the
// test, just to check that their workers won't be retrieved by getAllTargets/watchTargets.
await addTab(`${FISSION_TEST_URL}?id=first-untargetted-tab&noServiceWorker`);
await addTab(`${FISSION_TEST_URL}?id=second-untargetted-tab&noServiceWorker`);
info("Test bfcache navigations");
const tab = await addTab(`${FISSION_TEST_URL}?&noServiceWorker`);
// Create a TargetCommand for the tab
const commands = await CommandsFactory.forTab(tab);
const targetCommand = commands.targetCommand;
// Workaround to allow listening for workers in the content toolbox
// without the fission preferences
targetCommand.listenForWorkers = true;
await targetCommand.startListening();
const { TYPES } = targetCommand;
info(
"Assert that watchTargets will call the onAvailable callback for existing dedicated workers"
);
const targets = [];
const destroyedTargets = [];
const onAvailable = async ({ targetFront }) => {
info(`onAvailable called for ${targetFront.url}`);
is(
targetFront.targetType,
TYPES.WORKER,
"We are only notified about worker targets"
);
ok(!targetFront.isTopLevel, "The workers are never top level");
targets.push(targetFront);
info(`Handled ${targets.length} new targets`);
};
const onDestroy = async ({ targetFront }) => {
is(
targetFront.targetType,
TYPES.WORKER,
"We are only notified about worker targets"
);
ok(!targetFront.isTopLevel, "The workers are never top level");
destroyedTargets.push(targetFront);
};
await targetCommand.watchTargets(
[TYPES.WORKER, TYPES.SHARED_WORKER],
onAvailable,
onDestroy
);
is(targets.length, 2, "watchTargets retrieved 2 workers…");
const mainPageWorkerTarget = targets.find(
worker => worker.url == `${WORKER_URL}#simple-worker`
);
const iframeWorkerTarget = targets.find(
worker => worker.url == `${IFRAME_WORKER_URL}#simple-worker-in-iframe`
);
ok(
mainPageWorkerTarget,
"…the dedicated worker in main page, which is the same front we received from getAllTargets"
);
ok(
iframeWorkerTarget,
"…the dedicated worker in iframe, which is the same front we received from getAllTargets"
);
info("Check that navigating away does destroy all targets");
BrowserTestUtils.loadURI(
tab.linkedBrowser,
"data:text/html,<meta charset=utf8>Away"
);
await waitFor(
() => destroyedTargets.length === 2,
"Wait for all the targets to be reported as destroyed"
);
info("Navigate back to the first page");
gBrowser.goBack();
await waitFor(
() => targets.length === 4,
"Wait for the target list to notify us about the first page workers, restored from the BF Cache"
);
const mainPageWorkerTargetAfterGoingBack = targets.find(
t => t !== mainPageWorkerTarget && t.url == `${WORKER_URL}#simple-worker`
);
const iframeWorkerTargetAfterGoingBack = targets.find(
t =>
t !== iframeWorkerTarget &&
t.url == `${IFRAME_WORKER_URL}#simple-worker-in-iframe`
);
ok(
mainPageWorkerTargetAfterGoingBack,
"The target list handled the worker created from the BF Cache"
);
ok(
iframeWorkerTargetAfterGoingBack,
"The target list handled the worker created in the iframe from the BF Cache"
);
});