browser_navigationPreload_read_after_respondWith.js (3960B)
1 const TOP_DOMAIN = "http://mochi.test:8888/"; 2 const SW_DOMAIN = "https://example.org/"; 3 4 const TOP_TEST_ROOT = getRootDirectory(gTestPath).replace( 5 "chrome://mochitests/content/", 6 TOP_DOMAIN 7 ); 8 const SW_TEST_ROOT = getRootDirectory(gTestPath).replace( 9 "chrome://mochitests/content/", 10 SW_DOMAIN 11 ); 12 13 const TOP_EMPTY_PAGE = `${TOP_TEST_ROOT}empty_with_utils.html`; 14 const SW_REGISTER_PAGE = `${SW_TEST_ROOT}empty_with_utils.html`; 15 const SW_IFRAME_PAGE = `${SW_TEST_ROOT}navigationPreload_page.html`; 16 // An empty script suffices for our SW needs; it's by definition no-fetch. 17 const SW_REL_SW_SCRIPT = "sw_with_navigationPreload.js"; 18 19 /** 20 * Test the FetchEvent.preloadResponse can be read after FetchEvent.respondWith() 21 * 22 * Step 1. register a ServiceWorker which only handles FetchEvent when request 23 * url includes navigationPreload_page.html. Otherwise, it alwasy 24 * fallbacks the fetch to the network. 25 * If the request url includes navigationPreload_page.html, it call 26 * FetchEvent.respondWith() with a new Resposne, and then call 27 * FetchEvent.waitUtil() to wait FetchEvent.preloadResponse and post the 28 * preloadResponse's text to clients. 29 * Step 2. Open a controlled page and register message event handler to receive 30 * the postMessage from ServiceWorker. 31 * Step 3. Create a iframe which url is navigationPreload_page.html, such that 32 * ServiceWorker can fake the response and then send preloadResponse's 33 * result. 34 * Step 4. Unregister the ServiceWorker and cleanup the environment. 35 */ 36 add_task(async function () { 37 await SpecialPowers.pushPrefEnv({ 38 set: [ 39 ["dom.serviceWorkers.enabled", true], 40 ["dom.serviceWorkers.testing.enabled", true], 41 ], 42 }); 43 44 // Step 1. 45 info("Opening a new tab: " + SW_REGISTER_PAGE); 46 let topTab = await BrowserTestUtils.openNewForegroundTab({ 47 gBrowser, 48 opening: SW_REGISTER_PAGE, 49 }); 50 51 // ## Install SW 52 await SpecialPowers.spawn( 53 topTab.linkedBrowser, 54 [{ sw: SW_REL_SW_SCRIPT }], 55 async function ({ sw }) { 56 // Waive the xray to use the content utils.js script functions. 57 dump(`register serviceworker...\n`); 58 await content.wrappedJSObject.registerAndWaitForActive(sw); 59 } 60 ); 61 62 // Step 2. 63 info("Loading a controlled page: " + SW_REGISTER_PAGE); 64 let browserLoadedPromise = BrowserTestUtils.browserLoaded( 65 topTab.linkedBrowser 66 ); 67 BrowserTestUtils.startLoadingURIString( 68 topTab.linkedBrowser, 69 SW_REGISTER_PAGE 70 ); 71 await browserLoadedPromise; 72 73 info("Create a target iframe: " + SW_IFRAME_PAGE); 74 let result = await SpecialPowers.spawn( 75 topTab.linkedBrowser, 76 [{ url: SW_IFRAME_PAGE }], 77 async function ({ url }) { 78 async function waitForNavigationPreload() { 79 return new Promise(resolve => { 80 content.wrappedJSObject.navigator.serviceWorker.addEventListener( 81 `message`, 82 event => { 83 resolve(event.data); 84 } 85 ); 86 }); 87 } 88 89 let promise = waitForNavigationPreload(); 90 91 // Step 3. 92 const iframe = content.wrappedJSObject.document.createElement("iframe"); 93 iframe.src = url; 94 content.wrappedJSObject.document.body.appendChild(iframe); 95 await new Promise(r => { 96 iframe.onload = r; 97 }); 98 99 let result = await promise; 100 return result; 101 } 102 ); 103 104 is(result, "NavigationPreload\n", "Should get NavigationPreload result"); 105 106 // Step 4. 107 info("Loading the SW unregister page: " + SW_REGISTER_PAGE); 108 browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser); 109 BrowserTestUtils.startLoadingURIString( 110 topTab.linkedBrowser, 111 SW_REGISTER_PAGE 112 ); 113 await browserLoadedPromise; 114 115 await SpecialPowers.spawn(topTab.linkedBrowser, [], async function () { 116 await content.wrappedJSObject.unregisterAll(); 117 }); 118 119 // Close the testing tab. 120 BrowserTestUtils.removeTab(topTab); 121 });