blob: ac3456e9d1a9868b11d5571862560afda0a46fef [file] [log] [blame]
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
const timingEventOrder = [
'startTime',
'workerStart',
'fetchStart',
'requestStart',
'responseStart',
'responseEnd',
];
function verify(timing) {
for (let i = 0; i < timingEventOrder.length - 1; i++) {
assert_true(timing[timingEventOrder[i]] <= timing[timingEventOrder[i + 1]],
`Expected ${timingEventOrder[i]} <= ${timingEventOrder[i + 1]}`);
}
}
function navigate_in_frame(frame, url) {
frame.contentWindow.location = url;
return new Promise((resolve) => {
frame.addEventListener('load', () => {
const timing = frame.contentWindow.performance.getEntriesByType('navigation')[0];
resolve(timing);
});
});
}
const worker_url = 'resources/navigation-timing-worker.js';
promise_test(t => {
const scope = 'resources/empty.html';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/empty.html');
})
.then(timing => {
verify(timing);
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing');
promise_test(t => {
const scope = 'resources/empty.html?network-fallback';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/empty.html?network-fallback');
})
.then(timing => {
verify(timing);
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing network fallback');
promise_test(t => {
const scope = 'resources/redirect.py?Redirect=empty.html';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/redirect.py?Redirect=empty.html');
})
.then(timing => {
verify(timing);
// Additional checks for redirected navigation.
assert_true(timing.redirectStart <= timing.redirectEnd,
'Expected redirectStart <= redirectEnd');
assert_true(timing.redirectEnd <= timing.fetchStart,
'Expected redirectEnd <= fetchStart');
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing redirect');
</script>