| <!DOCTYPE html> |
| <title>Service Worker: postMessage</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/test-helpers.sub.js"></script> |
| <script> |
| promise_test(t => { |
| var script = 'resources/postmessage-worker.js'; |
| var scope = 'resources/blank.html'; |
| var registration; |
| var worker; |
| var port; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| t.add_cleanup(() => r.unregister()); |
| registration = r; |
| worker = registration.installing; |
| |
| var messageChannel = new MessageChannel(); |
| port = messageChannel.port1; |
| return new Promise(resolve => { |
| port.onmessage = resolve; |
| worker.postMessage({port: messageChannel.port2}, |
| [messageChannel.port2]); |
| worker.postMessage({value: 1}); |
| worker.postMessage({value: 2}); |
| worker.postMessage({done: true}); |
| }); |
| }) |
| .then(e => { |
| assert_equals(e.data, 'Acking value: 1'); |
| return new Promise(resolve => { port.onmessage = resolve; }); |
| }) |
| .then(e => { |
| assert_equals(e.data, 'Acking value: 2'); |
| return new Promise(resolve => { port.onmessage = resolve; }); |
| }) |
| .then(e => { |
| assert_equals(e.data, 'quit'); |
| return registration.unregister(scope); |
| }); |
| }, 'postMessage to a ServiceWorker (and back via MessagePort)'); |
| |
| promise_test(t => { |
| var script = 'resources/postmessage-transferables-worker.js'; |
| var scope = 'resources/blank.html'; |
| var sw = navigator.serviceWorker; |
| |
| var message = 'Hello, world!'; |
| var text_encoder = new TextEncoder; |
| var text_decoder = new TextDecoder; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| t.add_cleanup(() => r.unregister()); |
| |
| var ab = text_encoder.encode(message); |
| assert_equals(ab.byteLength, message.length); |
| r.installing.postMessage(ab, [ab.buffer]); |
| assert_equals(text_decoder.decode(ab), ''); |
| assert_equals(ab.byteLength, 0); |
| |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the transferred array buffer. |
| assert_equals(e.data.content, message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the array buffer sent back from |
| // ServiceWorker via Client.postMessage. |
| assert_equals(text_decoder.decode(e.data), message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify that the array buffer on ServiceWorker is neutered. |
| assert_equals(e.data.content, ''); |
| assert_equals(e.data.byteLength, 0); |
| }); |
| }, 'postMessage a transferable ArrayBuffer between ServiceWorker and Client'); |
| |
| promise_test(t => { |
| var script = 'resources/postmessage-transferables-worker.js'; |
| var scope = 'resources/blank.html'; |
| var message = 'Hello, world!'; |
| var text_encoder = new TextEncoder; |
| var text_decoder = new TextDecoder; |
| var port; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| t.add_cleanup(() => r.unregister()); |
| |
| var channel = new MessageChannel; |
| port = channel.port1; |
| r.installing.postMessage(undefined, [channel.port2]); |
| |
| var ab = text_encoder.encode(message); |
| assert_equals(ab.byteLength, message.length); |
| port.postMessage(ab, [ab.buffer]); |
| assert_equals(text_decoder.decode(ab), ''); |
| assert_equals(ab.byteLength, 0); |
| |
| return new Promise(resolve => { port.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the transferred array buffer. |
| assert_equals(e.data.content, message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { port.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the array buffer sent back from |
| // ServiceWorker via Client.postMessage. |
| assert_equals(text_decoder.decode(e.data), message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { port.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify that the array buffer on ServiceWorker is neutered. |
| assert_equals(e.data.content, ''); |
| assert_equals(e.data.byteLength, 0); |
| }); |
| }, 'postMessage a transferable ArrayBuffer between ServiceWorker and Client' + |
| ' over MessagePort'); |
| |
| promise_test(t => { |
| var script = 'resources/postmessage-dictionary-transferables-worker.js'; |
| var scope = 'resources/blank.html'; |
| var sw = navigator.serviceWorker; |
| |
| var message = 'Hello, world!'; |
| var text_encoder = new TextEncoder; |
| var text_decoder = new TextDecoder; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| t.add_cleanup(() => r.unregister()); |
| |
| var ab = text_encoder.encode(message); |
| assert_equals(ab.byteLength, message.length); |
| r.installing.postMessage(ab, {transfer: [ab.buffer]}); |
| assert_equals(text_decoder.decode(ab), ''); |
| assert_equals(ab.byteLength, 0); |
| |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the transferred array buffer. |
| assert_equals(e.data.content, message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify the integrity of the array buffer sent back from |
| // ServiceWorker via Client.postMessage. |
| assert_equals(text_decoder.decode(e.data), message); |
| assert_equals(e.data.byteLength, message.length); |
| return new Promise(resolve => { sw.onmessage = resolve; }); |
| }) |
| .then(e => { |
| // Verify that the array buffer on ServiceWorker is neutered. |
| assert_equals(e.data.content, ''); |
| assert_equals(e.data.byteLength, 0); |
| }); |
| }, 'postMessage with dictionary a transferable ArrayBuffer between ServiceWorker and Client'); |
| |
| promise_test(async t => { |
| const firstScript = 'resources/postmessage-echo-worker.js?one'; |
| const secondScript = 'resources/postmessage-echo-worker.js?two'; |
| const scope = 'resources/'; |
| |
| const registration = await service_worker_unregister_and_register(t, firstScript, scope); |
| t.add_cleanup(() => registration.unregister()); |
| const firstWorker = registration.installing; |
| |
| const messagePromise = new Promise(resolve => { |
| navigator.serviceWorker.addEventListener('message', (event) => { |
| resolve(event.data); |
| }, {once: true}); |
| }); |
| |
| await wait_for_state(t, firstWorker, 'activated'); |
| await navigator.serviceWorker.register(secondScript, {scope}); |
| const secondWorker = registration.installing; |
| await wait_for_state(t, firstWorker, 'redundant'); |
| |
| // postMessage() to a redundant worker should be dropped silently. |
| // Historically, this threw an exception. |
| firstWorker.postMessage('firstWorker'); |
| |
| // To test somewhat that it was not received, send a message to another |
| // worker and check that we get a reply for that one. |
| secondWorker.postMessage('secondWorker'); |
| const data = await messagePromise; |
| assert_equals(data, 'secondWorker'); |
| }, 'postMessage to a redundant worker'); |
| </script> |