tor-browser

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

browser_multie10s_update.js (5032B)


      1 "use strict";
      2 
      3 // Testing if 2 child processes are correctly managed when they both try to do
      4 // an SW update.
      5 
      6 const BASE_URI =
      7  "http://mochi.test:8888/browser/dom/serviceworkers/test/isolated/multi-e10s-update/";
      8 
      9 add_task(async function test_update() {
     10  info("Setting the prefs to having multi-e10s enabled");
     11  await SpecialPowers.pushPrefEnv({
     12    set: [
     13      ["dom.ipc.processCount", 4],
     14      ["dom.serviceWorkers.enabled", true],
     15      ["dom.serviceWorkers.testing.enabled", true],
     16    ],
     17  });
     18 
     19  let url = BASE_URI + "file_multie10s_update.html";
     20 
     21  info("Creating the first tab...");
     22  let tab1 = BrowserTestUtils.addTab(gBrowser, url);
     23  let browser1 = gBrowser.getBrowserForTab(tab1);
     24  await BrowserTestUtils.browserLoaded(browser1);
     25 
     26  info("Creating the second tab...");
     27  let tab2 = BrowserTestUtils.addTab(gBrowser, url);
     28  let browser2 = gBrowser.getBrowserForTab(tab2);
     29  await BrowserTestUtils.browserLoaded(browser2);
     30 
     31  let sw = BASE_URI + "server_multie10s_update.sjs";
     32 
     33  info("Let's make sure there are no existing registrations...");
     34  let existingCount = await SpecialPowers.spawn(
     35    browser1,
     36    [],
     37    async function () {
     38      const regs = await content.navigator.serviceWorker.getRegistrations();
     39      return regs.length;
     40    }
     41  );
     42  is(existingCount, 0, "Previous tests should have cleaned up!");
     43 
     44  info("Let's start the test...");
     45  /* eslint-disable no-shadow */
     46  let status = await SpecialPowers.spawn(browser1, [sw], function (url) {
     47    // Let the SW be served immediately once by triggering a relase immediately.
     48    // We don't need to await this.  We do this from a frame script because
     49    // it has fetch.
     50    content.fetch(url + "?release");
     51 
     52    // Registration of the SW
     53    return (
     54      content.navigator.serviceWorker
     55        .register(url)
     56 
     57        // Activation
     58        .then(function (r) {
     59          content.registration = r;
     60          return new content.window.Promise(resolve => {
     61            let worker = r.installing;
     62            worker.addEventListener("statechange", () => {
     63              if (worker.state === "installed") {
     64                resolve(true);
     65              }
     66            });
     67          });
     68        })
     69 
     70        // Waiting for the result.
     71        .then(() => {
     72          return new content.window.Promise(resolveResults => {
     73            // Once both updates have been issued and a single update has failed, we
     74            // can tell the .sjs to release a single copy of the SW script.
     75            let updateCount = 0;
     76            const uc = new content.window.BroadcastChannel("update");
     77            // This promise tracks the updates tally.
     78            const updatesIssued = new Promise(resolveUpdatesIssued => {
     79              uc.onmessage = function (e) {
     80                updateCount++;
     81                console.log("got update() number", updateCount);
     82                if (updateCount === 2) {
     83                  resolveUpdatesIssued();
     84                }
     85              };
     86            });
     87 
     88            let results = [];
     89            const rc = new content.window.BroadcastChannel("result");
     90            // This promise resolves when an update has failed.
     91            const oneFailed = new Promise(resolveOneFailed => {
     92              rc.onmessage = function (e) {
     93                console.log("got result", e.data);
     94                results.push(e.data);
     95                if (e.data === 1) {
     96                  resolveOneFailed();
     97                }
     98                if (results.length != 2) {
     99                  return;
    100                }
    101 
    102                resolveResults(results[0] + results[1]);
    103              };
    104            });
    105 
    106            Promise.all([updatesIssued, oneFailed]).then(() => {
    107              console.log("releasing update");
    108              content.fetch(url + "?release").catch(ex => {
    109                console.error("problem releasing:", ex);
    110              });
    111            });
    112 
    113            // Let's inform the tabs.
    114            const sc = new content.window.BroadcastChannel("start");
    115            sc.postMessage("go");
    116          });
    117        })
    118    );
    119  });
    120  /* eslint-enable no-shadow */
    121 
    122  if (status == 0) {
    123    ok(false, "both succeeded. This is wrong.");
    124  } else if (status == 1) {
    125    ok(true, "one succeded, one failed. This is good.");
    126  } else {
    127    ok(false, "both failed. This is definitely wrong.");
    128  }
    129 
    130  // let's clean up the registration and get the fetch count.  The count
    131  // should be 1 for the initial fetch and 1 for the update.
    132  /* eslint-disable no-shadow */
    133  const count = await SpecialPowers.spawn(browser1, [sw], async function (url) {
    134    // We stored the registration on the frame script's wrapper, hence directly
    135    // accesss content without using wrappedJSObject.
    136    await content.registration.unregister();
    137    const { count } = await content
    138      .fetch(url + "?get-and-clear-count")
    139      .then(r => r.json());
    140    return count;
    141  });
    142  /* eslint-enable no-shadow */
    143  is(count, 2, "SW should have been fetched only twice");
    144 
    145  BrowserTestUtils.removeTab(tab1);
    146  BrowserTestUtils.removeTab(tab2);
    147 });