Bug 1630908 - Part 2: Test that we include OriginAttributes in remoteType with Fission enabled, r=nika

Differential Revision: https://phabricator.services.mozilla.com/D101074
This commit is contained in:
Anny Gakhokidze
2021-01-19 23:00:01 +00:00
parent 465bfe416d
commit 7d238c3c4a
15 changed files with 1430 additions and 1 deletions

View File

@@ -5,6 +5,7 @@ support-files =
../general/audio.ogg
file_mediaPlayback.html
test_process_flags_chrome.html
helper_origin_attrs_testing.js
[browser_accessibility_indicator.js]
skip-if = (verify && debug && (os == 'linux')) || (os == 'win' && processor == 'aarch64')
@@ -113,3 +114,9 @@ skip-if = true #bug 1642084
[browser_visibleTabs_contextMenu.js]
[browser_tabswitch_window_focus.js]
support-files = open_window_in_new_tab.html
[browser_origin_attrs_in_remote_type.js]
[browser_origin_attrs_rel.js]
skip-if = (verify && os == 'mac' && webrender)
support-files = file_rel_opener_noopener.html
[browser_navigate_through_urls_origin_attributes.js]
skip-if = (verify && os == 'mac' && webrender)

View File

@@ -0,0 +1,187 @@
/* 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/. */
/* import-globals-from helper_origin_attrs_testing.js */
loadTestSubscript("helper_origin_attrs_testing.js");
const PATH = "browser/browser/base/content/test/tabs/blank.html";
var TEST_CASES = [
{ uri: "https://example.com/" + PATH },
{ uri: "https://example.org/" + PATH },
{ uri: "about:preferences" },
{ uri: "about:config" },
];
// 3 container tabs, 1 regular tab and 1 private tab
const NUM_PAGES_OPEN_FOR_EACH_TEST_CASE = 5;
var remoteTypes;
var xulFrameLoaderCreatedCounter = {};
function handleEventLocal(aEvent) {
if (aEvent.type != "XULFrameLoaderCreated") {
return;
}
// Ignore <browser> element in about:preferences and any other special pages
if ("gBrowser" in aEvent.target.ownerGlobal) {
xulFrameLoaderCreatedCounter.numCalledSoFar++;
}
}
var gPrevRemoteTypeRegularTab;
var gPrevRemoteTypeContainerTab;
var gPrevRemoteTypePrivateTab;
add_task(async function setup() {
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],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
requestLongerTimeout(4);
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await testNavigate();
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await testNavigate();
});
}
});
function setupRemoteTypes() {
gPrevRemoteTypeRegularTab = null;
gPrevRemoteTypeContainerTab = {};
gPrevRemoteTypePrivateTab = null;
remoteTypes = getExpectedRemoteTypes(
gFissionBrowser,
NUM_PAGES_OPEN_FOR_EACH_TEST_CASE
);
}
async function testNavigate() {
setupRemoteTypes();
/**
* Open a regular tab, 3 container tabs and a private window, load about:blank
* For each test case
* load the uri
* verify correct remote type
* close tabs
*/
let regularPage = await openURIInRegularTab("about:blank", window);
gPrevRemoteTypeRegularTab = regularPage.tab.linkedBrowser.remoteType;
let containerPages = [];
for (
var user_context_id = 1;
user_context_id <= NUM_USER_CONTEXTS;
user_context_id++
) {
let containerPage = await openURIInContainer(
"about:blank",
window,
user_context_id
);
gPrevRemoteTypeContainerTab[user_context_id] =
containerPage.tab.linkedBrowser.remoteType;
containerPages.push(containerPage);
}
let privatePage = await openURIInPrivateTab("about:blank");
gPrevRemoteTypePrivateTab = privatePage.tab.linkedBrowser.remoteType;
for (const testCase of TEST_CASES) {
let uri = testCase.uri;
await loadURIAndCheckRemoteType(
regularPage.tab.linkedBrowser,
uri,
"regular tab",
gPrevRemoteTypeRegularTab
);
gPrevRemoteTypeRegularTab = regularPage.tab.linkedBrowser.remoteType;
for (const page of containerPages) {
await loadURIAndCheckRemoteType(
page.tab.linkedBrowser,
uri,
`container tab ${page.user_context_id}`,
gPrevRemoteTypeContainerTab[page.user_context_id]
);
gPrevRemoteTypeContainerTab[page.user_context_id] =
page.tab.linkedBrowser.remoteType;
}
await loadURIAndCheckRemoteType(
privatePage.tab.linkedBrowser,
uri,
"private tab",
gPrevRemoteTypePrivateTab
);
gPrevRemoteTypePrivateTab = privatePage.tab.linkedBrowser.remoteType;
}
// Close tabs
containerPages.forEach(containerPage => {
BrowserTestUtils.removeTab(containerPage.tab);
});
BrowserTestUtils.removeTab(regularPage.tab);
BrowserTestUtils.removeTab(privatePage.tab);
}
async function loadURIAndCheckRemoteType(
aBrowser,
aURI,
aText,
aPrevRemoteType
) {
let expectedCurr = remoteTypes.shift();
initXulFrameLoaderCreatedCounter(xulFrameLoaderCreatedCounter);
aBrowser.ownerGlobal.gBrowser.addEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
let loaded = BrowserTestUtils.browserLoaded(aBrowser, false, aURI);
info(`About to load ${aURI} in ${aText}`);
await BrowserTestUtils.loadURI(aBrowser, aURI);
await loaded;
// Verify correct remote type
is(
expectedCurr,
aBrowser.remoteType,
`correct remote type for ${aURI} ${aText}`
);
// Verify XULFrameLoaderCreated firing correct number of times
info(
`XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedCounter.numCalledSoFar} time(s) for ${aURI} ${aText}`
);
var numExpected = expectedCurr == aPrevRemoteType ? 0 : 1;
is(
xulFrameLoaderCreatedCounter.numCalledSoFar,
numExpected,
`XULFrameLoaderCreated fired correct number of times for ${aURI} ${aText}
prev=${aPrevRemoteType} curr =${aBrowser.remoteType}`
);
aBrowser.ownerGlobal.gBrowser.removeEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
}

