62 lines
3.1 KiB
HTML
62 lines
3.1 KiB
HTML
<!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>
|