1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 ChromeUtils.defineESModuleGetters(globalThis, {
7 SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
10 async function add_new_tab(URL, win = window) {
11 const tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, URL);
15 async function close_tab(tab) {
16 const sessionStorePromise = BrowserTestUtils.waitForSessionStoreUpdate(tab);
17 BrowserTestUtils.removeTab(tab);
18 await sessionStorePromise;
21 async function restoreRecentlyClosedTab(browser, urlToRestore) {
22 const { document } = browser.contentWindow;
23 const tabListItem = document.querySelector(
24 `ol.closed-tabs-list .closed-tab-li[data-targeturi="${urlToRestore}"]`
26 ok(tabListItem, `Found the ${urlToRestore} item to restore`);
28 `will restore closed-tab ${urlToRestore} to sourceWindowId: ${tabListItem.dataset.sourceWindowid}`
31 let gBrowser = browser.getTabBrowser();
32 let tabRestored = BrowserTestUtils.waitForNewTab(
37 let sessionStoreUpdated = TestUtils.topicObserved(
38 "sessionstore-closed-objects-changed"
40 await SimpleTest.promiseFocus(browser.ownerGlobal);
41 await BrowserTestUtils.synthesizeMouseAtCenter(
42 `.closed-tab-li[data-targeturi="${urlToRestore}"] .closed-tab-li-main`,
46 info("waiting for sessionstore update");
47 await sessionStoreUpdated;
48 info("waiting the new tab to open");
51 gBrowser.selectedBrowser.currentURI.spec,
53 "Current tab is the restored tab"
55 return gBrowser.selectedTab;
58 async function dismissRecentlyClosedTab(browser, urlToDismiss) {
59 const { document } = browser.contentWindow;
61 const tabListItem = document.querySelector(
62 `ol.closed-tabs-list .closed-tab-li[data-targeturi="${urlToDismiss}"]`
64 ok(tabListItem, `Found the ${urlToDismiss} item to dismiss`);
65 const tabsList = tabListItem.closest(".closed-tabs-list");
66 const initialCount = tabsList.children.length;
68 `Before dismissing the ${urlToDismiss} item, there are ${initialCount} list items`
71 const sessionStoreUpdated = TestUtils.topicObserved(
72 "sessionstore-closed-objects-changed"
74 const listUpdated = BrowserTestUtils.waitForMutationCondition(
78 return tabsList.children.length == initialCount - 1;
81 info("Waiting for the mouse click");
82 await BrowserTestUtils.synthesizeMouseAtCenter(
83 `.closed-tab-li[data-targeturi="${urlToDismiss}"] .closed-tab-li-dismiss`,
87 info("Waiting for sessionStore updated");
88 await sessionStoreUpdated;
89 info("Waiting for listUpdated");
93 async function checkClosedTabList(browser, expected) {
94 const { document } = browser.contentWindow;
95 const tabsList = document.querySelector("ol.closed-tabs-list");
98 document.getElementById("recently-closed-tabs-container").open,
99 "recently-closed-tabs container is open"
102 await BrowserTestUtils.waitForMutationCondition(
105 () => tabsList.children.length >= expected.length
107 let items = tabsList.querySelectorAll(".closed-tab-li");
111 `recently-closed-tabs-list should have ${expected.length} list items`
113 for (let expectedURL of expected) {
114 const tabItem = tabsList.querySelector(
115 `.closed-tab-li[data-targeturi="${expectedURL}"]`
117 ok(tabItem, "Expected closed tabItem with url:" + expectedURL);
121 add_setup(async function setup() {
122 Services.prefs.clearUserPref(RECENTLY_CLOSED_STATE_PREF);
123 // disable the feature recommendations so they don't get in the way of fx-view interactions
124 await SpecialPowers.pushPrefEnv({
127 "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features",
130 ["browser.firefox-view.view-count", 10],
135 function taskSetup() {
136 Services.obs.notifyObservers(null, "browser:purge-session-history");
138 SessionStore.getClosedTabCount(window),
140 "0 closed tabs after purging session history"
143 SessionStore.getClosedWindowCount(),
145 "0 closed windows after purging session history"
149 add_task(async function close_tab_in_other_window() {
151 const initialWin = window;
154 "https://example.org/",
157 "about:blank", // junk tab, we don't expect this to be recorded or restored
159 const newWin = await BrowserTestUtils.openNewBrowserWindow();
160 await SimpleTest.promiseFocus(newWin);
163 for (let url of urlsToOpen) {
164 const tab = await add_new_tab(url, newWin);
165 info("Opened tab: " + tab);
168 info(`Opened ${newTabs.length} tabs`);
170 for (let tab of newTabs) {
171 info("closing tab:" + tab);
172 await close_tab(tab);
175 // first check the closed tab is listed in the window it was opened in
176 info("Checking firefoxview recently-closed tab list in new window");
177 await withFirefoxView({ win: newWin }, async browser => {
178 const expectedURLs = [
180 "https://example.org/",
183 await checkClosedTabList(browser, expectedURLs);
186 info("Checking firefoxview recently-closed tab list in the original window");
187 await withFirefoxView({ win: initialWin }, async browser => {
188 const expectedURLs = [
190 "https://example.org/",
193 await checkClosedTabList(browser, expectedURLs);
197 let urlToRestore = "about:about";
198 // check that tabs get restored into the current window
199 info("restoring tab to the initial window");
200 await withFirefoxView({ win: initialWin }, async browser => {
201 restoredTab = await restoreRecentlyClosedTab(browser, urlToRestore);
202 info("restored tab to the initial window");
204 ok(restoredTab, "Tab was restored");
206 newWin.gBrowser.selectedBrowser.currentURI.spec != urlToRestore,
207 "We didnt restore to the source window"
210 // check the list was updated in fx-view in the other window
211 await withFirefoxView({ win: newWin }, async browser => {
212 await checkClosedTabList(browser, ["https://example.org/", "about:robots"]);
215 await withFirefoxView({ win: initialWin }, async browser => {
216 let gBrowser = browser.getTabBrowser();
218 gBrowser.selectedBrowser.currentURI.spec,
220 "Current tab is fx-view"
222 await checkClosedTabList(browser, ["https://example.org/", "about:robots"]);
225 // We closed tabs in newWin, verify that tabs can be dismissed from the initial window
226 await withFirefoxView({ win: initialWin }, async browser => {
227 const urlToDismiss = "https://example.org/";
228 await dismissRecentlyClosedTab(browser, urlToDismiss);
229 await checkClosedTabList(browser, ["about:robots"]);
231 await withFirefoxView({ win: newWin }, async browser => {
232 await checkClosedTabList(browser, ["about:robots"]);
236 await BrowserTestUtils.removeTab(restoredTab);
237 await promiseAllButPrimaryWindowClosed();