| <!DOCTYPE html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="utils.js"></script> |
| <body> |
| <script> |
| function getNextMessage(channel) { |
| return new Promise(resolve => { |
| channel.addEventListener('message', e => resolve(e.data), {once: true}); |
| }); |
| } |
| |
| function getActivationStart() { |
| const entry = performance.getEntriesByType('navigation')[0]; |
| assert_equals( |
| entry.activationStart, |
| entry.toJSON()['activationStart'], |
| 'activationStart value must be available in the result of toJSON().'); |
| return entry.activationStart; |
| } |
| |
| (async () => { |
| const testChannel = new PrerenderChannel('test-channel'); |
| const params = new URLSearchParams(location.search); |
| const isPrerenderingMainFrame = params.has('prerendering') && |
| !params.has('iframe'); |
| const isIframe = params.has('iframe'); |
| const isInitiator = !isPrerenderingMainFrame && !isIframe; |
| |
| const ACTIVATION_DELAY = 10; |
| |
| // 1. The initiator document (isInitiator) is opened using window.open() by |
| // activation-start.html in the parent directory. |
| // 2. The initiator document starts prerendering the prerendering document |
| // (isPrerenderingMainFrame). |
| // 3. The prerendering document opens the iframe document (isIframe). |
| try { |
| if (isInitiator) { |
| // We use a PrerenderChannel to receive a message from the prerendering |
| // iframe. |
| const prerenderChannel = new PrerenderChannel('prerender-channel'); |
| const prerendering_url = new URL(document.URL); |
| prerendering_url.searchParams.set('prerendering', ''); |
| startPrerendering(prerendering_url); |
| assert_equals(await getNextMessage(prerenderChannel), 'iframe ready'); |
| |
| // Wait ACTIVATION_DELAY ms before activation. |
| await new Promise(resolve => setTimeout(resolve, ACTIVATION_DELAY)); |
| // Activate the prerendered page. |
| location.href = prerendering_url; |
| } else if (isPrerenderingMainFrame) { |
| const initial_value = getActivationStart(); |
| const activation_start_promise = new Promise(resolve => { |
| document.addEventListener('prerenderingchange', () => { |
| resolve(getActivationStart()); |
| }); |
| }); |
| // We use the window's message event handler to receive a message from the |
| // iframe. |
| const msg_from_iframe_promise = getNextMessage(window); |
| |
| // Add an iframe. |
| const iframe_url = new URL(document.URL); |
| iframe_url.searchParams.set('iframe', ''); |
| const iframe = document.createElement('iframe'); |
| iframe.src = iframe_url; |
| document.body.appendChild(iframe); |
| |
| assert_equals( |
| initial_value, |
| 0, |
| 'activationStart must be 0 while prerendering'); |
| assert_greater_than_equal( |
| await activation_start_promise, |
| ACTIVATION_DELAY, |
| 'activationStart after activation must be greater than or equal to ' + |
| 'ACTIVATION_DELAY.'); |
| assert_equals(await msg_from_iframe_promise, 'iframe activated'); |
| |
| // Finishes the test. |
| testChannel.postMessage('Done'); |
| } else if (isIframe) { |
| const prerenderChannel = new PrerenderChannel('prerender-channel'); |
| const initial_value = getActivationStart(); |
| const activation_start_promise = new Promise(resolve => { |
| document.addEventListener('prerenderingchange', () => { |
| resolve(getActivationStart()); |
| }); |
| }); |
| prerenderChannel.postMessage('iframe ready'); |
| assert_equals( |
| initial_value, |
| 0, |
| 'activationStart must be 0 while prerendering in iframe.'); |
| assert_greater_than_equal( |
| await activation_start_promise, |
| ACTIVATION_DELAY, |
| 'activationStart after activation must be greater than or equal to ' + |
| 'ACTIVATION_DELAY in iframe.'); |
| window.parent.postMessage('iframe activated'); |
| } |
| } catch (e) { |
| testChannel.postMessage(e.toString()); |
| } |
| })(); |
| </script> |
| </body> |