diff options
Diffstat (limited to '')
-rw-r--r-- | dom/serviceworkers/test/browser_navigationPreload_read_after_respondWith.js | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/dom/serviceworkers/test/browser_navigationPreload_read_after_respondWith.js b/dom/serviceworkers/test/browser_navigationPreload_read_after_respondWith.js new file mode 100644 index 0000000000..d321fd8b54 --- /dev/null +++ b/dom/serviceworkers/test/browser_navigationPreload_read_after_respondWith.js @@ -0,0 +1,121 @@ +const TOP_DOMAIN = "http://mochi.test:8888/"; +const SW_DOMAIN = "https://example.org/"; + +const TOP_TEST_ROOT = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + TOP_DOMAIN +); +const SW_TEST_ROOT = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + SW_DOMAIN +); + +const TOP_EMPTY_PAGE = `${TOP_TEST_ROOT}empty_with_utils.html`; +const SW_REGISTER_PAGE = `${SW_TEST_ROOT}empty_with_utils.html`; +const SW_IFRAME_PAGE = `${SW_TEST_ROOT}navigationPreload_page.html`; +// An empty script suffices for our SW needs; it's by definition no-fetch. +const SW_REL_SW_SCRIPT = "sw_with_navigationPreload.js"; + +/** + * Test the FetchEvent.preloadResponse can be read after FetchEvent.respondWith() + * + * Step 1. register a ServiceWorker which only handles FetchEvent when request + * url includes navigationPreload_page.html. Otherwise, it alwasy + * fallbacks the fetch to the network. + * If the request url includes navigationPreload_page.html, it call + * FetchEvent.respondWith() with a new Resposne, and then call + * FetchEvent.waitUtil() to wait FetchEvent.preloadResponse and post the + * preloadResponse's text to clients. + * Step 2. Open a controlled page and register message event handler to receive + * the postMessage from ServiceWorker. + * Step 3. Create a iframe which url is navigationPreload_page.html, such that + * ServiceWorker can fake the response and then send preloadResponse's + * result. + * Step 4. Unregister the ServiceWorker and cleanup the environment. + */ +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.serviceWorkers.enabled", true], + ["dom.serviceWorkers.testing.enabled", true], + ], + }); + + // Step 1. + info("Opening a new tab: " + SW_REGISTER_PAGE); + let topTab = await BrowserTestUtils.openNewForegroundTab({ + gBrowser, + opening: SW_REGISTER_PAGE, + }); + + // ## Install SW + await SpecialPowers.spawn( + topTab.linkedBrowser, + [{ sw: SW_REL_SW_SCRIPT }], + async function ({ sw }) { + // Waive the xray to use the content utils.js script functions. + dump(`register serviceworker...\n`); + await content.wrappedJSObject.registerAndWaitForActive(sw); + } + ); + + // Step 2. + info("Loading a controlled page: " + SW_REGISTER_PAGE); + let browserLoadedPromise = BrowserTestUtils.browserLoaded( + topTab.linkedBrowser + ); + BrowserTestUtils.startLoadingURIString( + topTab.linkedBrowser, + SW_REGISTER_PAGE + ); + await browserLoadedPromise; + + info("Create a target iframe: " + SW_IFRAME_PAGE); + let result = await SpecialPowers.spawn( + topTab.linkedBrowser, + [{ url: SW_IFRAME_PAGE }], + async function ({ url }) { + async function waitForNavigationPreload() { + return new Promise(resolve => { + content.wrappedJSObject.navigator.serviceWorker.addEventListener( + `message`, + event => { + resolve(event.data); + } + ); + }); + } + + let promise = waitForNavigationPreload(); + + // Step 3. + const iframe = content.wrappedJSObject.document.createElement("iframe"); + iframe.src = url; + content.wrappedJSObject.document.body.appendChild(iframe); + await new Promise(r => { + iframe.onload = r; + }); + + let result = await promise; + return result; + } + ); + + is(result, "NavigationPreload\n", "Should get NavigationPreload result"); + + // Step 4. + info("Loading the SW unregister page: " + SW_REGISTER_PAGE); + browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser); + BrowserTestUtils.startLoadingURIString( + topTab.linkedBrowser, + SW_REGISTER_PAGE + ); + await browserLoadedPromise; + + await SpecialPowers.spawn(topTab.linkedBrowser, [], async function () { + await content.wrappedJSObject.unregisterAll(); + }); + + // Close the testing tab. + BrowserTestUtils.removeTab(topTab); +}); |