author | Jake Archibald <jaffathecake@gmail.com> |
Fri, 20 Dec 2019 11:40:17 +0000 | |
changeset 508277 | 6123c330aeb777d0680e31da41133d4a9d71df29 |
parent 508276 | 6962ba69360b5114afce440907bf271098474d1d |
child 508278 | e2bc90bd87b88f774f63335f32db836b43686ca2 |
push id | 103869 |
push user | wptsync@mozilla.com |
push date | Mon, 23 Dec 2019 11:18:28 +0000 |
treeherder | autoland@e2bc90bd87b8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1601977, 20655 |
milestone | 73.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
deleted file mode 100644 --- a/testing/web-platform/tests/service-workers/service-worker/ready.https.html +++ /dev/null @@ -1,317 +0,0 @@ -<!DOCTYPE html> -<title>Service Worker: navigator.serviceWorker.ready</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/test-helpers.sub.js"></script> -<body> -<script> -test(function() { - var promise = navigator.serviceWorker.ready; - assert_equals(promise, navigator.serviceWorker.ready, - 'repeated access to ready without intervening ' + - 'registrations should return the same Promise object'); - }, 'ready returns the same Promise object'); - -promise_test(function(t) { - return with_iframe('resources/blank.html?uncontrolled') - .then(t.step_func(function(frame) { - var promise = frame.contentWindow.navigator.serviceWorker.ready; - t.add_cleanup(function() { - frame.remove(); - }); - - assert_equals(Object.getPrototypeOf(promise), - frame.contentWindow.Promise.prototype, - 'the Promise should be in the context of the ' + - 'related document'); - })); - }, 'ready returns a Promise object in the context of the related document'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var scope = 'resources/blank.html?ready-controlled'; - var expected_url = normalizeURL(url); - var frame; - - return service_worker_unregister_and_register(t, url, scope) - .then(function(registration) { - add_completion_callback(function() { - registration.unregister(); - }); - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(function() { return with_iframe(scope); }) - .then(function(f) { - t.add_cleanup(function() { - f.remove(); - }); - frame = f; - return frame.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(registration) { - assert_equals(registration.installing, null, - 'installing should be null'); - assert_equals(registration.waiting, null, - 'waiting should be null'); - assert_equals(registration.active.scriptURL, expected_url, - 'active after ready should not be null'); - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - registration.active, - 'the controller should be the active worker'); - assert_in_array(registration.active.state, - ['activating', 'activated'], - '.ready should be resolved when the registration ' + - 'has an active worker'); - }); - }, 'ready on a controlled document'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var scope = 'resources/blank.html?ready-potential-controlled'; - var expected_url = normalizeURL(url); - var frame; - - return with_iframe(scope) - .then(function(f) { - t.add_cleanup(function() { - f.remove(); - }); - frame = f; - return navigator.serviceWorker.register(url, {scope:scope}); - }) - .then(function(r) { - add_completion_callback(function() { - r.unregister(); - }); - return frame.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(registration) { - assert_equals(registration.installing, null, - 'installing should be null'); - assert_equals(registration.waiting, null, - 'waiting should be null.') - assert_equals(registration.active.scriptURL, expected_url, - 'active after ready should not be null'); - assert_in_array(registration.active.state, - ['activating', 'activated'], - '.ready should be resolved when the registration ' + - 'has an active worker'); - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - null, - 'uncontrolled document should not have a controller'); - }); - }, 'ready on a potential controlled document'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var scope = 'resources/blank.html?ready-installing'; - - return service_worker_unregister(t, scope) - .then(function() { - return with_iframe(scope); - }) - .then(function(f) { - var promise = f.contentWindow.navigator.serviceWorker.ready; - t.add_cleanup(function() { - f.remove(); - }); - navigator.serviceWorker.register(url, {scope: scope}); - return promise; - }) - .then(function(registration) { - add_completion_callback(function() { - registration.unregister(); - }); - - assert_equals(registration.installing, null, - 'installing should be null'); - assert_equals(registration.waiting, null, 'waiting should be null'); - assert_not_equals(registration.active, null, - 'active after ready should not be null'); - assert_in_array(registration.active.state, - ['activating', 'activated'], - '.ready should be resolved when the registration ' + - 'has an active worker'); - }); - }, 'ready on an iframe whose parent registers a new service worker'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var scope = 'resources/register-iframe.html'; - var expected_url = normalizeURL(url); - - return with_iframe(scope) - .then(function(f) { - t.add_cleanup(function() { - f.remove(); - }); - return f.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(registration) { - add_completion_callback(function() { - registration.unregister(); - }); - - assert_equals(registration.installing, null, - 'installing should be null'); - assert_equals(registration.waiting, null, 'waiting should be null'); - assert_not_equals(registration.active, null, - 'active after ready should not be null'); - assert_in_array(registration.active.state, - ['activating', 'activated'], - '.ready should be resolved with "active worker"'); - }); - }, 'ready on an iframe that installs a new service worker'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var matched_scope = 'resources/blank.html?ready-after-match'; - var longer_matched_scope = 'resources/blank.html?ready-after-match-longer'; - var frame, registration; - - return Promise.all([service_worker_unregister(t, matched_scope), - service_worker_unregister(t, longer_matched_scope)]) - .then(function() { - return with_iframe(longer_matched_scope); - }) - .then(function(f) { - t.add_cleanup(function() { - f.remove(); - }); - frame = f; - return navigator.serviceWorker.register(url, {scope: matched_scope}); - }) - .then(function(r) { - add_completion_callback(function() { - r.unregister(); - }); - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return navigator.serviceWorker.register( - url, {scope: longer_matched_scope}); - }) - .then(function(r) { - add_completion_callback(function() { - r.unregister(); - }); - return frame.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(r) { - assert_equals(r.scope, normalizeURL(longer_matched_scope), - 'longer matched registration should be returned'); - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - null, 'controller should be null'); - }); - }, 'ready after a longer matched registration registered'); - -promise_test(function(t) { - var url = 'resources/empty-worker.js'; - var matched_scope = 'resources/blank.html?ready-after-resolve'; - var longer_matched_scope = - 'resources/blank.html?ready-after-resolve-longer'; - var frame, registration; - - return service_worker_unregister_and_register(t, url, matched_scope) - .then(function(r) { - add_completion_callback(function() { - r.unregister(); - }); - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(longer_matched_scope); - }) - .then(function(f) { - t.add_cleanup(function() { - f.remove(); - }); - frame = f; - return f.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(r) { - assert_equals(r.scope, normalizeURL(matched_scope), - 'matched registration should be returned'); - return navigator.serviceWorker.register( - url, {scope: longer_matched_scope}); - }) - .then(function(r) { - add_completion_callback(function() { - r.unregister(); - }); - return frame.contentWindow.navigator.serviceWorker.ready; - }) - .then(function(r) { - assert_equals(r.scope, normalizeURL(matched_scope), - 'ready should only be resolved once'); - }); - }, 'access ready after it has been resolved'); - -promise_test(async function(t) { - const url1 = 'resources/empty-worker.js'; - const url2 = url1 + '?2'; - const matched_scope = 'resources/blank.html?ready-after-unregister'; - - const reg1 = await service_worker_unregister_and_register(t, url1, matched_scope); - t.add_cleanup(() => reg1.unregister()); - - await wait_for_state(t, reg1.installing, 'activating'); - // This registration will resolve all ready promises in clients that match the scope. - // But there are no clients. - - const frame = await with_iframe(matched_scope); - t.add_cleanup(() => frame.remove()); - - await reg1.unregister(); - - // Access the ready promise while the registration is unregistering. - const readyPromise = frame.contentWindow.navigator.serviceWorker.ready; - - // Create a new registration. - const reg2 = await navigator.serviceWorker.register(url2, { scope: matched_scope }); - t.add_cleanup(() => reg2.unregister()); - // This registration will resolve all ready promises in clients that match the scope. - // That includes frame's client. - - const readyReg = await readyPromise; - - assert_equals(readyReg.active.scriptURL, reg2.active.scriptURL, 'Resolves with the second registration'); - assert_not_equals(reg1, reg2, 'Registrations should be different'); -}, 'resolve ready after unregistering and reregistering'); - -promise_test(async function(t) { - const url1 = 'resources/empty-worker.js'; - const url2 = url1 + '?2'; - const matched_scope = 'resources/blank.html?ready-after-unregister'; - - const frame = await with_iframe(matched_scope); - t.add_cleanup(() => frame.remove()); - - const reg1 = await service_worker_unregister_and_register(t, url1, matched_scope); - t.add_cleanup(() => reg1.unregister()); - - await wait_for_state(t, reg1.installing, 'activated'); - // This registration will resolve all ready promises in clients that match the scope. - // That includes frame's client. - - const reg1Active = reg1.active; - - await reg1.unregister(); - - // Access the ready promise while the registration is unregistering. - const readyPromise = frame.contentWindow.navigator.serviceWorker.ready; - - // Create a new registration. - const reg2 = await navigator.serviceWorker.register(url2, { scope: matched_scope }); - t.add_cleanup(() => reg2.unregister()); - // This registration will resolve all ready promises in clients that match the scope. - // That includes frame's client, but its ready promise has already resolved. - - const readyReg = await readyPromise; - - assert_equals(readyReg.active.scriptURL, reg1Active.scriptURL, 'Resolves with the first registration'); - assert_not_equals(reg1, reg2, 'Registrations should be different'); -}, 'resolve ready before unregistering and reregistering'); -</script>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/ready.https.window.js @@ -0,0 +1,223 @@ +// META: title=Service Worker: navigator.serviceWorker.ready +// META: script=resources/test-helpers.sub.js + +test(() => { + assert_equals( + navigator.serviceWorker.ready, + navigator.serviceWorker.ready, + 'repeated access to ready without intervening registrations should return the same Promise object' + ); +}, 'ready returns the same Promise object'); + +promise_test(async t => { + const frame = await with_iframe('resources/blank.html?uncontrolled'); + t.add_cleanup(() => frame.remove()); + + const promise = frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + Object.getPrototypeOf(promise), + frame.contentWindow.Promise.prototype, + 'the Promise should be in the context of the related document' + ); +}, 'ready returns a Promise object in the context of the related document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-controlled'; + const expectedURL = normalizeURL(url); + const registration = await service_worker_unregister_and_register(t, url, scope); + t.add_cleanup(() => registration.unregister()); + + await wait_for_state(t, registration.installing, 'activated'); + + const frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals(readyReg.installing, null, 'installing should be null'); + assert_equals(readyReg.waiting, null, 'waiting should be null'); + assert_equals(readyReg.active.scriptURL, expectedURL, 'active after ready should not be null'); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + readyReg.active, + 'the controller should be the active worker' + ); + assert_in_array( + readyReg.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); +}, 'ready on a controlled document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-potential-controlled'; + const expected_url = normalizeURL(url); + const frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + + const registration = await navigator.serviceWorker.register(url, { scope }); + t.add_cleanup(() => registration.unregister()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals(readyReg.installing, null, 'installing should be null'); + assert_equals(readyReg.waiting, null, 'waiting should be null.') + assert_equals(readyReg.active.scriptURL, expected_url, 'active after ready should not be null'); + assert_in_array( + readyReg.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + null, + 'uncontrolled document should not have a controller' + ); +}, 'ready on a potential controlled document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-installing'; + + await service_worker_unregister(t, scope); + + const frame = await with_iframe(scope); + const promise = frame.contentWindow.navigator.serviceWorker.ready; + navigator.serviceWorker.register(url, { scope }); + const registration = await promise; + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + assert_equals(registration.installing, null, 'installing should be null'); + assert_equals(registration.waiting, null, 'waiting should be null'); + assert_not_equals(registration.active, null, 'active after ready should not be null'); + assert_in_array( + registration.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); +}, 'ready on an iframe whose parent registers a new service worker'); + +promise_test(async t => { + const scope = 'resources/register-iframe.html'; + const frame = await with_iframe(scope); + + const registration = await frame.contentWindow.navigator.serviceWorker.ready; + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + assert_equals(registration.installing, null, 'installing should be null'); + assert_equals(registration.waiting, null, 'waiting should be null'); + assert_not_equals(registration.active, null, 'active after ready should not be null'); + assert_in_array( + registration.active.state, + ['activating', 'activated'], + '.ready should be resolved with "active worker"' + ); + }, 'ready on an iframe that installs a new service worker'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const matchedScope = 'resources/blank.html?ready-after-match'; + const longerMatchedScope = 'resources/blank.html?ready-after-match-longer'; + + await service_worker_unregister(t, matchedScope); + await service_worker_unregister(t, longerMatchedScope); + + const frame = await with_iframe(longerMatchedScope); + const registration = await navigator.serviceWorker.register(url, { scope: matchedScope }); + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + await wait_for_state(t, registration.installing, 'activated'); + + const longerRegistration = await navigator.serviceWorker.register(url, { scope: longerMatchedScope }); + + t.add_cleanup(() => longerRegistration.unregister()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg.scope, + normalizeURL(longerMatchedScope), + 'longer matched registration should be returned' + ); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + null, + 'controller should be null' + ); +}, 'ready after a longer matched registration registered'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const matchedScope = 'resources/blank.html?ready-after-resolve'; + const longerMatchedScope = 'resources/blank.html?ready-after-resolve-longer'; + const registration = await service_worker_unregister_and_register(t, url, matchedScope); + t.add_cleanup(() => registration.unregister()); + + await wait_for_state(t, registration.installing, 'activated'); + + const frame = await with_iframe(longerMatchedScope); + t.add_cleanup(() => frame.remove()); + + const readyReg1 = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg1.scope, + normalizeURL(matchedScope), + 'matched registration should be returned' + ); + + const longerReg = await navigator.serviceWorker.register(url, { scope: longerMatchedScope }); + t.add_cleanup(() => longerReg.unregister()); + + const readyReg2 = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg2.scope, + normalizeURL(matchedScope), + 'ready should only be resolved once' + ); +}, 'access ready after it has been resolved'); + +promise_test(async t => { + const url1 = 'resources/empty-worker.js'; + const url2 = url1 + '?2'; + const matchedScope = 'resources/blank.html?ready-after-unregister'; + const reg1 = await service_worker_unregister_and_register(t, url1, matchedScope); + t.add_cleanup(() => reg1.unregister()); + + await wait_for_state(t, reg1.installing, 'activating'); + + const frame = await with_iframe(matchedScope); + t.add_cleanup(() => frame.remove()); + + await reg1.unregister(); + + // Ready promise should be pending, waiting for a new registration to arrive + const readyPromise = frame.contentWindow.navigator.serviceWorker.ready; + + const reg2 = await navigator.serviceWorker.register(url2, { scope: matchedScope }); + t.add_cleanup(() => reg2.unregister()); + + const readyReg = await readyPromise; + + // Wait for registration update, since it comes from another global, the states are racy. + await wait_for_state(t, reg2.installing || reg2.waiting || reg2.active, 'activated'); + + assert_equals(readyReg.active.scriptURL, reg2.active.scriptURL, 'Resolves with the second registration'); + assert_not_equals(reg1, reg2, 'Registrations should be different'); +}, 'resolve ready after unregistering');