OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <title>Service Worker: navigator.serviceWorker.ready</title> | 2 <title>Service Worker: navigator.serviceWorker.ready</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="resources/test-helpers.js"></script> | 5 <script src="resources/test-helpers.sub.js"></script> |
6 <body> | 6 <body> |
7 <script> | 7 <script> |
8 test(function() { | 8 test(function() { |
9 var promise = navigator.serviceWorker.ready; | 9 var promise = navigator.serviceWorker.ready; |
10 assert_equals(promise, navigator.serviceWorker.ready, | 10 assert_equals(promise, navigator.serviceWorker.ready, |
11 'repeated access to ready without intervening ' + | 11 'repeated access to ready without intervening ' + |
12 'registrations should return the same Promise object'); | 12 'registrations should return the same Promise object'); |
13 }, 'ready returns the same Promise object'); | 13 }, 'ready returns the same Promise object'); |
14 | 14 |
15 promise_test(function(t) { | 15 async_test(function(t) { |
16 return with_iframe('resources/blank.html?uncontrolled') | 16 with_iframe('resources/blank.html?uncontrolled') |
17 .then(t.step_func(function(frame) { | 17 .then(t.step_func(function(frame) { |
18 var promise = frame.contentWindow.navigator.serviceWorker.ready; | 18 var promise = frame.contentWindow.navigator.serviceWorker.ready; |
19 assert_equals(Object.getPrototypeOf(promise), | 19 assert_equals(Object.getPrototypeOf(promise), |
20 frame.contentWindow.Promise.prototype, | 20 frame.contentWindow.Promise.prototype, |
21 'the Promise should be in the context of the ' + | 21 'the Promise should be in the context of the ' + |
22 'related document'); | 22 'related document'); |
| 23 frame.remove(); |
| 24 t.done(); |
23 })); | 25 })); |
24 }, 'ready returns a Promise object in the context of the related document'); | 26 }, 'ready returns a Promise object in the context of the related document'); |
25 | 27 |
26 promise_test(function(t) { | 28 async_test(function(t) { |
27 var url = 'resources/empty-worker.js'; | 29 var url = 'resources/empty-worker.js'; |
28 var scope = 'resources/blank.html?ready-controlled'; | 30 var scope = 'resources/blank.html?ready-controlled'; |
29 var expected_url = normalizeURL(url); | 31 var expected_url = normalizeURL(url); |
30 var frame; | 32 var frame; |
31 | 33 |
32 return service_worker_unregister_and_register(t, url, scope) | 34 service_worker_unregister_and_register(t, url, scope) |
33 .then(function(registration) { | 35 .then(function(registration) { |
34 add_completion_callback(function() { registration.unregister(); }); | |
35 return wait_for_state(t, registration.installing, 'activated'); | 36 return wait_for_state(t, registration.installing, 'activated'); |
36 }) | 37 }) |
37 .then(function() { return with_iframe(scope); }) | 38 .then(function() { return with_iframe(scope); }) |
38 .then(function(f) { | 39 .then(function(f) { |
39 frame = f; | 40 frame = f; |
40 return frame.contentWindow.navigator.serviceWorker.ready; | 41 return frame.contentWindow.navigator.serviceWorker.ready; |
41 }) | 42 }) |
42 .then(function(registration) { | 43 .then(function(registration) { |
43 assert_equals(registration.installing, null, | 44 assert_equals(registration.installing, null, |
44 'installing should be null'); | 45 'installing should be null'); |
45 assert_equals(registration.waiting, null, | 46 assert_equals(registration.waiting, null, |
46 'waiting should be null'); | 47 'waiting should be null'); |
47 assert_equals(registration.active.scriptURL, expected_url, | 48 assert_equals(registration.active.scriptURL, expected_url, |
48 'active after ready should not be null'); | 49 'active after ready should not be null'); |
49 assert_equals( | 50 assert_equals( |
50 frame.contentWindow.navigator.serviceWorker.controller.scriptURL, | 51 frame.contentWindow.navigator.serviceWorker.controller.scriptURL, |
51 expected_url, | 52 expected_url, |
52 'controlled document should have a controller'); | 53 'controlled document should have a controller'); |
53 assert_in_array(registration.active.state, | 54 |
54 ['activating', 'activated'], | 55 frame.remove(); |
55 '.ready should be resolved when the registration ' + | 56 service_worker_unregister_and_done(t, scope); |
56 'has an active worker'); | 57 }) |
57 }); | 58 .catch(unreached_rejection(t)); |
58 }, 'ready on a controlled document'); | 59 }, 'ready on a controlled document'); |
59 | 60 |
60 promise_test(function(t) { | 61 async_test(function(t) { |
61 var url = 'resources/empty-worker.js'; | 62 var url = 'resources/empty-worker.js'; |
62 var scope = 'resources/blank.html?ready-potential-controlled'; | 63 var scope = 'resources/blank.html?ready-potential-controlled'; |
63 var expected_url = normalizeURL(url); | 64 var expected_url = normalizeURL(url); |
64 var frame; | 65 var frame; |
65 | 66 |
66 return with_iframe(scope) | 67 with_iframe(scope) |
67 .then(function(f) { | 68 .then(function(f) { |
68 frame = f; | 69 frame = f; |
69 return navigator.serviceWorker.register(url, {scope:scope}); | 70 return navigator.serviceWorker.register(url, {scope:scope}); |
70 }) | 71 }) |
71 .then(function(r) { | 72 .then(function() { |
72 add_completion_callback(function() { r.unregister(); }); | |
73 return frame.contentWindow.navigator.serviceWorker.ready; | 73 return frame.contentWindow.navigator.serviceWorker.ready; |
74 }) | 74 }) |
75 .then(function(registration) { | 75 .then(function(registration) { |
76 assert_equals(registration.installing, null, | 76 assert_equals(registration.installing, null, |
77 'installing should be null'); | 77 'installing should be null'); |
78 assert_equals(registration.waiting, null, | 78 assert_equals(registration.waiting, null, |
79 'waiting should be null.') | 79 'waiting should be null.') |
80 assert_equals(registration.active.scriptURL, expected_url, | 80 assert_equals(registration.active.scriptURL, expected_url, |
81 'active after ready should not be null'); | 81 'active after ready should not be null'); |
82 assert_in_array(registration.active.state, | |
83 ['activating', 'activated'], | |
84 '.ready should be resolved when the registration ' + | |
85 'has an active worker'); | |
86 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, | 82 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, |
87 null, | 83 null, |
88 'uncontrolled document should not have a controller'); | 84 'uncontrolled document should not have a controller'); |
89 }); | 85 |
| 86 frame.remove(); |
| 87 service_worker_unregister_and_done(t, scope); |
| 88 }) |
| 89 .catch(unreached_rejection(t)); |
90 }, 'ready on a potential controlled document'); | 90 }, 'ready on a potential controlled document'); |
91 | 91 |
92 promise_test(function(t) { | 92 async_test(function(t) { |
93 var url = 'resources/empty-worker.js'; | |
94 var scope = 'resources/blank.html?ready-installing'; | |
95 | |
96 return service_worker_unregister(t, scope) | |
97 .then(function() { | |
98 return with_iframe(scope); | |
99 }) | |
100 .then(function(f) { | |
101 var promise = f.contentWindow.navigator.serviceWorker.ready; | |
102 navigator.serviceWorker.register(url, {scope: scope}); | |
103 return promise; | |
104 }) | |
105 .then(function(registration) { | |
106 // add_completion_callback(function() { registration.unregister(); }) | |
107 // might not work because the registration is associated with an | |
108 // iframe's context, and if the iframe is removed before calling the | |
109 // callback, unregistraion would fail. Hence we manually call | |
110 // unregister() before finishing this test and removing the iframe. | |
111 var promise = registration.unregister(); | |
112 | |
113 // |registration| should still be valid even after unregister(). | |
114 assert_equals(registration.installing, null, | |
115 'installing should be null'); | |
116 assert_equals(registration.waiting, null, 'waiting should be null'); | |
117 assert_not_equals(registration.active, null, | |
118 'active after ready should not be null'); | |
119 assert_in_array(registration.active.state, | |
120 ['activating', 'activated'], | |
121 '.ready should be resolved when the registration ' + | |
122 'has an active worker'); | |
123 return promise; | |
124 }); | |
125 }, 'ready on an iframe whose parent registers a new service worker'); | |
126 | |
127 promise_test(function(t) { | |
128 var url = 'resources/empty-worker.js'; | |
129 var scope = 'resources/register-iframe.html'; | |
130 var expected_url = normalizeURL(url); | |
131 | |
132 return with_iframe(scope) | |
133 .then(function(f) { | |
134 return f.contentWindow.navigator.serviceWorker.ready; | |
135 }) | |
136 .then(function(registration) { | |
137 // add_completion_callback(function() { registration.unregister(); }) | |
138 // might not work because the registration is associated with an | |
139 // iframe's context, and if the iframe is removed before calling the | |
140 // callback, unregistraion would fail. Hence we manually call | |
141 // unregister() before finishing this test and removing the iframe. | |
142 var promise = registration.unregister(); | |
143 | |
144 // |registration| should still be valid even after unregister(). | |
145 assert_equals(registration.installing, null, | |
146 'installing should be null'); | |
147 assert_equals(registration.waiting, null, 'waiting should be null'); | |
148 assert_not_equals(registration.active, null, | |
149 'active after ready should not be null'); | |
150 assert_in_array(registration.active.state, | |
151 ['activating', 'activated'], | |
152 '.ready should be resolved with "active worker"'); | |
153 return promise; | |
154 }); | |
155 }, 'ready on an iframe with installing a new service worker by itself'); | |
156 | |
157 promise_test(function(t) { | |
158 var url = 'resources/empty-worker.js'; | 93 var url = 'resources/empty-worker.js'; |
159 var matched_scope = 'resources/blank.html?ready-after-match'; | 94 var matched_scope = 'resources/blank.html?ready-after-match'; |
160 var longer_matched_scope = 'resources/blank.html?ready-after-match-longer'; | 95 var longer_matched_scope = 'resources/blank.html?ready-after-match-longer'; |
161 var frame, registration; | 96 var frame, registration; |
162 | 97 |
163 return Promise.all([service_worker_unregister(t, matched_scope), | 98 Promise.all([service_worker_unregister(t, matched_scope), |
164 service_worker_unregister(t, longer_matched_scope)]) | 99 service_worker_unregister(t, longer_matched_scope)]) |
165 .then(function() { | 100 .then(function() { |
166 return with_iframe(longer_matched_scope); | 101 return with_iframe(longer_matched_scope); |
167 }) | 102 }) |
168 .then(function(f) { | 103 .then(function(f) { |
169 frame = f; | 104 frame = f; |
170 return navigator.serviceWorker.register(url, {scope: matched_scope}); | 105 return navigator.serviceWorker.register(url, {scope: matched_scope}); |
171 }) | 106 }) |
172 .then(function(r) { | 107 .then(function(r) { |
173 add_completion_callback(function() { r.unregister(); }); | |
174 registration = r; | 108 registration = r; |
175 return wait_for_state(t, r.installing, 'activated'); | 109 return wait_for_state(t, r.installing, 'activated'); |
176 }) | 110 }) |
177 .then(function() { | 111 .then(function() { |
178 return navigator.serviceWorker.register( | 112 return navigator.serviceWorker.register( |
179 url, {scope: longer_matched_scope}); | 113 url, {scope: longer_matched_scope}); |
180 }) | 114 }) |
181 .then(function(r) { | 115 .then(function() { |
182 add_completion_callback(function() { r.unregister(); }); | |
183 return frame.contentWindow.navigator.serviceWorker.ready; | 116 return frame.contentWindow.navigator.serviceWorker.ready; |
184 }) | 117 }) |
185 .then(function(r) { | 118 .then(function(r) { |
186 assert_equals(r.scope, normalizeURL(longer_matched_scope), | 119 assert_equals(r.scope, normalizeURL(longer_matched_scope), |
187 'longer matched registration should be returned'); | 120 'longer matched registration should be returned'); |
188 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, | 121 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, |
189 null, 'controller should be null'); | 122 null, 'controller should be null'); |
190 }); | 123 return registration.unregister(); |
| 124 }) |
| 125 .then(function() { |
| 126 frame.remove(); |
| 127 return service_worker_unregister_and_done(t, longer_matched_scope); |
| 128 }) |
| 129 .catch(unreached_rejection(t)); |
191 }, 'ready after a longer matched registration registered'); | 130 }, 'ready after a longer matched registration registered'); |
192 | 131 |
193 promise_test(function(t) { | 132 async_test(function(t) { |
194 var url = 'resources/empty-worker.js'; | 133 var url = 'resources/empty-worker.js'; |
195 var matched_scope = 'resources/blank.html?ready-after-resolve'; | 134 var matched_scope = 'resources/blank.html?ready-after-resolve'; |
196 var longer_matched_scope = | 135 var longer_matched_scope = |
197 'resources/blank.html?ready-after-resolve-longer'; | 136 'resources/blank.html?ready-after-resolve-longer'; |
198 var frame, registration; | 137 var frame, registration; |
199 | 138 |
200 return service_worker_unregister_and_register(t, url, matched_scope) | 139 service_worker_unregister_and_register(t, url, matched_scope) |
201 .then(function(r) { | 140 .then(function(r) { |
202 add_completion_callback(function() { r.unregister(); }); | |
203 registration = r; | 141 registration = r; |
204 return wait_for_state(t, r.installing, 'activated'); | 142 return wait_for_state(t, r.installing, 'activated'); |
205 }) | 143 }) |
206 .then(function() { | 144 .then(function() { |
207 return with_iframe(longer_matched_scope); | 145 return with_iframe(longer_matched_scope); |
208 }) | 146 }) |
209 .then(function(f) { | 147 .then(function(f) { |
210 frame = f; | 148 frame = f; |
211 return f.contentWindow.navigator.serviceWorker.ready; | 149 return f.contentWindow.navigator.serviceWorker.ready; |
212 }) | 150 }) |
213 .then(function(r) { | 151 .then(function(r) { |
214 assert_equals(r.scope, normalizeURL(matched_scope), | 152 assert_equals(r.scope, normalizeURL(matched_scope), |
215 'matched registration should be returned'); | 153 'matched registration should be returned'); |
216 return navigator.serviceWorker.register( | 154 return navigator.serviceWorker.register( |
217 url, {scope: longer_matched_scope}); | 155 url, {scope: longer_matched_scope}); |
218 }) | 156 }) |
219 .then(function(r) { | 157 .then(function() { |
220 add_completion_callback(function() { r.unregister(); }); | |
221 return frame.contentWindow.navigator.serviceWorker.ready; | 158 return frame.contentWindow.navigator.serviceWorker.ready; |
222 }) | 159 }) |
223 .then(function(r) { | 160 .then(function(r) { |
224 assert_equals(r.scope, normalizeURL(matched_scope), | 161 assert_equals(r.scope, normalizeURL(matched_scope), |
225 'ready should only be resolved once'); | 162 'ready should only be resolved once'); |
226 }); | 163 return registration.unregister(); |
| 164 }) |
| 165 .then(function() { |
| 166 frame.remove(); |
| 167 return service_worker_unregister_and_done(t, longer_matched_scope); |
| 168 }) |
| 169 .catch(unreached_rejection(t)); |
227 }, 'access ready after it has been resolved'); | 170 }, 'access ready after it has been resolved'); |
228 | 171 |
229 </script> | 172 </script> |
OLD | NEW |