Chromium Code Reviews| 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( |
| 51 frame.contentWindow.navigator.serviceWorker.controller.scriptURL, | 59 frame.contentWindow.navigator.serviceWorker.controller.scriptURL, |
| 52 expected_url, | 60 expected_url, |
| 53 'controlled document should have a controller'); | 61 'controlled document should have a controller'); |
|
falken
2017/05/15 05:48:59
I think now the spec intends to require JS equalit
mike3
2017/05/15 19:48:26
I'm not so sure about this. The spec language rega
-jakearchibald-
2017/05/15 20:44:56
I agree that the spec wording isn't great, but equ
mike3
2017/05/15 21:48:27
Thanks, Jake! I've updated the patch to replace th
| |
| 54 | 62 assert_in_array(registration.active.state, |
| 55 frame.remove(); | 63 ['activating', 'activated'], |
| 56 service_worker_unregister_and_done(t, scope); | 64 '.ready should be resolved when the registration ' + |
| 57 }) | 65 'has an active worker'); |
| 58 .catch(unreached_rejection(t)); | 66 }); |
| 59 }, 'ready on a controlled document'); | 67 }, 'ready on a controlled document'); |
| 60 | 68 |
| 61 async_test(function(t) { | 69 promise_test(function(t) { |
| 62 var url = 'resources/empty-worker.js'; | 70 var url = 'resources/empty-worker.js'; |
| 63 var scope = 'resources/blank.html?ready-potential-controlled'; | 71 var scope = 'resources/blank.html?ready-potential-controlled'; |
| 64 var expected_url = normalizeURL(url); | 72 var expected_url = normalizeURL(url); |
| 65 var frame; | 73 var frame; |
| 66 | 74 |
| 67 with_iframe(scope) | 75 return with_iframe(scope) |
| 68 .then(function(f) { | 76 .then(function(f) { |
| 77 t.add_cleanup(function() { | |
| 78 f.remove(); | |
| 79 }); | |
| 69 frame = f; | 80 frame = f; |
| 70 return navigator.serviceWorker.register(url, {scope:scope}); | 81 return navigator.serviceWorker.register(url, {scope:scope}); |
| 71 }) | 82 }) |
| 72 .then(function() { | 83 .then(function(r) { |
| 84 add_completion_callback(function() { | |
| 85 r.unregister(); | |
| 86 }); | |
| 73 return frame.contentWindow.navigator.serviceWorker.ready; | 87 return frame.contentWindow.navigator.serviceWorker.ready; |
| 74 }) | 88 }) |
| 75 .then(function(registration) { | 89 .then(function(registration) { |
| 76 assert_equals(registration.installing, null, | 90 assert_equals(registration.installing, null, |
| 77 'installing should be null'); | 91 'installing should be null'); |
| 78 assert_equals(registration.waiting, null, | 92 assert_equals(registration.waiting, null, |
| 79 'waiting should be null.') | 93 'waiting should be null.') |
| 80 assert_equals(registration.active.scriptURL, expected_url, | 94 assert_equals(registration.active.scriptURL, expected_url, |
| 81 'active after ready should not be null'); | 95 'active after ready should not be null'); |
| 96 assert_in_array(registration.active.state, | |
| 97 ['activating', 'activated'], | |
| 98 '.ready should be resolved when the registration ' + | |
| 99 'has an active worker'); | |
| 82 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, | 100 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, |
| 83 null, | 101 null, |
| 84 'uncontrolled document should not have a controller'); | 102 'uncontrolled document should not have a controller'); |
| 85 | 103 }); |
| 86 frame.remove(); | |
| 87 service_worker_unregister_and_done(t, scope); | |
| 88 }) | |
| 89 .catch(unreached_rejection(t)); | |
| 90 }, 'ready on a potential controlled document'); | 104 }, 'ready on a potential controlled document'); |
| 91 | 105 |
| 92 async_test(function(t) { | 106 promise_test(function(t) { |
| 107 var url = 'resources/empty-worker.js'; | |
| 108 var scope = 'resources/blank.html?ready-installing'; | |
| 109 | |
| 110 return service_worker_unregister(t, scope) | |
| 111 .then(function() { | |
| 112 return with_iframe(scope); | |
| 113 }) | |
| 114 .then(function(f) { | |
| 115 var promise = f.contentWindow.navigator.serviceWorker.ready; | |
| 116 t.add_cleanup(function() { | |
| 117 f.remove(); | |
| 118 }); | |
| 119 navigator.serviceWorker.register(url, {scope: scope}); | |
| 120 return promise; | |
| 121 }) | |
| 122 .then(function(registration) { | |
| 123 add_completion_callback(function() { | |
| 124 registration.unregister(); | |
| 125 }); | |
| 126 | |
| 127 assert_equals(registration.installing, null, | |
| 128 'installing should be null'); | |
| 129 assert_equals(registration.waiting, null, 'waiting should be null'); | |
| 130 assert_not_equals(registration.active, null, | |
| 131 'active after ready should not be null'); | |
| 132 assert_in_array(registration.active.state, | |
| 133 ['activating', 'activated'], | |
| 134 '.ready should be resolved when the registration ' + | |
| 135 'has an active worker'); | |
| 136 }); | |
| 137 }, 'ready on an iframe whose parent registers a new service worker'); | |
| 138 | |
| 139 promise_test(function(t) { | |
| 140 var url = 'resources/empty-worker.js'; | |
| 141 var scope = 'resources/register-iframe.html'; | |
| 142 var expected_url = normalizeURL(url); | |
| 143 | |
| 144 return with_iframe(scope) | |
| 145 .then(function(f) { | |
| 146 t.add_cleanup(function() { | |
| 147 f.remove(); | |
| 148 }); | |
| 149 return f.contentWindow.navigator.serviceWorker.ready; | |
| 150 }) | |
| 151 .then(function(registration) { | |
| 152 add_completion_callback(function() { | |
| 153 registration.unregister(); | |
| 154 }); | |
| 155 | |
| 156 assert_equals(registration.installing, null, | |
| 157 'installing should be null'); | |
| 158 assert_equals(registration.waiting, null, 'waiting should be null'); | |
| 159 assert_not_equals(registration.active, null, | |
| 160 'active after ready should not be null'); | |
| 161 assert_in_array(registration.active.state, | |
| 162 ['activating', 'activated'], | |
| 163 '.ready should be resolved with "active worker"'); | |
| 164 }); | |
| 165 }, 'ready on an iframe with installing a new service worker by itself'); | |
|
falken
2017/05/15 05:48:59
"with installing" -> "that installs" and remove "b
mike3
2017/05/15 19:48:26
Done.
| |
| 166 | |
| 167 promise_test(function(t) { | |
| 93 var url = 'resources/empty-worker.js'; | 168 var url = 'resources/empty-worker.js'; |
| 94 var matched_scope = 'resources/blank.html?ready-after-match'; | 169 var matched_scope = 'resources/blank.html?ready-after-match'; |
| 95 var longer_matched_scope = 'resources/blank.html?ready-after-match-longer'; | 170 var longer_matched_scope = 'resources/blank.html?ready-after-match-longer'; |
| 96 var frame, registration; | 171 var frame, registration; |
| 97 | 172 |
| 98 Promise.all([service_worker_unregister(t, matched_scope), | 173 return Promise.all([service_worker_unregister(t, matched_scope), |
| 99 service_worker_unregister(t, longer_matched_scope)]) | 174 service_worker_unregister(t, longer_matched_scope)]) |
| 100 .then(function() { | 175 .then(function() { |
| 101 return with_iframe(longer_matched_scope); | 176 return with_iframe(longer_matched_scope); |
| 102 }) | 177 }) |
| 103 .then(function(f) { | 178 .then(function(f) { |
| 179 t.add_cleanup(function() { | |
| 180 f.remove(); | |
| 181 }); | |
| 104 frame = f; | 182 frame = f; |
| 105 return navigator.serviceWorker.register(url, {scope: matched_scope}); | 183 return navigator.serviceWorker.register(url, {scope: matched_scope}); |
| 106 }) | 184 }) |
| 107 .then(function(r) { | 185 .then(function(r) { |
| 186 add_completion_callback(function() { | |
| 187 r.unregister(); | |
| 188 }); | |
| 108 registration = r; | 189 registration = r; |
| 109 return wait_for_state(t, r.installing, 'activated'); | 190 return wait_for_state(t, r.installing, 'activated'); |
| 110 }) | 191 }) |
| 111 .then(function() { | 192 .then(function() { |
| 112 return navigator.serviceWorker.register( | 193 return navigator.serviceWorker.register( |
| 113 url, {scope: longer_matched_scope}); | 194 url, {scope: longer_matched_scope}); |
| 114 }) | 195 }) |
| 115 .then(function() { | 196 .then(function(r) { |
| 197 add_completion_callback(function() { | |
| 198 r.unregister(); | |
| 199 }); | |
| 116 return frame.contentWindow.navigator.serviceWorker.ready; | 200 return frame.contentWindow.navigator.serviceWorker.ready; |
| 117 }) | 201 }) |
| 118 .then(function(r) { | 202 .then(function(r) { |
| 119 assert_equals(r.scope, normalizeURL(longer_matched_scope), | 203 assert_equals(r.scope, normalizeURL(longer_matched_scope), |
| 120 'longer matched registration should be returned'); | 204 'longer matched registration should be returned'); |
| 121 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, | 205 assert_equals(frame.contentWindow.navigator.serviceWorker.controller, |
| 122 null, 'controller should be null'); | 206 null, 'controller should be null'); |
| 123 return registration.unregister(); | 207 }); |
| 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'); | 208 }, 'ready after a longer matched registration registered'); |
| 131 | 209 |
| 132 async_test(function(t) { | 210 promise_test(function(t) { |
| 133 var url = 'resources/empty-worker.js'; | 211 var url = 'resources/empty-worker.js'; |
| 134 var matched_scope = 'resources/blank.html?ready-after-resolve'; | 212 var matched_scope = 'resources/blank.html?ready-after-resolve'; |
| 135 var longer_matched_scope = | 213 var longer_matched_scope = |
| 136 'resources/blank.html?ready-after-resolve-longer'; | 214 'resources/blank.html?ready-after-resolve-longer'; |
| 137 var frame, registration; | 215 var frame, registration; |
| 138 | 216 |
| 139 service_worker_unregister_and_register(t, url, matched_scope) | 217 return service_worker_unregister_and_register(t, url, matched_scope) |
| 140 .then(function(r) { | 218 .then(function(r) { |
| 219 add_completion_callback(function() { | |
| 220 r.unregister(); | |
| 221 }); | |
| 141 registration = r; | 222 registration = r; |
| 142 return wait_for_state(t, r.installing, 'activated'); | 223 return wait_for_state(t, r.installing, 'activated'); |
| 143 }) | 224 }) |
| 144 .then(function() { | 225 .then(function() { |
| 145 return with_iframe(longer_matched_scope); | 226 return with_iframe(longer_matched_scope); |
| 146 }) | 227 }) |
| 147 .then(function(f) { | 228 .then(function(f) { |
| 229 t.add_cleanup(function() { | |
| 230 f.remove(); | |
| 231 }); | |
| 148 frame = f; | 232 frame = f; |
| 149 return f.contentWindow.navigator.serviceWorker.ready; | 233 return f.contentWindow.navigator.serviceWorker.ready; |
| 150 }) | 234 }) |
| 151 .then(function(r) { | 235 .then(function(r) { |
| 152 assert_equals(r.scope, normalizeURL(matched_scope), | 236 assert_equals(r.scope, normalizeURL(matched_scope), |
| 153 'matched registration should be returned'); | 237 'matched registration should be returned'); |
| 154 return navigator.serviceWorker.register( | 238 return navigator.serviceWorker.register( |
| 155 url, {scope: longer_matched_scope}); | 239 url, {scope: longer_matched_scope}); |
| 156 }) | 240 }) |
| 157 .then(function() { | 241 .then(function(r) { |
| 242 add_completion_callback(function() { | |
| 243 r.unregister(); | |
| 244 }); | |
| 158 return frame.contentWindow.navigator.serviceWorker.ready; | 245 return frame.contentWindow.navigator.serviceWorker.ready; |
| 159 }) | 246 }) |
| 160 .then(function(r) { | 247 .then(function(r) { |
| 161 assert_equals(r.scope, normalizeURL(matched_scope), | 248 assert_equals(r.scope, normalizeURL(matched_scope), |
| 162 'ready should only be resolved once'); | 249 'ready should only be resolved once'); |
| 163 return registration.unregister(); | 250 }); |
| 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'); | 251 }, 'access ready after it has been resolved'); |
| 171 | |
| 172 </script> | 252 </script> |
| OLD | NEW |