Skip to content

Commit e3070fa

Browse files
nidhijajumoz-wptsync-bot
authored andcommitted
Bug 1783602 [wpt PR 35374] - Fetch: Add tests for AbortSignal's abort reason, a=testonly
Automatic update from web-platform-tests Fetch: Add tests for AbortSignal's abort reason (#35374) Add test cases to check the functionality of AbortSignal's abort reason when aborting fetch, including serialization and that the service worker can observe the reason. See whatwg/fetch#1343 for accompanying spec changes. -- wpt-commits: 0e5f85c08e05fb1b9b67fb12c4d7c0de77a4ee9b wpt-pr: 35374
1 parent 562157a commit e3070fa

3 files changed

Lines changed: 142 additions & 5 deletions

File tree

testing/web-platform/tests/fetch/api/abort/general.any.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
const BODY_METHODS = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
88

9+
const error1 = new Error('error1');
10+
error1.name = 'error1';
11+
912
// This is used to close connections that weren't correctly closed during the tests,
1013
// otherwise you can end up running out of HTTP connections.
1114
let requestAbortKeys = [];
@@ -31,6 +34,16 @@ promise_test(async t => {
3134
await promise_rejects_dom(t, "AbortError", fetchPromise);
3235
}, "Aborting rejects with AbortError");
3336