View File

@@ -0,0 +1,125 @@
/* 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/blank.html";
var TEST_CASES = [
{ uri: "https://example.com/" + PATH },
{ uri: "https://example.org/" + PATH },
{ uri: "about:preferences" },
{ uri: "about:config" },
// file:// uri will be added in setup()
];
// 3 container tabs, 1 regular tab and 1 private tab
const NUM_PAGES_OPEN_FOR_EACH_TEST_CASE = 5;
var remoteTypes;
add_task(async function setup() {
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],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
requestLongerTimeout(5);
// Add a file:// uri
let dir = getChromeDir(getResolvedURI(gTestPath));
dir.append("blank.html");
// The file can be a symbolic link on local build. Normalize it to make sure
// the path matches to the actual URI opened in the new tab.
dir.normalize();
const uriString = Services.io.newFileURI(dir).spec;
TEST_CASES.push({ uri: uriString });
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await test_user_identity_simple();
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await test_user_identity_simple();
});
}
});
function setupRemoteTypes() {
remoteTypes = getExpectedRemoteTypes(
gFissionBrowser,
NUM_PAGES_OPEN_FOR_EACH_TEST_CASE
);
remoteTypes = remoteTypes.concat(
Array(NUM_PAGES_OPEN_FOR_EACH_TEST_CASE).fill("file")
); // file uri
}
async function test_user_identity_simple() {
setupRemoteTypes();
var currentRemoteType;
for (let testData of TEST_CASES) {
info(`Will open ${testData.uri} in different tabs`);
// Open uri without a container
info(`About to open a regular page`);
currentRemoteType = remoteTypes.shift();
let page_regular = await openURIInRegularTab(testData.uri, window);
is(
page_regular.tab.linkedBrowser.remoteType,
currentRemoteType,
"correct remote type"
);
// Open the same uri in different user contexts
info(`About to open container pages`);
let containerPages = [];
for (
var user_context_id = 1;
user_context_id <= NUM_USER_CONTEXTS;
user_context_id++
) {
currentRemoteType = remoteTypes.shift();
let containerPage = await openURIInContainer(
testData.uri,
window,
user_context_id
);
is(
containerPage.tab.linkedBrowser.remoteType,
currentRemoteType,
"correct remote type"
);
containerPages.push(containerPage);
}
// Open the same uri in a private browser
currentRemoteType = remoteTypes.shift();
let page_private = await openURIInPrivateTab(testData.uri);
let privateRemoteType = page_private.tab.linkedBrowser.remoteType;
is(privateRemoteType, currentRemoteType, "correct remote type");
// Close all the tabs
containerPages.forEach(page => {
BrowserTestUtils.removeTab(page.tab);
});
BrowserTestUtils.removeTab(page_regular.tab);
BrowserTestUtils.removeTab(page_private.tab);
}
}

View File

@@ -0,0 +1,325 @@
/* 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 <browser> element in about:preferences and any other special pages
if ("gBrowser" in aEvent.target.ownerGlobal) {
xulFrameLoaderCreatedCounter.numCalledSoFar++;
}
}
add_task(async function setup() {
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],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
requestLongerTimeout(3);
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await test_user_identity_simple();
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await test_user_identity_simple();
});
}
});
function setupRemoteTypes() {
let useOriginAttributesInRemoteType = Services.prefs.getBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType"
);
if (gFissionBrowser && useOriginAttributesInRemoteType) {
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 if (gFissionBrowser) {
remoteTypes = {
initial: [
...Array(NUM_NAVIGATIONS).fill("webIsolated=https://example.com"),
...Array(NUM_NAVIGATIONS).fill("webIsolated=https://example.org"),
],
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";
remoteTypes["1"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes["2"][URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes["2"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes["3"][URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes["3"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes.private[URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes.private[URI_EXAMPLEORG] = "webIsolated=https://example.org";
} 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";
}
}
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);
}

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<a target="_blank" rel="noopener" href="https://example.com/browser/browser/base/content/test/tabs/blank.html" id="link_noopener_examplecom">Go to example.com</a>
<a target="_blank" rel="opener" href="https://example.com/browser/browser/base/content/test/tabs/blank.html" id="link_opener_examplecom">Go to example.com</a>
<a target="_blank" rel="noopener" href="https://example.org/browser/browser/base/content/test/tabs/blank.html" id="link_noopener_exampleorg">Go to example.org</a>
<a target="_blank" rel="opener" href="https://example.org/browser/browser/base/content/test/tabs/blank.html" id="link_opener_exampleorg">Go to example.org</a>
</body>
</html>

View File

@@ -508,3 +508,7 @@ function httpURL(filename, host = "https://example.com/") {
);
return root + filename;
}
function loadTestSubscript(filePath) {
Services.scriptloader.loadSubScript(new URL(filePath, gTestPath).href, this);
}

View File

@@ -0,0 +1,143 @@
/* 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";
const NUM_USER_CONTEXTS = 3;
var xulFrameLoaderCreatedListenerInfo;
function initXulFrameLoaderListenerInfo() {
xulFrameLoaderCreatedListenerInfo = {};
xulFrameLoaderCreatedListenerInfo.numCalledSoFar = 0;
}
function handleEvent(aEvent) {
if (aEvent.type != "XULFrameLoaderCreated") {
return;
}
// Ignore <browser> element in about:preferences and any other special pages
if ("gBrowser" in aEvent.target.ownerGlobal) {
xulFrameLoaderCreatedListenerInfo.numCalledSoFar++;
}
}
async function openURIInRegularTab(uri, win = window) {
info(`Opening url ${uri} in a regular tab`);
initXulFrameLoaderListenerInfo();
win.gBrowser.addEventListener("XULFrameLoaderCreated", handleEvent);
let tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, uri);
info(
`XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedListenerInfo.numCalledSoFar} time(s) for ${uri} in regular tab`
);
is(
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
1,
"XULFrameLoaderCreated fired correct number of times"
);
win.gBrowser.removeEventListener("XULFrameLoaderCreated", handleEvent);
return { tab, uri };
}
async function openURIInContainer(uri, win, userContextId) {
info(`Opening url ${uri} in user context ${userContextId}`);
initXulFrameLoaderListenerInfo();
win.gBrowser.addEventListener("XULFrameLoaderCreated", handleEvent);
let tab = BrowserTestUtils.addTab(win.gBrowser, uri, {
userContextId,
});
is(
tab.getAttribute("usercontextid"),
userContextId.toString(),
"New tab has correct user context id"
);
let browser = tab.linkedBrowser;
await BrowserTestUtils.browserLoaded(browser, false, uri);
info(
`XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedListenerInfo.numCalledSoFar}
time(s) for ${uri} in container tab ${userContextId}`
);
is(
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
1,
"XULFrameLoaderCreated fired correct number of times"
);
win.gBrowser.removeEventListener("XULFrameLoaderCreated", handleEvent);
return { tab, user_context_id: userContextId, uri };
}
async function openURIInPrivateTab(uri) {
info(`Opening url ${uri} in a private browsing tab`);
let win = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
initXulFrameLoaderListenerInfo();
win.gBrowser.addEventListener("XULFrameLoaderCreated", handleEvent);
const browser = win.gBrowser.selectedTab.linkedBrowser;
let prevRemoteType = browser.remoteType;
BrowserTestUtils.loadURI(browser, uri);
await BrowserTestUtils.browserLoaded(browser, false, uri);
let currRemoteType = browser.remoteType;
info(
`XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedListenerInfo.numCalledSoFar} time(s) for ${uri} in private tab`
);
is(
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
currRemoteType == prevRemoteType ? 0 : 1,
"XULFrameLoaderCreated fired correct number of times"
);
win.gBrowser.removeEventListener("XULFrameLoaderCreated", handleEvent);
return { tab: win.gBrowser.selectedTab, uri };
}
function initXulFrameLoaderCreatedCounter(aXulFrameLoaderCreatedListenerInfo) {
aXulFrameLoaderCreatedListenerInfo.numCalledSoFar = 0;
}
// Expected remote types for the following tests:
// browser/base/content/test/tabs/browser_navigate_through_urls_origin_attributes.js
// browser/base/content/test/tabs/browser_origin_attrs_in_remote_type.js
function getExpectedRemoteTypes(gFissionBrowser, numPagesOpen) {
var remoteTypes;
let useOriginAttributesInRemoteType = Services.prefs.getBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType"
);
if (gFissionBrowser && useOriginAttributesInRemoteType) {
remoteTypes = [
"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",
];
} else if (gFissionBrowser) {
remoteTypes = [
...Array(numPagesOpen).fill("webIsolated=https://example.com"),
...Array(numPagesOpen).fill("webIsolated=https://example.org"),
];
} else {
remoteTypes = Array(numPagesOpen * 2).fill("web"); // example.com and example.org
}
remoteTypes = remoteTypes.concat(Array(numPagesOpen * 2).fill(null)); // about: pages
return remoteTypes;
}

View File

@@ -0,0 +1,2 @@
<!doctype html>
This page intentionally left blank.

View File

@@ -1,11 +1,13 @@
[DEFAULT]
support-files =
head.js
empty_file.html
file_reflect_cookie_into_title.html
favicon-normal32.png
file_set_storages.html
serviceworker.html
worker.js
blank.html
[browser_aboutURLs.js]
[browser_eme.js]
@@ -43,4 +45,4 @@ skip-if = (verify && !debug && (os == 'win'))
support-files =
saveLink.sjs
!/toolkit/content/tests/browser/common/mockTransfer.js
[browser_reopenIn.js]
[browser_originattrs_reopenin.js]

View File

@@ -0,0 +1,215 @@
/* 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/. */
/* import-globals-from ../../../../base/content/test/tabs/helper_origin_attrs_testing.js */
loadTestSubscript(
"../../../../base/content/test/tabs/helper_origin_attrs_testing.js"
);
const PATH =
"/browser/browser/components/contextualidentity/test/browser/blank.html";
const URI_EXAMPLECOM = "https://example.com/" + PATH;
const URI_EXAMPLEORG = "https://example.org/" + PATH;
var TEST_CASES = [
URI_EXAMPLECOM,
URI_EXAMPLEORG,
"about:preferences",
"about:config",
];
var remoteTypes;
var xulFrameLoaderCreatedCounter = {};
function handleEventLocal(aEvent) {
if (aEvent.type != "XULFrameLoaderCreated") {
return;
}
// Ignore <browser> element in about:preferences and any other special pages
if ("gBrowser" in aEvent.target.ownerGlobal) {
xulFrameLoaderCreatedCounter.numCalledSoFar++;
}
}
const NUM_PAGES_OPEN_FOR_EACH_TEST_CASE = 5;
add_task(async function setup() {
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],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
requestLongerTimeout(5);
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await testReopen();
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await testReopen();
});
}
});
function setupRemoteTypes() {
remoteTypes = {
regular: { "about:preferences": null, "about:config": null },
"1": { "about:preferences": null, "about:config": null },
"2": { "about:preferences": null, "about:config": null },
"3": { "about:preferences": null, "about:config": null },
};
let useOriginAttributesInRemoteType = Services.prefs.getBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType"
);
if (gFissionBrowser && useOriginAttributesInRemoteType) {
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";
} else if (gFissionBrowser) {
remoteTypes.regular[URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes.regular[URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes["1"][URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes["1"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes["2"][URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes["2"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
remoteTypes["3"][URI_EXAMPLECOM] = "webIsolated=https://example.com";
remoteTypes["3"][URI_EXAMPLEORG] = "webIsolated=https://example.org";
} else {
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";
}
}
async function testReopen() {
setupRemoteTypes();
/**
* Open a regular tab
* For each url
* navigate regular tab to that url
* pid_seen = [regular tab pid]
* For each container
* reopen regular tab in that container
* verify remote type
* reopen container tab in regular tab
* Close all the tabs
* This tests that behaviour of reopening tabs is correct
* */
let regularPage = await openURIInRegularTab("about:blank");
var currRemoteType;
for (const uri of TEST_CASES) {
// Navigate regular tab to a test-uri
let loaded = BrowserTestUtils.browserLoaded(
regularPage.tab.linkedBrowser,
false,
uri
);
await BrowserTestUtils.loadURI(regularPage.tab.linkedBrowser, uri);
await loaded;
info(`Start Opened ${uri} in a regular tab`);
currRemoteType = regularPage.tab.linkedBrowser.remoteType;
is(currRemoteType, remoteTypes.regular[uri], "correct remote type");
let containerTabs = [];
// Reopen this test-uri in different containers and ensure pids are different
for (var userCtxId = 1; userCtxId <= NUM_USER_CONTEXTS; userCtxId++) {
// Prepare the reopen menu
let reopenMenu = await openReopenMenuForTab(regularPage.tab);
// Add a listener for XULFrameLoaderCreated
initXulFrameLoaderCreatedCounter(xulFrameLoaderCreatedCounter);
regularPage.tab.ownerGlobal.gBrowser.addEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
// Reopen the page in a container
let containerTab = await openTabInContainer(
gBrowser,
uri,
reopenMenu,
userCtxId.toString()
);
info(`Re-opened ${uri} in a container tab ${userCtxId}`);
// Check correct remote type
currRemoteType = containerTab.linkedBrowser.remoteType;
is(
currRemoteType,
remoteTypes[userCtxId.toString()][uri],
"correct remote type"
);
// Check that XULFrameLoaderCreated has fired off correct number of times
is(
xulFrameLoaderCreatedCounter.numCalledSoFar,
1,
`XULFrameLoaderCreated was fired once when reopening ${uri} in container ${userCtxId}`
);
regularPage.tab.ownerGlobal.gBrowser.removeEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
// Save the tab so we can close it later
containerTabs.push(containerTab);
}
let containedTabsOpenedInNoContainer = [];
for (const containerTab of containerTabs) {
info(`About to re-open ${uri} in a regular, no-container tab`);
let reopenMenu = await openReopenMenuForTab(containerTab);
let reopenedInNoContainerTab = await openTabInContainer(
gBrowser,
uri,
reopenMenu,
"0"
);
info(`Re-opened ${uri} in a regular, no-container tab`);
// Check remote type
currRemoteType = reopenedInNoContainerTab.linkedBrowser.remoteType;
is(currRemoteType, remoteTypes.regular[uri], "correct remote type");
containedTabsOpenedInNoContainer.push(reopenedInNoContainerTab);
}
// Close tabs
for (const tab of containerTabs.concat(containedTabsOpenedInNoContainer)) {
BrowserTestUtils.removeTab(tab);
}
}
BrowserTestUtils.removeTab(regularPage.tab);
}

View File

@@ -0,0 +1,49 @@
async function openTabMenuFor(tab) {
let tabMenu = tab.ownerDocument.getElementById("tabContextMenu");
let tabMenuShown = BrowserTestUtils.waitForEvent(tabMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(
tab,
{ type: "contextmenu" },
tab.ownerGlobal
);
await tabMenuShown;
return tabMenu;
}
async function openReopenMenuForTab(tab) {
openTabMenuFor(tab);
let reopenItem = tab.ownerDocument.getElementById(
"context_reopenInContainer"
);
ok(!reopenItem.hidden, "Reopen in Container item should be shown");
const menuPopup = tab.ownerDocument.getElementById(
"context_reopenInContainer"
).menupopup;
const menuPopupPromise = BrowserTestUtils.waitForEvent(
menuPopup,
"popupshown"
);
info(`About to open a popup`);
menuPopup.openPopup();
info(`Waiting for the menu popup promise`);
await menuPopupPromise;
info(`Awaited menu popup promise`);
return menuPopup;
}
function openTabInContainer(gBrowser, url, reopenMenu, id) {
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, url, true);
let menuitem = reopenMenu.querySelector(
`menuitem[data-usercontextid="${id}"]`
);
EventUtils.synthesizeMouseAtCenter(menuitem, {}, menuitem.ownerGlobal);
return tabPromise;
}
function loadTestSubscript(filePath) {
Services.scriptloader.loadSubScript(new URL(filePath, gTestPath).href, this);
}

View File

@@ -317,3 +317,5 @@ skip-if = true #Bug 1455602
[browser_cookies_sameSite.js]
[browser_urlbarSearchMode.js]
[browser_restore_container_tabs_oa.js]
[browser_restore_private_tab_os.js]

View File

@@ -0,0 +1,272 @@
/* 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";
const PATH = "browser/browser/components/sessionstore/test/empty.html";
/* import-globals-from ../../../base/content/test/tabs/helper_origin_attrs_testing.js */
loadTestSubscript(
"../../../base/content/test/tabs/helper_origin_attrs_testing.js"
);
var TEST_CASES = [
"https://example.com/" + PATH,
"https://example.org/" + PATH,
"about:preferences",
"about:config",
];
var remoteTypes;
var xulFrameLoaderCreatedCounter = {};
function handleEventLocal(aEvent) {
if (aEvent.type != "XULFrameLoaderCreated") {
return;
}
// Ignore <browser> element in about:preferences and any other special pages
if ("gBrowser" in aEvent.target.ownerGlobal) {
xulFrameLoaderCreatedCounter.numCalledSoFar++;
}
}
var NUM_DIFF_TAB_MODES = NUM_USER_CONTEXTS + 1; /** regular tab */
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [
// Set the pref to true so we know exactly how many tabs should be restoring at
// any given time. This guarantees that a finishing load won't start another.
["browser.sessionstore.restore_on_demand", true],
// Don't restore tabs lazily.
["browser.sessionstore.restore_tabs_lazily", true],
// don't preload tabs so we don't have extra XULFrameLoaderCreated events
// firing
["browser.newtab.preload", false],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
requestLongerTimeout(7);
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await testRestore();
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await testRestore();
});
}
});
function setupRemoteTypes() {
let useOriginAttributesInRemoteType = Services.prefs.getBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType"
);
if (gFissionBrowser && useOriginAttributesInRemoteType) {
remoteTypes = [
"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.org",
"webIsolated=https://example.org^userContextId=1",
"webIsolated=https://example.org^userContextId=2",
"webIsolated=https://example.org^userContextId=3",
];
} else if (gFissionBrowser) {
remoteTypes = [
...Array(NUM_DIFF_TAB_MODES).fill("webIsolated=https://example.com"),
...Array(NUM_DIFF_TAB_MODES).fill("webIsolated=https://example.org"),
];
} else {
remoteTypes = Array(
NUM_DIFF_TAB_MODES * 2 /** 2 is the number of non parent uris */
).fill("web");
}
remoteTypes.push(...Array(NUM_DIFF_TAB_MODES * 2).fill(null)); // remote types for about: pages
forgetClosedWindows();
is(SessionStore.getClosedWindowCount(), 0, "starting with no closed windows");
}
/*
* 1. Open several tabs in different containers and in regular tabs
[page1, page2, page3] [ [(page1 - work) (page1 - home)] [(page2 - work) (page2 - home)] ]
* 2. Close the window
* 3. Restore session, window will have the following tabs
* [initial blank page, page1, page1-work, page1-home, page2, page2-work, page2-home]
* 4. Verify correct remote types and that XULFrameLoaderCreated gets fired correct number of times
*/
async function testRestore() {
setupRemoteTypes();
let newWin = await promiseNewWindowLoaded();
var regularPages = [];
var containerPages = {};
// Go through all the test cases and open same set of urls in regular tabs and in container tabs
for (const uri of TEST_CASES) {
// Open a url in a regular tab
let regularPage = await openURIInRegularTab(uri, newWin);
regularPages.push(regularPage);
// Open the same url in different user contexts
for (
var user_context_id = 1;
user_context_id <= NUM_USER_CONTEXTS;
user_context_id++
) {
let containerPage = await openURIInContainer(
uri,
newWin,
user_context_id
);
containerPages[uri] = containerPage;
}
}
await TabStateFlusher.flushWindow(newWin);
// Close the window
await BrowserTestUtils.closeWindow(newWin);
await forceSaveState();
is(
SessionStore.getClosedWindowCount(),
1,
"Should have restore data for the closed window"
);
// Now restore the window
newWin = SessionStore.undoCloseWindow(0);
// Make sure to wait for the window to be restored.
await Promise.all([
BrowserTestUtils.waitForEvent(newWin, "SSWindowStateReady"),
]);
await BrowserTestUtils.waitForEvent(
newWin.gBrowser.tabContainer,
"SSTabRestored"
);
var nonblank_pages_len =
TEST_CASES.length + NUM_USER_CONTEXTS * TEST_CASES.length;
is(
newWin.gBrowser.tabs.length,
nonblank_pages_len + 1 /* initial page */,
"Correct number of tabs restored"
);
// Now we have pages opened in the following manner
// [blank page, page1, page1-work, page1-home, page2, page2-work, page2-home]
info(`Number of tabs restored: ${newWin.gBrowser.tabs.length}`);
var currRemoteType, expectedRemoteType;
let loaded;
for (var tab_idx = 1; tab_idx < nonblank_pages_len; ) {
info(`Accessing regular tab at index ${tab_idx}`);
var test_page_data = regularPages.shift();
let regular_tab = newWin.gBrowser.tabs[tab_idx];
let regular_browser = regular_tab.linkedBrowser;
// I would have used browserLoaded but for about:config it doesn't work
let correctLocation = BrowserTestUtils.waitForCondition(() => {
return regular_browser.currentURI.spec == test_page_data.uri;
});
newWin.gBrowser.selectedTab = regular_tab;
await TabStateFlusher.flush(regular_browser);
await correctLocation;
currRemoteType = regular_browser.remoteType;
expectedRemoteType = remoteTypes.shift();
is(
currRemoteType,
expectedRemoteType,
"correct remote type for regular tab"
);
let page_uri = regular_browser.currentURI.spec;
info(`Current uri = ${page_uri}`);
// Iterate over container pages, starting after the regular page and ending before the next regular page
var userContextId = 1;
for (
var container_tab_idx = tab_idx + 1;
container_tab_idx < tab_idx + 1 + NUM_USER_CONTEXTS;
container_tab_idx++, userContextId++
) {
info(`Accessing container tab at index ${container_tab_idx}`);
let container_tab = newWin.gBrowser.tabs[container_tab_idx];
initXulFrameLoaderCreatedCounter(xulFrameLoaderCreatedCounter);
container_tab.ownerGlobal.gBrowser.addEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
loaded = BrowserTestUtils.browserLoaded(
container_tab.linkedBrowser,
false,
test_page_data.uri
);
newWin.gBrowser.selectedTab = container_tab;
await TabStateFlusher.flush(container_tab.linkedBrowser);
await loaded;
let uri = container_tab.linkedBrowser.currentURI.spec;
// Verify XULFrameLoaderCreated was fired once
if (
test_page_data.uri == "about:preferences" ||
test_page_data.uri == "about:config" ||
gFissionBrowser
) {
todo_is(
xulFrameLoaderCreatedCounter.numCalledSoFar,
1,
`XULFrameLoaderCreated was fired once, when restoring ${uri} in container ${userContextId} `
);
} else {
is(
xulFrameLoaderCreatedCounter.numCalledSoFar,
1,
`XULFrameLoaderCreated was fired once, when restoring ${uri} in container ${userContextId} `
);
}
// While the above assertion is `todo_is`, ensure that we don't have a regression
// from current behaviour by checking that the event is fired < 3 times.
ok(
xulFrameLoaderCreatedCounter.numCalledSoFar <= 2,
`XULFrameLoaderCreated was fired [1,2] times, when restoring ${uri} in container ${userContextId} `
);
container_tab.ownerGlobal.gBrowser.removeEventListener(
"XULFrameLoaderCreated",
handleEventLocal
);
// Verify correct remote type for container tab
currRemoteType = container_tab.linkedBrowser.remoteType;
expectedRemoteType = remoteTypes.shift();
info(
`Remote type for container tab ${userContextId} is ${currRemoteType}`
);
is(
currRemoteType,
expectedRemoteType,
"correct remote type for container tab"
);
}
// Advance to the next regular page in our tabs list
tab_idx = container_tab_idx;
}
await BrowserTestUtils.closeWindow(newWin);
}

