OLD | NEW |
---|---|
(Empty) | |
1 <!DOCTYPE html> | |
2 <title>Service Worker: Navigation redirection</title> | |
3 <script src="../resources/testharness.js"></script> | |
4 <script src="../resources/testharnessreport.js"></script> | |
5 <script src="../resources/get-host-info.js?pipe=sub"></script> | |
6 <script src="resources/test-helpers.js"></script> | |
7 <body> | |
8 <script> | |
9 function get_effective_worker(registration) { | |
10 if (registration.active) | |
11 return registration.active; | |
12 if (registration.waiting) | |
13 return registration.waiting; | |
14 if (registration.installing) | |
15 return registration.installing; | |
16 } | |
17 | |
18 var host_info = get_host_info(); | |
19 | |
20 window.addEventListener('message', on_message, false); | |
21 | |
22 var message_resolvers = {}; | |
23 var next_message_id = 0; | |
24 | |
25 function on_message(e) { | |
26 if (e.origin != host_info['HTTP_REMOTE_ORIGIN'] && | |
27 e.origin != host_info['HTTP_ORIGIN'] ) { | |
28 console.error('invalid origin: ' + e.origin); | |
29 return; | |
30 } | |
31 var resolve = message_resolvers[e.data.id]; | |
32 delete message_resolvers[e.data.id]; | |
33 resolve(e.data.result); | |
34 } | |
35 | |
36 function send_to_iframe(frame, message) { | |
37 var message_id = next_message_id++; | |
38 return new Promise(function(resolve) { | |
39 message_resolvers[message_id] = resolve; | |
40 frame.contentWindow.postMessage( | |
41 {id: message_id, message: message}, | |
42 host_info['HTTP_REMOTE_ORIGIN']); | |
43 }); | |
44 } | |
45 | |
46 function get_intercepted_urls(worker) { | |
47 return new Promise(function(resolve) { | |
48 var channel = new MessageChannel(); | |
49 channel.port1.onmessage = function(msg) { resolve(msg.data.urls); }; | |
50 worker.postMessage({port: channel.port2}, [channel.port2]); | |
51 }); | |
52 } | |
53 | |
54 async_test(function(t) { | |
55 // This test registers three Service Workers at SCOPE1, SCOPE2 and | |
56 // OTHER_ORIGIN_SCOPE. And checks the redirected page's URL and the requests | |
57 // which are intercepted by Service Worker while loading redirect page. | |
58 var BASE_URL = host_info['HTTP_ORIGIN'] + base_path(); | |
59 var OTHER_BASE_URL = host_info['HTTP_REMOTE_ORIGIN'] + base_path(); | |
60 | |
61 var SCOPE1 = BASE_URL + 'resources/navigation-redirect-scope1.php?'; | |
62 var SCOPE2 = BASE_URL + 'resources/navigation-redirect-scope2.php?'; | |
63 var OUT_SCOPE = BASE_URL + 'resources/navigation-redirect-out-scope.php?'; | |
64 var SCRIPT = 'resources/navigation-redirect-worker.js'; | |
65 | |
66 var OTHER_ORIGIN_IFRAME_URL = | |
67 OTHER_BASE_URL + 'resources/navigation-redirect-other-origin.html'; | |
68 var OTHER_ORIGIN_SCOPE = | |
69 OTHER_BASE_URL + 'resources/navigation-redirect-scope1.php?'; | |
70 var OTHER_ORIGIN_OUT_SCOPE = | |
71 OTHER_BASE_URL + 'resources/navigation-redirect-out-scope.php?'; | |
72 | |
73 var workers; | |
74 var other_origin_frame; | |
75 | |
76 function check_all_intercepted_urls(expected_urls, description) { | |
77 return Promise.all([ | |
78 // Gets the request URLs which are intercepted by SCOPE1's SW. | |
79 get_intercepted_urls(workers[0]), | |
80 // Gets the request URLs which are intercepted by SCOPE2's SW. | |
81 get_intercepted_urls(workers[1]), | |
82 // Gets the request URLs which are intercepted by OTHER_ORIGIN_SCOPE's | |
83 // SW. This promise will resolve when get_intercepted_urls() in | |
84 // OTHER_ORIGIN_IFRAME_URL resolves. | |
85 send_to_iframe(other_origin_frame, 'get_intercepted_urls')]) | |
86 .then(function(urls) { | |
87 assert_object_equals( | |
88 urls, expected_urls, | |
89 'Intercepted URLs should match: ' + description); | |
90 }); | |
91 } | |
92 | |
93 function test_redirect(url, expected_last_url, | |
94 expected_intercepted_urls, description) { | |
95 var message_promise = new Promise(function(resolve) { | |
96 // A message which ID is 'last_url' will be sent from the iframe. | |
97 message_resolvers['last_url'] = resolve; | |
98 }); | |
99 return with_iframe(url) | |
100 .then(function(f) { | |
101 f.remove(); | |
102 return check_all_intercepted_urls(expected_intercepted_urls, | |
103 description); | |
104 }) | |
105 .then(function() { return message_promise; }) | |
106 .then(function(last_url) { | |
107 assert_equals( | |
108 last_url, expected_last_url, | |
109 'Last URL should match: ' + description); | |
110 }); | |
111 } | |
112 | |
113 with_iframe(OTHER_ORIGIN_IFRAME_URL) | |
114 .then(function(f) { | |
115 // In this frame we register a Service Worker at OTHER_ORIGIN_SCOPE. | |
116 // And will use this frame to communicate with the worker. | |
117 other_origin_frame = f; | |
118 return Promise.all( | |
119 [service_worker_unregister_and_register(t, SCRIPT, SCOPE1), | |
120 service_worker_unregister_and_register(t, SCRIPT, SCOPE2)]); | |
121 }) | |
122 .then(function(registrations) { | |
123 workers = registrations.map(get_effective_worker); | |
124 return Promise.all([ | |
125 wait_for_state(t, workers[0], 'activated'), | |
126 wait_for_state(t, workers[1], 'activated'), | |
127 // This promise will resolve when |wait_for_worker_promise| | |
128 // in OTHER_ORIGIN_IFRAME_URL resolves. | |
129 send_to_iframe(other_origin_frame, "wait_for_worker")]); | |
130 }) | |
131 // Normal redirect. | |
132 .then(function() { | |
133 return test_redirect( | |
134 OUT_SCOPE + "url=" + encodeURIComponent(SCOPE1), | |
135 SCOPE1, | |
136 [[SCOPE1], [], []], | |
137 'Normal redirect to same-origin scope.'); | |
138 }) | |
139 .then(function() { | |
140 return test_redirect( | |
141 OUT_SCOPE + "url=" + encodeURIComponent(OTHER_ORIGIN_SCOPE), | |
142 OTHER_ORIGIN_SCOPE, | |
143 [[], [], [OTHER_ORIGIN_SCOPE]], | |
144 'Normal redirect to other-origin scope.'); | |
145 }) | |
146 | |
147 // SW fallbacked redirect. SW doesn't handle the fetch request. | |
148 .then(function() { | |
149 return test_redirect( | |
bkelly
2015/08/19 14:21:06
If we intend to uplift these as WPT tests, it woul
horo
2015/08/20 06:35:51
Acknowledged.
I will create crbug for this issue a
| |
150 SCOPE1 + "url=" + encodeURIComponent(OUT_SCOPE), | |
151 OUT_SCOPE, | |
152 [[SCOPE1 + "url=" + encodeURIComponent(OUT_SCOPE)], | |
153 [], | |
154 []], | |
155 'SW-fallbacked redirect to same-origin out-scope.'); | |
156 }) | |
157 .then(function() { | |
158 return test_redirect( | |
159 SCOPE1 + "url=" + encodeURIComponent(SCOPE1), | |
160 SCOPE1, | |
161 [[SCOPE1 + "url=" + encodeURIComponent(SCOPE1), SCOPE1], | |
162 [], | |
163 []], | |
164 'SW-fallbacked redirect to same-origin same-scope.'); | |
165 }) | |
166 .then(function() { | |
167 return test_redirect( | |
168 SCOPE1 + "url=" + encodeURIComponent(SCOPE2), | |
169 SCOPE2, | |
170 [[SCOPE1 + "url=" + encodeURIComponent(SCOPE2)], | |
171 [SCOPE2], | |
172 []], | |
173 'SW-fallbacked redirect to same-origin other-scope.'); | |
174 }) | |
175 .then(function() { | |
176 return test_redirect( | |
177 SCOPE1 + "url=" + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE), | |
178 OTHER_ORIGIN_OUT_SCOPE, | |
179 [[SCOPE1 + "url=" + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)], | |
180 [], | |
181 []], | |
182 'SW-fallbacked redirect to other-origin out-scope.'); | |
183 }) | |
184 .then(function() { | |
185 return test_redirect( | |
186 SCOPE1 + "url=" + encodeURIComponent(OTHER_ORIGIN_SCOPE), | |
187 OTHER_ORIGIN_SCOPE, | |
188 [[SCOPE1 + "url=" + encodeURIComponent(OTHER_ORIGIN_SCOPE)], | |
189 [], | |
190 [OTHER_ORIGIN_SCOPE]], | |
191 'SW-fallbacked redirect to other-origin in-scope.'); | |
192 }) | |
193 | |
194 // SW generated redirect. | |
195 // SW: event.respondWith(Response.redirect(params['url'])); | |
196 .then(function() { | |
197 return test_redirect( | |
198 SCOPE1 + "sw=gen&url=" + encodeURIComponent(OUT_SCOPE), | |
199 OUT_SCOPE, | |
200 [[SCOPE1 + "sw=gen&url=" + encodeURIComponent(OUT_SCOPE)], | |
201 [], | |
202 []], | |
203 'SW-generated redirect to same-origin out-scope.'); | |
204 }) | |
205 .then(function() { | |
206 return test_redirect( | |
207 SCOPE1 + "sw=gen&url=" + encodeURIComponent(SCOPE1), | |
208 SCOPE1, | |
209 [[SCOPE1 + "sw=gen&url=" + encodeURIComponent(SCOPE1), SCOPE1], | |
210 [], | |
211 []], | |
212 'SW-generated redirect to same-origin same-scope.'); | |
213 }) | |
214 .then(function() { | |
215 return test_redirect( | |
216 SCOPE1 + "sw=gen&url=" + encodeURIComponent(SCOPE2), | |
217 SCOPE2, | |
218 [[SCOPE1 + "sw=gen&url=" + encodeURIComponent(SCOPE2)], | |
219 [SCOPE2], | |
220 []], | |
221 'SW-generated redirect to same-origin other-scope.'); | |
222 }) | |
223 .then(function() { | |
224 return test_redirect( | |
225 SCOPE1 + "sw=gen&url=" + | |
226 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE), | |
227 OTHER_ORIGIN_OUT_SCOPE, | |
228 [[SCOPE1 + "sw=gen&url=" + | |
229 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)], | |
230 [], | |
231 []], | |
232 'SW-generated redirect to other-origin out-scope.'); | |
233 }) | |
234 .then(function() { | |
235 return test_redirect( | |
236 SCOPE1 + "sw=gen&url=" + encodeURIComponent(OTHER_ORIGIN_SCOPE), | |
237 OTHER_ORIGIN_SCOPE, | |
238 [[SCOPE1 + "sw=gen&url=" + | |
239 encodeURIComponent(OTHER_ORIGIN_SCOPE)], | |
240 [], | |
241 [OTHER_ORIGIN_SCOPE]], | |
242 'SW-generated redirect to other-origin in-scope.'); | |
243 }) | |
244 | |
245 // SW fetched redirect. | |
246 // SW: event.respondWith(fetch(event.request)); | |
247 // TODO(horo): When we change Request.redirect of navigation requests to | |
248 // 'manual', the expected last URL shuold be changed. (crbug.com/510650) | |
249 // Spec Issue: https://github.com/whatwg/fetch/issues/106 | |
250 .then(function() { | |
251 return test_redirect( | |
252 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(OUT_SCOPE), | |
253 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(OUT_SCOPE), | |
254 [[SCOPE1 + "sw=fetch&url=" + encodeURIComponent(OUT_SCOPE)], | |
255 [], | |
256 []], | |
257 'SW-fetched redirect to same-origin out-scope.'); | |
258 }) | |
259 .then(function() { | |
260 return test_redirect( | |
261 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE1), | |
262 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE1), | |
263 [[SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE1)], | |
264 [], | |
265 []], | |
266 'SW-fetched redirect to same-origin same-scope.'); | |
267 }) | |
268 .then(function() { | |
269 return test_redirect( | |
270 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE2), | |
271 SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE2), | |
272 [[SCOPE1 + "sw=fetch&url=" + encodeURIComponent(SCOPE2)], | |
273 [], | |
274 []], | |
275 'SW fetched redirect to same-origin other-scope.'); | |
276 }) | |
277 | |
278 // Opaque redirect. | |
279 // SW: event.respondWith(fetch( | |
280 // new Request(event.request.url, {redirect: 'manual'}))); | |
281 .then(function() { | |
282 return test_redirect( | |
283 SCOPE1 + "sw=opaque&url=" + encodeURIComponent(OUT_SCOPE), | |
284 OUT_SCOPE, | |
285 [[SCOPE1 + "sw=opaque&url=" + encodeURIComponent(OUT_SCOPE)], | |
286 [], | |
287 []], | |
288 'Redirect to same-origin out-scope with opaque redirect ' + | |
289 'response.'); | |
290 }) | |
291 .then(function() { | |
292 return test_redirect( | |
293 SCOPE1 + "sw=opaque&url=" + encodeURIComponent(SCOPE1), | |
294 SCOPE1, | |
295 [[SCOPE1 + "sw=opaque&url=" + encodeURIComponent(SCOPE1), SCOPE1], | |
296 [], | |
297 []], | |
298 'Redirect to same-origin same-scope with opaque redirect ' + | |
299 'response.'); | |
300 }) | |
301 .then(function() { | |
302 return test_redirect( | |
303 SCOPE1 + "sw=opaque&url=" + encodeURIComponent(SCOPE2), | |
304 SCOPE2, | |
305 [[SCOPE1 + "sw=opaque&url=" + encodeURIComponent(SCOPE2)], | |
306 [SCOPE2], | |
307 []], | |
308 'Redirect to same-origin other-scope with opaque redirect ' + | |
309 'response.'); | |
310 }) | |
311 .then(function() { | |
312 return test_redirect( | |
313 SCOPE1 + "sw=opaque&url=" + | |
314 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE), | |
315 OTHER_ORIGIN_OUT_SCOPE, | |
316 [[SCOPE1 + "sw=opaque&url=" + | |
317 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)], | |
318 [], | |
319 []], | |
320 'Redirect to other-origin out-scope with opaque redirect ' + | |
321 'response.'); | |
322 }) | |
323 .then(function() { | |
324 return test_redirect( | |
325 SCOPE1 + "sw=opaque&url=" + | |
326 encodeURIComponent(OTHER_ORIGIN_SCOPE), | |
327 OTHER_ORIGIN_SCOPE, | |
328 [[SCOPE1 + "sw=opaque&url=" + | |
329 encodeURIComponent(OTHER_ORIGIN_SCOPE)], | |
330 [], | |
331 [OTHER_ORIGIN_SCOPE]], | |
332 'Redirect to other-origin in-scope with opaque redirect ' + | |
333 'response.'); | |
334 }) | |
335 | |
336 // Opaque redirect passed through Cache. | |
337 // SW responds with an opaque redirectresponse from the Cache API. | |
338 .then(function() { | |
339 return test_redirect( | |
340 SCOPE1 + "sw=opaqueThroughCache&url=" + | |
341 encodeURIComponent(OUT_SCOPE), | |
342 OUT_SCOPE, | |
343 [[SCOPE1 + "sw=opaqueThroughCache&url=" + | |
344 encodeURIComponent(OUT_SCOPE)], | |
345 [], | |
346 []], | |
347 'Redirect to same-origin out-scope with opaque redirect ' + | |
348 'response which is passed through Cache.'); | |
349 }) | |
350 .then(function() { | |
351 return test_redirect( | |
352 SCOPE1 + "sw=opaqueThroughCache&url=" + | |
353 encodeURIComponent(SCOPE1), | |
354 SCOPE1, | |
355 [[SCOPE1 + "sw=opaqueThroughCache&url=" + | |
356 encodeURIComponent(SCOPE1), SCOPE1], | |
357 [], | |
358 []], | |
359 'Redirect to same-origin same-scope with opaque redirect ' + | |
360 'response which is passed through Cache.'); | |
361 }) | |
362 .then(function() { | |
363 return test_redirect( | |
364 SCOPE1 + "sw=opaqueThroughCache&url=" + | |
365 encodeURIComponent(SCOPE2), | |
366 SCOPE2, | |
367 [[SCOPE1 + "sw=opaqueThroughCache&url=" + | |
368 encodeURIComponent(SCOPE2)], | |
369 [SCOPE2], | |
370 []], | |
371 'Redirect to same-origin other-scope with opaque redirect ' + | |
372 'response which is passed through Cache.'); | |
373 }) | |
374 .then(function() { | |
375 return test_redirect( | |
376 SCOPE1 + "sw=opaqueThroughCache&url=" + | |
377 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE), | |
378 OTHER_ORIGIN_OUT_SCOPE, | |
379 [[SCOPE1 + "sw=opaqueThroughCache&url=" + | |
380 encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)], | |
381 [], | |
382 []], | |
383 'Redirect to other-origin out-scope with opaque redirect ' + | |
384 'response which is passed through Cache.'); | |
385 }) | |
386 .then(function() { | |
387 return test_redirect( | |
388 SCOPE1 + "sw=opaqueThroughCache&url=" + | |
389 encodeURIComponent(OTHER_ORIGIN_SCOPE), | |
390 OTHER_ORIGIN_SCOPE, | |
391 [[SCOPE1 + "sw=opaqueThroughCache&url=" + | |
392 encodeURIComponent(OTHER_ORIGIN_SCOPE)], | |
393 [], | |
394 [OTHER_ORIGIN_SCOPE]], | |
395 'Redirect to other-origin in-scope with opaque redirect ' + | |
396 'response which is passed through Cache.'); | |
397 }) | |
398 .then(function() { | |
399 return Promise.all( | |
400 [service_worker_unregister(t, SCOPE1), | |
401 service_worker_unregister(t, SCOPE2), | |
402 send_to_iframe(other_origin_frame, 'unregister')]); | |
403 }) | |
404 .then(function() { | |
405 other_origin_frame.remove(); | |
406 t.done(); | |
407 }) | |
408 .catch(unreached_rejection(t)); | |
409 }, 'Verify the behavior of navigation redirection with Service Worker.'); | |
410 </script> | |
411 </body> | |
OLD | NEW |