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