diff options
Diffstat (limited to 'toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js')
-rw-r--r-- | toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js b/toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js new file mode 100644 index 0000000000..13a7bd0c10 --- /dev/null +++ b/toolkit/components/remotebrowserutils/tests/browser/browser_httpCrossOriginOpenerPolicy.js @@ -0,0 +1,365 @@ +"use strict"; + +const { E10SUtils } = ChromeUtils.import( + "resource://gre/modules/E10SUtils.jsm" +); + +const COOP_PREF = "browser.tabs.remote.useCrossOriginOpenerPolicy"; + +async function setPref() { + await SpecialPowers.pushPrefEnv({ + set: [[COOP_PREF, true]], + }); +} + +async function unsetPref() { + await SpecialPowers.pushPrefEnv({ + set: [[COOP_PREF, false]], + }); +} + +function httpURL(filename, host = "https://example.com") { + let root = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + host + ); + return root + filename; +} + +async function performLoad(browser, opts, action) { + let loadedPromise = BrowserTestUtils.browserStopped( + browser, + opts.url, + opts.maybeErrorPage + ); + await action(); + await loadedPromise; +} + +async function test_coop( + start, + target, + expectedProcessSwitch, + startRemoteTypeCheck, + targetRemoteTypeCheck +) { + return BrowserTestUtils.withNewTab( + { + gBrowser, + url: start, + waitForStateStop: true, + }, + async function(_browser) { + info(`test_coop: Test tab ready: ${start}`); + + let browser = gBrowser.selectedBrowser; + let firstRemoteType = browser.remoteType; + let firstBC = browser.browsingContext; + + info(`firstBC: ${firstBC.id} remoteType: ${firstRemoteType}`); + + if (startRemoteTypeCheck) { + startRemoteTypeCheck(firstRemoteType); + } + + await performLoad( + browser, + { + url: target, + maybeErrorPage: false, + }, + async () => BrowserTestUtils.loadURI(browser, target) + ); + + info(`Navigated to: ${target}`); + browser = gBrowser.selectedBrowser; + let secondRemoteType = browser.remoteType; + let secondBC = browser.browsingContext; + + info(`secondBC: ${secondBC.id} remoteType: ${secondRemoteType}`); + if (targetRemoteTypeCheck) { + targetRemoteTypeCheck(secondRemoteType); + } + if (expectedProcessSwitch) { + Assert.notEqual(firstBC.id, secondBC.id, `from: ${start} to ${target}`); + } else { + Assert.equal(firstBC.id, secondBC.id, `from: ${start} to ${target}`); + } + } + ); +} + +function waitForDownloadWindow() { + return new Promise(resolve => { + var listener = { + onOpenWindow: aXULWindow => { + info("Download window shown..."); + Services.wm.removeListener(listener); + + function downloadOnLoad() { + domwindow.removeEventListener("load", downloadOnLoad, true); + + is( + domwindow.document.location.href, + "chrome://mozapps/content/downloads/unknownContentType.xhtml", + "Download page appeared" + ); + resolve(domwindow); + } + + var domwindow = aXULWindow.docShell.domWindow; + domwindow.addEventListener("load", downloadOnLoad, true); + }, + onCloseWindow: aXULWindow => {}, + }; + + Services.wm.addListener(listener); + }); +} + +async function test_download_from(initCoop, downloadCoop) { + return BrowserTestUtils.withNewTab("about:blank", async function(_browser) { + info(`test_download: Test tab ready`); + + let start = httpURL( + "coop_header.sjs?downloadPage&coop=" + initCoop, + "https://example.com" + ); + await performLoad( + _browser, + { + url: start, + maybeErrorPage: false, + }, + async () => { + info(`test_download: Loading download page ${start}`); + return BrowserTestUtils.loadURI(_browser, start); + } + ); + + info(`test_download: Download page ready ${start}`); + info(`Downloading ${downloadCoop}`); + + let winPromise = waitForDownloadWindow(); + let browser = gBrowser.selectedBrowser; + SpecialPowers.spawn(browser, [downloadCoop], downloadCoop => { + content.document.getElementById(downloadCoop).click(); + }); + + // if the download page doesn't appear, the promise leads a timeout. + let win = await winPromise; + + await BrowserTestUtils.closeWindow(win); + }); +} + +// Check that multiple navigations of the same tab will only switch processes +// when it's expected. +add_task(async function test_multiple_nav_process_switches() { + await setPref(); + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: httpURL("coop_header.sjs", "https://example.org"), + waitForStateStop: true, + }, + async function(browser) { + let prevBC = browser.browsingContext; + + let target = httpURL("coop_header.sjs?.", "https://example.org"); + await performLoad( + browser, + { + url: target, + maybeErrorPage: false, + }, + async () => BrowserTestUtils.loadURI(browser, target) + ); + + Assert.equal(prevBC, browser.browsingContext); + prevBC = browser.browsingContext; + + target = httpURL( + "coop_header.sjs?coop=same-origin", + "https://example.org" + ); + await performLoad( + browser, + { + url: target, + maybeErrorPage: false, + }, + async () => BrowserTestUtils.loadURI(browser, target) + ); + + Assert.notEqual(prevBC, browser.browsingContext); + prevBC = browser.browsingContext; + + target = httpURL( + "coop_header.sjs?coop=same-origin", + "https://example.com" + ); + await performLoad( + browser, + { + url: target, + maybeErrorPage: false, + }, + async () => BrowserTestUtils.loadURI(browser, target) + ); + + Assert.notEqual(prevBC, browser.browsingContext); + prevBC = browser.browsingContext; + + target = httpURL( + "coop_header.sjs?coop=same-origin&index=4", + "https://example.com" + ); + await performLoad( + browser, + { + url: target, + maybeErrorPage: false, + }, + async () => BrowserTestUtils.loadURI(browser, target) + ); + + Assert.equal(prevBC, browser.browsingContext); + } + ); +}); + +add_task(async function test_disabled() { + await unsetPref(); + await test_coop( + httpURL("coop_header.sjs", "https://example.com"), + httpURL("coop_header.sjs", "https://example.com"), + false + ); + await test_coop( + httpURL("coop_header.sjs?coop=same-origin", "http://example.com"), + httpURL("coop_header.sjs", "http://example.com"), + false + ); + await test_coop( + httpURL("coop_header.sjs", "http://example.com"), + httpURL("coop_header.sjs?coop=same-origin", "http://example.com"), + false + ); +}); + +add_task(async function test_enabled() { + await setPref(); + + function checkIsCoopRemoteType(remoteType) { + Assert.ok( + remoteType.startsWith(E10SUtils.WEB_REMOTE_COOP_COEP_TYPE_PREFIX), + `${remoteType} expected to be coop` + ); + } + + function checkIsNotCoopRemoteType(remoteType) { + if (gFissionBrowser) { + Assert.ok( + remoteType.startsWith("webIsolated="), + `${remoteType} expected to start with webIsolated=` + ); + } else { + Assert.equal( + remoteType, + E10SUtils.WEB_REMOTE_TYPE, + `${remoteType} expected to be web` + ); + } + } + + await test_coop( + httpURL("coop_header.sjs", "https://example.com"), + httpURL("coop_header.sjs", "https://example.com"), + false, + checkIsNotCoopRemoteType, + checkIsNotCoopRemoteType + ); + await test_coop( + httpURL("coop_header.sjs", "https://example.com"), + httpURL("coop_header.sjs?coop=same-origin", "https://example.org"), + true, + checkIsNotCoopRemoteType, + checkIsNotCoopRemoteType + ); + await test_coop( + httpURL("coop_header.sjs?coop=same-origin&index=1", "https://example.com"), + httpURL("coop_header.sjs?coop=same-origin&index=1", "https://example.org"), + true, + checkIsNotCoopRemoteType, + checkIsNotCoopRemoteType + ); + await test_coop( + httpURL("coop_header.sjs", "https://example.com"), + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp", + "https://example.com" + ), + true, + checkIsNotCoopRemoteType, + checkIsCoopRemoteType + ); + await test_coop( + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp&index=2", + "https://example.com" + ), + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp&index=3", + "https://example.com" + ), + false, + checkIsCoopRemoteType, + checkIsCoopRemoteType + ); + await test_coop( + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp&index=4", + "https://example.com" + ), + httpURL("coop_header.sjs", "https://example.com"), + true, + checkIsCoopRemoteType, + checkIsNotCoopRemoteType + ); + await test_coop( + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp&index=5", + "https://example.com" + ), + httpURL( + "coop_header.sjs?coop=same-origin&coep=require-corp&index=6", + "https://example.org" + ), + true, + checkIsCoopRemoteType, + checkIsCoopRemoteType + ); +}); + +add_task(async function test_download() { + requestLongerTimeout(4); + await setPref(); + + let initCoopArray = ["", "same-origin"]; + + let downloadCoopArray = [ + "no-coop", + "same-origin", + "same-origin-allow-popups", + ]; + + // If the coop mismatch between current page and download link, clicking the + // download link will make the page empty and popup the download window. That + // forces us to reload the page every time. + for (var initCoop of initCoopArray) { + for (var downloadCoop of downloadCoopArray) { + await test_download_from(initCoop, downloadCoop); + } + } +}); |