37+
promise_test(async t => {
38+
const controller = new AbortController();
39+
const signal = controller.signal;
40+
controller.abort(error1);
41+
42+
const fetchPromise = fetch('../resources/data.json', { signal });
43+
44+
await promise_rejects_exactly(t, error1, fetchPromise, 'fetch() should reject with abort reason');
45+
}, "Aborting rejects with abort reason");
46+
3447
promise_test(async t => {
3548
const controller = new AbortController();
3649
const signal = controller.signal;
@@ -91,6 +104,22 @@ promise_test(async t => {
91104
await promise_rejects_dom(t, "AbortError", fetchPromise);
92105
}, "Signal on request object");
93106

107+
promise_test(async t => {
108+
const controller = new AbortController();
109+
const signal = controller.signal;
110+
controller.abort(error1);
111+
112+
const request = new Request('../resources/data.json', { signal });
113+
114+
assert_not_equals(request.signal, signal, 'Request has a new signal, not a reference');
115+
assert_true(request.signal.aborted, `Request's signal has aborted`);
116+
assert_equals(request.signal.reason, error1, `Request's signal's abort reason is error1`);
117+
118+
const fetchPromise = fetch(request);
119+
120+
await promise_rejects_exactly(t, error1, fetchPromise, "fetch() should reject with abort reason");
121+
}, "Signal on request object should also have abort reason");
122+
94123
promise_test(async t => {
95124
const controller = new AbortController();
96125
const signal = controller.signal;

testing/web-platform/tests/fetch/api/abort/serviceworker-intercepted.https.html

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
const SCOPE = '../resources/basic.html';
1414
const BODY_METHODS = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
1515

16-
async function setupRegistration(t, scope) {
17-
const reg = await navigator.serviceWorker.register('../resources/sw-intercept.js', { scope });
16+
const error1 = new Error('error1');
17+
error1.name = 'error1';
18+
19+
async function setupRegistration(t, scope, service_worker) {
20+
const reg = await navigator.serviceWorker.register(service_worker, { scope });
1821
await wait_for_state(t, reg.installing, 'activated');
1922
add_completion_callback(_ => reg.unregister());
2023
return reg;
@@ -23,7 +26,7 @@
2326
promise_test(async t => {
2427
const suffix = "?q=aborted-not-intercepted";
2528
const scope = SCOPE + suffix;
26-
await setupRegistration(t, scope);
29+
await setupRegistration(t, scope, '../resources/sw-intercept.js');
2730
const iframe = await with_iframe(scope);
2831
add_completion_callback(_ => iframe.remove());
2932
const w = iframe.contentWindow;
@@ -56,7 +59,7 @@
5659
for (const bodyMethod of BODY_METHODS) {
5760
promise_test(async t => {
5861
const scope = SCOPE + "?q=aborted-" + bodyMethod + "-rejects";
59-
await setupRegistration(t, scope);
62+
await setupRegistration(t, scope, '../resources/sw-intercept.js');
6063
const iframe = await with_iframe(scope);
6164
add_completion_callback(_ => iframe.remove());
6265
const w = iframe.contentWindow;
@@ -84,7 +87,7 @@
8487

8588
promise_test(async t => {
8689
const scope = SCOPE + "?q=aborted-stream-errors";
87-
await setupRegistration(t, scope);
90+
await setupRegistration(t, scope, '../resources/sw-intercept.js');
8891
const iframe = await with_iframe(scope);
8992
add_completion_callback(_ => iframe.remove());
9093
const w = iframe.contentWindow;
@@ -100,6 +103,92 @@
100103
await promise_rejects_dom(t, "AbortError", w.DOMException, reader.read());
101104
await promise_rejects_dom(t, "AbortError", w.DOMException, reader.closed);
102105
}, "Stream errors once aborted.");
106+
107+
promise_test(async t => {
108+
const scope = SCOPE + "?q=aborted-with-abort-reason";
109+
await setupRegistration(t, scope, '../resources/sw-intercept.js');
110+
const iframe = await with_iframe(scope);
111+
add_completion_callback(_ => iframe.remove());
112+
const w = iframe.contentWindow;
113+
114+
const controller = new w.AbortController();
115+
const signal = controller.signal;
116+
117+
const fetchPromise = await w.fetch('data.json', { signal });
118+
119+
controller.abort(error1);
120+
121+
await promise_rejects_exactly(t, error1, fetchPromise);
122+
}, "fetch() rejects with abort reason");
123+
124+
promise_test(async t => {
125+
const scope = SCOPE + "?q=service-worker-observes-abort-reason";
126+
await setupRegistration(t, scope, '../resources/sw-intercept-abort.js');
127+
const iframe = await with_iframe(scope);
128+
add_completion_callback(_ => iframe.remove());
129+
const w = iframe.contentWindow;
130+
131+
const controller = new w.AbortController();
132+
const signal = controller.signal;
133+
134+
const fetchPromise = w.fetch('data.json', { signal });
135+
136+
await new Promise(resolve => {
137+
w.navigator.serviceWorker.addEventListener('message', t.step_func(event => {
138+
assert_equals(event.data, "fetch event has arrived");
139+
resolve();
140+
}), {once: true});
141+
});
142+
143+
controller.abort(error1);
144+
145+
await new Promise(resolve => {
146+
w.navigator.serviceWorker.addEventListener('message', t.step_func(event => {
147+
assert_equals(event.data.message, error1.message);
148+
resolve();
149+
}), {once: true});
150+
});
151+
152+
await promise_rejects_exactly(t, error1, fetchPromise);
153+
}, "Service Worker can observe the fetch abort and associated abort reason");
154+
155+
promise_test(async t => {
156+
let incrementing_error = new Error('error1');
157+
incrementing_error.name = 'error1';
158+
159+
const scope = SCOPE + "?q=serialization-on-abort";
160+
await setupRegistration(t, scope, '../resources/sw-intercept-abort.js');
161+
const iframe = await with_iframe(scope);
162+
add_completion_callback(_ => iframe.remove());
163+
const w = iframe.contentWindow;
164+
165+
const controller = new w.AbortController();
166+
const signal = controller.signal;
167+
168+
const fetchPromise = w.fetch('data.json', { signal });
169+
170+
await new Promise(resolve => {
171+
w.navigator.serviceWorker.addEventListener('message', t.step_func(event => {
172+
assert_equals(event.data, "fetch event has arrived");
173+
resolve();
174+
}), {once: true});
175+
});
176+
177+
controller.abort(incrementing_error);
178+
179+
const original_error_name = incrementing_error.name;
180+
181+
incrementing_error.name = 'error2';
182+
183+
await new Promise(resolve => {
184+
w.navigator.serviceWorker.addEventListener('message', t.step_func(event => {
185+
assert_equals(event.data.name, original_error_name);
186+
resolve();
187+
}), {once: true});
188+
});
189+
190+
await promise_rejects_exactly(t, incrementing_error, fetchPromise);
191+
}, "Abort reason serialization happens on abort");
103192
</script>
104193
</body>
105194
</html>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
async function messageClient(clientId, message) {
2+
const client = await clients.get(clientId);
3+
client.postMessage(message);
4+
}
5+
6+
addEventListener('fetch', event => {
7+
let resolve;
8+
const promise = new Promise(r => resolve = r);
9+
10+
function onAborted() {
11+
messageClient(event.clientId, event.request.signal.reason);
12+
resolve();
13+
}
14+
15+
messageClient(event.clientId, 'fetch event has arrived');
16+
17+
event.respondWith(promise.then(() => new Response('hello')));
18+
event.request.signal.addEventListener('abort', onAborted);
19+
});

0 commit comments

Comments
 (0)