partitioned.tentative.https.html (9330B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"/> 3 <title>Service Worker: Partitioned Service Workers</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="resources/test-helpers.sub.js"></script> 7 <script src="/common/get-host-info.sub.js"></script> 8 <script src="resources/partitioned-utils.js"></script> 9 10 <body> 11 <!-- Debugging text for both test cases --> 12 The 3p iframe's postMessage: 13 <p id="iframe_response">No message received</p> 14 15 The nested iframe's postMessage: 16 <p id="nested_iframe_response">No message received</p> 17 18 <script> 19 promise_test(async t => { 20 const script = './resources/partitioned-storage-sw.js' 21 const scope = './resources/partitioned-' 22 23 // Add service worker to this 1P context. wait_for_state() and 24 // service_worker_unregister_and_register() are helper functions 25 // for creating test ServiceWorkers defined in: 26 // service-workers/service-worker/resources/test-helpers.sub.js 27 const reg = await service_worker_unregister_and_register(t, script, scope); 28 t.add_cleanup(() => reg.unregister()); 29 await wait_for_state(t, reg.installing, 'activated'); 30 31 // Registers the message listener with messageEventHandler(), defined in: 32 // service-workers/service-worker/resources/partitioned-utils.js 33 self.addEventListener('message', messageEventHandler); 34 35 // Open an iframe that will create a promise within the SW. 36 // Defined in service-workers/service-worker/resources/partitioned-storage-sw.js: 37 // `waitUntilResolved.fakehtml`: URL scope that creates the promise. 38 // `?From1pFrame`: query param that tracks which request the service worker is 39 // handling. 40 const wait_frame_url = new URL( 41 './resources/partitioned-waitUntilResolved.fakehtml?From1pFrame', 42 self.location); 43 44 // Loads a child iframe with wait_frame_url as the content and returns 45 // a promise for the data messaged from the loaded iframe. 46 // loadAndReturnSwData() defined in: 47 // service-workers/service-worker/resources/partitioned-utils.js: 48 const wait_frame_1p_data = await loadAndReturnSwData(t, wait_frame_url, 49 'iframe'); 50 assert_equals(wait_frame_1p_data.source, 'From1pFrame', 51 'The data for the 1p frame came from the wrong source'); 52 53 // Now create a 3p iframe that will try to resolve the SW in a 3p context. 54 const third_party_iframe_url = new URL( 55 './resources/partitioned-service-worker-third-party-iframe.html', 56 get_host_info().HTTPS_ORIGIN + self.location.pathname); 57 58 // loadAndReturnSwData() creates a HTTPS_NOTSAMESITE_ORIGIN or 3p `window` 59 // element which embeds an iframe with the ServiceWorker and returns 60 // a promise of the data messaged from that frame. 61 const frame_3p_data = await loadAndReturnSwData(t, third_party_iframe_url, 'window'); 62 assert_equals(frame_3p_data.source, 'From3pFrame', 63 'The data for the 3p frame came from the wrong source'); 64 65 // Print some debug info to the main frame. 66 document.getElementById("iframe_response").innerHTML = 67 "3p iframe's has_pending: " + frame_3p_data.has_pending + " source: " + 68 frame_3p_data.source + ". "; 69 70 // Now do the same for the 1p iframe. 71 // Defined in service-workers/service-worker/resources/partitioned-storage-sw.js: 72 // `resolve.fakehtml`: URL scope that resolves the promise. 73 const resolve_frame_url = new URL( 74 './resources/partitioned-resolve.fakehtml?From1pFrame', self.location); 75 76 const frame_1p_data = await loadAndReturnSwData(t, resolve_frame_url, 77 'iframe'); 78 assert_equals(frame_1p_data.source, 'From1pFrame', 79 'The data for the 1p frame came from the wrong source'); 80 // Both the 1p frames should have been serviced by the same service worker ID. 81 // If this isn't the case then that means the SW could have been deactivated 82 // which invalidates the test. 83 assert_equals(frame_1p_data.ID, wait_frame_1p_data.ID, 84 'The 1p frames were serviced by different service workers.'); 85 86 document.getElementById("iframe_response").innerHTML += 87 "1p iframe's has_pending: " + frame_1p_data.has_pending + " source: " + 88 frame_1p_data.source; 89 90 // If partitioning is working correctly then only the 1p iframe should see 91 // (and resolve) its SW's promise. Additionally the two frames should see 92 // different IDs. 93 assert_true(frame_1p_data.has_pending, 94 'The 1p iframe saw a pending promise in the service worker.'); 95 assert_false(frame_3p_data.has_pending, 96 'The 3p iframe saw a pending promise in the service worker.'); 97 assert_not_equals(frame_1p_data.ID, frame_3p_data.ID, 98 'The frames were serviced by the same service worker thread.'); 99 }, 'Services workers under different top-level sites are partitioned.'); 100 101 // Optional Test: Checking for partitioned ServiceWorkers in an A->B->A 102 // (nested-iframes with cross-site ancestor) scenario. 103 promise_test(async t => { 104 const script = './resources/partitioned-storage-sw.js' 105 const scope = './resources/partitioned-' 106 107 // Add service worker to this 1P context. wait_for_state() and 108 // service_worker_unregister_and_register() are helper functions 109 // for creating test ServiceWorkers defined in: 110 // service-workers/service-worker/resources/test-helpers.sub.js 111 const reg = await service_worker_unregister_and_register(t, script, scope); 112 t.add_cleanup(() => reg.unregister()); 113 await wait_for_state(t, reg.installing, 'activated'); 114 115 // Registers the message listener with messageEventHandler(), defined in: 116 // service-workers/service-worker/resources/partitioned-utils.js 117 self.addEventListener('message', messageEventHandler); 118 119 // Open an iframe that will create a promise within the SW. 120 // Defined in service-workers/service-worker/resources/partitioned-storage-sw.js: 121 // `waitUntilResolved.fakehtml`: URL scope that creates the promise. 122 // `?From1pFrame`: query param that tracks which request the service worker is 123 // handling. 124 const wait_frame_url = new URL( 125 './resources/partitioned-waitUntilResolved.fakehtml?From1pFrame', 126 self.location); 127 128 // Load a child iframe with wait_frame_url as the content. 129 // loadAndReturnSwData() defined in: 130 // service-workers/service-worker/resources/partitioned-utils.js: 131 const wait_frame_1p_data = await loadAndReturnSwData(t, wait_frame_url, 132 'iframe'); 133 assert_equals(wait_frame_1p_data.source, 'From1pFrame', 134 'The data for the 1p frame came from the wrong source'); 135 136 // Now create a set of nested iframes in the configuration A1->B->A2 137 // where B is cross-site and A2 is same-site to this top-level 138 // site (A1). The innermost iframe of the nested iframes (A2) will 139 // create an additional iframe to finally resolve the ServiceWorker. 140 const nested_iframe_url = new URL( 141 './resources/partitioned-service-worker-nested-iframe-parent.html', 142 get_host_info().HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname); 143 144 // Create the nested iframes (which will in turn create the iframe 145 // with the ServiceWorker) and await on receiving its data. 146 const nested_iframe_data = await loadAndReturnSwData(t, nested_iframe_url, 'iframe'); 147 assert_equals(nested_iframe_data.source, 'FromNestedFrame', 148 'The data for the nested iframe frame came from the wrong source'); 149 150 // Print some debug info to the main frame. 151 document.getElementById("nested_iframe_response").innerHTML = 152 "Nested iframe's has_pending: " + nested_iframe_data.has_pending + " source: " + 153 nested_iframe_data.source + ". "; 154 155 // Now do the same for the 1p iframe. 156 // Defined in service-workers/service-worker/resources/partitioned-storage-sw.js: 157 // `resolve.fakehtml`: URL scope that resolves the promise. 158 const resolve_frame_url = new URL( 159 './resources/partitioned-resolve.fakehtml?From1pFrame', self.location); 160 161 const frame_1p_data = await loadAndReturnSwData(t, resolve_frame_url, 162 'iframe'); 163 assert_equals(frame_1p_data.source, 'From1pFrame', 164 'The data for the 1p frame came from the wrong source'); 165 // Both the 1p frames should have been serviced by the same service worker ID. 166 // If this isn't the case then that means the SW could have been deactivated 167 // which invalidates the test. 168 assert_equals(frame_1p_data.ID, wait_frame_1p_data.ID, 169 'The 1p frames were serviced by different service workers.'); 170 171 document.getElementById("nested_iframe_response").innerHTML += 172 "1p iframe's has_pending: " + frame_1p_data.has_pending + " source: " + 173 frame_1p_data.source; 174 175 // If partitioning is working correctly then only the 1p iframe should see 176 // (and resolve) its SW's promise. Additionally, the innermost iframe of 177 // the nested iframes (A2 in the configuration A1->B->A2) should have a 178 // different service worker ID than the 1p (A1) frame. 179 assert_true(frame_1p_data.has_pending, 180 'The 1p iframe saw a pending promise in the service worker.'); 181 assert_false(nested_iframe_data.has_pending, 182 'The 3p iframe saw a pending promise in the service worker.'); 183 assert_not_equals(frame_1p_data.ID, nested_iframe_data.ID, 184 'The frames were serviced by the same service worker thread.'); 185 }, 'Services workers with cross-site ancestors are partitioned.'); 186 187 </script> 188 </body>