Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
-
CI results over the last 21 days3,958Runs99.97%Pass0Failures1Timeouts0Crashes0Skips
Runs with issues per day (up to 0.3%) Oct 25Nov 14- Timeouts
- Manifest: browser/base/content/test/browser-sanitize/browser.toml
/* Any copyright is dedicated to the Public Domain.
// Tests the helpers that the openWindows cleaner uses for its keepPinnedTabs
// option: clearing open windows for real would close the test's own window.
const { TabStateFlusher } = ChromeUtils.importESModule(
"moz-src:///browser/components/sessionstore/TabStateFlusher.sys.mjs"
);
async function addLoadedTab(win, url, options = {}) {
let tab = BrowserTestUtils.addTab(win.gBrowser, url, options);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url);
return tab;
}
add_task(async function keepsPinnedTabsOfNonPrivateWindows() {
await SpecialPowers.pushPrefEnv({
set: [["privacy.userContext.enabled", true]],
});
const FIRST_URL =
// A pinned tab that navigated from the page itself, so that its current
// entry has a referrer and a content triggering principal, with back
// history, page state and sessionStorage.
let tabWithHistory = await addLoadedTab(window, FIRST_URL);
gBrowser.selectedTab = tabWithHistory;
await SpecialPowers.spawn(tabWithHistory.linkedBrowser, [SECOND_URL], url => {
let link = content.document.createElement("a");
link.href = url;
link.id = "link";
link.textContent = "link";
content.document.body.append(link);
});
let loaded = BrowserTestUtils.browserLoaded(
tabWithHistory.linkedBrowser,
false,
SECOND_URL
);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#link",
{},
tabWithHistory.linkedBrowser
);
await loaded;
await SpecialPowers.spawn(tabWithHistory.linkedBrowser, [], async () => {
content.history.replaceState({ page: "state" }, "");
content.sessionStorage.setItem("key", "value");
});
tabWithHistory.toggleMuteAudio();
gBrowser.pinTab(tabWithHistory);
await TabStateFlusher.flush(tabWithHistory.linkedBrowser);
let originalState = JSON.parse(SessionStore.getTabState(tabWithHistory));
let originalEntry = originalState.entries[originalState.index - 1];
Assert.greater(originalState.entries.length, 1, "The tab has history");
Assert.ok(originalEntry.referrerInfo, "The tab has a referrer");
Assert.ok(originalEntry.structuredCloneState, "The tab has page state");
Assert.ok(originalState.storage, "The tab has sessionStorage");
let otherWin = await BrowserTestUtils.openNewBrowserWindow();
let containerTab = await addLoadedTab(otherWin, CONTAINER_URL, {
userContextId: 1,
});
otherWin.gBrowser.pinTab(containerTab);
let privateWin = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
privateWin.gBrowser.pinTab(privateTab);
// Like the openWindows cleaner does before collecting.
for (let win of [window, otherWin, privateWin]) {
await TabStateFlusher.flushWindow(win);
}
let { openWindows } = Sanitizer.items;
let pinnedTabs = openWindows._collectPinnedTabs([
window,
otherWin,
privateWin,
]);
Assert.deepEqual(
pinnedTabs.map(state => [state.entries[0].url, state.userContextId]),
[
[SECOND_URL, 0],
[CONTAINER_URL, 1],
],
"Collects the pinned tabs of non-private windows in window order"
);
let newWin = await BrowserTestUtils.openNewBrowserWindow();
openWindows._restorePinnedTabs(newWin, pinnedTabs);
let restored = newWin.gBrowser.tabs.filter(tab => tab.pinned);
Assert.deepEqual(
restored.map(tab => [tab.linkedBrowser.currentURI.spec, tab.userContextId]),
[
[SECOND_URL, 0],
[CONTAINER_URL, 1],
],
"Both pinned tabs are restored with their address and container"
);
for (let tab of restored) {
Assert.ok(!tab.linkedPanel, "The tab is not loaded");
}
let [restoredTab] = restored;
Assert.equal(restoredTab.label, tabWithHistory.label, "Keeps the title");
Assert.ok(restoredTab.muted, "Stays muted");
let state = JSON.parse(SessionStore.getTabState(restoredTab));
Assert.equal(state.entries.length, 1, "Has no back or forward history");
let [entry] = state.entries;
Assert.equal(
entry.triggeringPrincipal_base64,
originalEntry.triggeringPrincipal_base64,
"Keeps the triggering principal"
);
Assert.equal(
entry.referrerInfo,
originalEntry.referrerInfo,
"Keeps the referrer"
);
Assert.ok(!entry.structuredCloneState, "Drops the page state");
Assert.ok(!state.storage, "Drops sessionStorage");
for (let win of [newWin, privateWin, otherWin]) {
await BrowserTestUtils.closeWindow(win);
}
BrowserTestUtils.removeTab(tabWithHistory);
await SpecialPowers.popPrefEnv();
});
/**
* Restoring runs while the sanitizer waits for the new window, so a tab that
* fails to restore must not throw and keep the other tabs from being added.
*/
add_task(async function skipsTabsThatFailToRestore() {
let tab = await addLoadedTab(window, URL);
await TabStateFlusher.flush(tab.linkedBrowser);
let { openWindows } = Sanitizer.items;
let state = openWindows._scrubTabState(
JSON.parse(SessionStore.getTabState(tab))
);
state.pinned = true;
BrowserTestUtils.removeTab(tab);
let newWin = await BrowserTestUtils.openNewBrowserWindow();
openWindows._restorePinnedTabs(newWin, [{}, state]);
let [firstTab] = newWin.gBrowser.tabs;
Assert.ok(firstTab.pinned, "The valid tab is restored, pinned, first");
Assert.equal(
firstTab.linkedBrowser.currentURI.spec,
URL,
"The valid tab keeps its address"
);
Assert.equal(
newWin.gBrowser.tabs.filter(t => t.pinned).length,
1,
"The invalid state adds no tab"
);
await BrowserTestUtils.closeWindow(newWin);
});
/**
* The pinned tabs are only added back once everything else is cleared, so
* that selecting one can't load anything while clearing is still running.
*/
add_task(async function restoresAfterClearing() {
let tab = await addLoadedTab(window, URL);
await TabStateFlusher.flush(tab.linkedBrowser);
let { items } = Sanitizer;
let state = items.openWindows._scrubTabState(
JSON.parse(SessionStore.getTabState(tab))
);
state.pinned = true;
BrowserTestUtils.removeTab(tab);
let newWin = await BrowserTestUtils.openNewBrowserWindow();
// Clearing open windows for real would close the test's own window.
let originalClear = items.openWindows.clear;
items.openWindows.clear = async () => ({
newWindow: newWin,
pinnedTabs: [state],
});
let { promise: slowCleared, resolve: finishSlowCleaner } =
Promise.withResolvers();
let slowCleanerStarted = false;
items.testSlowCleaner = {
clear() {
slowCleanerStarted = true;
return slowCleared;
},
};
let pinnedCount = () => newWin.gBrowser.tabs.filter(t => t.pinned).length;
try {
let sanitized = Sanitizer.sanitize(["openWindows", "testSlowCleaner"], {
keepPinnedTabs: true,
});
await TestUtils.waitForCondition(
() => slowCleanerStarted,
"Waiting for the other cleaners to start."
);
Assert.equal(pinnedCount(), 0, "No pinned tab while clearing runs");
finishSlowCleaner();
await sanitized;
Assert.equal(pinnedCount(), 1, "The pinned tab is added once cleared");
} finally {
items.openWindows.clear = originalClear;
delete items.testSlowCleaner;
}
await BrowserTestUtils.closeWindow(newWin);
});
add_task(async function scrubsSessionData() {
let state = Sanitizer.items.openWindows._scrubTabState({
entries: [
{
title: "2",
triggeringPrincipal_base64: "principal",
referrerInfo: "referrer",
presState: [{}],
scroll: "0,10",
structuredCloneState: "state",
structuredCloneVersion: 8,
},
],
index: 2,
requestedIndex: 3,
pinned: true,
muted: true,
muteReason: "user",
userContextId: 2,
attributes: { customizemode: "true" },
image: "icon",
extData: { key: "value" },
formdata: { id: { field: "typed" } },
scroll: { scroll: "0,10" },
searchMode: { engineName: "engine" },
userTypedClear: 1,
userTypedValue: "typed",
});
Assert.deepEqual(
state,
{
entries: [
{
title: "2",
triggeringPrincipal_base64: "principal",
referrerInfo: "referrer",
},
],
index: 1,
pinned: true,
muted: true,
muteReason: "user",
userContextId: 2,
attributes: { customizemode: "true" },
image: "icon",
},
"Keeps the current entry and the tab's own state only"
);
});