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>