Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

requestLongerTimeout(2);
const DUMMY_PATH = "browser/browser/base/content/test/general/dummy_page.html";
const gExpectedHistory = {
index: -1,
entries: [],
};
async function get_remote_history(browser) {
if (SpecialPowers.Services.appinfo.sessionHistoryInParent) {
let sessionHistory = browser.browsingContext?.sessionHistory;
if (!sessionHistory) {
return null;
}
let result = {
index: sessionHistory.index,
entries: [],
};
for (let i = 0; i < sessionHistory.count; i++) {
let entry = sessionHistory.getEntryAtIndex(i);
result.entries.push({
uri: entry.URI.spec,
title: entry.title,
});
}
return result;
}
return SpecialPowers.spawn(browser, [], () => {
let webNav = content.docShell.QueryInterface(Ci.nsIWebNavigation);
let sessionHistory = webNav.sessionHistory;
let result = {
index: sessionHistory.index,
entries: [],
};
for (let i = 0; i < sessionHistory.count; i++) {
let entry = sessionHistory.legacySHistory.getEntryAtIndex(i);
result.entries.push({
uri: entry.URI.spec,
title: entry.title,
});
}
return result;
});
}
var check_history = async function () {
let sessionHistory = await get_remote_history(gBrowser.selectedBrowser);
let count = sessionHistory.entries.length;
is(
count,
gExpectedHistory.entries.length,
"Should have the right number of history entries"
);
is(
sessionHistory.index,
gExpectedHistory.index,
"Should have the right history index"
);
for (let i = 0; i < count; i++) {
let entry = sessionHistory.entries[i];
info("Checking History Entry: " + entry.uri);
is(entry.uri, gExpectedHistory.entries[i].uri, "Should have the right URI");
is(
entry.title,
gExpectedHistory.entries[i].title,
"Should have the right title"
);
}
};
function clear_history() {
gExpectedHistory.index = -1;
gExpectedHistory.entries = [];
}
// Waits for a load and updates the known history
var waitForLoad = async function (uriString) {
info("Loading " + uriString);
// Longwinded but this ensures we don't just shortcut to LoadInNewProcess
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
};
gBrowser.selectedBrowser.webNavigation.loadURI(
Services.io.newURI(uriString),
loadURIOptions
);
await BrowserTestUtils.browserStopped(gBrowser, uriString);
// Some of the documents we're using in this test use Fluent,
// and they may finish localization later.
// To prevent this test from being intermittent, we'll
// wait for the `document.l10n.ready` promise to resolve.
if (
gBrowser.selectedBrowser.contentWindow &&
gBrowser.selectedBrowser.contentWindow.document.l10n
) {
await gBrowser.selectedBrowser.contentWindow.document.l10n.ready;
}
gExpectedHistory.index++;
gExpectedHistory.entries.push({
uri: gBrowser.currentURI.spec,
title: gBrowser.contentTitle,
});
};
// Waits for a load and updates the known history
var waitForLoadWithFlags = async function (
uriString,
flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE
) {
info("Loading " + uriString + " flags = " + flags);
gBrowser.selectedBrowser.loadURI(Services.io.newURI(uriString), {
flags,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
await BrowserTestUtils.browserStopped(gBrowser, uriString);
if (!(flags & Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY)) {
if (flags & Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY) {
gExpectedHistory.entries.pop();
} else {
gExpectedHistory.index++;
}
gExpectedHistory.entries.push({
uri: gBrowser.currentURI.spec,
title: gBrowser.contentTitle,
});
}
};
var back = async function () {
info("Going back");
gBrowser.goBack();
await BrowserTestUtils.browserStopped(gBrowser);
gExpectedHistory.index--;
};
var forward = async function () {
info("Going forward");
gBrowser.goForward();
await BrowserTestUtils.browserStopped(gBrowser);
gExpectedHistory.index++;
};
// Tests that navigating from a page that should be in the remote process and
// a page that should be in the main process works and retains history
add_task(async function test_navigation() {
await SpecialPowers.pushPrefEnv({
set: [["browser.navigation.requireUserInteraction", false]],
});
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
skipAnimation: true,
});
let { permanentKey } = gBrowser.selectedBrowser;
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await waitForLoad("http://example.org/" + DUMMY_PATH);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
info("2");
// Load another page
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await waitForLoad("http://example.com/" + DUMMY_PATH);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("3");
// Load a non-remote page
await waitForLoad("about:robots");
await TestUtils.waitForCondition(
() => !!gBrowser.selectedBrowser.contentTitle.length,
"Waiting for about:robots title to update"
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("4");
// Load a remote page
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await waitForLoad("http://example.org/" + DUMMY_PATH);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("5");
await back();
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await TestUtils.waitForCondition(
() => !!gBrowser.selectedBrowser.contentTitle.length,
"Waiting for about:robots title to update"
);
await check_history();
info("6");
await back();
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("7");
await forward();
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await TestUtils.waitForCondition(
() => !!gBrowser.selectedBrowser.contentTitle.length,
"Waiting for about:robots title to update"
);
await check_history();
info("8");
await forward();
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("9");
await back();
await TestUtils.waitForCondition(
() => !!gBrowser.selectedBrowser.contentTitle.length,
"Waiting for about:robots title to update"
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("10");
// Load a new remote page, this should replace the last history entry
gExpectedHistory.entries.splice(gExpectedHistory.entries.length - 1, 1);
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await waitForLoad("http://example.com/" + DUMMY_PATH);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
await check_history();
info("11");
gBrowser.removeCurrentTab();
clear_history();
});
// Tests that calling gBrowser.loadURI or browser.loadURI to load a page in a
// different process updates the browser synchronously
add_task(async function test_synchronous() {
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
skipAnimation: true,
});
let { permanentKey } = gBrowser.selectedBrowser;
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await waitForLoad("http://example.org/" + DUMMY_PATH);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
info("2");
// Load another page
info("Loading about:robots");
BrowserTestUtils.startLoadingURIString(
gBrowser.selectedBrowser,
"about:robots"
);
await BrowserTestUtils.browserStopped(gBrowser);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
info("3");
// Load the remote page again
info("Loading http://example.org/" + DUMMY_PATH);
BrowserTestUtils.startLoadingURIString(
gBrowser.selectedBrowser,
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
"http://example.org/" + DUMMY_PATH
);
await BrowserTestUtils.browserStopped(gBrowser);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
is(
gBrowser.selectedBrowser.permanentKey,
permanentKey,
"browser.permanentKey is still the same"
);
info("4");
gBrowser.removeCurrentTab();
clear_history();
});
// Tests that load flags are correctly passed through to the child process with
// normal loads
add_task(async function test_loadflags() {
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
skipAnimation: true,
});
await waitForLoadWithFlags("about:robots");
await TestUtils.waitForCondition(
() => gBrowser.selectedBrowser.contentTitle != "about:robots",
"Waiting for about:robots title to update"
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
await check_history();
info("2");
// Load a page in the remote process with some custom flags
await waitForLoadWithFlags(
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
"http://example.com/" + DUMMY_PATH,
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
await check_history();
info("3");
// Load a non-remote page
await waitForLoadWithFlags("about:robots");
await TestUtils.waitForCondition(
() => !!gBrowser.selectedBrowser.contentTitle.length,
"Waiting for about:robots title to update"
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
false,
"Remote attribute should be correct"
);
await check_history();
info("4");
// Load another remote page
await waitForLoadWithFlags(
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
"http://example.org/" + DUMMY_PATH,
Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
await check_history();
info("5");
// Load another remote page from a different origin
await waitForLoadWithFlags(
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
"http://example.com/" + DUMMY_PATH,
Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY
);
is(
gBrowser.selectedBrowser.isRemoteBrowser,
expectedRemote,
"Remote attribute should be correct"
);
await check_history();
is(
gExpectedHistory.entries.length,
2,
"Should end with the right number of history entries"
);
info("6");
gBrowser.removeCurrentTab();
clear_history();
});