diff options
Diffstat (limited to 'testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html')
-rw-r--r-- | testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html b/testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html new file mode 100644 index 0000000000..cc49e202c3 --- /dev/null +++ b/testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<title>WindowClient.navigate() on a prerendered iframe</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script> +<body> +<script> +// The main test page loads the initiator page, then the initiator page will +// prerender itself with the `prerendering` parameter and add an iframe. Once +// the prerendered iframe is ready, post a message to a service worker to call +// WindowClient.navigate(). + +const params = new URLSearchParams(location.search); +const prerendering = params.has('prerendering'); +const navigationUrl = params.get('navigationUrl'); +const uid = params.get('uid'); + +const IFRAME_URL = `prerendered-iframe.html?uid=${uid}`; + +function addIframe() { + const iframe = document.createElement('iframe'); + iframe.src = IFRAME_URL; + document.body.appendChild(iframe); +} + +// If the navigation is expected to be deferred, wait to navigate to +// `navigationUrl` until a prerendered iframe is activated by +// PrerenderEventCollector. The result of the navigation is sent to +// "navigation-channel" PrerenderChannel and the prerendering states and events +// is sent to "test-channel" PrerenderChannel by PrerenderEventCollector. +async function startNavigationToCrossOriginUrl() { + assert_not_equals(new URL(navigationUrl).origin, window.location.origin); + + const navigationPromise = new Promise(resolve => { + const bc = new PrerenderChannel('navigation-channel', uid); + bc.addEventListener('message', e => { + assert_equals(e.data, 'navigate() succeeded'); + resolve() + bc.close(); + }); + bc.postMessage(JSON.stringify({ + navigationUrl: navigationUrl, + clientUrl: new URL(IFRAME_URL, window.location).toString(), + respondTo: 'navigation-channel', + })); + }); + + const prerenderEventCollector = new PrerenderEventCollector(); + prerenderEventCollector.start(navigationPromise, 'navigation on iframe'); +} + +// If the navigation is expected to succeed without delay, the navigation result +// is directly sent to "test-channel" PrerenderChannel. +function startNavigationToSameOriginUrl() { + assert_equals(new URL(navigationUrl).origin, window.location.origin); + + const bc = new PrerenderChannel('navigation-channel', uid); + bc.postMessage(JSON.stringify({ + navigationUrl: navigationUrl, + clientUrl: new URL(IFRAME_URL, window.location).toString(), + respondTo: 'test-channel', + })); + bc.close(); +} + +if (prerendering) { + assert_not_equals(null, navigator.serviceWorker.controller, + 'should be controlled by a service worker'); + + const bc = new PrerenderChannel('iframe-channel', uid); + const readyPromise = new Promise(resolve => { + bc.addEventListener('message', e => { + resolve(e.data); + }, { + once: true + }); + }); + + addIframe(); + + readyPromise.then(result => { + assert_equals(result, 'prerender success'); + + if (new URL(navigationUrl).origin === window.location.origin) { + startNavigationToSameOriginUrl(); + } else { + startNavigationToCrossOriginUrl(); + } + + bc.close(); + }); +} else { + loadInitiatorPage(); +} +</script> +</body> |