summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/target/tests/browser_target_command_scope_flag.js
blob: 65d9e9a62210712d749a7bd02c151d6c638061ca (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Test the TargetCommand API with changes made to devtools.browsertoolbox.scope

const TEST_URL =
  "data:text/html;charset=utf-8," + encodeURIComponent(`<div id="test"></div>`);

add_task(async function () {
  // Do not run this test when both fission and EFT is disabled as it changes
  // the number of targets
  if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
    return;
  }

  // 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);

  // First test with multiprocess debugging enabled
  await pushPref("devtools.browsertoolbox.scope", "everything");

  const commands = await CommandsFactory.forMainProcess();
  const targetCommand = commands.targetCommand;
  await targetCommand.startListening();
  const { TYPES } = targetCommand;

  const targets = new Set();
  const destroyedTargetIsModeSwitchingMap = new Map();
  const onAvailable = async ({ targetFront }) => {
    targets.add(targetFront);
  };
  const onDestroyed = ({ targetFront, isModeSwitching }) => {
    destroyedTargetIsModeSwitchingMap.set(targetFront, isModeSwitching);
    targets.delete(targetFront);
  };
  await targetCommand.watchTargets({
    types: [TYPES.PROCESS, TYPES.FRAME],
    onAvailable,
    onDestroyed,
  });
  Assert.greater(targets.size, 1, "We get many targets");

  info("Open a tab in a new content process");
  await BrowserTestUtils.openNewForegroundTab({
    gBrowser,
    url: TEST_URL,
    forceNewProcess: true,
  });

  const newTabProcessID =
    gBrowser.selectedTab.linkedBrowser.browsingContext.currentWindowGlobal
      .osPid;
  const newTabInnerWindowId =
    gBrowser.selectedTab.linkedBrowser.browsingContext.currentWindowGlobal
      .innerWindowId;

  info("Wait for the tab content process target");
  const processTarget = await waitFor(() =>
    [...targets].find(
      target =>
        target.targetType == TYPES.PROCESS &&
        target.processID == newTabProcessID
    )
  );

  info("Wait for the tab window global target");
  const windowGlobalTarget = await waitFor(() =>
    [...targets].find(
      target =>
        target.targetType == TYPES.FRAME &&
        target.innerWindowId == newTabInnerWindowId
    )
  );

  let multiprocessTargetCount = targets.size;

  info("Disable multiprocess debugging");
  await pushPref("devtools.browsertoolbox.scope", "parent-process");

  info("Wait for all targets but top level and workers to be destroyed");
  await waitFor(() =>
    [...targets].every(
      target =>
        target == targetCommand.targetFront || target.targetType == TYPES.WORKER
    )
  );

  ok(processTarget.isDestroyed(), "The process target is destroyed");
  ok(
    destroyedTargetIsModeSwitchingMap.get(processTarget),
    "isModeSwitching was passed to onTargetDestroyed and is true for the process target"
  );
  ok(windowGlobalTarget.isDestroyed(), "The window global target is destroyed");
  ok(
    destroyedTargetIsModeSwitchingMap.get(windowGlobalTarget),
    "isModeSwitching was passed to onTargetDestroyed and is true for the window global target"
  );

  info("Open a second tab in a new content process");
  const parentProcessTargetCount = targets.size;
  await BrowserTestUtils.openNewForegroundTab({
    gBrowser,
    url: TEST_URL,
    forceNewProcess: true,
  });

  await wait(1000);
  is(
    parentProcessTargetCount,
    targets.size,
    "The new tab process should be ignored and no target be created"
  );

  info("Re-enable multiprocess debugging");
  await pushPref("devtools.browsertoolbox.scope", "everything");

  // The second tab relates to one content process target and one window global target
  multiprocessTargetCount += 2;

  await waitFor(
    () => targets.size == multiprocessTargetCount,
    "Wait for all targets we used to have before disable multiprocess debugging"
  );

  info("Wait for the tab content process target to be available again");
  ok(
    [...targets].some(
      target =>
        target.targetType == TYPES.PROCESS &&
        target.processID == newTabProcessID
    ),
    "We have the tab content process target"
  );

  info("Wait for the tab window global target to be available again");
  ok(
    [...targets].some(
      target =>
        target.targetType == TYPES.FRAME &&
        target.innerWindowId == newTabInnerWindowId
    ),
    "We have the tab window global target"
  );

  info("Open a third tab in a new content process");
  await BrowserTestUtils.openNewForegroundTab({
    gBrowser,
    url: TEST_URL,
    forceNewProcess: true,
  });

  const thirdTabProcessID =
    gBrowser.selectedTab.linkedBrowser.browsingContext.currentWindowGlobal
      .osPid;
  const thirdTabInnerWindowId =
    gBrowser.selectedTab.linkedBrowser.browsingContext.currentWindowGlobal
      .innerWindowId;

  info("Wait for the third tab content process target");
  await waitFor(() =>
    [...targets].find(
      target =>
        target.targetType == TYPES.PROCESS &&
        target.processID == thirdTabProcessID
    )
  );

  info("Wait for the third tab window global target");
  await waitFor(() =>
    [...targets].find(
      target =>
        target.targetType == TYPES.FRAME &&
        target.innerWindowId == thirdTabInnerWindowId
    )
  );

  targetCommand.destroy();

  // Wait for all the targets to be fully attached so we don't have pending requests.
  await Promise.all(
    targetCommand.getAllTargets(targetCommand.ALL_TYPES).map(t => t.initialized)
  );

  await commands.destroy();
});