View File

@@ -0,0 +1,80 @@
/* 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";
const TEST_URI =
"https://example.com/" +
"browser/browser/components/sessionstore/test/empty.html";
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [
// Set the pref to true so we know exactly how many tabs should be restoring at
// any given time. This guarantees that a finishing load won't start another.
["browser.sessionstore.restore_on_demand", true],
// Don't restore tabs lazily.
["browser.sessionstore.restore_tabs_lazily", true],
// don't preload tabs so we don't have extra XULFrameLoaderCreated events
// firing
["browser.newtab.preload", false],
// We want changes to this pref to be reverted at the end of the test
["browser.tabs.remote.useOriginAttributesInRemoteType", false],
],
});
var expectedRemoteTypeWithOA = gFissionBrowser
? "webIsolated=https://example.com^privateBrowsingId=1"
: "web";
add_task(async function testWithOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
true
);
await testRestore(expectedRemoteTypeWithOA);
});
if (gFissionBrowser) {
add_task(async function testWithoutOA() {
Services.prefs.setBoolPref(
"browser.tabs.remote.useOriginAttributesInRemoteType",
false
);
await testRestore("webIsolated=https://example.com");
});
}
});
async function testRestore(aExpectedRemoteType) {
// Clear the list of closed windows.
forgetClosedWindows();
// Create a new private window
let win = await promiseNewWindowLoaded({ private: true });
// Create a new private tab
let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_URI);
let browser = tab.linkedBrowser;
await promiseBrowserLoaded(browser);
await TabStateFlusher.flush(browser);
// Ensure that closed tabs in a private windows can be restored.
win.gBrowser.removeTab(tab);
is(ss.getClosedTabCount(win), 1, "there is a single tab to restore");
tab = SessionStore.undoCloseTab(win, 0);
info(`Undo close tab`);
browser = tab.linkedBrowser;
await promiseTabRestored(tab);
info(`Private tab restored`);
is(browser.remoteType, aExpectedRemoteType, "correct remote type");
await BrowserTestUtils.closeWindow(win);
// Cleanup
info("Forgetting closed tabs");
while (ss.getClosedTabCount(window)) {
ss.forgetClosedTab(window, 0);
}
}

View File

@@ -712,3 +712,7 @@ function promiseOnHistoryReplaceEntry(browser) {
});
});
}
function loadTestSubscript(filePath) {
Services.scriptloader.loadSubScript(new URL(filePath, gTestPath).href, this);
}