Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

"use strict";
// A controlled page embeds a cross-origin iframe. The iframe navigates itself
// to about:blank, its SH entry is an about:blank with cross-origin principal.
// When the embedder is reloaded, that iframe entry is restored onto the new
// docshell and treated as initial load. But the initial about:blank code
// expects to inherit a controller from the embedder into the client.
// See bug 2021375
const PARENT_ORIGIN = "https://example.com";
const SUBFRAME_ORIGIN = "https://test1.example.com";
const TEST_PATH = "/browser/dom/serviceworkers/test/";
const PARENT_URI = PARENT_ORIGIN + TEST_PATH + "subframe_container.html";
const SW_SCRIPT = PARENT_ORIGIN + TEST_PATH + "empty.js";
const SW_SCOPE = PARENT_ORIGIN + TEST_PATH;
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
],
});
});
async function isControlled(browsingContextOrBrowser) {
return SpecialPowers.spawn(browsingContextOrBrowser, [], () => {
return !!content.navigator.serviceWorker.controller;
});
}
function checkSubframeIsAboutBlank(wgp, when) {
is(wgp.documentURI.spec, "about:blank", `Subframe on about:blank ${when}`);
is(wgp.documentPrincipal.origin, SUBFRAME_ORIGIN, `Origin kept ${when}`);
}
add_task(async function testSubframeHistoryRestoreOntoInitialAboutBlank() {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PARENT_URI);
const browser = tab.linkedBrowser;
info("Register a ServiceWorker for the top level page");
await SpecialPowers.spawn(
browser,
[{ script: SW_SCRIPT, scope: SW_SCOPE }],
async opts => {
await content.wrappedJSObject.registerAndWaitForActive(
opts.script,
opts.scope
);
}
);
info("Reload so that the top level page becomes controlled");
await BrowserTestUtils.reloadTab(tab);
ok(await isControlled(browser), "Top page controlled");
info("Navigate the subframe to about:blank from within the subframe");
await SpecialPowers.spawn(browser, [], async () => {
const ifr = content.document.getElementById("subframe");
const loaded = ContentTaskUtils.waitForEvent(ifr, "load");
ifr.contentWindow.postMessage("about:blank", "*");
await loaded;
});
checkSubframeIsAboutBlank(
browser.browsingContext.children[0].currentWindowGlobal,
"before reload"
);
info("Reload the top level page, restoring the subframe's history entry");
await BrowserTestUtils.reloadTab(tab);
ok(!browser.isCrashed, "Content process didn't crash restoring subframe");
const childBC = browser.browsingContext.children[0];
checkSubframeIsAboutBlank(childBC.currentWindowGlobal, "after reload");
ok(await isControlled(browser), "Top page still controlled");
ok(
!(await isControlled(childBC)),
"Restored about:blank must not inherit cross-origin controller"
);
info("Clean up");
await SpecialPowers.spawn(browser, [], async () => {
await content.wrappedJSObject.unregisterAll();
});
BrowserTestUtils.removeTab(tab);
});