summaryrefslogtreecommitdiffstats
path: root/dom/xhr/tests/browser_sync_xhr_event_handing_switch_bcg.js
blob: d7966b2dac4b5a6f6b3f923a8d9bc94a129c6d39 (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
const baseURL = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

const childURL = `${baseURL}empty.html`;
const parentURL = `${baseURL}empty_parent.html`;

add_setup(async function () {
  await SpecialPowers.pushPrefEnv({
    set: [["dom.input_events.canSuspendInBCG.enabled", true]],
  });
  if (!Services.appinfo.fissionAutostart) {
    // Make sure the tab that is opened with noopener
    // also in the same process as the parent.
    await SpecialPowers.pushPrefEnv({
      set: [["dom.ipc.processCount", 1]],
    });
  }
});

async function checkInputManagerStatus(openChildInSameBCG) {
  let childTabPromise = BrowserTestUtils.waitForNewTab(
    gBrowser,
    childURL,
    true,
    true
  );

  let xhrTab = await BrowserTestUtils.openNewForegroundTab(
    gBrowser,
    parentURL,
    true
  );

  let xhrTabIsHidden = BrowserTestUtils.waitForContentEvent(
    xhrTab.linkedBrowser,
    "visibilitychange"
  );

  await SpecialPowers.spawn(
    xhrTab.linkedBrowser.browsingContext,
    [openChildInSameBCG, childURL],
    async function (sameBCG, url) {
      if (sameBCG) {
        content.open(url);
      } else {
        content.open(url, "", "noopener");
      }
    }
  );

  await childTabPromise;
  await xhrTabIsHidden;

  let xhrRequestIsReady = BrowserTestUtils.waitForContentEvent(
    xhrTab.linkedBrowser,
    "xhrRequestIsReady"
  );

  let xhrRequest = SpecialPowers.spawn(
    xhrTab.linkedBrowser.browsingContext,
    [],
    () => {
      var xhr = new content.XMLHttpRequest();
      xhr.open("GET", "slow.sjs", false);
      content.document.dispatchEvent(
        new content.Event("xhrRequestIsReady", { bubbles: true })
      );
      xhr.send(null);
    }
  );

  // Need to wait for the xhrIsReady event because spawn is async,
  // so the content needs to give us a signal that the sync XHR request
  // has started
  await xhrRequestIsReady;

  let childTab = gBrowser.tabs[2];

  // Since the xhrTab has started the sync XHR request,
  // the InputTaskManager should be suspended here
  // if it is in the same browsing context as the opener
  let isSuspendedBeforeSwitch = await SpecialPowers.spawn(
    childTab.linkedBrowser.browsingContext,
    [],
    () => {
      var utils = SpecialPowers.getDOMWindowUtils(content);
      return utils.isInputTaskManagerSuspended;
    }
  );

  is(
    isSuspendedBeforeSwitch,
    openChildInSameBCG,
    "InputTaskManager should be suspended before tab switching"
  );

  // Switching away from the childTab and switching back to
  // test the status of InputTaskManager gets updated accordingly
  // based on whether the childTab is in the same BCG as the xhrTab or not.
  await BrowserTestUtils.switchTab(gBrowser, xhrTab);
  await BrowserTestUtils.switchTab(gBrowser, childTab);

  let isSuspendedAfterTabSwitch = await SpecialPowers.spawn(
    childTab.linkedBrowser.browsingContext,
    [],
    () => {
      var utils = SpecialPowers.getDOMWindowUtils(content);
      return utils.isInputTaskManagerSuspended;
    }
  );

  is(
    isSuspendedAfterTabSwitch,
    openChildInSameBCG,
    "InputTaskManager should be either suspended or not suspended based whether childTab was opened in the same BCG"
  );

  await xhrRequest;

  let isSuspendedAfterXHRRequest = await SpecialPowers.spawn(
    xhrTab.linkedBrowser.browsingContext,
    [],
    () => {
      var utils = SpecialPowers.getDOMWindowUtils(content);
      return utils.isInputTaskManagerSuspended;
    }
  );

  is(
    isSuspendedAfterXHRRequest,
    false,
    "InputTaskManager should not be suspended before after the sync XHR is done"
  );

  gBrowser.removeTab(xhrTab);
  gBrowser.removeTab(childTab);
}

add_task(async function switchBCG() {
  await checkInputManagerStatus(true);
  await checkInputManagerStatus(false);
});