summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/speculation-rules/prerender/resources/windowclient-navigate-on-iframe.html
diff options
context:
space:
mode:
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.html97
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>