summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/tabs/browser_e10s_switchbrowser.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/tabs/browser_e10s_switchbrowser.js')
-rw-r--r--browser/base/content/test/tabs/browser_e10s_switchbrowser.js490
1 files changed, 490 insertions, 0 deletions
diff --git a/browser/base/content/test/tabs/browser_e10s_switchbrowser.js b/browser/base/content/test/tabs/browser_e10s_switchbrowser.js
new file mode 100644
index 0000000000..0104f3c60c
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_e10s_switchbrowser.js
@@ -0,0 +1,490 @@
+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.loadURIString(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.loadURIString(
+ 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();
+});