Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /service-workers/service-worker/postmessage.https.html - WPT Dashboard Interop Dashboard
<!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>