Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

"use strict";
async function createTabWithRandomValue(url) {
let tab = BrowserTestUtils.addTab(gBrowser, url);
let browser = tab.linkedBrowser;
await promiseBrowserLoaded(browser);
// Set a random value.
let r = `rand-${Math.random()}`;
ss.setCustomTabValue(tab, "foobar", r);
// Flush to ensure there are no scheduled messages.
await TabStateFlusher.flush(browser);
return { tab, r };
}
function isValueInClosedData(rval) {
return JSON.stringify(ss.getClosedTabDataForWindow(window)).includes(rval);
}
function restoreClosedTabWithValue(rval) {
let closedTabData = ss.getClosedTabDataForWindow(window);
let index = closedTabData.findIndex(function (data) {
return (data.state.extData && data.state.extData.foobar) == rval;
});
if (index == -1) {
throw new Error("no closed tab found for given rval");
}
return ss.undoCloseTab(window, index);
}
add_task(async function dont_save_empty_tabs() {
let { tab, r } = await createTabWithRandomValue("about:blank");
// Remove the tab before the update arrives.
let promise = promiseRemoveTabAndSessionState(tab);
// No tab state worth saving.
ok(!isValueInClosedData(r), "closed tab not saved");
await promise;
// Still no tab state worth saving.
ok(!isValueInClosedData(r), "closed tab not saved");
});
add_task(async function save_worthy_tabs_remote() {
let { tab, r } = await createTabWithRandomValue("https://example.com/");
ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
// Remove the tab before the update arrives.
let promise = promiseRemoveTabAndSessionState(tab);
// Tab state deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
await promise;
// Tab state still deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
});
add_task(async function save_worthy_tabs_nonremote() {
let { tab, r } = await createTabWithRandomValue("about:robots");
ok(!tab.linkedBrowser.isRemoteBrowser, "browser is not remote");
// Remove the tab before the update arrives.
let promise = promiseRemoveTabAndSessionState(tab);
// Tab state deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
await promise;
// Tab state still deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
});
add_task(async function save_worthy_tabs_remote_final() {
let { tab, r } = await createTabWithRandomValue("about:blank");
let browser = tab.linkedBrowser;
ok(browser.isRemoteBrowser, "browser is remote");
// Replace about:blank with a new remote page.
let entryReplaced = promiseOnHistoryReplaceEntry(browser);
browser.loadURI(Services.io.newURI("https://example.com/"), {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
await entryReplaced;
// Remotness shouldn't have changed.
ok(browser.isRemoteBrowser, "browser is still remote");
// Remove the tab before the update arrives.
await promiseRemoveTabAndSessionState(tab);
// Turns out there is a tab state worth saving.
ok(isValueInClosedData(r), "closed tab saved");
});
add_task(async function save_worthy_tabs_nonremote_final() {
let { tab, r } = await createTabWithRandomValue("about:blank");
let browser = tab.linkedBrowser;
ok(browser.isRemoteBrowser, "browser is remote");
// Replace about:blank with a non-remote entry.
BrowserTestUtils.startLoadingURIString(browser, "about:robots");
await BrowserTestUtils.browserLoaded(browser);
ok(!browser.isRemoteBrowser, "browser is not remote anymore");
// Remove the tab before the update arrives.
await promiseRemoveTabAndSessionState(tab);
// Turns out there is a tab state worth saving.
ok(isValueInClosedData(r), "closed tab saved");
});
add_task(async function dont_save_empty_tabs_final() {
let { tab, r } = await createTabWithRandomValue("https://example.com/");
let browser = tab.linkedBrowser;
ok(browser.isRemoteBrowser, "browser is remote");
// Replace the current page with an about:blank entry.
let entryReplaced = promiseOnHistoryReplaceEntry(browser);
// We're doing a cross origin navigation, so we can't reliably use a
// SpecialPowers task here. Instead we just emulate a location.replace() call.
browser.loadURI(Services.io.newURI("about:blank"), {
loadFlags:
Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT |
Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
await entryReplaced;
// Remove the tab before the update arrives.
await promiseRemoveTabAndSessionState(tab);
// Turns out we don't want to save the tab state.
ok(!isValueInClosedData(r), "closed tab not saved");
});
add_task(async function undo_worthy_tabs() {
let { tab, r } = await createTabWithRandomValue("https://example.com/");
ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
// Remove the tab before the update arrives.
let promise = promiseRemoveTabAndSessionState(tab);
// Tab state deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
// Restore the closed tab before receiving its final message.
tab = restoreClosedTabWithValue(r);
// Wait for the final update message.
await promise;
// Check we didn't add the tab back to the closed list.
ok(!isValueInClosedData(r), "tab no longer closed");
// Cleanup.
BrowserTestUtils.removeTab(tab);
});
add_task(async function forget_worthy_tabs_remote() {
let { tab, r } = await createTabWithRandomValue("https://example.com/");
ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
// Remove the tab before the update arrives.
let promise = promiseRemoveTabAndSessionState(tab);
// Tab state deemed worth saving.
ok(isValueInClosedData(r), "closed tab saved");
// Forget the closed tab.
ss.forgetClosedTab(window, 0);
// Wait for the final update message.
await promise;
// Check we didn't add the tab back to the closed list.
ok(!isValueInClosedData(r), "we forgot about the tab");
});