diff options
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_sessions_restore_private.js')
-rw-r--r-- | browser/components/extensions/test/browser/browser_ext_sessions_restore_private.js | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_restore_private.js b/browser/components/extensions/test/browser/browser_ext_sessions_restore_private.js new file mode 100644 index 0000000000..2eda77be45 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_sessions_restore_private.js @@ -0,0 +1,236 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +SimpleTest.requestCompleteLog(); +loadTestSubscript("head_sessions.js"); +const { TabStateFlusher } = ChromeUtils.importESModule( + "resource:///modules/sessionstore/TabStateFlusher.sys.mjs" +); + +async function openAndCloseTab(window, url) { + let tab = BrowserTestUtils.addTab(window.gBrowser, url); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, url); + await TabStateFlusher.flush(tab.linkedBrowser); + let sessionUpdatePromise = BrowserTestUtils.waitForSessionStoreUpdate(tab); + BrowserTestUtils.removeTab(tab); + await sessionUpdatePromise; +} + +async function run_test_extension(incognitoOverride, testData) { + const initialURL = gBrowser.selectedBrowser.currentURI.spec; + // We'll be closing tabs from a private window and a non-private window and attempting + // to call session.restore() at each step. The goal is to compare the actual and + // expected outcome when the extension is/isn't configured for incognito window use. + + function background() { + browser.test.onMessage.addListener(async (msg, sessionId) => { + let result; + try { + result = await browser.sessions.restore(sessionId); + } catch (e) { + result = { error: e.message }; + } + browser.test.sendMessage("result", result); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["sessions", "tabs"], + }, + background, + incognitoOverride, + }); + await extension.startup(); + + // Open a private browsing window and with a non-empty tab + // (so we dont end up closing the window when the close the other tab) + let privateWin = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + await BrowserTestUtils.openNewForegroundTab( + privateWin.gBrowser, + testData.private.initialTabURL + ); + + // open and close a tab in the non-private window + await openAndCloseTab(window, testData.notPrivate.tabToClose); + + let { closedId: nonPrivateClosedTabId, pos: nonPrivateIndex } = + SessionStore.getClosedTabDataForWindow(window)[0]; + if (!testData.notPrivate.expected.error) { + testData.notPrivate.expected.index = nonPrivateIndex; + } + + // open and close a tab in the private window + info( + "open & close a tab in the private window with URL: " + + testData.private.tabToClose + ); + await openAndCloseTab(privateWin, testData.private.tabToClose); + let { pos: privateIndex } = + SessionStore.getClosedTabDataForWindow(privateWin)[0]; + if (!testData.private.expected.error) { + testData.private.expected.index = privateIndex; + } + + // focus the non-private window to ensure the outcome isn't just a side-effect of the + // private window being the top window + await SimpleTest.promiseFocus(window); + + // Try to restore the last-closed tab - which was private. + // If incognito access is allowed, we should successfully restore it to the private window. + // We pass no closedId so it should just try to restore the last closed tab + info("Sending 'restore' to attempt restore the closed private tab"); + extension.sendMessage("restore"); + let sessionStoreChanged = TestUtils.topicObserved( + "sessionstore-closed-objects-changed" + ); + let extResult = await extension.awaitMessage("result"); + let result = {}; + if (extResult.tab) { + await sessionStoreChanged; + // session.restore() was returning "about:blank" as the tab.url, + // we'll wait to ensure the correct URL eventually loads in the restored tab + await BrowserTestUtils.browserLoaded( + privateWin.gBrowser.selectedTab.linkedBrowser, + true, + testData.private.tabToClose + ); + // only keep the properties we want to compare + for (let pname of Object.keys(testData.private.expected)) { + result[pname] = extResult.tab[pname]; + } + result.url = privateWin.gBrowser.selectedTab.linkedBrowser.currentURI.spec; + } else { + // Trim off the sessionId value so we can easily equality-match on the result + result.error = extResult.error.replace(/sessionId\s+\d+/, "sessionId"); + } + Assert.deepEqual( + result, + testData.private.expected, + "Restoring the private tab didn't match expected result" + ); + + await SimpleTest.promiseFocus(privateWin); + + // Try to restore the last-closed tab in the non-private window + info("Sending 'restore' to restore the non-private tab"); + extension.sendMessage("restore", String(nonPrivateClosedTabId)); + sessionStoreChanged = TestUtils.topicObserved( + "sessionstore-closed-objects-changed" + ); + extResult = await extension.awaitMessage("result"); + result = {}; + + if (extResult.tab) { + await sessionStoreChanged; + await BrowserTestUtils.browserLoaded( + window.gBrowser.selectedTab.linkedBrowser, + true, + testData.notPrivate.tabToClose + ); + // only keep the properties we want to compare + for (let pname of Object.keys(testData.notPrivate.expected)) { + result[pname] = extResult.tab[pname]; + } + result.url = window.gBrowser.selectedTab.linkedBrowser.currentURI.spec; + } else { + // Trim off the sessionId value so we can easily equality-match on the result + result.error = extResult.error.replace(/sessionId\s+\d+/, "sessionId"); + } + Assert.deepEqual( + result, + testData.notPrivate.expected, + "Restoring the non-private tab didn't match expected result" + ); + + // Close the private window and cleanup + await BrowserTestUtils.closeWindow(privateWin); + for (let tab of gBrowser.tabs.filter( + tab => !tab.hidden && tab.linkedBrowser.currentURI.spec !== initialURL + )) { + await BrowserTestUtils.removeTab(tab); + } + await extension.unload(); +} + +const spanningTestData = { + private: { + initialTabURL: "https://example.com/", + tabToClose: "https://example.org/?private", + // restore should succeed when incognito is allowed + expected: { + url: "https://example.org/?private", + incognito: true, + }, + }, + notPrivate: { + initialTabURL: "https://example.com/", + tabToClose: "https://example.org/?notprivate", + expected: { + url: "https://example.org/?notprivate", + incognito: false, + }, + }, +}; + +add_task( + async function test_sessions_get_recently_closed_private_incognito_spanning() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.sessionstore.closedTabsFromAllWindows", true]], + }); + await run_test_extension("spanning", spanningTestData); + SpecialPowers.popPrefEnv(); + } +); +add_task( + async function test_sessions_get_recently_closed_private_incognito_spanning_pref_off() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.sessionstore.closedTabsFromAllWindows", false]], + }); + await run_test_extension("spanning", spanningTestData); + SpecialPowers.popPrefEnv(); + } +); + +const notAllowedTestData = { + private: { + initialTabURL: "https://example.com/", + tabToClose: "https://example.org/?private", + // this is expected to fail when incognito is not_allowed + expected: { + error: "Could not restore object using sessionId.", + }, + }, + notPrivate: { + // we'll open tabs for each URL + initialTabURL: "https://example.com/", + tabToClose: "https://example.org/?notprivate", + expected: { + url: "https://example.org/?notprivate", + incognito: false, + }, + }, +}; + +add_task( + async function test_sessions_get_recently_closed_private_incognito_not_allowed() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.sessionstore.closedTabsFromAllWindows", true]], + }); + await run_test_extension("not_allowed", notAllowedTestData); + SpecialPowers.popPrefEnv(); + } +); + +add_task( + async function test_sessions_get_recently_closed_private_incognito_not_allowed_pref_off() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.sessionstore.closedTabsFromAllWindows", false]], + }); + await run_test_extension("not_allowed", notAllowedTestData); + SpecialPowers.popPrefEnv(); + } +); |