blob: 6df6aef2cdaa1a95c40ffd1dd22dc5cd0928b44e [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Aborting fetch when intercepted by a service worker</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../../service-workers/service-worker/resources/test-helpers.sub.js"></script>
</head>
<body>
<script>
// Duplicating this resource to make service worker scoping simpler.
const SCOPE = '../resources/basic.html';
const BODY_METHODS = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
async function cleanup() {
for (const iframe of document.querySelectorAll('.test-iframe')) {
iframe.parentNode.removeChild(iframe);
}
const reg = await navigator.serviceWorker.getRegistration(SCOPE);
if (reg) await reg.unregister();
}
async function setupRegistration(t) {
await cleanup();
const reg = await navigator.serviceWorker.register('../resources/sw-intercept.js', { scope: SCOPE });
await wait_for_state(t, reg.installing, 'activated');
return reg;
}
promise_test(async t => {
await setupRegistration(t);
const iframe = await with_iframe(SCOPE);
const w = iframe.contentWindow;
const controller = new w.AbortController();
const signal = controller.signal;
controller.abort();
const nextData = new Promise(resolve => {
w.navigator.serviceWorker.addEventListener('message', function once(event) {
w.navigator.serviceWorker.removeEventListener('message', once);
resolve(event.data);
})
});
const fetchPromise = w.fetch('data.json', { signal });
await promise_rejects(t, "AbortError", fetchPromise);
await w.fetch('data.json?no-abort');
assert_true((await nextData).endsWith('?no-abort'), "Aborted request does not go through service worker");
}, "Already aborted request does not land in service worker");
for (const bodyMethod of BODY_METHODS) {
promise_test(async t => {
await setupRegistration(t);
const iframe = await with_iframe(SCOPE);
const w = iframe.contentWindow;
const controller = new w.AbortController();
const signal = controller.signal;
const log = [];
const response = await w.fetch('data.json', { signal });
controller.abort();
const bodyPromise = response[bodyMethod]();
await Promise.all([
bodyPromise.catch(() => log.push(`${bodyMethod}-reject`)),
Promise.resolve().then(() => log.push('next-microtask'))
]);
await promise_rejects(t, "AbortError", bodyPromise);
assert_array_equals(log, [`${bodyMethod}-reject`, 'next-microtask']);
}, `response.${bodyMethod}() rejects if already aborted`);
}
promise_test(async t => {
await setupRegistration(t);
const iframe = await with_iframe(SCOPE);
const w = iframe.contentWindow;
const controller = new w.AbortController();
const signal = controller.signal;
const response = await w.fetch('data.json', { signal });
const reader = response.body.getReader();
controller.abort();
await promise_rejects(t, "AbortError", reader.read());
await promise_rejects(t, "AbortError", reader.closed);
}, "Stream errors once aborted.");
</script>
</body>
</html>