tor-browser

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

partitioned-estimate-usage-details-service-workers.tentative.https.sub.html (7991B)


      1 <!DOCTYPE html>
      2 <meta name=help href="https://privacycg.github.io/storage-partitioning/">
      3 <title>Partitioned estimate() usage details for service workers test</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 
      7 <body>
      8  <script>
      9    // Helper function to obtain service worker usage data for this test window.
     10    const usageDetails = async () => {
     11      return (await navigator.storage.estimate())
     12        .usageDetails.serviceWorkerRegistrations || 0;
     13    }
     14 
     15    // Helper function to create a service worker registration so that our test
     16    // can estimate that usage.
     17    const createSomeUsage = async () => {
     18      const wait_for_active = worker => new Promise(resolve => {
     19        if (worker.active) { resolve(worker.active); }
     20 
     21        const listen_for_active = worker => e => {
     22          if (e.target.state === 'activated') { resolve(worker.active); }
     23        }
     24 
     25        if (worker.waiting) {
     26          worker.waiting
     27            .addEventListener('statechange', listen_for_active(worker.waiting));
     28        }
     29        if (worker.installing) {
     30          worker.installing.addEventListener('statechange',
     31            listen_for_active(worker.installing));
     32        }
     33      });
     34 
     35      const service_worker_registration =
     36        await navigator.serviceWorker.register('resources/worker.js');
     37      await wait_for_active(service_worker_registration);
     38      return service_worker_registration;
     39    }
     40 
     41    // Helper function for creating pathnames to test resources.
     42    const testPath = () => location.pathname.split("/").slice(0, -1).join("/");
     43 
     44    // Define our test variables.
     45    let alt_origin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
     46    let details = {};
     47 
     48    // Step 0: Construct an iframe. The content of this iframe includes
     49    // a script that will intercept and send postMessages back to this test
     50    // window.
     51    const iframe = document.createElement("iframe");
     52    iframe.src = `https://{{host}}:{{ports[https][0]}}${testPath()}/resources` +
     53      `/partitioned-estimate-usage-details-service-workers-helper-frame.html`
     54    document.body.appendChild(iframe);
     55 
     56    // Our test will perform the following steps to demonstrate the partitioning
     57    // of storage estimate usage details for service worker registrations. Some
     58    // steps are defined in:
     59    // wpt/storage/resources/partitioned-estimate-usage-details-service-workers-helper-frame.html
     60    // --------------------
     61    // (0) Construct a same-partition iframe on our test page. The content of
     62    // this iframe includes a script that will intercept and send postMessages
     63    // back to this test window.
     64    // (1) The same-partition iframe sends a postMessage notifying that the
     65    // iframe was constructed and we are ready to proceed with the test.
     66    // (2) Our test window intercepts this "iframe-is-ready" message.
     67    // (3) We create a service worker registration and ensure that the
     68    // service worker usage data reflects that increase in the test window.
     69    // (4) postMessage the same-partition iframe to obtain the service worker
     70    // usage data from that frame.
     71    // (5) Our same-partition iframe intercepts the "get-details" postMessage,
     72    // obtains the service worker usage details available to the iframe, and
     73    // postMessages the usage back to the test window.
     74    // (6) Our test window intercepts the "same-site" message from the same-
     75    // partition iframe containing usage data obtained there.
     76    // (7) We record the same-partition usage data. Then, we open a cross-site
     77    // window containing this test script. As a result, Step 0 will be repeated,
     78    // and a cross-partition iframe will be created in that cross-site window.
     79    // Our cross-partition iframe will receive the same script as our same-
     80    // partition iframe. We then return early to avoid running another instance
     81    // of this test.
     82    // (8) Once created and loaded, our cross-partition iframe has an on-load
     83    // listener that is triggered. To check that our script is executing in the
     84    // cross-partition iframe (and not the same-partition iframe), we check that
     85    // our parent has a valid opener value.
     86    // (9) Then, our cross-partition iframe obtains the service worker usage
     87    // details available to it and postMessages the usage back to the test
     88    // window.
     89    // (10) Our test window intercepts the "cross-site" message from the cross-
     90    // partition iframe containing the usage data obtained there.
     91    // (11) We record the cross-partition usage data. Then we make our final
     92    // assertions.
     93    async_test(test => {
     94      // Since this script is loaded in two windows (our original test window
     95      // and the cross-partition window opened later in the test), and we only
     96      // want to run the test body in the original test window, we return early
     97      // if our origin matches the "cross-site" window.
     98      if (location.origin === alt_origin)
     99        return;
    100 
    101      // Step 2: Our test window intercepts the "iframe-is-ready" message from
    102      // the same-partition iframe.
    103      let service_worker_registration;
    104      window.addEventListener("message", test.step_func(async event => {
    105        if (event.data === "iframe-is-ready") {
    106          // Step 3: We create a service worker registration and ensure that
    107          // the service worker usage data reflects that increase in the
    108          // test window.
    109          details.init = await usageDetails();
    110          service_worker_registration = await createSomeUsage();
    111          details.after = await usageDetails();
    112          assert_greater_than(details.after, details.init);
    113 
    114          // Step 4: postMessage the same-partition iframe to request that
    115          // service worker usage data be obtained and sent from that frame.
    116          iframe.contentWindow.postMessage("get-details", iframe.origin);
    117        }
    118      }));
    119 
    120      window.addEventListener("message", test.step_func(event => {
    121        // Step 6: Our test window intercepts the "same-site" message from the
    122        // same-partition iframe containing usage data obtained there.
    123        if (event.data.source === "same-site") {
    124          // Step 7: We record the same-partition data here. Then, we open a
    125          // cross-site window containing this test script. As a result,
    126          // Step 0 will be repeated, and a cross-partition iframe will be
    127          // created in that cross-site window. Our cross-partition iframe
    128          // will receive the same script as our same-partition iframe. We then
    129          // return early to avoid running another instance of this test.
    130          details.same_site = event.data;
    131 
    132          const cross_site_window = window
    133            .open(`${alt_origin}${location.pathname}`, "", "noopener=false");
    134          test.add_cleanup(() => cross_site_window.close());
    135        }
    136        // Step 10: Our test window intercepts the "cross-site" message from
    137        // the cross-partition iframe containing the usage data obtained there.
    138        if (event.data.source === "cross-site") {
    139          // Step 11: We record the cross-partition data. Then we make our
    140          // final assertions.
    141          details.cross_site = event.data;
    142 
    143          // More cleanup.
    144          test.step(() => service_worker_registration.unregister());
    145 
    146          // Usage data is correctly partitioned if:
    147          // a. Our cross-partition iframe recorded no service worker usage
    148          // data AND
    149          // b. The service worker usage data for our test window (after the
    150          // service worker is registered) is equal to the service worker
    151          // usage data recorded by our same-partition iframe.
    152          test.step(() => {
    153            assert_true(details.cross_site.init == 0, "Usage should be 0.");
    154            assert_equals(details.same_site.init, details.after);
    155          });
    156 
    157          test.done();
    158        }
    159      }));
    160    }, "Partitioned estimate() usage details for service workers test.");
    161  </script>
    162 </body>