blob: 456f15ff699eb36b230b5079f918cbd57ea2705a [file] [log] [blame] [edit]
<!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>