summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/target/tests/browser_target_command_tab_workers_bfcache_navigation.js
blob: e628f827e2eec8ddb43cc7dd3fa245a081dcac55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* 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,<meta charset=utf8>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();
});