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