different-initiators.sub.https.html (3122B)
1 <!DOCTYPE html> 2 <meta name="timeout" content="long"> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="/common/utils.js"></script> 6 <script src="/common/dispatcher/dispatcher.js"></script> 7 <script src="../resources/utils.js"></script> 8 <script src="resources/utils.sub.js"></script> 9 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> 10 11 <meta name="variant" content="?cross-site-1"> 12 <meta name="variant" content="?cross-site-2"> 13 <meta name="variant" content="?same-site"> 14 15 <script> 16 setup(() => assertSpeculationRulesIsSupported()); 17 18 // Regression test for https://crbug.com/1423234. 19 promise_test(async t => { 20 // Open 2 windows. 21 const hostname1 = 22 location.search === '?cross-site-1' ? '{{hosts[alt][www]}}' : undefined; 23 const hostname2 = 24 location.search === '?cross-site-2' ? '{{hosts[alt][www]}}' : undefined; 25 const initiator1 = await spawnWindow( 26 t, { protocol: 'https', hostname: hostname1 }); 27 const initiator2 = await spawnWindow( 28 t, { protocol: 'https', hostname: hostname2 }); 29 30 // Start speculation rules prefetch from `initiator1`. 31 const nextUrl = initiator1.getExecutorURL({ protocol: 'https', page: 2 }); 32 await initiator1.forceSinglePrefetch(nextUrl); 33 34 // Register a SW for `nextUrl` -- this is a trick to make the prefetched 35 // result to put in `PrefetchService::prefetches_ready_to_serve_` in 36 // Chromium implementation but actually not used by this navigation. 37 const r = await service_worker_unregister_and_register( 38 t, 'resources/sw.js', nextUrl); 39 await wait_for_state(t, r.installing, 'activated'); 40 41 // Navigate `initiator1`. 42 // This doesn't use the prefetched result due to the ServiceWorker. 43 await initiator1.navigate(nextUrl); 44 45 // Navigate `initiator1` away from `nextUrl`. 46 const headers1 = await initiator1.execute_script(() => { 47 window.executor.suspend(() => { 48 location.href = 'about:blank'; 49 }); 50 return requestHeaders; 51 }, []); 52 53 // Unregister the SW. 54 await service_worker_unregister(t, nextUrl); 55 56 // Navigate `initiator2`. 57 // This shouldn't use the prefetched result because the initiator Documents 58 // (even sites) are different. 59 await initiator2.execute_script((url) => { 60 window.executor.suspend(() => { 61 location.href = url; 62 }); 63 }, [nextUrl]); 64 65 // Note: while the Window for `initiator2` remains open, the executor ID of 66 // the page is the ID of `nextUrl`, which is `initiator1.context_id`. 67 // So `initiator1` is used below for manipulating the Window for `initiator2`. 68 assert_equals( 69 await initiator1.execute_script(() => location.href), 70 nextUrl.toString(), 71 "expected navigation to reach destination URL"); 72 73 const headers2 = await initiator1.execute_script(() => { 74 return requestHeaders; 75 }, []); 76 77 assert_not_prefetched(headers1, 78 "Prefetch should not work due to ServiceWorker."); 79 80 assert_not_prefetched(headers2, 81 "Prefetch should not work for different initiators."); 82 }, "Cross-initiator prefetches using ServiceWorker tricks"); 83 </script>