summaryrefslogtreecommitdiffstats
path: root/dom/tests/browser/browser_sessionStorage_navigation.js
blob: 094527dd4429b6fe92af6eecc027850a5340ea17 (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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
"use strict";

const DIRPATH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content/",
  ""
);
const PATH = DIRPATH + "file_empty.html";

const ORIGIN1 = "https://example.com";
const ORIGIN2 = "https://example.org";
const URL1 = `${ORIGIN1}/${PATH}`;
const URL2 = `${ORIGIN2}/${PATH}`;
const URL1_WITH_COOP_COEP = `${ORIGIN1}/${DIRPATH}file_coop_coep.html`;

add_task(async function () {
  await BrowserTestUtils.withNewTab(URL1, async function (browser) {
    const key = "key";
    const value = "value";

    info(
      `Verifying sessionStorage is preserved after navigating to a ` +
        `cross-origin site and then navigating back`
    );

    await SpecialPowers.pushPrefEnv({
      set: [
        [
          "privacy.partition.always_partition_third_party_non_cookie_storage",
          false,
        ],
      ],
    });

    BrowserTestUtils.loadURIString(browser, URL1);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN1, key, value],
      async (ORIGIN, key, value) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);

        let value1 = content.window.sessionStorage.getItem(key);
        is(
          value1,
          null,
          `SessionStorage for ${key} in ${content.window.origin} is null ` +
            `since it's the first visit`
        );

        content.window.sessionStorage.setItem(key, value);

        let value2 = content.window.sessionStorage.getItem(key);
        is(
          value2,
          value,
          `SessionStorage for ${key} in ${content.window.origin} is set ` +
            `correctly`
        );
      }
    );

    BrowserTestUtils.loadURIString(browser, URL2);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN2, key, value],
      async (ORIGIN, key, value) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);

        let value1 = content.window.sessionStorage.getItem(key);
        is(
          value1,
          null,
          `SessionStorage for ${key} in ${content.window.origin} is null ` +
            `since it's the first visit`
        );
      }
    );

    BrowserTestUtils.loadURIString(browser, URL1);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN1, key, value],
      async (ORIGIN, key, value) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);

        let value1 = content.window.sessionStorage.getItem(key);
        is(
          value1,
          value,
          `SessionStorage for ${key} in ${content.window.origin} is preserved`
        );
      }
    );

    info(`Verifying sessionStorage is preserved for ${URL1} after navigating`);

    BrowserTestUtils.loadURIString(browser, URL2);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN2, ORIGIN1, URL1, key, value],
      async (ORIGIN, iframeORIGIN, iframeURL, key, value) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);

        let iframe = content.document.createElement("iframe");
        iframe.src = iframeURL;
        content.document.body.appendChild(iframe);
        await ContentTaskUtils.waitForEvent(iframe, "load");

        await content.SpecialPowers.spawn(
          iframe,
          [iframeORIGIN, key, value],
          async function (ORIGIN, key, value) {
            is(
              content.window.origin,
              ORIGIN,
              `Navigate to ${ORIGIN} as expected`
            );

            // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
            // Acquire storage access permission here so that the iframe has
            // first-party access to the sessionStorage. Without this, it is
            // isolated and this test will always fail
            SpecialPowers.wrap(content.document).notifyUserGestureActivation();
            await SpecialPowers.addPermission(
              "storageAccessAPI",
              true,
              content.window.location.href
            );
            await SpecialPowers.wrap(content.document).requestStorageAccess();

            let value1 = content.window.sessionStorage.getItem(key);
            is(
              value1,
              value,
              `SessionStorage for ${key} in ${content.window.origin} is ` +
                `preserved`
            );
          }
        );
      }
    );

    info(`Verifying SSCache is loaded to the content process only once`);

    BrowserTestUtils.loadURIString(browser, URL1);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN1, URL1, key, value],
      async (ORIGIN, iframeURL, key, value) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);

        let iframe = content.document.createElement("iframe");
        iframe.src = iframeURL;
        content.document.body.appendChild(iframe);
        await ContentTaskUtils.waitForEvent(iframe, "load");

        await content.SpecialPowers.spawn(
          iframe,
          [ORIGIN, key, value],
          async function (ORIGIN, key, value) {
            is(
              content.window.origin,
              ORIGIN,
              `Load an iframe to ${ORIGIN} as expected`
            );

            let value1 = content.window.sessionStorage.getItem(key);
            is(
              value1,
              value,
              `SessionStorage for ${key} in ${content.window.origin} is ` +
                `preserved.`
            );

            // When we are here, it means we didn't hit the assertion for
            // ensuring a SSCache can only be loaded on the content process
            // once.
          }
        );
      }
    );

    info(
      `Verifying the sessionStorage for a tab shares between ` +
        `cross-origin-isolated and non cross-origin-isolated environments`
    );
    const anotherKey = `anotherKey`;
    const anotherValue = `anotherValue;`;

    BrowserTestUtils.loadURIString(browser, URL1_WITH_COOP_COEP);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN1, key, value, anotherKey, anotherValue],
      async (ORIGIN, key, value, anotherKey, anotherValue) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);
        ok(
          content.window.crossOriginIsolated,
          `The window is cross-origin-isolated.`
        );

        let value1 = content.window.sessionStorage.getItem(key);
        is(
          value1,
          value,
          `SessionStorage for ${key} in ${content.window.origin} was ` +
            `propagated to COOP+COEP process correctly.`
        );

        let value2 = content.window.sessionStorage.getItem(anotherKey);
        is(
          value2,
          null,
          `SessionStorage for ${anotherKey} in ${content.window.origin} ` +
            `hasn't been set yet.`
        );

        content.window.sessionStorage.setItem(anotherKey, anotherValue);

        let value3 = content.window.sessionStorage.getItem(anotherKey);
        is(
          value3,
          anotherValue,
          `SessionStorage for ${anotherKey} in ${content.window.origin} ` +
            `was set as expected.`
        );
      }
    );

    BrowserTestUtils.loadURIString(browser, URL1);
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(
      browser,
      [ORIGIN1, key, value, anotherKey, anotherValue],
      async (ORIGIN, key, value, anotherKey, anotherValue) => {
        is(content.window.origin, ORIGIN, `Navigate to ${ORIGIN} as expected`);
        ok(
          !content.window.crossOriginIsolated,
          `The window is not cross-origin-isolated.`
        );

        let value1 = content.window.sessionStorage.getItem(key);
        is(
          value1,
          value,
          `SessionStorage for ${key} in ${content.window.origin} is ` +
            `preserved.`
        );

        let value2 = content.window.sessionStorage.getItem(anotherKey);
        is(
          value2,
          anotherValue,
          `SessionStorage for ${anotherKey} in ${content.window.origin} was ` +
            `propagated to non-COOP+COEP process correctly.`
        );
      }
    );
  });
});