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