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