| <!DOCTYPE html> |
| <title>Service Worker: getRegistrations()</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/test-helpers.sub.js"></script> |
| <script src="/common/get-host-info.sub.js"></script> |
| <script> |
| // Purge the existing registrations for the origin. |
| // getRegistrations() is used in order to avoid adding additional complexity |
| // e.g. adding an internal function. |
| promise_test(async () => { |
| const registrations = await navigator.serviceWorker.getRegistrations(); |
| await Promise.all(registrations.map(r => r.unregister())); |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals( |
| value, [], |
| 'getRegistrations should resolve with an empty array.'); |
| }, 'registrations are not returned following unregister'); |
| |
| promise_test(async t => { |
| const scope = 'resources/scope/getregistrations/normal'; |
| const script = 'resources/empty-worker.js'; |
| const registrations = [ |
| await service_worker_unregister_and_register(t, script, scope)]; |
| t.add_cleanup(() => registrations[0].unregister()); |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals(value, registrations, |
| 'getRegistrations should resolve with an array of registrations'); |
| }, 'Register then getRegistrations'); |
| |
| promise_test(async t => { |
| const scope1 = 'resources/scope/getregistrations/scope1'; |
| const scope2 = 'resources/scope/getregistrations/scope2'; |
| const scope3 = 'resources/scope/getregistrations/scope12'; |
| |
| const script = 'resources/empty-worker.js'; |
| t.add_cleanup(() => service_worker_unregister(t, scope1)); |
| t.add_cleanup(() => service_worker_unregister(t, scope2)); |
| t.add_cleanup(() => service_worker_unregister(t, scope3)); |
| |
| const registrations = [ |
| await service_worker_unregister_and_register(t, script, scope1), |
| await service_worker_unregister_and_register(t, script, scope2), |
| await service_worker_unregister_and_register(t, script, scope3), |
| ]; |
| |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals(value, registrations); |
| }, 'Register multiple times then getRegistrations'); |
| |
| promise_test(async t => { |
| const scope = 'resources/scope/getregistrations/register-unregister'; |
| const script = 'resources/empty-worker.js'; |
| const registration = await service_worker_unregister_and_register(t, script, scope); |
| await registration.unregister(); |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals( |
| value, [], 'getRegistrations should resolve with an empty array.'); |
| }, 'Register then Unregister then getRegistrations'); |
| |
| promise_test(async t => { |
| const scope = 'resources/scope/getregistrations/register-unregister-controlled'; |
| const script = 'resources/empty-worker.js'; |
| const registration = await service_worker_unregister_and_register(t, script, scope); |
| await wait_for_state(t, registration.installing, 'activated'); |
| |
| // Create a frame controlled by the service worker and unregister the |
| // worker. |
| const frame = await with_iframe(scope); |
| t.add_cleanup(() => frame.remove()); |
| await registration.unregister(); |
| |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals( |
| value, [], |
| 'getRegistrations should resolve with an empty array.'); |
| assert_equals(registration.installing, null); |
| assert_equals(registration.waiting, null); |
| assert_equals(registration.active.state, 'activated'); |
| }, 'Register then Unregister with controlled frame then getRegistrations'); |
| |
| promise_test(async t => { |
| const host_info = get_host_info(); |
| // Rewrite the url to point to remote origin. |
| const frame_same_origin_url = new URL("resources/frame-for-getregistrations.html", window.location); |
| const frame_url = host_info['HTTPS_REMOTE_ORIGIN'] + frame_same_origin_url.pathname; |
| const scope = 'resources/scope-for-getregistrations'; |
| const script = 'resources/empty-worker.js'; |
| |
| // Loads an iframe and waits for 'ready' message from it to resolve promise. |
| // Caller is responsible for removing frame. |
| function with_iframe_ready(url) { |
| return new Promise(resolve => { |
| const frame = document.createElement('iframe'); |
| frame.src = url; |
| window.addEventListener('message', function onMessage(e) { |
| window.removeEventListener('message', onMessage); |
| if (e.data == 'ready') { |
| resolve(frame); |
| } |
| }); |
| document.body.appendChild(frame); |
| }); |
| } |
| |
| // We need this special frame loading function because the frame is going |
| // to register it's own service worker and there is the possibility that that |
| // register() finishes after the register() for the same domain later in the |
| // test. So we have to wait until the cross origin register() is done, and not |
| // just until the frame loads. |
| const frame = await with_iframe_ready(frame_url); |
| t.add_cleanup(async () => { |
| // Wait until the cross-origin worker is unregistered. |
| let resolve; |
| const channel = new MessageChannel(); |
| channel.port1.onmessage = e => { |
| if (e.data == 'unregistered') |
| resolve(); |
| }; |
| frame.contentWindow.postMessage('unregister', '*', [channel.port2]); |
| await new Promise(r => { resolve = r; }); |
| |
| frame.remove(); |
| }); |
| |
| const registrations = [ |
| await service_worker_unregister_and_register(t, script, scope)]; |
| t.add_cleanup(() => registrations[0].unregister()); |
| const value = await navigator.serviceWorker.getRegistrations(); |
| assert_array_equals( |
| value, registrations, |
| 'getRegistrations should only return same origin registrations.'); |
| }, 'getRegistrations promise resolves only with same origin registrations.'); |
| </script> |