tor-browser

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

browser_multipleCrashedTabs.js (4513B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // eslint-disable-next-line @microsoft/sdl/no-insecure-url
      7 const PAGE_1 = "http://example.com";
      8 // eslint-disable-next-line @microsoft/sdl/no-insecure-url
      9 const PAGE_2 = "http://example.org";
     10 // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     11 const PAGE_3 = "http://example.net";
     12 
     13 /**
     14 * Checks that a particular about:tabcrashed page has the attribute set to
     15 * use the "multiple about:tabcrashed" UI.
     16 *
     17 * @param browser (<xul:browser>)
     18 *   The browser to check.
     19 * @param expected (Boolean)
     20 *   True if we expect the "multiple" state to be set.
     21 * @returns {Promise<void>}
     22 *   Resolves when the check has completed.
     23 */
     24 async function assertShowingMultipleUI(browser, expected) {
     25  let showingMultiple = await SpecialPowers.spawn(browser, [], async () => {
     26    return (
     27      content.document.getElementById("main").getAttribute("multiple") == "true"
     28    );
     29  });
     30  Assert.equal(showingMultiple, expected, "Got the expected 'multiple' state.");
     31 }
     32 
     33 /**
     34 * Takes a Telemetry histogram snapshot and returns the sum of all counts.
     35 *
     36 * @param snapshot (Object)
     37 *        The Telemetry histogram snapshot to examine.
     38 * @return (int)
     39 *         The sum of all counts in the snapshot.
     40 */
     41 function snapshotCount(snapshot) {
     42  return Object.values(snapshot.values).reduce((a, b) => a + b, 0);
     43 }
     44 
     45 /**
     46 * Switches to a tab, crashes it, and waits for about:tabcrashed
     47 * to load.
     48 *
     49 * @param tab (<xul:tab>)
     50 *   The tab to switch to and crash.
     51 * @returns {Promise<void>}
     52 *   Resolves when about:tabcrashed is loaded.
     53 */
     54 async function switchToAndCrashTab(tab) {
     55  let browser = tab.linkedBrowser;
     56 
     57  await BrowserTestUtils.switchTab(gBrowser, tab);
     58  let tabcrashed = BrowserTestUtils.waitForEvent(
     59    browser,
     60    "AboutTabCrashedReady",
     61    false,
     62    null,
     63    true
     64  );
     65  await BrowserTestUtils.crashFrame(browser);
     66  await tabcrashed;
     67 }
     68 
     69 /**
     70 * Tests that the appropriate pieces of UI in the about:tabcrashed pages
     71 * are updated to reflect how many other about:tabcrashed pages there
     72 * are.
     73 */
     74 add_task(async function test_multiple_tabcrashed_pages() {
     75  let histogram = Services.telemetry.getHistogramById(
     76    "FX_CONTENT_CRASH_NOT_SUBMITTED"
     77  );
     78  histogram.clear();
     79 
     80  let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE_1);
     81  let browser1 = tab1.linkedBrowser;
     82 
     83  let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE_2);
     84  let browser2 = tab2.linkedBrowser;
     85 
     86  let tab3 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE_3);
     87  let browser3 = tab3.linkedBrowser;
     88 
     89  await switchToAndCrashTab(tab1);
     90  Assert.ok(tab1.hasAttribute("crashed"), "tab1 has crashed");
     91  Assert.ok(!tab2.hasAttribute("crashed"), "tab2 has not crashed");
     92  Assert.ok(!tab3.hasAttribute("crashed"), "tab3 has not crashed");
     93 
     94  // Should not be showing UI for multiple tabs in tab1.
     95  await assertShowingMultipleUI(browser1, false);
     96 
     97  await switchToAndCrashTab(tab2);
     98  Assert.ok(tab1.hasAttribute("crashed"), "tab1 is still crashed");
     99  Assert.ok(tab2.hasAttribute("crashed"), "tab2 has crashed");
    100  Assert.ok(!tab3.hasAttribute("crashed"), "tab3 has not crashed");
    101 
    102  // tab1 and tab2 should now be showing UI for multiple tab crashes.
    103  await assertShowingMultipleUI(browser1, true);
    104  await assertShowingMultipleUI(browser2, true);
    105 
    106  await switchToAndCrashTab(tab3);
    107  Assert.ok(tab1.hasAttribute("crashed"), "tab1 is still crashed");
    108  Assert.ok(tab2.hasAttribute("crashed"), "tab2 is still crashed");
    109  Assert.ok(tab3.hasAttribute("crashed"), "tab3 has crashed");
    110 
    111  // tab1 and tab2 should now be showing UI for multiple tab crashes.
    112  await assertShowingMultipleUI(browser1, true);
    113  await assertShowingMultipleUI(browser2, true);
    114  await assertShowingMultipleUI(browser3, true);
    115 
    116  BrowserTestUtils.removeTab(tab1);
    117  await assertShowingMultipleUI(browser2, true);
    118  await assertShowingMultipleUI(browser3, true);
    119 
    120  BrowserTestUtils.removeTab(tab2);
    121  await assertShowingMultipleUI(browser3, false);
    122 
    123  BrowserTestUtils.removeTab(tab3);
    124 
    125  // We only record the FX_CONTENT_CRASH_NOT_SUBMITTED probe if there
    126  // was a single about:tabcrashed page at unload time, so we expect
    127  // only a single entry for the probe for when we removed the last
    128  // crashed tab.
    129  await BrowserTestUtils.waitForCondition(() => {
    130    return snapshotCount(histogram.snapshot()) == 1;
    131  }, `Collected value should become 1.`);
    132 
    133  histogram.clear();
    134 });