| <!DOCTYPE html> |
| <title>Service Worker: Clients.get</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/test-helpers.sub.js"></script> |
| <script> |
| function wait_for_clientId() { |
| return new Promise(function(resolve, reject) { |
| window.onmessage = e => { |
| resolve(e.data.clientId); |
| }; |
| }); |
| } |
| |
| promise_test(async t => { |
| // Register service worker. |
| const scope = 'resources/clients-get-frame.html'; |
| const client_ids = []; |
| const registration = await service_worker_unregister_and_register( |
| t, 'resources/clients-get-worker.js', scope); |
| t.add_cleanup(() => registration.unregister()); |
| await wait_for_state(t, registration.installing, 'activated'); |
| |
| // Prepare for test cases. |
| // Case 1: frame1 which is focused. |
| const frame1 = await with_iframe(scope + '#1'); |
| t.add_cleanup(() => frame1.remove()); |
| frame1.focus(); |
| client_ids.push(await wait_for_clientId()); |
| // Case 2: frame2 which is not focused. |
| const frame2 = await with_iframe(scope + '#2'); |
| t.add_cleanup(() => frame2.remove()); |
| client_ids.push(await wait_for_clientId()); |
| // Case 3: invalid id. |
| client_ids.push('invalid-id'); |
| |
| // Call clients.get() for each id on the service worker. |
| const message_event = await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = resolve; |
| registration.active.postMessage({clientIds: client_ids}); |
| }); |
| |
| const expected = [ |
| // visibilityState, focused, url, type, frameType |
| ['visible', true, normalizeURL(scope) + '#1', 'window', 'nested'], |
| ['visible', false, normalizeURL(scope) + '#2', 'window', 'nested'], |
| undefined |
| ]; |
| assert_equals(message_event.data.length, 3); |
| assert_array_equals(message_event.data[0], expected[0]); |
| assert_array_equals(message_event.data[1], expected[1]); |
| assert_equals(message_event.data[2], expected[2]); |
| }, 'Test Clients.get()'); |
| |
| promise_test(async t => { |
| // Register service worker. |
| const scope = 'resources/simple.html'; |
| const registration = await service_worker_unregister_and_register( |
| t, 'resources/clients-get-resultingClientId-worker.js', scope) |
| t.add_cleanup(() => registration.unregister()); |
| await wait_for_state(t, registration.installing, 'activated'); |
| const worker = registration.active; |
| |
| // Load frame within the scope. |
| const frame = await with_iframe(scope); |
| t.add_cleanup(() => frame.remove()); |
| frame.focus(); |
| |
| // Get resulting client id. |
| const resultingClientId = await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { |
| if (e.data.msg == 'getResultingClientId') { |
| resolve(e.data.resultingClientId); |
| } |
| }; |
| worker.postMessage({msg: 'getResultingClientId'}); |
| }); |
| |
| // Query service worker for clients.get(resultingClientId). |
| const isResultingClientUndefined = await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { |
| if (e.data.msg == 'getIsResultingClientUndefined') { |
| resolve(e.data.isResultingClientUndefined); |
| } |
| }; |
| worker.postMessage({msg: 'getIsResultingClientUndefined', |
| resultingClientId}); |
| }); |
| |
| assert_false( |
| isResultingClientUndefined, |
| 'Clients.get(FetchEvent.resultingClientId) resolved with a Client'); |
| }, 'Test successful Clients.get(FetchEvent.resultingClientId)'); |
| |
| promise_test(async t => { |
| // Register service worker. |
| const scope = 'resources/simple.html?fail'; |
| const registration = await service_worker_unregister_and_register( |
| t, 'resources/clients-get-resultingClientId-worker.js', scope); |
| t.add_cleanup(() => registration.unregister()); |
| await wait_for_state(t, registration.installing, 'activated'); |
| |
| // Load frame, and destroy it while loading. |
| const worker = registration.active; |
| let frame = document.createElement('iframe'); |
| frame.src = scope; |
| t.add_cleanup(() => { |
| if (frame) { |
| frame.remove(); |
| } |
| }); |
| |
| await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { |
| // The service worker posts a message to remove the iframe during fetch |
| // event. |
| if (e.data.msg == 'destroyResultingClient') { |
| frame.remove(); |
| frame = null; |
| worker.postMessage({msg: 'resultingClientDestroyed'}); |
| resolve(); |
| } |
| }; |
| document.body.appendChild(frame); |
| }); |
| |
| resultingDestroyedClientId = await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { |
| // The worker sends a message back when it receives the message |
| // 'resultingClientDestroyed' with the resultingClientId. |
| if (e.data.msg == 'resultingClientDestroyedAck') { |
| assert_equals(frame, null, 'Frame should be destroyed at this point.'); |
| resolve(e.data.resultingDestroyedClientId); |
| } |
| }; |
| }); |
| |
| // Query service worker for clients.get(resultingDestroyedClientId). |
| const isResultingClientUndefined = await new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { |
| if (e.data.msg == 'getIsResultingClientUndefined') { |
| resolve(e.data.isResultingClientUndefined); |
| } |
| }; |
| worker.postMessage({msg: 'getIsResultingClientUndefined', |
| resultingClientId: resultingDestroyedClientId }); |
| }); |
| |
| assert_true( |
| isResultingClientUndefined, |
| 'Clients.get(FetchEvent.resultingClientId) resolved with `undefined`'); |
| }, 'Test unsuccessful Clients.get(FetchEvent.resultingClientId)'); |
| |
| </script> |