summaryrefslogtreecommitdiffstats
path: root/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js')
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js824
1 files changed, 824 insertions, 0 deletions
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js
new file mode 100644
index 0000000000..a80d818c87
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_resetPBM.js
@@ -0,0 +1,824 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { SessionStoreTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/SessionStoreTestUtils.sys.mjs"
+);
+
+const PREF_ID_ALWAYS_ASK =
+ "browser.privatebrowsing.resetPBM.showConfirmationDialog";
+
+const SELECTOR_TOOLBAR_BUTTON = "#reset-pbm-toolbar-button";
+
+const SELECTOR_PANELVIEW = "panel #reset-pbm-panel";
+const SELECTOR_CONTAINER = "#reset-pbm-panel-container";
+const SELECTOR_PANEL_HEADING = "#reset-pbm-panel-header > description";
+const SELECTOR_PANEL_DESCRIPTION = "#reset-pbm-panel-description";
+const SELECTOR_PANEL_CHECKBOX = "#reset-pbm-panel-checkbox";
+const SELECTOR_PANEL_CONFIRM_BTN = "#reset-pbm-panel-confirm-button";
+const SELECTOR_PANEL_CANCEL_BTN = "#reset-pbm-panel-cancel-button";
+
+const SELECTOR_PANEL_COMPLETION_TOAST = "#confirmation-hint";
+
+/**
+ * Wait for the reset pbm confirmation panel to open. May also be called if the
+ * panel is already open.
+ * @param {ChromeWindow} win - Chrome window in which the panel is embedded.
+ * @returns {Promise} - Promise which resolves once the panel has been shown.
+ * Resolves directly if the panel is already visible.
+ */
+async function waitForConfirmPanelShow(win) {
+ // Check for the panel, if it's not present yet wait for it to be inserted.
+ let panelview = win.document.querySelector(SELECTOR_PANELVIEW);
+ if (!panelview) {
+ let navToolbox = win.document.getElementById("navigator-toolbox");
+ await BrowserTestUtils.waitForMutationCondition(
+ navToolbox,
+ { childList: true, subtree: true },
+ () => {
+ panelview = win.document.querySelector(SELECTOR_PANELVIEW);
+ return !!panelview;
+ }
+ );
+ }
+
+ // Panel already visible, we can exit early.
+ if (BrowserTestUtils.isVisible(panelview)) {
+ return;
+ }
+
+ // Wait for panel shown event.
+ await BrowserTestUtils.waitForEvent(panelview.closest("panel"), "popupshown");
+}
+
+/**
+ * Hides the completion toast which is shown after the reset action has been
+ * completed.
+ * @param {ChromeWindow} win - Chrome window the toast is shown in.
+ */
+async function hideCompletionToast(win) {
+ let promiseHidden = BrowserTestUtils.waitForEvent(
+ win.ConfirmationHint._panel,
+ "popuphidden"
+ );
+
+ win.ConfirmationHint._panel.hidePopup();
+
+ await promiseHidden;
+}
+
+/**
+ * Trigger the reset pbm toolbar button which may open the confirm panel in the
+ * given window.
+ * @param {nsIDOMWindow} win - PBM window to trigger the button in.
+ * @param {boolean} [expectPanelOpen] - After the button action: whether the
+ * panel is expected to open (true) or remain closed (false).
+ * @returns {Promise} - Promise which resolves once the button has been
+ * triggered and, if applicable, the panel has been opened.
+ */
+async function triggerResetBtn(win, expectPanelOpen = true) {
+ Assert.ok(
+ PrivateBrowsingUtils.isWindowPrivate(win),
+ "Window to open panel is in PBM."
+ );
+
+ let shownPromise;
+ if (expectPanelOpen) {
+ shownPromise = waitForConfirmPanelShow(win);
+ }
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ SELECTOR_TOOLBAR_BUTTON,
+ {},
+ win.browsingContext
+ );
+
+ // Promise may not be defined at this point in which case this is a no-op.
+ await shownPromise;
+}
+
+/**
+ * Provides a promise that resolves once the reset confirmation panel has been hidden.
+ * @param nsIDOMWindow win - Chrome window that has the panel.
+ * @returns {Promise}
+ */
+function waitForConfirmPanelHidden(win) {
+ return BrowserTestUtils.waitForEvent(
+ win.document.querySelector(SELECTOR_PANELVIEW).closest("panel"),
+ "popuphidden"
+ );
+}
+
+/**
+ * Provides a promise that resolves once the completion toast has been shown.
+ * @param nsIDOMWindow win - Chrome window that has the panel.
+ * @returns {Promise}
+ */
+function waitForCompletionToastShown(win) {
+ // Init the confirmation hint panel so we can listen for show events.
+ win.ConfirmationHint._ensurePanel();
+ return BrowserTestUtils.waitForEvent(
+ win.document.querySelector(SELECTOR_PANEL_COMPLETION_TOAST),
+ "popupshown"
+ );
+}
+
+/**
+ * Wait for private browsing data clearing to be triggered.
+ * Clearing is not guaranteed to be done at this point. Bug 1846494 will add a
+ * promise based mechanism and potentially a new triggering method for clearing,
+ * at which point this helper should be updated.
+ * @returns {Promise} Promise which resolves when the last-pb-context-exited
+ * message has been dispatched.
+ */
+function waitForPBMDataClear() {
+ return TestUtils.topicObserved("last-pb-context-exited");
+}
+
+/**
+ * Test panel visibility.
+ * @param {nsIDOMWindow} win - Chrome window which is the parent of the panel.
+ * @param {string} selector - Query selector for the panel.
+ * @param {boolean} expectVisible - Whether the panel should be visible (true) or invisible or not present (false).
+ */
+function assertPanelVisibility(win, selector, expectVisible) {
+ let panelview = win.document.querySelector(selector);
+
+ if (expectVisible) {
+ Assert.ok(panelview, `Panelview element ${selector} should exist.`);
+ Assert.ok(
+ BrowserTestUtils.isVisible(panelview),
+ `Panelview ${selector} should be visible.`
+ );
+ return;
+ }
+
+ Assert.ok(
+ !panelview || !BrowserTestUtils.isVisible(panelview),
+ `Panelview ${selector} should be invisible or non-existent.`
+ );
+}
+
+function transformGleanEvents(events) {
+ if (!events) {
+ return [];
+ }
+ return events.map(e => ({ ...e.extra }));
+}
+
+function assertTelemetry(expectedConfirmPanel, expectedResetAction, message) {
+ info(message);
+
+ let confirmPanelEvents = transformGleanEvents(
+ Glean.privateBrowsingResetPbm.confirmPanel.testGetValue()
+ );
+ Assert.deepEqual(
+ confirmPanelEvents,
+ expectedConfirmPanel,
+ "confirmPanel events should match."
+ );
+
+ let resetActionEvents = transformGleanEvents(
+ Glean.privateBrowsingResetPbm.resetAction.testGetValue()
+ );
+ Assert.deepEqual(
+ resetActionEvents,
+ expectedResetAction,
+ "resetAction events should match."
+ );
+}
+
+/**
+ * Tests that the reset button is only visible in private browsing windows and
+ * when the feature is enabled.
+ */
+add_task(async function test_toolbar_button_visibility() {
+ assertTelemetry([], [], "No glean events initially.");
+
+ for (let isEnabled of [false, true]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", isEnabled]],
+ });
+
+ info(
+ "Test that the toolbar button is never visible in a normal browsing window."
+ );
+ let toolbarButtonNormalBrowsing = document.querySelector(
+ SELECTOR_TOOLBAR_BUTTON
+ );
+ Assert.equal(
+ !!toolbarButtonNormalBrowsing,
+ isEnabled,
+ "Normal browsing toolbar button element exists, depending on enabled pref state."
+ );
+ if (toolbarButtonNormalBrowsing) {
+ Assert.ok(
+ !BrowserTestUtils.isVisible(toolbarButtonNormalBrowsing),
+ "Toolbar button is not visible in normal browsing"
+ );
+ }
+
+ info(
+ "Test that the toolbar button is visible in a private browsing window, depending on enabled pref state."
+ );
+ let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ let toolbarButtonPrivateBrowsing = privateWindow.document.querySelector(
+ SELECTOR_TOOLBAR_BUTTON
+ );
+ Assert.equal(
+ !!toolbarButtonPrivateBrowsing,
+ isEnabled,
+ "Private browsing toolbar button element exists, depending on enabled pref state."
+ );
+ if (toolbarButtonPrivateBrowsing) {
+ Assert.equal(
+ BrowserTestUtils.isVisible(toolbarButtonPrivateBrowsing),
+ isEnabled,
+ "Toolbar button is visible in private browsing if enabled."
+ );
+ }
+
+ await BrowserTestUtils.closeWindow(privateWindow);
+
+ await SpecialPowers.popPrefEnv();
+ }
+
+ assertTelemetry([], [], "No glean events after test.");
+});
+
+/**
+ * Tests the panel UI, the 'always ask' checkbox and the confirm and cancel
+ * actions.
+ */
+add_task(async function test_panel() {
+ assertTelemetry([], [], "No glean events initially.");
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", true]],
+ });
+
+ let privateWin = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ // Panel does either not exist (because it's lazy and hasn't been opened yet),
+ // or it is invisible.
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, false);
+ assertPanelVisibility(privateWin, SELECTOR_PANEL_COMPLETION_TOAST, false);
+
+ info("Open the panel.");
+ await triggerResetBtn(privateWin);
+
+ assertTelemetry(
+ [{ action: "show", reason: "toolbar-btn" }],
+ [],
+ "There should be a panel show event."
+ );
+
+ info("Check that all expected elements are present and visible.");
+ [
+ SELECTOR_PANEL_HEADING,
+ SELECTOR_PANEL_DESCRIPTION,
+ SELECTOR_PANEL_CHECKBOX,
+ SELECTOR_PANEL_CONFIRM_BTN,
+ SELECTOR_PANEL_CANCEL_BTN,
+ ].forEach(elSelector => {
+ let el = privateWin.document.querySelector(elSelector);
+ Assert.ok(el, `Panel element ${elSelector} exists.`);
+ if (el) {
+ Assert.ok(
+ BrowserTestUtils.isVisible(el),
+ `Panel element ${elSelector} is visible.`
+ );
+ }
+ });
+
+ info("Inspect checkbox and pref state.");
+ let checkbox = privateWin.document.querySelector(SELECTOR_PANEL_CHECKBOX);
+ Assert.ok(
+ checkbox.checked,
+ "The 'always ask' checkbox should be checked initially."
+ );
+ Assert.ok(
+ Services.prefs.getBoolPref(
+ "browser.privatebrowsing.resetPBM.showConfirmationDialog"
+ ),
+ "The always ask pref should be true."
+ );
+
+ info("Accessibility checks");
+ let panel = privateWin.document.querySelector(SELECTOR_PANELVIEW);
+ Assert.equal(
+ panel.getAttribute("role"),
+ "document",
+ "Panel should have role document."
+ );
+
+ let container = panel.querySelector(SELECTOR_CONTAINER);
+ Assert.equal(
+ container.getAttribute("role"),
+ "alertdialog",
+ "Panel container should have role alertdialog."
+ );
+ Assert.equal(
+ container.getAttribute("aria-labelledby"),
+ "reset-pbm-panel-header",
+ "aria-labelledby should point to heading."
+ );
+
+ let heading = panel.querySelector(SELECTOR_PANEL_HEADING);
+ Assert.equal(
+ heading.getAttribute("role"),
+ "heading",
+ "Heading should have role heading."
+ );
+ Assert.equal(
+ heading.getAttribute("aria-level"),
+ "2",
+ "heading should have aria-level 2"
+ );
+
+ info("Click the checkbox to uncheck it.");
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ SELECTOR_PANEL_CHECKBOX,
+ {},
+ privateWin.browsingContext
+ );
+ Assert.ok(
+ !checkbox.checked,
+ "The 'always ask' checkbox should no longer be checked."
+ );
+ info(
+ "The pref shouldn't update after clicking the checkbox. It only updates on panel confirm."
+ );
+ Assert.ok(
+ Services.prefs.getBoolPref(
+ "browser.privatebrowsing.resetPBM.showConfirmationDialog"
+ ),
+ "The always ask pref should still be true."
+ );
+
+ info("Close the panel via cancel.");
+ let promisePanelHidden = waitForConfirmPanelHidden(privateWin);
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ SELECTOR_PANEL_CANCEL_BTN,
+ {},
+ privateWin.browsingContext
+ );
+ await promisePanelHidden;
+
+ assertTelemetry(
+ [
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "cancel-btn" },
+ ],
+ [],
+ "There should be a panel show and a hide event."
+ );
+
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, false);
+ assertPanelVisibility(privateWin, SELECTOR_PANEL_COMPLETION_TOAST, false);
+
+ info("Reopen the panel.");
+ await triggerResetBtn(privateWin);
+
+ assertTelemetry(
+ [
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "cancel-btn" },
+ { action: "show", reason: "toolbar-btn" },
+ ],
+ [],
+ "Should have added a show event."
+ );
+
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, true);
+ assertPanelVisibility(privateWin, SELECTOR_PANEL_COMPLETION_TOAST, false);
+ Assert.ok(
+ checkbox.checked,
+ "The 'always ask' checkbox should be checked again."
+ );
+ Assert.ok(
+ Services.prefs.getBoolPref(PREF_ID_ALWAYS_ASK),
+ "The always ask pref should be true."
+ );
+
+ info("Test the checkbox on confirm.");
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ SELECTOR_PANEL_CHECKBOX,
+ {},
+ privateWin.browsingContext
+ );
+ Assert.ok(
+ !checkbox.checked,
+ "The 'always ask' checkbox should no longer be checked."
+ );
+
+ info("Close the panel via confirm.");
+ let promiseDataCleared = waitForPBMDataClear();
+ promisePanelHidden = waitForConfirmPanelHidden(privateWin);
+ let promiseCompletionToastShown = waitForCompletionToastShown(privateWin);
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ SELECTOR_PANEL_CONFIRM_BTN,
+ {},
+ privateWin.browsingContext
+ );
+ await promisePanelHidden;
+
+ assertTelemetry(
+ [
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "cancel-btn" },
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "confirm-btn" },
+ ],
+ [{ did_confirm: "true" }],
+ "Should have added a hide and a reset event."
+ );
+ await promiseCompletionToastShown;
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, false);
+ assertPanelVisibility(privateWin, SELECTOR_PANEL_COMPLETION_TOAST, true);
+
+ await promiseDataCleared;
+
+ Assert.ok(
+ !Services.prefs.getBoolPref(PREF_ID_ALWAYS_ASK),
+ "The always ask pref should now be false."
+ );
+
+ // Need to hide the completion toast, otherwise the next click on the toolbar
+ // button won't work.
+ info("Hide the completion toast.");
+ await hideCompletionToast(privateWin);
+
+ info(
+ "Simulate a click on the toolbar button. This time the panel should not open - we have unchecked 'always ask'."
+ );
+ promiseDataCleared = waitForPBMDataClear();
+ promiseCompletionToastShown = waitForCompletionToastShown(privateWin);
+
+ await triggerResetBtn(privateWin, false);
+
+ info("Waiting for PBM session to end.");
+ await promiseDataCleared;
+ info("Data has been cleared.");
+
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, false);
+
+ info("Waiting for the completion toast to show.");
+ await promiseCompletionToastShown;
+
+ assertPanelVisibility(privateWin, SELECTOR_PANELVIEW, false);
+ assertPanelVisibility(privateWin, SELECTOR_PANEL_COMPLETION_TOAST, true);
+
+ assertTelemetry(
+ [
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "cancel-btn" },
+ { action: "show", reason: "toolbar-btn" },
+ { action: "hide", reason: "confirm-btn" },
+ ],
+ [{ did_confirm: "true" }, { did_confirm: "false" }],
+ "Should have added a reset event."
+ );
+
+ await BrowserTestUtils.closeWindow(privateWin);
+ Services.prefs.clearUserPref(PREF_ID_ALWAYS_ASK);
+
+ // Clean up telemetry
+ Services.fog.testResetFOG();
+});
+
+/**
+ * Tests that the reset action closes all other private browsing windows and
+ * tabs and triggers private browsing data clearing.
+ */
+add_task(async function test_reset_action() {
+ assertTelemetry([], [], "No glean events initially.");
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", true]],
+ });
+
+ info("Open a few private browsing windows.");
+ let privateBrowsingWindows = [];
+ for (let i = 0; i < 3; i += 1) {
+ privateBrowsingWindows.push(
+ await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ })
+ );
+ }
+
+ info(
+ "Open an additional normal browsing window. It should remain open on reset PBM action."
+ );
+ let additionalNormalWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: false,
+ });
+
+ info("Use one of the PBM windows to trigger the PBM restart action.");
+ let [win] = privateBrowsingWindows;
+ win.focus();
+
+ Assert.ok(
+ PrivateBrowsingUtils.isWindowPrivate(win),
+ "Window for PBM reset trigger is private window."
+ );
+
+ info("Load a bunch of tabs in the private window.");
+ let loadPromises = [
+ "https://example.com",
+ "https://example.org",
+ "https://example.net",
+ ].map(async url => {
+ let tab = BrowserTestUtils.addTab(win.gBrowser, url);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ });
+ await Promise.all(loadPromises);
+
+ info("Switch to the last tab.");
+ win.gBrowser.selectedTab = win.gBrowser.tabs[win.gBrowser.tabs.length - 1];
+ Assert.ok(
+ win.gBrowser.selectedBrowser.currentURI.spec != "about:privatebrowsing",
+ "The selected tab should not show about:privatebrowsing."
+ );
+
+ let windowClosePromises = [
+ ...privateBrowsingWindows.filter(w => win != w),
+ ].map(w => BrowserTestUtils.windowClosed(w));
+
+ // Create promises for tab close for all tabs in the triggering private browsing window.
+ let promisesTabsClosed = win.gBrowser.tabs.map(tab =>
+ BrowserTestUtils.waitForTabClosing(tab)
+ );
+
+ info("Trigger the restart PBM action");
+
+ let promiseDataClear = waitForPBMDataClear();
+ await ResetPBMPanel._restartPBM(win);
+
+ info(
+ "Wait for all the windows but the default normal window and the private window which triggered the reset action to be closed."
+ );
+ await Promise.all(windowClosePromises);
+
+ info("Wait for tabs in the trigger private window to close.");
+ await Promise.all(promisesTabsClosed);
+
+ info("Wait for data to be cleared.");
+ await promiseDataClear;
+
+ Assert.equal(
+ win.gBrowser.tabs.length,
+ 1,
+ "Should only have 1 tab remaining."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () =>
+ win.gBrowser.selectedBrowser.currentURI.spec == "about:privatebrowsing"
+ );
+ Assert.equal(
+ win.gBrowser.selectedBrowser.currentURI.spec,
+ "about:privatebrowsing",
+ "The remaining tab should point to about:privatebrowsing."
+ );
+
+ // Close the private window that remained open.
+ await BrowserTestUtils.closeWindow(win);
+ await BrowserTestUtils.closeWindow(additionalNormalWindow);
+
+ // We bypass telemetry by calling ResetPBMPanel._restartPBM directly.
+ assertTelemetry([], [], "No glean events after the test.");
+});
+
+/**
+ * Ensure that we don't show the tab close warning when closing multiple tabs
+ * with the reset PBM action.
+ */
+add_task(async function test_tab_close_warning_suppressed() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["browser.privatebrowsing.resetPBM.enabled", true],
+ ["browser.tabs.warnOnClose", true],
+ ["browser.tabs.warnOnCloseOtherTabs", true],
+ ],
+ });
+
+ info("Open a private browsing window.");
+ let win = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ info("Open enough tabs so the tab close warning would show.");
+ let loadPromises = [];
+ // warnAboutClosingTabs uses this number to determine whether to show the tab
+ // close warning.
+ let maxTabsUndo = Services.prefs.getIntPref(
+ "browser.sessionstore.max_tabs_undo"
+ );
+ for (let i = 0; i < maxTabsUndo + 2; i++) {
+ let tab = BrowserTestUtils.addTab(win.gBrowser, "about:blank");
+ loadPromises.push(BrowserTestUtils.browserLoaded(tab.linkedBrowser));
+ }
+ await Promise.all(loadPromises);
+
+ // Create promises for tab close for all tabs in the triggering private browsing window.
+ let promisesTabsClosed = win.gBrowser.tabs.map(tab =>
+ BrowserTestUtils.waitForTabClosing(tab)
+ );
+
+ info("Trigger the restart PBM action");
+
+ let promiseDataClear = waitForPBMDataClear();
+ await ResetPBMPanel._restartPBM(win);
+
+ info("Wait for tabs in the trigger private window to close.");
+ await Promise.all(promisesTabsClosed);
+
+ info("Wait for data to be cleared.");
+ await promiseDataClear;
+
+ Assert.equal(
+ win.gBrowser.tabs.length,
+ 1,
+ "Should only have 1 tab remaining."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () =>
+ win.gBrowser.selectedBrowser.currentURI.spec == "about:privatebrowsing"
+ );
+ Assert.equal(
+ win.gBrowser.selectedBrowser.currentURI.spec,
+ "about:privatebrowsing",
+ "The remaining tab should point to about:privatebrowsing."
+ );
+
+ // Close the private window that remained open.
+ await BrowserTestUtils.closeWindow(win);
+});
+
+/**
+ * Test that if the browser sidebar is open the reset action closes it.
+ */
+add_task(async function test_reset_action_closes_sidebar() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", true]],
+ });
+
+ info("Open a private browsing window.");
+ let win = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ info(
+ "Open the sidebar of both the private browsing window and the normal browsing window."
+ );
+ await SidebarUI.show("viewBookmarksSidebar");
+ await win.SidebarUI.show("viewBookmarksSidebar");
+
+ info("Trigger the restart PBM action");
+ await ResetPBMPanel._restartPBM(win);
+
+ Assert.ok(
+ SidebarUI.isOpen,
+ "Normal browsing window sidebar should still be open."
+ );
+ Assert.ok(
+ !win.SidebarUI.isOpen,
+ "Private browsing sidebar should be closed."
+ );
+
+ // Cleanup: Close the sidebar of the normal browsing window.
+ SidebarUI.hide();
+
+ // Cleanup: Close the private window that remained open.
+ await BrowserTestUtils.closeWindow(win);
+});
+
+/**
+ * Test that the session store history gets purged by the reset action.
+ */
+add_task(async function test_reset_action_purges_session_store() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", true]],
+ });
+
+ info("Open a private browsing window.");
+ let win = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ Assert.equal(
+ SessionStore.getClosedTabCountForWindow(win),
+ 0,
+ "Initially there should be no closed tabs recorded for the PBM window in SessionStore."
+ );
+
+ info("Load a bunch of tabs in the private window.");
+
+ let tab;
+ let loadPromises = [
+ "https://example.com",
+ "https://example.org",
+ "https://example.net",
+ ].map(async url => {
+ tab = BrowserTestUtils.addTab(win.gBrowser, url);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ });
+ await Promise.all(loadPromises);
+
+ info("Manually close a tab");
+ await SessionStoreTestUtils.closeTab(tab);
+
+ Assert.equal(
+ SessionStore.getClosedTabCountForWindow(win),
+ 1,
+ "The manually closed tab should be recorded in SessionStore."
+ );
+
+ info("Trigger the restart PBM action");
+ await ResetPBMPanel._restartPBM(win);
+
+ Assert.equal(
+ SessionStore.getClosedTabCountForWindow(win),
+ 0,
+ "After triggering the PBM reset action there should be no closed tabs recorded for the PBM window in SessionStore."
+ );
+
+ // Cleanup: Close the private window that remained open.
+ await BrowserTestUtils.closeWindow(win);
+});
+
+/**
+ * Test that the the reset action closes all tabs, including pinned and (multi-)selected
+ * tabs.
+ */
+add_task(async function test_reset_action_closes_pinned_and_selected_tabs() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.resetPBM.enabled", true]],
+ });
+
+ info("Open a private browsing window.");
+ let win = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ info("Load a list of tabs.");
+ let loadPromises = [
+ "https://example.com",
+ "https://example.org",
+ "https://example.net",
+ "about:blank",
+ ].map(async url => {
+ let tab = BrowserTestUtils.addTab(win.gBrowser, url);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ return tab;
+ });
+ let tabs = await Promise.all(loadPromises);
+
+ info("Pin a tab");
+ win.gBrowser.pinTab(tabs[0]);
+
+ info("Multi-select tabs.");
+ await BrowserTestUtils.switchTab(win.gBrowser, tabs[2]);
+ win.gBrowser.addToMultiSelectedTabs(tabs[3]);
+
+ // Create promises for tab close for all tabs in the triggering private browsing window.
+ let promisesTabsClosed = win.gBrowser.tabs.map(tab =>
+ BrowserTestUtils.waitForTabClosing(tab)
+ );
+
+ info("Trigger the restart PBM action");
+ await ResetPBMPanel._restartPBM(win);
+
+ info("Wait for all tabs to be closed.");
+ await promisesTabsClosed;
+
+ Assert.equal(
+ win.gBrowser.tabs.length,
+ 1,
+ "Should only have 1 tab remaining."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () =>
+ win.gBrowser.selectedBrowser.currentURI.spec == "about:privatebrowsing"
+ );
+ Assert.equal(
+ win.gBrowser.selectedBrowser.currentURI.spec,
+ "about:privatebrowsing",
+ "The remaining tab should point to about:privatebrowsing."
+ );
+
+ // Cleanup: Close the private window/
+ await BrowserTestUtils.closeWindow(win);
+});