/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /* import-globals-from helper_origin_attrs_testing.js */ loadTestSubscript("helper_origin_attrs_testing.js"); const PATH = "browser/browser/base/content/test/tabs/file_rel_opener_noopener.html"; const URI_EXAMPLECOM = "https://example.com/browser/browser/base/content/test/tabs/blank.html"; const URI_EXAMPLEORG = "https://example.org/browser/browser/base/content/test/tabs/blank.html"; var TEST_CASES = ["https://example.com/" + PATH, "https://example.org/" + PATH]; // How many times we navigate (exclude going back) const NUM_NAVIGATIONS = 5; // Remote types we expect for all pages that we open, in the order of being opened // (we don't include remote type for when we navigate back after clicking on a link) var remoteTypes; var xulFrameLoaderCreatedCounter = {}; var LINKS_INFO = [ { uri: URI_EXAMPLECOM, id: "link_noopener_examplecom", }, { uri: URI_EXAMPLECOM, id: "link_opener_examplecom", }, { uri: URI_EXAMPLEORG, id: "link_noopener_exampleorg", }, { uri: URI_EXAMPLEORG, id: "link_opener_exampleorg", }, ]; function handleEventLocal(aEvent) { if (aEvent.type != "XULFrameLoaderCreated") { return; } // Ignore element in about:preferences and any other special pages if ("gBrowser" in aEvent.target.ownerGlobal) { xulFrameLoaderCreatedCounter.numCalledSoFar++; } } add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [ ["privacy.userContext.enabled", true], // don't preload tabs so we don't have extra XULFrameLoaderCreated events // firing ["browser.newtab.preload", false], ], }); requestLongerTimeout(3); }); function setupRemoteTypes() { if (gFissionBrowser) { remoteTypes = { initial: [ "webIsolated=https://example.com", "webIsolated=https://example.com^userContextId=1", "webIsolated=https://example.com^userContextId=2", "webIsolated=https://example.com^userContextId=3", "webIsolated=https://example.com^privateBrowsingId=1", "webIsolated=https://example.org", "webIsolated=https://example.org^userContextId=1", "webIsolated=https://example.org^userContextId=2", "webIsolated=https://example.org^userContextId=3", "webIsolated=https://example.org^privateBrowsingId=1", ], regular: {}, 1: {}, 2: {}, 3: {}, private: {}, }; remoteTypes.regular[URI_EXAMPLECOM] = "webIsolated=https://example.com"; remoteTypes.regular[URI_EXAMPLEORG] = "webIsolated=https://example.org"; remoteTypes["1"][URI_EXAMPLECOM] = "webIsolated=https://example.com^userContextId=1"; remoteTypes["1"][URI_EXAMPLEORG] = "webIsolated=https://example.org^userContextId=1"; remoteTypes["2"][URI_EXAMPLECOM] = "webIsolated=https://example.com^userContextId=2"; remoteTypes["2"][URI_EXAMPLEORG] = "webIsolated=https://example.org^userContextId=2"; remoteTypes["3"][URI_EXAMPLECOM] = "webIsolated=https://example.com^userContextId=3"; remoteTypes["3"][URI_EXAMPLEORG] = "webIsolated=https://example.org^userContextId=3"; remoteTypes.private[URI_EXAMPLECOM] = "webIsolated=https://example.com^privateBrowsingId=1"; remoteTypes.private[URI_EXAMPLEORG] = "webIsolated=https://example.org^privateBrowsingId=1"; } else { let web = Array(NUM_NAVIGATIONS).fill("web"); remoteTypes = { initial: [...web, ...web], regular: {}, 1: {}, 2: {}, 3: {}, private: {}, }; remoteTypes.regular[URI_EXAMPLECOM] = "web"; remoteTypes.regular[URI_EXAMPLEORG] = "web"; remoteTypes["1"][URI_EXAMPLECOM] = "web"; remoteTypes["1"][URI_EXAMPLEORG] = "web"; remoteTypes["2"][URI_EXAMPLECOM] = "web"; remoteTypes["2"][URI_EXAMPLEORG] = "web"; remoteTypes["3"][URI_EXAMPLECOM] = "web"; remoteTypes["3"][URI_EXAMPLEORG] = "web"; remoteTypes.private[URI_EXAMPLECOM] = "web"; remoteTypes.private[URI_EXAMPLEORG] = "web"; } } add_task(async function test_user_identity_simple() { setupRemoteTypes(); /** * For each test case * - open regular, private and container tabs and load uri * - in all the tabs, click on 4 links, going back each time in between clicks * and verifying the remote type stays the same throughout * - close tabs */ for (var idx = 0; idx < TEST_CASES.length; idx++) { var uri = TEST_CASES[idx]; info(`Will open ${uri} in different tabs`); // Open uri without a container let page_regular = await openURIInRegularTab(uri); is( page_regular.tab.linkedBrowser.remoteType, remoteTypes.initial.shift(), "correct remote type" ); let pages_usercontexts = []; for ( var user_context_id = 1; user_context_id <= NUM_USER_CONTEXTS; user_context_id++ ) { let containerPage = await openURIInContainer( uri, window, user_context_id.toString() ); is( containerPage.tab.linkedBrowser.remoteType, remoteTypes.initial.shift(), "correct remote type" ); pages_usercontexts.push(containerPage); } // Open the same uri in a private browser let page_private = await openURIInPrivateTab(uri); is( page_private.tab.linkedBrowser.remoteType, remoteTypes.initial.shift(), "correct remote type" ); info(`Opened initial set of pages`); for (const linkInfo of LINKS_INFO) { info( `Will make all tabs click on link ${linkInfo.uri} id ${linkInfo.id}` ); info(`Will click on link ${linkInfo.uri} in regular tab`); await clickOnLink( page_regular.tab.linkedBrowser, uri, linkInfo, "regular" ); info(`Will click on link ${linkInfo.uri} in private tab`); await clickOnLink( page_private.tab.linkedBrowser, uri, linkInfo, "private" ); for (const page of pages_usercontexts) { info( `Will click on link ${linkInfo.uri} in container ${page.user_context_id}` ); await clickOnLink( page.tab.linkedBrowser, uri, linkInfo, page.user_context_id.toString() ); } } // Close all the tabs pages_usercontexts.forEach(page => { BrowserTestUtils.removeTab(page.tab); }); BrowserTestUtils.removeTab(page_regular.tab); BrowserTestUtils.removeTab(page_private.tab); } }); async function clickOnLink(aBrowser, aCurrURI, aLinkInfo, aIdxForRemoteTypes) { var remoteTypeBeforeNavigation = aBrowser.remoteType; var currRemoteType; // Add a listener initXulFrameLoaderCreatedCounter(xulFrameLoaderCreatedCounter); aBrowser.ownerGlobal.gBrowser.addEventListener( "XULFrameLoaderCreated", handleEventLocal ); // Retrieve the expected remote type var expectedRemoteType = remoteTypes[aIdxForRemoteTypes][aLinkInfo.uri]; // Click on the link info(`Clicking on link, expected remote type= ${expectedRemoteType}`); let newTabLoaded = BrowserTestUtils.waitForNewTab( aBrowser.ownerGlobal.gBrowser, aLinkInfo.uri, true ); SpecialPowers.spawn(aBrowser, [aLinkInfo.id], link_id => { content.document.getElementById(link_id).click(); }); // Wait for the new tab to be opened info(`About to wait for the clicked link to load in browser`); let newTab = await newTabLoaded; // Check remote type, once we have opened a new tab info(`Finished waiting for the clicked link to load in browser`); currRemoteType = newTab.linkedBrowser.remoteType; is(currRemoteType, expectedRemoteType, "Got correct remote type"); // Verify firing of XULFrameLoaderCreated event info( `XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedCounter.numCalledSoFar} time(s) for tab ${aIdxForRemoteTypes} when clicking on ${aLinkInfo.id} from page ${aCurrURI}` ); var numExpected; if (!gFissionBrowser && aLinkInfo.id.includes("noopener")) { numExpected = 1; } else { numExpected = currRemoteType == remoteTypeBeforeNavigation ? 1 : 2; } info( `num XULFrameLoaderCreated events expected ${numExpected}, curr ${currRemoteType} prev ${remoteTypeBeforeNavigation}` ); is( xulFrameLoaderCreatedCounter.numCalledSoFar, numExpected, `XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedCounter.numCalledSoFar} time(s) for tab ${aIdxForRemoteTypes} when clicking on ${aLinkInfo.id} from page ${aCurrURI}` ); // Remove the event listener aBrowser.ownerGlobal.gBrowser.removeEventListener( "XULFrameLoaderCreated", handleEventLocal ); BrowserTestUtils.removeTab(newTab); }