OLD | NEW |
---|---|
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <title>Service Worker: the fallback behavior of FetchEvent</title> | 2 <title>Service Worker: the fallback behavior of FetchEvent</title> |
3 <script src="/resources/testharness.js"></script> | 3 <script src="/resources/testharness.js"></script> |
4 <script src="/resources/testharnessreport.js"></script> | 4 <script src="/resources/testharnessreport.js"></script> |
5 <script src="/common/get-host-info.sub.js"></script> | 5 <script src="/common/get-host-info.sub.js"></script> |
6 <script src="resources/test-helpers.sub.js?pipe=sub"></script> | 6 <script src="resources/test-helpers.sub.js?pipe=sub"></script> |
7 <script> | 7 <script> |
8 var expected_urls = []; | 8 function assert_resolves(promise, description) { |
9 | |
10 function xhr_fail_test(frame, url) { | |
11 expected_urls.push(url); | |
12 return new Promise(function(resolve, reject) { | 9 return new Promise(function(resolve, reject) { |
13 frame.contentWindow.xhr(url) | 10 promise |
Marijn Kruisselbrink
2017/05/04 00:28:25
Is this any different from promise.catch(t.unreach
mike3
2017/05/05 18:56:12
No difference. I'll use that approach.
| |
14 .then(function(){ | 11 .then( |
15 reject(url + ' should fail.'); | 12 function() { resolve(); }, |
16 }) | 13 function() { reject(description); }); |
17 .catch(function(){ | |
18 resolve(); | |
19 }); | |
20 }); | 14 }); |
21 } | 15 } |
22 | 16 |
23 function xhr_succeed_test(frame, url) { | 17 function assert_rejects(promise, description) { |
Marijn Kruisselbrink
2017/05/04 00:28:25
assert_rejects is pretty much promise_rejects(t, n
mike3
2017/05/05 18:56:12
Acknowledged.
| |
24 expected_urls.push(url); | |
25 return new Promise(function(resolve, reject) { | 18 return new Promise(function(resolve, reject) { |
26 frame.contentWindow.xhr(url) | 19 promise |
27 .then(function(){ | 20 .then( |
28 resolve(); | 21 function() { reject(description); }, |
29 }) | 22 function() { resolve(); }); |
30 .catch(function(){ | |
31 reject(url + ' should succeed.'); | |
32 }); | |
33 }); | 23 }); |
34 } | 24 } |
35 | 25 |
26 function get_fetched_urls(worker) { | |
27 return new Promise(function(resolve) { | |
28 var channel = new MessageChannel(); | |
29 channel.port1.onmessage = function(msg) { resolve(msg); }; | |
30 worker.postMessage({port: channel.port2}, [channel.port2]); | |
31 }); | |
32 } | |
33 | |
34 function check_urls(worker, expected_requests, description) { | |
35 return get_fetched_urls(worker) | |
36 .then(function(msg) { | |
37 var requests = msg.data.requests; | |
38 assert_object_equals(requests, expected_requests, description); | |
39 }); | |
40 } | |
41 | |
36 async_test(function(t) { | 42 async_test(function(t) { |
37 var path = new URL(".", window.location).pathname; | 43 var path = new URL(".", window.location).pathname; |
38 var SCOPE = 'resources/fetch-request-fallback-iframe.html'; | 44 var SCOPE = 'resources/fetch-request-fallback-iframe.html'; |
39 var SCRIPT = 'resources/fetch-request-fallback-worker.js'; | 45 var SCRIPT = 'resources/fetch-request-fallback-worker.js'; |
40 var host_info = get_host_info(); | 46 var host_info = get_host_info(); |
41 var BASE_URL = host_info['HTTPS_ORIGIN'] + | 47 var BASE_URL = host_info['HTTPS_ORIGIN'] + |
42 path + 'resources/fetch-access-control.py?'; | 48 path + 'resources/fetch-access-control.py?'; |
49 var BASE_PNG_URL = BASE_URL + 'PNGIMAGE&'; | |
43 var OTHER_BASE_URL = host_info['HTTPS_REMOTE_ORIGIN'] + | 50 var OTHER_BASE_URL = host_info['HTTPS_REMOTE_ORIGIN'] + |
44 path + 'resources/fetch-access-control.py?'; | 51 path + 'resources/fetch-access-control.py?'; |
52 var OTHER_BASE_PNG_URL = OTHER_BASE_URL + 'PNGIMAGE&'; | |
45 var REDIRECT_URL = host_info['HTTPS_ORIGIN'] + | 53 var REDIRECT_URL = host_info['HTTPS_ORIGIN'] + |
46 path + 'resources/redirect.py?Redirect='; | 54 path + 'resources/redirect.py?Redirect='; |
47 var frame; | 55 var frame; |
48 var worker; | 56 var worker; |
49 service_worker_unregister_and_register(t, SCRIPT, SCOPE) | 57 service_worker_unregister_and_register(t, SCRIPT, SCOPE) |
50 .then(function(registration) { | 58 .then(function(registration) { |
51 worker = registration.installing; | 59 worker = registration.installing; |
52 return wait_for_state(t, worker, 'activated'); | 60 return wait_for_state(t, worker, 'activated'); |
53 }) | 61 }) |
54 .then(function() { return with_iframe(SCOPE); }) | 62 .then(function() { return with_iframe(SCOPE); }) |
55 .then(function(f) { | 63 .then(function(f) { |
64 t.add_cleanup(function() { | |
65 f.remove(); | |
66 }); | |
56 frame = f; | 67 frame = f; |
57 return xhr_succeed_test(frame, BASE_URL); | 68 return check_urls( |
58 }) | 69 worker, |
59 .then(function(f) { | 70 [{ |
60 return xhr_fail_test(frame, OTHER_BASE_URL); | 71 url: host_info['HTTPS_ORIGIN'] + path + SCOPE, |
61 }) | 72 mode: 'navigate' |
62 .then(function(f) { | 73 }], |
63 return xhr_succeed_test(frame, OTHER_BASE_URL + 'ACAOrigin=*'); | 74 'The SW must intercept the request for a main resource.'); |
64 }) | 75 }) |
65 .then(function(f) { | 76 .then(function() { |
66 return xhr_succeed_test(frame, | 77 return assert_resolves( |
67 REDIRECT_URL + encodeURIComponent(BASE_URL)); | 78 frame.contentWindow.xhr(BASE_URL), |
68 }) | 79 'SW fallbacked same origin XHR should succeed.'); |
69 .then(function() { | 80 }) |
70 return xhr_fail_test( | 81 .then(function() { |
71 frame, | 82 return check_urls( |
72 REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL)); | 83 worker, |
73 }) | 84 [{ url: BASE_URL, mode: 'cors' }], |
74 .then(function() { | 85 'The SW must intercept the request of same origin XHR.'); |
75 return xhr_succeed_test( | 86 }) |
76 frame, | 87 .then(function() { |
77 REDIRECT_URL + | 88 return assert_rejects( |
78 encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*')); | 89 frame.contentWindow.xhr(OTHER_BASE_URL), |
79 }) | 90 'SW fallbacked CORS-unsupported other origin XHR should fail.'); |
80 .then(function() { | 91 }) |
81 return new Promise(function(resolve) { | 92 .then(function() { |
82 var channel = new MessageChannel(); | 93 return check_urls( |
83 channel.port1.onmessage = t.step_func(function(msg) { | 94 worker, |
84 frame.remove(); | 95 [{ url: OTHER_BASE_URL, mode: 'cors' }], |
85 resolve(msg); | 96 'The SW must intercept the request of CORS-unsupported other ' + |
86 }); | 97 'origin XHR.'); |
87 worker.postMessage({port: channel.port2}, [channel.port2]); | 98 }) |
88 }); | 99 .then(function() { |
89 }) | 100 return assert_resolves( |
90 .then(function(msg) { | 101 frame.contentWindow.xhr(OTHER_BASE_URL + 'ACAOrigin=*'), |
91 var requests = msg.data.requests; | 102 'SW fallbacked CORS-supported other origin XHR should succeed.'); |
92 assert_equals(requests.length, expected_urls.length + 1, | 103 }) |
93 'The count of the requests which are passed to the ' + | 104 .then(function() { |
94 'ServiceWorker must be correct.'); | 105 return check_urls( |
95 assert_equals(requests[0].url, new URL(SCOPE, location).toString(), | 106 worker, |
96 'The first request to the SW must be the request for ' + | 107 [{ url: OTHER_BASE_URL + 'ACAOrigin=*', mode: 'cors' }], |
97 'the page.'); | 108 'The SW must intercept the request of CORS-supported other ' + |
98 assert_equals(requests[0].mode, 'navigate', | 109 'origin XHR.'); |
99 'The mode of the first request to the SW must be ' + | 110 }) |
100 'navigate'); | 111 .then(function() { |
101 for (var i = 0; i < expected_urls.length; ++i) { | 112 return assert_resolves( |
102 assert_equals(requests[i + 1].url, expected_urls[i], | 113 frame.contentWindow.xhr( |
103 'The URL of the request which was passed from XHR ' + | 114 REDIRECT_URL + encodeURIComponent(BASE_URL)), |
104 'to the ServiceWorker must be correct.'); | 115 'SW fallbacked redirected XHR should succeed.'); |
105 assert_equals(requests[i + 1].mode, 'cors', | 116 }) |
106 'The mode of the request which was passed from XHR ' + | 117 .then(function() { |
107 'to the ServiceWorker must be cors.'); | 118 return check_urls( |
108 } | 119 worker, |
120 [{ | |
121 url: REDIRECT_URL + encodeURIComponent(BASE_URL), | |
122 mode: 'cors' | |
123 }], | |
124 'The SW must intercept only the first request of redirected ' + | |
125 'XHR.'); | |
126 }) | |
127 .then(function() { | |
128 return assert_rejects( | |
129 frame.contentWindow.xhr( | |
130 REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL)), | |
131 'SW fallbacked XHR which is redirected to CORS-unsupported ' + | |
132 'other origin should fail.'); | |
133 }) | |
134 .then(function() { | |
135 return check_urls( | |
136 worker, | |
137 [{ | |
138 url: REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL), | |
139 mode: 'cors' | |
140 }], | |
141 'The SW must intercept only the first request for XHR which is' + | |
142 ' redirected to CORS-unsupported other origin.'); | |
143 }) | |
144 .then(function() { | |
145 return assert_resolves( | |
146 frame.contentWindow.xhr( | |
147 REDIRECT_URL + | |
148 encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*')), | |
149 'SW fallbacked XHR which is redirected to CORS-supported other ' + | |
150 'origin should succeed.'); | |
151 }) | |
152 .then(function() { | |
153 return check_urls( | |
154 worker, | |
155 [{ | |
156 url: REDIRECT_URL + | |
157 encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'), | |
158 mode: 'cors' | |
159 }], | |
160 'The SW must intercept only the first request for XHR which is ' + | |
161 'redirected to CORS-supported other origin.'); | |
162 }) | |
163 .then(function() { | |
164 return assert_resolves( | |
165 frame.contentWindow.load_image(BASE_PNG_URL, ''), | |
166 'SW fallbacked image request should succeed.'); | |
167 }) | |
168 .then(function() { | |
169 return check_urls( | |
170 worker, | |
171 [{ url: BASE_PNG_URL, mode: 'no-cors' }], | |
172 'The SW must intercept the request for image.'); | |
173 }) | |
174 .then(function() { | |
175 return assert_resolves( | |
176 frame.contentWindow.load_image(OTHER_BASE_PNG_URL, ''), | |
177 'SW fallbacked other origin image request should succeed.'); | |
178 }) | |
179 .then(function() { | |
180 return check_urls( | |
181 worker, | |
182 [{ url: OTHER_BASE_PNG_URL, mode: 'no-cors' }], | |
183 'The SW must intercept the request for other origin image.') | |
184 }) | |
185 .then(function() { | |
186 return assert_rejects( | |
187 frame.contentWindow.load_image(OTHER_BASE_PNG_URL, 'anonymous'), | |
188 'SW fallbacked CORS-unsupported other origin image request ' + | |
189 'should fail.'); | |
190 }) | |
191 .then(function() { | |
192 return check_urls( | |
193 worker, | |
194 [{ url: OTHER_BASE_PNG_URL, mode: 'cors' }], | |
195 'The SW must intercept the request for CORS-unsupported other ' + | |
196 'origin image.') | |
197 }) | |
198 .then(function() { | |
199 return assert_resolves( | |
200 frame.contentWindow.load_image( | |
201 OTHER_BASE_PNG_URL + 'ACAOrigin=*', 'anonymous'), | |
202 'SW fallbacked CORS-supported other origin image request should' + | |
203 ' succeed.'); | |
204 }) | |
205 .then(function() { | |
206 return check_urls( | |
207 worker, | |
208 [{ url: OTHER_BASE_PNG_URL + 'ACAOrigin=*', mode: 'cors' }], | |
209 'The SW must intercept the request for CORS-supported other ' + | |
210 'origin image.') | |
211 }) | |
212 .then(function() { | |
213 return assert_resolves( | |
214 frame.contentWindow.load_image( | |
215 REDIRECT_URL + encodeURIComponent(BASE_PNG_URL), ''), | |
216 'SW fallbacked redirected image request should succeed.'); | |
217 }) | |
218 .then(function() { | |
219 return check_urls( | |
220 worker, | |
221 [{ | |
222 url: REDIRECT_URL + encodeURIComponent(BASE_PNG_URL), | |
223 mode: 'no-cors' | |
224 }], | |
225 'The SW must intercept only the first request for redirected ' + | |
226 'image resource.'); | |
227 }) | |
228 .then(function() { | |
229 return assert_resolves( | |
230 frame.contentWindow.load_image( | |
231 REDIRECT_URL + encodeURIComponent(OTHER_BASE_PNG_URL), ''), | |
232 'SW fallbacked image request which is redirected to other ' + | |
233 'origin should succeed.'); | |
234 }) | |
235 .then(function() { | |
236 return check_urls( | |
237 worker, | |
238 [{ | |
239 url: REDIRECT_URL + encodeURIComponent(OTHER_BASE_PNG_URL), | |
240 mode: 'no-cors' | |
241 }], | |
242 'The SW must intercept only the first request for image ' + | |
243 'resource which is redirected to other origin.'); | |
244 }) | |
245 .then(function() { | |
246 return assert_rejects( | |
247 frame.contentWindow.load_image( | |
248 REDIRECT_URL + encodeURIComponent(OTHER_BASE_PNG_URL), | |
249 'anonymous'), | |
250 'SW fallbacked image request which is redirected to ' + | |
251 'CORS-unsupported other origin should fail.'); | |
252 }) | |
253 .then(function() { | |
254 return check_urls( | |
255 worker, | |
256 [{ | |
257 url: REDIRECT_URL + encodeURIComponent(OTHER_BASE_PNG_URL), | |
258 mode: 'cors' | |
259 }], | |
260 'The SW must intercept only the first request for image ' + | |
261 'resource which is redirected to CORS-unsupported other origin.'); | |
262 }) | |
263 .then(function() { | |
264 return assert_resolves( | |
265 frame.contentWindow.load_image( | |
266 REDIRECT_URL + | |
267 encodeURIComponent(OTHER_BASE_PNG_URL + 'ACAOrigin=*'), | |
268 'anonymous'), | |
269 'SW fallbacked image request which is redirected to ' + | |
270 'CORS-supported other origin should succeed.'); | |
271 }) | |
272 .then(function() { | |
273 return check_urls( | |
274 worker, | |
275 [{ | |
276 url: REDIRECT_URL + | |
277 encodeURIComponent(OTHER_BASE_PNG_URL + 'ACAOrigin=*'), | |
278 mode: 'cors' | |
279 }], | |
280 'The SW must intercept only the first request for image ' + | |
281 'resource which is redirected to CORS-supported other origin.'); | |
282 }) | |
283 .then(function() { | |
109 service_worker_unregister_and_done(t, SCOPE); | 284 service_worker_unregister_and_done(t, SCOPE); |
110 }) | 285 }) |
111 .catch(unreached_rejection(t)); | 286 .catch(unreached_rejection(t)); |
112 }, 'Verify the fallback behavior of FetchEvent'); | 287 }, 'Verify the fallback behavior of FetchEvent'); |
113 </script> | 288 </script> |
OLD | NEW |