summaryrefslogtreecommitdiffstats
path: root/dom/workers/test/test_multi_sharedWorker_lifetimes_bfcache.html
blob: 346950020f8adb9738a71f9846897c05fc7de207 (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
<!--
  Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
  <head>
    <title>Test for SharedWorker</title>
    <script src="/tests/SimpleTest/SimpleTest.js"></script>
    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
      <script class="testbody" type="text/javascript">
        "use strict";
        const windowRelativeURL = "multi_sharedWorker_frame_bfcache.html";
        // This suffix will be used as a search query parameter when we are
        // navigating from navigate.html to the multi_sharedWorker_frame_bfcache
        // page again. Since we are not using history.back() we are not loading
        // that page from bfcache, but instead loading it anew, while the page
        // we loaded initially stays in bfcache. In order to not kick out the
        // page that is currently in the bfcache, we need to use a different
        // BroadcastChannel. So we use search query param as part of
        // BroadcastChannel's  name.
        const suffix = "?3";
        const storedData = "0123456789abcdefghijklmnopqrstuvwxyz";
        var bc, bc2, bc3;
        SimpleTest.waitForExplicitFinish();


        function postToWorker(aBc, workerMessage) {
          aBc.postMessage({command: "postToWorker", workerMessage});
        }

        let testGenerator = (function*() {

          bc = new BroadcastChannel("bugSharedWorkerLiftetime");
          bc3 = new BroadcastChannel("bugSharedWorkerLiftetime" + suffix);
          bc.onmessage = (event) => {
            var msg = event.data;
            var command = msg.command;
            if (command == "debug") {
              info(msg.message);
            } else if (command == "fromWorker" || command == "loaded") {
              sendToGenerator(msg.workerMessage);
            }
          }
          bc3.onmessage = (event) => {
            var msg = event.data;
            var command = msg.command;
            if (command == "finished") {
              bc.close();
              bc3.close();
              bc2.close();
              SimpleTest.finish();
            } else if (command == "debug") {
              info(msg.message);
            } else if (command == "fromWorker" || command == "loaded") {
              sendToGenerator(msg.workerMessage);
            }
          }
          bc2 = new BroadcastChannel("navigate");
          bc2.onmessage = (event) => {
            if (event.data.command == "loaded") {
              sendToGenerator();
            }
          }

          // Open the window
          window.open(windowRelativeURL, "testWin", "noopener");
          yield undefined;

          postToWorker(bc, { command: "retrieve" });

          var msg = yield undefined;
          is(msg.type, "result", "Got a result message");
          is(msg.data, undefined, "No data stored");

          postToWorker(bc, { command: "store", data: storedData });
          postToWorker(bc, { command: "retrieve" });

          msg = yield undefined;
          is(msg.type, "result", "Got a result message");
          is(msg.data, storedData, "Got stored data");


          // Navigate when the bfcache is enabled.
          info("Navigating to a different page");
          bc.postMessage({command: "navigate", location: "navigate.html"});
          yield undefined;

          for (let i = 0; i < 3; i++) {
            info("Running GC");
            SpecialPowers.exactGC(sendToGenerator);
            yield undefined;

            // It seems using SpecialPowers.executeSoon() would make the
            // entryGlobal being the BrowserChildGlobal (and that would make the
            // baseURI in the location assignment below being incorrect);
            // setTimeout on the otherhand ensures the entryGlobal is this
            // window.
            info("Waiting the event queue to clear");
            setTimeout(sendToGenerator, 0);
            yield undefined;
          }

          info("Navigating to " + windowRelativeURL);
          bc2.postMessage({command: "navigate", location: windowRelativeURL + suffix});
          yield undefined;

          postToWorker(bc3, { command: "retrieve" });

          msg = yield undefined;
          is(msg.type, "result", "Got a result message");
          is(msg.data, storedData, "Still have data stored");

          bc3.postMessage({command: "finish"});
        })();

        let sendToGenerator = testGenerator.next.bind(testGenerator);

        function runTest() {
          if (isXOrigin) {
            // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
            // Acquire storage access permission here so that the BroadcastChannel used to
            // communicate with the opened windows works in xorigin tests. Otherwise,
            // the iframe containing this page is isolated from first-party storage access,
            // which isolates BroadcastChannel communication.
            SpecialPowers.wrap(document).notifyUserGestureActivation();
            SpecialPowers.pushPermissions([{'type': 'storageAccessAPI', 'allow': 1, 'context': document}], () =>{
              SpecialPowers.wrap(document).requestStorageAccess().then(() => {
                // If Fission is disabled, the pref is no-op.
                SpecialPowers.pushPrefEnv({set: [
                  ["fission.bfcacheInParent", true],
                  ["privacy.partition.always_partition_third_party_non_cookie_storage", false],
                ]}, () => {
                  testGenerator.next();
                });
              }).then(() => {
                SpecialPowers.removePermission("3rdPartyStorage^http://mochi.test:8888", "http://mochi.xorigin-test:8888");
              });
            });
          } else {
            // If Fission is disabled, the pref is no-op.
            SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => {
              testGenerator.next();
            });
          }
        }
      </script>
  </head>
  <body onload="runTest()">
  </body>
</html>