Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client.postMessage to unloaded Client #10153

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!doctype html>
<title>Service Worker: postMessage to unloaded Client</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
promise_test(t => {
const url = 'resources/blank.html';
const script = 'resources/postmessage-to-unloaded-client-worker.js';
const scope = 'resources/';
let registration;
let unload_client;
return service_worker_unregister_and_register(t, script, scope)
.then(r => {
t.add_cleanup(() => { r.unregister(); });
registration = r;
return wait_for_state(t, r.installing, 'activated');
})
.then(() => {
return with_iframe(url);
})
.then(f => {
unload_client = f;
f.contentWindow.navigator.serviceWorker.onmessage = t.step_func(() => {
throw new Error('The client should have been unloaded.');
});
const promise =
new Promise(resolve => navigator.serviceWorker.onmessage = resolve);
registration.active.postMessage('syn');
return promise;
})
.then(e => {
if (e.data == 'ack') {
// Unload the client the service worker will post a message to.
unload_client.remove();
const promise = new Promise(
resolve => navigator.serviceWorker.onmessage = resolve);
registration.active.postMessage('post-back-to-unloaded-client');
t.step_timeout(() => {
throw new Error('postMessage to unloaded Client did not throw.');
}, 2000);
return promise;
}
})
.then(e => {
assert_equals(
e.data,
'InvalidStateError',
'postMessage to unloaded Client must throw an "InvalidStateError" ' +
'DOMException.');
})
.catch(unreached_rejection(t));
}, 'postMessage from service worker to unloaded Client.');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
let main_client, unload_client;
let resolve;

self.addEventListener('message', e => {
if (e.data == 'syn') {
clients.matchAll({includeUncontrolled: true}).then(clients => {
clients.forEach(client => {
if (client.url.indexOf('postmessage-to-unloaded-client') > -1) {
main_client = client;
} else if (client.url.indexOf('blank') > -1) {
unload_client = client;
}
});
e.waitUntil(new Promise(r => {
resolve = r;
main_client.postMessage('ack');
}));
});
} else if (e.data == 'post-back-to-unloaded-client') {
try {
// Must throw an "InvalidStateError" DOMException.
unload_client.postMessage('never-get-this');
} catch(e) {
main_client.postMessage(e.name);
}
resolve();
}
});