Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="timeout" content="long">
<title>Navigation Timing: unload event with nested contexts</title>
<link rel="help" href="https://w3c.github.io/navigation-timing/"/>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
const dummyURL = () => `/navigation-timing/resources/blank_page_green.html?uid=${token()}`;
promise_test(async t => {
const mainWindowUnloadDuration = 100;
const iframeUnloadDuration = 400;
/*
We create 3 contexts: One for a popup window that will load a document and then later
unload it, one for an iframe inside that popup window, that will unload with the parent
document as well, and one for document the popup window will load in order to trigger
those previous unload events.
The iframe is going to busy-wait on unload for 400ms, and the unloading top-level
document is going to busy-wait on unload for 100ms.
We verify that the total unloadEvent duration measured at the final document is ~100 but
less than 500ms - does not include the unload event duration from the iframe.
*/
const popupContext = new RemoteContext(token());
const iframeContext = new RemoteContext(token());
const finalContext = new RemoteContext(token());
const popup = window.open(remoteExecutorUrl(popupContext.context_id));
t.add_cleanup(() => popup.close());
const registerBusyWaitUnload = duration => window.addEventListener('unload', () => {
const buffer = 3;
const timeoutEnd = performance.now() + duration + buffer;
while (timeoutEnd > performance.now()) {}
});
await popupContext.execute_script(registerBusyWaitUnload, [mainWindowUnloadDuration]);
const unloadIframe = iframeContext.execute_script(registerBusyWaitUnload, [iframeUnloadDuration]);
const loadPopup = popupContext.execute_script(async iframeUid => {
const iframe = document.createElement('iframe');
iframe.src = `/common/dispatcher/remote-executor.html?uuid=${iframeUid}`;
document.body.appendChild(iframe);
await new Promise(resolve => iframe.addEventListener('load', resolve));
}, [iframeContext.context_id]);
await Promise.all([unloadIframe, loadPopup]);
await popupContext.execute_script((uid) => location.href = `/common/dispatcher/remote-executor.html?uuid=${uid}`, [finalContext.context_id]);
const navigationTimingEntry = await finalContext.execute_script(() => performance.getEntriesByType('navigation')[0].toJSON());
const unloadDuration = navigationTimingEntry.unloadEventEnd - navigationTimingEntry.unloadEventStart;
assert_greater_than_equal(unloadDuration, mainWindowUnloadDuration);
assert_less_than(unloadDuration, mainWindowUnloadDuration + iframeUnloadDuration);
});
</script>
</body>