Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'mac' && os_version == '10.15' && processor == 'x86_64' && opt OR os == 'mac' && os_version == '11.20' && arch == 'aarch64' && opt
- Manifest: browser/components/sessionstore/test/browser.toml
/* Any copyright is dedicated to the Public Domain.
"use strict";
const { _LastSession, _lastClosedActions } = ChromeUtils.importESModule(
"resource:///modules/sessionstore/SessionStore.sys.mjs"
);
async function testLastClosedActionsEntries() {
SessionStore.resetLastClosedActions();
let win2 = await BrowserTestUtils.openNewBrowserWindow();
BrowserTestUtils.startLoadingURIString(
win2.gBrowser.selectedBrowser,
);
await BrowserTestUtils.browserLoaded(win2.gBrowser.selectedBrowser);
Assert.equal(
SessionStore.lastClosedActions.length,
1,
`1 closed action has been recorded`
);
await BrowserTestUtils.closeWindow(win2);
Assert.equal(
SessionStore.lastClosedActions.length,
2,
`2 closed actions have been recorded`
);
}
add_setup(() => {
forgetClosedTabs(window);
registerCleanupFunction(() => {
forgetClosedTabs(window);
});
// needed for verify tests so that forgetting tabs isn't recorded
SessionStore.resetLastClosedActions();
});
/**
* Tests that if the user invokes restoreLastClosedTabOrWindowOrSession it will
* result in either the last session will be restored, if possible, the last
* tab (or multiple selected tabs) that was closed is reopened, or the last
* window that is closed is reopened.
*/
add_task(async function test_undo_last_action() {
const state = {
windows: [
{
tabs: [
{
entries: [
{
title: "example.org",
triggeringPrincipal_base64,
},
],
},
{
entries: [
{
title: "example.com",
triggeringPrincipal_base64,
},
],
},
{
entries: [
{
title: "mozilla",
triggeringPrincipal_base64,
},
],
},
],
selected: 3,
},
],
};
_LastSession.setState(state);
let sessionRestored = promiseSessionStoreLoads(3 /* total restored tabs */);
restoreLastClosedTabOrWindowOrSession();
await sessionRestored;
Assert.equal(
window.gBrowser.tabs.length,
3,
"Window has three tabs after session is restored"
);
// open and close a window, then reopen it
let win2 = await BrowserTestUtils.openNewBrowserWindow();
Assert.equal(win2.gBrowser.tabs.length, 1, "Second window has one open tab");
BrowserTestUtils.startLoadingURIString(
win2.gBrowser.selectedBrowser,
);
await BrowserTestUtils.browserLoaded(win2.gBrowser.selectedBrowser);
await BrowserTestUtils.closeWindow(win2);
let restoredWinPromise = BrowserTestUtils.waitForNewWindow({
});
restoreLastClosedTabOrWindowOrSession();
let restoredWin = await restoredWinPromise;
Assert.equal(
restoredWin.gBrowser.tabs.length,
1,
"First tab in the second window has been reopened"
);
await BrowserTestUtils.closeWindow(restoredWin);
SessionStore.forgetClosedWindow(restoredWin.index);
restoreLastClosedTabOrWindowOrSession();
// close one tab and reopen it
BrowserTestUtils.removeTab(window.gBrowser.tabs[2]);
Assert.equal(window.gBrowser.tabs.length, 2, "Window has two open tabs");
restoreLastClosedTabOrWindowOrSession();
Assert.equal(
window.gBrowser.tabs.length,
3,
"Window now has three open tabs"
);
// select 2 tabs and close both via the 'close 2 tabs' context menu option
let tab2 = window.gBrowser.tabs[1];
let tab3 = window.gBrowser.tabs[2];
await triggerClickOn(tab2, { ctrlKey: true });
Assert.equal(tab2.multiselected, true);
Assert.equal(tab3.multiselected, true);
let menu = await openTabMenuFor(tab3);
let menuItemCloseTab = document.getElementById("context_closeTab");
let tab2Closing = BrowserTestUtils.waitForTabClosing(tab2);
let tab3Closing = BrowserTestUtils.waitForTabClosing(tab3);
menu.activateItem(menuItemCloseTab);
await tab2Closing;
await tab3Closing;
Assert.equal(window.gBrowser.tabs[0].selected, true);
await TestUtils.waitForCondition(() => window.gBrowser.tabs.length == 1);
Assert.equal(
window.gBrowser.tabs.length,
1,
"Window now has one open tab after closing two multi-selected tabs"
);
// ensure both tabs are reopened with a single click
restoreLastClosedTabOrWindowOrSession();
Assert.equal(
window.gBrowser.tabs.length,
3,
"Window now has three open tabs after reopening closed tabs"
);
// close one tab and forget it - it should not be reopened
BrowserTestUtils.removeTab(window.gBrowser.tabs[2]);
Assert.equal(window.gBrowser.tabs.length, 2, "Window has two open tabs");
SessionStore.forgetClosedTab(window, 0);
restoreLastClosedTabOrWindowOrSession();
Assert.equal(
window.gBrowser.tabs.length,
2,
"Window still has two open tabs"
);
gBrowser.removeAllTabsBut(gBrowser.tabs[0]);
});
add_task(async function test_forget_closed_window() {
await testLastClosedActionsEntries();
SessionStore.forgetClosedWindow();
// both the forgotten window and its closed tab has been removed from the list
Assert.ok(
!SessionStore.lastClosedActions.length,
`0 closed actions have been recorded`
);
});
add_task(async function test_user_clears_history() {
await testLastClosedActionsEntries();
Services.obs.notifyObservers(null, "browser:purge-session-history");
// both the forgotten window and its closed tab has been removed from the list
Assert.ok(
!SessionStore.lastClosedActions.length,
`0 closed actions have been recorded`
);
});
/**
* It the browser has restarted and the closed actions list is empty, we
* should fallback to re-opening the last closed tab if one exists.
*/
add_task(async function test_reopen_last_tab_if_no_closed_actions() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: "about:blank",
},
async () => {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let update = BrowserTestUtils.waitForSessionStoreUpdate(tab);
BrowserTestUtils.removeTab(tab);
await update;
SessionStore.resetLastClosedActions();
let promiseTab = BrowserTestUtils.waitForNewTab(gBrowser, TEST_URL);
restoreLastClosedTabOrWindowOrSession();
let newTab = await promiseTab;
Assert.equal(newTab.linkedBrowser.currentURI.spec, TEST_URL);
}
);
});
/**
* It the browser has restarted and the closed actions list is empty, and
* no closed tabs exist for the window, we should fallback to re-opening
* the last session if one exists.
*/
add_task(async function test_reopen_last_session_if_no_closed_actions() {
gBrowser.removeAllTabsBut(gBrowser.tabs[0]);
await TabStateFlusher.flushWindow(window);
forgetClosedTabs(window);
const state = {
windows: [
{
tabs: [
{
entries: [
{
title: "example.org",
triggeringPrincipal_base64,
},
],
},
{
entries: [
{
title: "example.com",
triggeringPrincipal_base64,
},
],
},
{
entries: [
{
title: "mozilla",
triggeringPrincipal_base64,
},
],
},
],
selected: 3,
},
],
};
_LastSession.setState(state);
SessionStore.resetLastClosedActions();
let sessionRestored = promiseSessionStoreLoads(3 /* total restored tabs */);
restoreLastClosedTabOrWindowOrSession();
await sessionRestored;
Assert.equal(gBrowser.tabs.length, 4, "Got the expected number of tabs");
gBrowser.removeAllTabsBut(gBrowser.tabs[0]);
});