/* 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 = URL_ROOT_ORG_SSL + 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 onDestroyed = 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: [TYPES.WORKER, TYPES.SHARED_WORKER], onAvailable, onDestroyed, }); 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"); const onBrowserLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser); BrowserTestUtils.startLoadingURIString( tab.linkedBrowser, "data:text/html,Away" ); await onBrowserLoaded; 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" ); targetCommand.destroy(); await commands.destroy(); });