tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_history_recently_closed_tabs.js (11071B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 /**
      4 * This test verifies behavior from bug 1819675:
      5 * https://bugzilla.mozilla.org/show_bug.cgi?id=1819675
      6 *
      7 * The recently closed tabs menu item should be enabled when there are tabs
      8 * closed from any window that is in the same private/non-private bucket as
      9 * the current window.
     10 */
     11 
     12 const { SessionStoreTestUtils } = ChromeUtils.importESModule(
     13  "resource://testing-common/SessionStoreTestUtils.sys.mjs"
     14 );
     15 const triggeringPrincipal_base64 = E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;
     16 SessionStoreTestUtils.init(this, window);
     17 
     18 async function checkMenu(window, expected) {
     19  await SimpleTest.promiseFocus(window);
     20  const historyMenubarItem = window.document.getElementById("history-menu");
     21  const historyMenu = window.document.getElementById("historyMenuPopup");
     22  const recentlyClosedTabsItem = historyMenu.querySelector("#historyUndoMenu");
     23 
     24  const menuShown = BrowserTestUtils.waitForEvent(historyMenu, "popupshown");
     25  historyMenubarItem.openMenu(true);
     26  info("checkMenu:, waiting for menuShown");
     27  await menuShown;
     28 
     29  Assert.equal(
     30    recentlyClosedTabsItem.disabled,
     31    expected.menuItemDisabled,
     32    `Recently closed tabs menu item is ${
     33      expected.menuItemDisabled ? "disabled" : "not disabled"
     34    }`
     35  );
     36  const menuHidden = BrowserTestUtils.waitForEvent(historyMenu, "popuphidden");
     37  historyMenu.hidePopup();
     38  info("checkMenu:, waiting for menuHidden");
     39  await menuHidden;
     40  info("checkMenu:, menuHidden, returning");
     41 }
     42 
     43 function resetClosedTabsAndWindows() {
     44  // Clear the lists of closed windows and tabs.
     45  Services.obs.notifyObservers(null, "browser:purge-session-history");
     46  is(SessionStore.getClosedWindowCount(), 0, "Expect 0 closed windows");
     47  for (const win of BrowserWindowTracker.orderedWindows) {
     48    is(
     49      SessionStore.getClosedTabCountForWindow(win),
     50      0,
     51      "Expect 0 closed tabs for this window"
     52    );
     53  }
     54 }
     55 
     56 add_setup(async function () {
     57  await SpecialPowers.pushPrefEnv({
     58    set: [["test.wait300msAfterTabSwitch", true]],
     59  });
     60 });
     61 
     62 add_task(async function test_recently_closed_tabs_nonprivate() {
     63  await resetClosedTabsAndWindows();
     64 
     65  const win1 = window;
     66  const win2 = await BrowserTestUtils.openNewBrowserWindow();
     67  await BrowserTestUtils.openNewForegroundTab(
     68    win1.gBrowser,
     69    "https://example.com"
     70  );
     71  // we're going to close a tab and don't want to accidentally close the window when it has 0 tabs
     72  await BrowserTestUtils.openNewForegroundTab(win2.gBrowser, "about:about");
     73  await BrowserTestUtils.openNewForegroundTab(
     74    win2.gBrowser,
     75    "https://example.org"
     76  );
     77 
     78  info("Checking the menuitem is initially disabled in both windows");
     79  for (let win of [win1, win2]) {
     80    await checkMenu(win, {
     81      menuItemDisabled: true,
     82    });
     83  }
     84 
     85  await SessionStoreTestUtils.closeTab(win2.gBrowser.selectedTab);
     86  is(
     87    SessionStore.getClosedTabCount(),
     88    1,
     89    "Expect closed tab count of 1 after closing a tab"
     90  );
     91 
     92  for (let win of [win1, win2]) {
     93    await checkMenu(win, {
     94      menuItemDisabled: false,
     95    });
     96  }
     97 
     98  // clean up
     99  info("clean up opened window");
    100  const sessionStoreChanged = TestUtils.topicObserved(
    101    "sessionstore-closed-objects-changed"
    102  );
    103  await BrowserTestUtils.closeWindow(win2);
    104  await sessionStoreChanged;
    105 
    106  info("starting tab cleanup");
    107  while (gBrowser.tabs.length > 1) {
    108    await SessionStoreTestUtils.closeTab(
    109      gBrowser.tabs[gBrowser.tabs.length - 1]
    110    );
    111  }
    112  info("finished tab cleanup");
    113 });
    114 
    115 add_task(async function test_recently_closed_tabs_nonprivate_pref_off() {
    116  await SpecialPowers.pushPrefEnv({
    117    set: [["browser.sessionstore.closedTabsFromAllWindows", false]],
    118  });
    119  await resetClosedTabsAndWindows();
    120 
    121  const win1 = window;
    122  const win2 = await BrowserTestUtils.openNewBrowserWindow();
    123  await BrowserTestUtils.openNewForegroundTab(
    124    win1.gBrowser,
    125    "https://example.com"
    126  );
    127  // we're going to close a tab and don't want to accidentally close the window when it has 0 tabs
    128  await BrowserTestUtils.openNewForegroundTab(win2.gBrowser, "about:about");
    129  await BrowserTestUtils.openNewForegroundTab(
    130    win2.gBrowser,
    131    "https://example.org"
    132  );
    133 
    134  info("Checking the menuitem is initially disabled in both windows");
    135  for (let win of [win1, win2]) {
    136    await checkMenu(win, {
    137      menuItemDisabled: true,
    138    });
    139  }
    140  await SimpleTest.promiseFocus(win2);
    141  await SessionStoreTestUtils.closeTab(win2.gBrowser.selectedTab);
    142  is(
    143    SessionStore.getClosedTabCount(),
    144    1,
    145    "Expect closed tab count of 1 after closing a tab"
    146  );
    147 
    148  await checkMenu(win1, {
    149    menuItemDisabled: true,
    150  });
    151  await checkMenu(win2, {
    152    menuItemDisabled: false,
    153  });
    154 
    155  // clean up
    156  info("clean up opened window");
    157  const sessionStoreChanged = TestUtils.topicObserved(
    158    "sessionstore-closed-objects-changed"
    159  );
    160  await BrowserTestUtils.closeWindow(win2);
    161  await sessionStoreChanged;
    162 
    163  info("starting tab cleanup");
    164  while (gBrowser.tabs.length > 1) {
    165    await SessionStoreTestUtils.closeTab(
    166      gBrowser.tabs[gBrowser.tabs.length - 1]
    167    );
    168  }
    169  info("finished tab cleanup");
    170  SpecialPowers.popPrefEnv();
    171 });
    172 
    173 add_task(async function test_recently_closed_tabs_mixed_private() {
    174  await resetClosedTabsAndWindows();
    175  is(
    176    SessionStore.getClosedTabCount(),
    177    0,
    178    "Expect closed tab count of 0 after reset"
    179  );
    180 
    181  await BrowserTestUtils.openNewForegroundTab(window.gBrowser, "about:robots");
    182  await BrowserTestUtils.openNewForegroundTab(
    183    window.gBrowser,
    184    "https://example.com"
    185  );
    186 
    187  const privateWin = await BrowserTestUtils.openNewBrowserWindow({
    188    private: true,
    189  });
    190  await BrowserTestUtils.openNewForegroundTab(
    191    privateWin.gBrowser,
    192    "about:about"
    193  );
    194  await BrowserTestUtils.openNewForegroundTab(
    195    privateWin.gBrowser,
    196    "https://example.org"
    197  );
    198 
    199  for (let win of [window, privateWin]) {
    200    await checkMenu(win, {
    201      menuItemDisabled: true,
    202    });
    203  }
    204 
    205  await SessionStoreTestUtils.closeTab(privateWin.gBrowser.selectedTab);
    206  is(
    207    SessionStore.getClosedTabCount(privateWin),
    208    1,
    209    "Expect closed tab count of 1 for private windows"
    210  );
    211  is(
    212    SessionStore.getClosedTabCount(window),
    213    0,
    214    "Expect closed tab count of 0 for non-private windows"
    215  );
    216 
    217  // the menu should be enabled only for the private window
    218  await checkMenu(window, {
    219    menuItemDisabled: true,
    220  });
    221  await checkMenu(privateWin, {
    222    menuItemDisabled: false,
    223  });
    224 
    225  await resetClosedTabsAndWindows();
    226  await SimpleTest.promiseFocus(window);
    227 
    228  info("closing tab in non-private window");
    229  await SessionStoreTestUtils.closeTab(window.gBrowser.selectedTab);
    230  is(
    231    SessionStore.getClosedTabCount(window),
    232    1,
    233    "Expect 1 closed tab count after closing the a tab in the non-private window"
    234  );
    235 
    236  // the menu should be enabled only for the non-private window
    237  await checkMenu(window, {
    238    menuItemDisabled: false,
    239  });
    240  await checkMenu(privateWin, {
    241    menuItemDisabled: true,
    242  });
    243 
    244  // clean up
    245  info("closing private window");
    246  await BrowserTestUtils.closeWindow(privateWin);
    247  await TestUtils.waitForTick();
    248 
    249  info("starting tab cleanup");
    250  while (gBrowser.tabs.length > 1) {
    251    await SessionStoreTestUtils.closeTab(
    252      gBrowser.tabs[gBrowser.tabs.length - 1]
    253    );
    254  }
    255  info("finished tab cleanup");
    256 });
    257 
    258 add_task(async function test_recently_closed_tabs_mixed_private_pref_off() {
    259  await SpecialPowers.pushPrefEnv({
    260    set: [["browser.sessionstore.closedTabsFromAllWindows", false]],
    261  });
    262  await resetClosedTabsAndWindows();
    263 
    264  await BrowserTestUtils.openNewForegroundTab(window.gBrowser, "about:robots");
    265  await BrowserTestUtils.openNewForegroundTab(
    266    window.gBrowser,
    267    "https://example.com"
    268  );
    269 
    270  const privateWin = await BrowserTestUtils.openNewBrowserWindow({
    271    private: true,
    272  });
    273  await BrowserTestUtils.openNewForegroundTab(
    274    privateWin.gBrowser,
    275    "about:about"
    276  );
    277  await BrowserTestUtils.openNewForegroundTab(
    278    privateWin.gBrowser,
    279    "https://example.org"
    280  );
    281 
    282  for (let win of [window, privateWin]) {
    283    await checkMenu(win, {
    284      menuItemDisabled: true,
    285    });
    286  }
    287 
    288  await SimpleTest.promiseFocus(privateWin);
    289  await SessionStoreTestUtils.closeTab(privateWin.gBrowser.selectedTab);
    290  is(
    291    SessionStore.getClosedTabCount(privateWin),
    292    1,
    293    "Expect closed tab count of 1 for private windows"
    294  );
    295  is(
    296    SessionStore.getClosedTabCount(window),
    297    0,
    298    "Expect closed tab count of 0 for non-private windows"
    299  );
    300 
    301  // the menu should be enabled only for the private window
    302  await checkMenu(window, {
    303    menuItemDisabled: true,
    304  });
    305  await checkMenu(privateWin, {
    306    menuItemDisabled: false,
    307  });
    308 
    309  await resetClosedTabsAndWindows();
    310  is(
    311    SessionStore.getClosedTabCount(privateWin),
    312    0,
    313    "Expect 0 closed tab count after reset"
    314  );
    315  is(
    316    SessionStore.getClosedTabCount(window),
    317    0,
    318    "Expect 0 closed tab count after reset"
    319  );
    320 
    321  info("closing tab in non-private window");
    322  await SimpleTest.promiseFocus(window);
    323  await SessionStoreTestUtils.closeTab(window.gBrowser.selectedTab);
    324 
    325  // the menu should be enabled only for the non-private window
    326  await checkMenu(window, {
    327    menuItemDisabled: false,
    328  });
    329  await checkMenu(privateWin, {
    330    menuItemDisabled: true,
    331  });
    332 
    333  // clean up
    334  info("closing private window");
    335  await BrowserTestUtils.closeWindow(privateWin);
    336  await TestUtils.waitForTick();
    337 
    338  info("starting tab cleanup");
    339  while (gBrowser.tabs.length > 1) {
    340    await SessionStoreTestUtils.closeTab(
    341      gBrowser.tabs[gBrowser.tabs.length - 1]
    342    );
    343  }
    344  info("finished tab cleanup");
    345  SpecialPowers.popPrefEnv();
    346 });
    347 
    348 add_task(async function test_recently_closed_tabs_closed_windows() {
    349  // prepare window state with closed tabs from closed windows
    350  await SpecialPowers.pushPrefEnv({
    351    set: [["sessionstore.closedTabsFromClosedWindows", true]],
    352  });
    353  const closedTabUrls = ["about:robots"];
    354  const closedWindowState = {
    355    tabs: [
    356      {
    357        entries: [{ url: "about:mozilla", triggeringPrincipal_base64 }],
    358      },
    359    ],
    360    _closedTabs: closedTabUrls.map(url => {
    361      return {
    362        state: {
    363          entries: [
    364            {
    365              url,
    366              triggeringPrincipal_base64,
    367            },
    368          ],
    369        },
    370      };
    371    }),
    372  };
    373  await SessionStoreTestUtils.promiseBrowserState({
    374    windows: [
    375      {
    376        tabs: [
    377          {
    378            entries: [{ url: "about:mozilla", triggeringPrincipal_base64 }],
    379          },
    380        ],
    381      },
    382    ],
    383    _closedWindows: [closedWindowState],
    384  });
    385 
    386  // verify the recently-closed-tabs menu item is enabled
    387  await checkMenu(window, {
    388    menuItemDisabled: false,
    389  });
    390 
    391  // flip the pref
    392  await SpecialPowers.popPrefEnv();
    393  await SpecialPowers.pushPrefEnv({
    394    set: [["browser.sessionstore.closedTabsFromClosedWindows", false]],
    395  });
    396 
    397  // verify the recently-closed-tabs menu item is disabled
    398  await checkMenu(window, {
    399    menuItemDisabled: true,
    400  });
    401 
    402  SpecialPowers.popPrefEnv();
    403 });