tor-browser

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

test_devtools_track_serviceworker_time.html (6977B)


      1 <html>
      2 <head>
      3  <title>Bug 1251238 - track service worker install time</title>
      4  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
      5  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
      6 </head>
      7 <iframe id="iframe"></iframe>
      8 <body>
      9 
     10 <script type="text/javascript">
     11 
     12 const State = {
     13  BYTECHECK: -1,
     14  PARSED: Ci.nsIServiceWorkerInfo.STATE_PARSED,
     15  INSTALLING: Ci.nsIServiceWorkerInfo.STATE_INSTALLING,
     16  INSTALLED: Ci.nsIServiceWorkerInfo.STATE_INSTALLED,
     17  ACTIVATING: Ci.nsIServiceWorkerInfo.STATE_ACTIVATING,
     18  ACTIVATED: Ci.nsIServiceWorkerInfo.STATE_ACTIVATED,
     19  REDUNDANT: Ci.nsIServiceWorkerInfo.STATE_REDUNDANT
     20 };
     21 let swm = Cc["@mozilla.org/serviceworkers/manager;1"].
     22          getService(Ci.nsIServiceWorkerManager);
     23 
     24 let EXAMPLE_URL = "https://example.com/chrome/dom/serviceworkers/test/";
     25 
     26 let swrlistener = null;
     27 let registrationInfo = null;
     28 
     29 // Use it to keep the sw after unregistration.
     30 let astrayServiceWorkerInfo = null;
     31 
     32 let expectedResults = [
     33  {
     34    // Speacial state for verifying update since we will do the byte-check
     35    // first.
     36    state: State.BYTECHECK, installedTimeRecorded: false,
     37    activatedTimeRecorded: false, redundantTimeRecorded: false
     38  },
     39  {
     40    state: State.PARSED, installedTimeRecorded: false,
     41    activatedTimeRecorded: false, redundantTimeRecorded: false
     42  },
     43  {
     44    state: State.INSTALLING, installedTimeRecorded: false,
     45    activatedTimeRecorded: false, redundantTimeRecorded: false
     46  },
     47  {
     48    state: State.INSTALLED, installedTimeRecorded: true,
     49    activatedTimeRecorded: false, redundantTimeRecorded: false
     50  },
     51  {
     52    state: State.ACTIVATING, installedTimeRecorded: true,
     53    activatedTimeRecorded: false, redundantTimeRecorded: false
     54  },
     55  {
     56    state: State.ACTIVATED, installedTimeRecorded: true,
     57    activatedTimeRecorded: true, redundantTimeRecorded: false
     58  },
     59 
     60  // When first being marked as unregistered (but the worker can remain
     61  // actively controlling pages)
     62  {
     63    state: State.ACTIVATED, installedTimeRecorded: true,
     64    activatedTimeRecorded: true, redundantTimeRecorded: false
     65  },
     66  // When cleared (when idle)
     67  {
     68    state: State.REDUNDANT, installedTimeRecorded: true,
     69    activatedTimeRecorded: true, redundantTimeRecorded: true
     70  },
     71 ];
     72 
     73 function waitForRegister(aScope, aCallback) {
     74  return new Promise(function (aResolve) {
     75    let listener = {
     76      onRegister (aRegistration) {
     77        if (aRegistration.scope !== aScope) {
     78          return;
     79        }
     80        swm.removeListener(listener);
     81        registrationInfo = aRegistration;
     82        aResolve();
     83      }
     84    };
     85    swm.addListener(listener);
     86  });
     87 }
     88 
     89 function waitForUnregister(aScope) {
     90  return new Promise(function (aResolve) {
     91    let listener = {
     92      onUnregister (aRegistration) {
     93        if (aRegistration.scope !== aScope) {
     94          return;
     95        }
     96        swm.removeListener(listener);
     97        aResolve();
     98      }
     99    };
    100    swm.addListener(listener);
    101  });
    102 }
    103 
    104 function register() {
    105  info("Register a ServiceWorker in the iframe");
    106 
    107  let iframe = document.querySelector("iframe");
    108  iframe.src = EXAMPLE_URL + "serviceworkerinfo_iframe.html";
    109 
    110  let promise = new Promise(function(aResolve) {
    111    iframe.onload = aResolve;
    112  });
    113 
    114  return promise.then(function() {
    115    iframe.contentWindow.postMessage("register", "*");
    116    return waitForRegister(EXAMPLE_URL);
    117  })
    118 }
    119 
    120 function verifyServiceWorkTime(aSWRInfo, resolve) {
    121  let expectedResult = expectedResults.shift();
    122  ok(!!expectedResult, "We should be able to get test from expectedResults");
    123 
    124  info("Check the ServiceWorker time in its state is " + expectedResult.state);
    125 
    126  // Get serviceWorkerInfo from swrInfo or get the astray one which we hold.
    127  let swInfo = aSWRInfo.evaluatingWorker ||
    128               aSWRInfo.installingWorker ||
    129               aSWRInfo.waitingWorker ||
    130               aSWRInfo.activeWorker ||
    131               astrayServiceWorkerInfo;
    132 
    133  ok(!!aSWRInfo.lastUpdateTime,
    134     "We should do the byte-check and update the update timeStamp");
    135 
    136  if (!swInfo) {
    137    is(expectedResult.state, State.BYTECHECK,
    138       "We shouldn't get sw when we are notified for first time updating");
    139    return;
    140  }
    141 
    142  ok(!!swInfo);
    143 
    144  is(expectedResult.state, swInfo.state,
    145     "The service worker's state should be " + swInfo.state + ", but got " +
    146     expectedResult.state);
    147 
    148  is(expectedResult.installedTimeRecorded, !!swInfo.installedTime,
    149     "InstalledTime should be recorded when their state is greater than " +
    150     "INSTALLING");
    151 
    152  is(expectedResult.activatedTimeRecorded, !!swInfo.activatedTime,
    153     "ActivatedTime should be recorded when their state is greater than " +
    154     "ACTIVATING");
    155 
    156  is(expectedResult.redundantTimeRecorded, !!swInfo.redundantTime,
    157     "RedundantTime should be recorded when their state is REDUNDANT");
    158 
    159  // We need to hold sw to avoid losing it since we'll unregister the swr later.
    160  if (expectedResult.state === State.ACTIVATED) {
    161    astrayServiceWorkerInfo = aSWRInfo.activeWorker;
    162 
    163    // Resolve the promise for testServiceWorkerInfo after sw is activated.
    164    resolve();
    165  }
    166 }
    167 
    168 function testServiceWorkerInfo() {
    169  info("Listen onChange event and verify service worker's information");
    170 
    171  let promise_resolve;
    172  let promise = new Promise(aResolve => promise_resolve = aResolve);
    173 
    174  swrlistener = {
    175    onChange: () => {
    176      verifyServiceWorkTime(registrationInfo, promise_resolve);
    177    }
    178  };
    179 
    180  registrationInfo.addListener(swrlistener);
    181 
    182  return promise;
    183 }
    184 
    185 async function testHttpCacheUpdateTime() {
    186  let iframe = document.querySelector("iframe");
    187  let reg = await iframe.contentWindow.navigator.serviceWorker.getRegistration();
    188  let lastUpdateTime = registrationInfo.lastUpdateTime;
    189  await reg.update();
    190  is(lastUpdateTime, registrationInfo.lastUpdateTime,
    191     "The update time should not change when SW script is read from http cache.");
    192 }
    193 
    194 function unregister() {
    195  info("Unregister the ServiceWorker");
    196 
    197  let iframe = document.querySelector("iframe");
    198  iframe.contentWindow.postMessage("unregister", "*");
    199  return waitForUnregister(EXAMPLE_URL);
    200 }
    201 
    202 function cleanAll() {
    203  return new Promise((aResolve, aReject) => {
    204    is(expectedResults.length, 0, "All the tests should be tested");
    205 
    206    registrationInfo.removeListener(swrlistener);
    207 
    208    swm = null;
    209    swrlistener = null;
    210    registrationInfo = null;
    211    astrayServiceWorkerInfo = null;
    212    aResolve();
    213  })
    214 }
    215 
    216 function runTest() {
    217  return Promise.resolve()
    218    .then(register)
    219    .then(testServiceWorkerInfo)
    220    .then(testHttpCacheUpdateTime)
    221    .then(unregister)
    222    .catch(aError => ok(false, "Some test failed with error " + aError))
    223    .then(cleanAll)
    224    .then(SimpleTest.finish);
    225 }
    226 
    227 SimpleTest.waitForExplicitFinish();
    228 SpecialPowers.pushPrefEnv({"set": [
    229  ["dom.serviceWorkers.exemptFromPerDomainMax", true],
    230  ["dom.serviceWorkers.enabled", true],
    231  ["dom.serviceWorkers.testing.enabled", true]
    232 ]}, runTest);
    233 
    234 </script>
    235 </body>
    236 </html>