tor-browser

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

browser_586068-browser_state_interrupted.js (5816B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
      6 
      7 requestLongerTimeout(2);
      8 
      9 add_task(async function test() {
     10  Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
     11  registerCleanupFunction(function () {
     12    Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
     13  });
     14 
     15  // The first state will be loaded using setBrowserState, followed by the 2nd
     16  // state also being loaded using setBrowserState, interrupting the first restore.
     17  let state1 = {
     18    windows: [
     19      {
     20        tabs: [
     21          {
     22            entries: [
     23              { url: "http://example.org#1", triggeringPrincipal_base64 },
     24            ],
     25            extData: { uniq: r() },
     26          },
     27          {
     28            entries: [
     29              { url: "http://example.org#2", triggeringPrincipal_base64 },
     30            ],
     31            extData: { uniq: r() },
     32          },
     33          {
     34            entries: [
     35              { url: "http://example.org#3", triggeringPrincipal_base64 },
     36            ],
     37            extData: { uniq: r() },
     38          },
     39          {
     40            entries: [
     41              { url: "http://example.org#4", triggeringPrincipal_base64 },
     42            ],
     43            extData: { uniq: r() },
     44          },
     45        ],
     46        selected: 1,
     47      },
     48      {
     49        tabs: [
     50          {
     51            entries: [
     52              { url: "http://example.com#1", triggeringPrincipal_base64 },
     53            ],
     54            extData: { uniq: r() },
     55          },
     56          {
     57            entries: [
     58              { url: "http://example.com#2", triggeringPrincipal_base64 },
     59            ],
     60            extData: { uniq: r() },
     61          },
     62          {
     63            entries: [
     64              { url: "http://example.com#3", triggeringPrincipal_base64 },
     65            ],
     66            extData: { uniq: r() },
     67          },
     68          {
     69            entries: [
     70              { url: "http://example.com#4", triggeringPrincipal_base64 },
     71            ],
     72            extData: { uniq: r() },
     73          },
     74        ],
     75        selected: 3,
     76      },
     77    ],
     78  };
     79  let state2 = {
     80    windows: [
     81      {
     82        tabs: [
     83          {
     84            entries: [
     85              { url: "http://example.org#5", triggeringPrincipal_base64 },
     86            ],
     87            extData: { uniq: r() },
     88          },
     89          {
     90            entries: [
     91              { url: "http://example.org#6", triggeringPrincipal_base64 },
     92            ],
     93            extData: { uniq: r() },
     94          },
     95          {
     96            entries: [
     97              { url: "http://example.org#7", triggeringPrincipal_base64 },
     98            ],
     99            extData: { uniq: r() },
    100          },
    101          {
    102            entries: [
    103              { url: "http://example.org#8", triggeringPrincipal_base64 },
    104            ],
    105            extData: { uniq: r() },
    106          },
    107        ],
    108        selected: 3,
    109      },
    110      {
    111        tabs: [
    112          {
    113            entries: [
    114              { url: "http://example.com#5", triggeringPrincipal_base64 },
    115            ],
    116            extData: { uniq: r() },
    117          },
    118          {
    119            entries: [
    120              { url: "http://example.com#6", triggeringPrincipal_base64 },
    121            ],
    122            extData: { uniq: r() },
    123          },
    124          {
    125            entries: [
    126              { url: "http://example.com#7", triggeringPrincipal_base64 },
    127            ],
    128            extData: { uniq: r() },
    129          },
    130          {
    131            entries: [
    132              { url: "http://example.com#8", triggeringPrincipal_base64 },
    133            ],
    134            extData: { uniq: r() },
    135          },
    136        ],
    137        selected: 1,
    138      },
    139    ],
    140  };
    141 
    142  // interruptedAfter will be set after the selected tab from each window have loaded.
    143  let interruptedAfter = 0;
    144  let loadedWindow1 = false;
    145  let loadedWindow2 = false;
    146  let numTabs = state2.windows[0].tabs.length + state2.windows[1].tabs.length;
    147 
    148  let loadCount = 0;
    149  let promiseRestoringTabs = new Promise(resolve => {
    150    gProgressListener.setCallback(function (aBrowser, aNeedRestore) {
    151      loadCount++;
    152 
    153      if (
    154        aBrowser.currentURI.spec == state1.windows[0].tabs[2].entries[0].url
    155      ) {
    156        loadedWindow1 = true;
    157      }
    158      if (
    159        aBrowser.currentURI.spec == state1.windows[1].tabs[0].entries[0].url
    160      ) {
    161        loadedWindow2 = true;
    162      }
    163 
    164      if (!interruptedAfter && loadedWindow1 && loadedWindow2) {
    165        interruptedAfter = loadCount;
    166        ss.setBrowserState(JSON.stringify(state2));
    167        return;
    168      }
    169 
    170      if (loadCount < numTabs + interruptedAfter) {
    171        return;
    172      }
    173 
    174      // We don't actually care about load order in this test, just that they all
    175      // do load.
    176      is(loadCount, numTabs + interruptedAfter, "all tabs were restored");
    177      is(aNeedRestore, 0, "there are no tabs left needing restore");
    178 
    179      // Remove the progress listener.
    180      gProgressListener.unsetCallback();
    181      resolve();
    182    });
    183  });
    184 
    185  // We also want to catch the extra windows (there should be 2), so we need to observe domwindowopened
    186  Services.ww.registerNotification(function observer(aSubject, aTopic) {
    187    if (aTopic == "domwindowopened") {
    188      let win = aSubject;
    189      win.addEventListener(
    190        "load",
    191        function () {
    192          Services.ww.unregisterNotification(observer);
    193          win.gBrowser.addTabsProgressListener(gProgressListener);
    194        },
    195        { once: true }
    196      );
    197    }
    198  });
    199 
    200  let backupState = ss.getBrowserState();
    201  ss.setBrowserState(JSON.stringify(state1));
    202  await promiseRestoringTabs;
    203 
    204  // Cleanup.
    205  await promiseAllButPrimaryWindowClosed();
    206  await promiseBrowserState(backupState);
    207 });