226 lines
7 KiB
JavaScript
226 lines
7 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
add_task(async function () {
|
|
const tab = await BrowserTestUtils.openNewForegroundTab(
|
|
gBrowser,
|
|
"about:blank"
|
|
);
|
|
const browser = tab.linkedBrowser;
|
|
const aboutBlankBrowsingContext = browser.browsingContext;
|
|
const { webProgress } = aboutBlankBrowsingContext;
|
|
ok(
|
|
webProgress,
|
|
"Got a WebProgress interface on BrowsingContext in the parent process"
|
|
);
|
|
is(
|
|
webProgress.browsingContext,
|
|
browser.browsingContext,
|
|
"WebProgress.browsingContext refers to the right BrowsingContext"
|
|
);
|
|
|
|
const onLocationChanged = waitForNextLocationChange(webProgress);
|
|
const newLocation = "data:text/html;charset=utf-8,first-page";
|
|
let loaded = BrowserTestUtils.browserLoaded(browser);
|
|
BrowserTestUtils.startLoadingURIString(browser, newLocation);
|
|
await loaded;
|
|
|
|
const firstPageBrowsingContext = browser.browsingContext;
|
|
const isBfcacheInParentEnabled =
|
|
SpecialPowers.Services.appinfo.sessionHistoryInParent &&
|
|
SpecialPowers.Services.prefs.getBoolPref("fission.bfcacheInParent");
|
|
if (isBfcacheInParentEnabled) {
|
|
isnot(
|
|
aboutBlankBrowsingContext,
|
|
firstPageBrowsingContext,
|
|
"With bfcache in parent, navigations spawn a new BrowsingContext"
|
|
);
|
|
} else {
|
|
is(
|
|
aboutBlankBrowsingContext,
|
|
firstPageBrowsingContext,
|
|
"Without bfcache in parent, navigations reuse the same BrowsingContext"
|
|
);
|
|
}
|
|
|
|
info("Wait for onLocationChange to be fired");
|
|
{
|
|
const { browsingContext, location, request, flags } =
|
|
await onLocationChanged;
|
|
is(
|
|
browsingContext,
|
|
firstPageBrowsingContext,
|
|
"Location change fires on the new BrowsingContext"
|
|
);
|
|
ok(location instanceof Ci.nsIURI);
|
|
is(location.spec, newLocation);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, newLocation);
|
|
is(flags, 0);
|
|
}
|
|
|
|
const onIframeLocationChanged = waitForNextLocationChange(webProgress);
|
|
const iframeLocation = "data:text/html;charset=utf-8,iframe";
|
|
const iframeBC = await SpecialPowers.spawn(
|
|
browser,
|
|
[iframeLocation],
|
|
async url => {
|
|
const iframe = content.document.createElement("iframe");
|
|
await new Promise(resolve => {
|
|
iframe.addEventListener("load", resolve, { once: true });
|
|
iframe.src = url;
|
|
content.document.body.appendChild(iframe);
|
|
});
|
|
|
|
return iframe.browsingContext;
|
|
}
|
|
);
|
|
ok(
|
|
iframeBC.webProgress,
|
|
"The iframe BrowsingContext also exposes a WebProgress"
|
|
);
|
|
{
|
|
const { browsingContext, location, request, flags } =
|
|
await onIframeLocationChanged;
|
|
is(
|
|
browsingContext,
|
|
iframeBC,
|
|
"Iframe location change fires on the iframe BrowsingContext"
|
|
);
|
|
ok(location instanceof Ci.nsIURI);
|
|
is(location.spec, iframeLocation);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, iframeLocation);
|
|
is(flags, 0);
|
|
}
|
|
|
|
const onSecondLocationChanged = waitForNextLocationChange(webProgress);
|
|
const onSecondPageDocumentStart = waitForNextDocumentStart(webProgress);
|
|
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
|
const secondLocation = "http://example.com/document-builder.sjs?html=com";
|
|
loaded = BrowserTestUtils.browserLoaded(browser);
|
|
BrowserTestUtils.startLoadingURIString(browser, secondLocation);
|
|
await loaded;
|
|
|
|
const secondPageBrowsingContext = browser.browsingContext;
|
|
if (isBfcacheInParentEnabled) {
|
|
isnot(
|
|
firstPageBrowsingContext,
|
|
secondPageBrowsingContext,
|
|
"With bfcache in parent, navigations spawn a new BrowsingContext"
|
|
);
|
|
} else {
|
|
is(
|
|
firstPageBrowsingContext,
|
|
secondPageBrowsingContext,
|
|
"Without bfcache in parent, navigations reuse the same BrowsingContext"
|
|
);
|
|
}
|
|
{
|
|
const { browsingContext, location, request, flags } =
|
|
await onSecondLocationChanged;
|
|
is(
|
|
browsingContext,
|
|
secondPageBrowsingContext,
|
|
"Second location change fires on the new BrowsingContext"
|
|
);
|
|
ok(location instanceof Ci.nsIURI);
|
|
is(location.spec, secondLocation);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, secondLocation);
|
|
is(flags, 0);
|
|
}
|
|
{
|
|
const { browsingContext, request } = await onSecondPageDocumentStart;
|
|
is(
|
|
browsingContext,
|
|
firstPageBrowsingContext,
|
|
"STATE_START, when navigating to another process, fires on the BrowsingContext we navigate *from*"
|
|
);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, secondLocation);
|
|
}
|
|
|
|
const onBackLocationChanged = waitForNextLocationChange(webProgress, true);
|
|
const onBackDocumentStart = waitForNextDocumentStart(webProgress);
|
|
browser.goBack();
|
|
|
|
{
|
|
const { browsingContext, location, request, flags } =
|
|
await onBackLocationChanged;
|
|
is(
|
|
browsingContext,
|
|
firstPageBrowsingContext,
|
|
"location change, when navigating back, fires on the BrowsingContext we navigate *to*"
|
|
);
|
|
ok(location instanceof Ci.nsIURI);
|
|
is(location.spec, newLocation);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, newLocation);
|
|
is(flags, 0);
|
|
}
|
|
{
|
|
const { browsingContext, request } = await onBackDocumentStart;
|
|
is(
|
|
browsingContext,
|
|
secondPageBrowsingContext,
|
|
"STATE_START, when navigating back, fires on the BrowsingContext we navigate *from*"
|
|
);
|
|
ok(request instanceof Ci.nsIChannel);
|
|
is(request.URI.spec, newLocation);
|
|
}
|
|
|
|
BrowserTestUtils.removeTab(tab);
|
|
});
|
|
|
|
function waitForNextLocationChange(webProgress, onlyTopLevel = false) {
|
|
return new Promise(resolve => {
|
|
const wpl = {
|
|
QueryInterface: ChromeUtils.generateQI([
|
|
"nsIWebProgressListener",
|
|
"nsISupportsWeakReference",
|
|
]),
|
|
onLocationChange(progress, request, location, flags) {
|
|
if (onlyTopLevel && progress.browsingContext.parent) {
|
|
// Ignore non-toplevel.
|
|
return;
|
|
}
|
|
webProgress.removeProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
|
|
resolve({
|
|
browsingContext: progress.browsingContext,
|
|
location,
|
|
request,
|
|
flags,
|
|
});
|
|
},
|
|
};
|
|
// Add a strong reference to the progress listener.
|
|
resolve.wpl = wpl;
|
|
webProgress.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
|
|
});
|
|
}
|
|
|
|
function waitForNextDocumentStart(webProgress) {
|
|
return new Promise(resolve => {
|
|
const wpl = {
|
|
QueryInterface: ChromeUtils.generateQI([
|
|
"nsIWebProgressListener",
|
|
"nsISupportsWeakReference",
|
|
]),
|
|
onStateChange(progress, request, flags) {
|
|
if (
|
|
flags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
|
|
flags & Ci.nsIWebProgressListener.STATE_START
|
|
) {
|
|
webProgress.removeProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
|
|
resolve({ browsingContext: progress.browsingContext, request });
|
|
}
|
|
},
|
|
};
|
|
// Add a strong reference to the progress listener.
|
|
resolve.wpl = wpl;
|
|
webProgress.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
|
|
});
|
|
}
|