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