Skip to content

Commit

Permalink
Add service worker tests related to resultingClientId
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=255194
rdar://problem/107793594

Reviewed by Alex Christensen.

We were not buffering messages sent to a service worker client before a client (Document or WorkerGlobalScope) was created.
We recently added this ability and it is good to cover this with tests.
We add some additional tests in that area to cover some of the cases like when a message event handler is added late or some edge cases
where we are not yet preserving order of messages.
Follow-up patches should further improve our support in this area.

* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controlled-dedicatedworker-postMessage.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controlled-iframe-postMessage.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controlled-iframe-postMessage.https.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postMessage-client-worker.js: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/controlled-frame-postMessage.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/controlled-worker-late-postMessage.js: Added.
(setTimeout):
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/controlled-worker-postMessage.js: Added.
(setTimeout):

Canonical link: https://commits.webkit.org/262757@main
  • Loading branch information
youennf committed Apr 9, 2023
1 parent 38946d4 commit 4a28e3c
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 0 deletions.
@@ -0,0 +1,5 @@

PASS Register service worker
FAIL Verify dedicated worker gets messages if setting event listener early assert_equals: expected (number) 0 but got (string) "No message received"
PASS Verify dedicated worker does not get all messages if not setting event listener early

@@ -0,0 +1,38 @@
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
</head>
<body>
<script>
promise_test(async (test) => {
const registration = await navigator.serviceWorker.register("postMessage-client-worker.js", { scope : 'resources' });
activeWorker = registration.active;
if (activeWorker)
return;

activeWorker = registration.installing;
await new Promise(resolve => {
activeWorker.addEventListener('statechange', () => {
if (activeWorker.state === "activated")
resolve();
});
});
}, "Register service worker");

promise_test(async (test) => {
const worker = new Worker('resources/controlled-worker-postMessage.js');
const event = await new Promise(resolve => worker.onmessage = resolve);
assert_equals(event.data, 0);
}, "Verify dedicated worker gets messages if setting event listener early");

promise_test(async (test) => {
const worker = new Worker('resources/controlled-worker-late-postMessage.js?repeatMessages');
const event = await new Promise(resolve => worker.onmessage = resolve);
assert_not_equals(event.data, "No message received");
assert_true(event.data > 0);
}, "Verify dedicated worker does not get all messages if not setting event listener early");
</script>
</body>
</html>
@@ -0,0 +1,7 @@


PASS Register service worker
PASS Verify frame gets early messages if setting synchronously message event listener
FAIL Verify frame does not get all messages if not setting event listener early assert_not_equals: got disallowed value 0
FAIL Verify frame does get messages in order assert_true: expected true got false

@@ -0,0 +1,66 @@
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
</head>
<body>
<script>
promise_test(async (test) => {
const registration = await navigator.serviceWorker.register("postMessage-client-worker.js", { scope : 'resources' });
activeWorker = registration.active;
if (activeWorker)
return;

activeWorker = registration.installing;
await new Promise(resolve => {
activeWorker.addEventListener('statechange', () => {
if (activeWorker.state === "activated")
resolve();
});
});
}, "Register service worker");

function with_iframe(url) {
return new Promise(function(resolve) {
var frame = document.createElement('iframe');
frame.className = 'test-iframe';
frame.src = url;
frame.onload = function() { resolve(frame); };
document.body.appendChild(frame);
});
}

promise_test(async (test) => {
const frame = await with_iframe('resources/controlled-frame-postMessage.html');
let counter = 0;
while (counter++ < 100 && frame.contentWindow.messageData == undefined)
await new Promise(resolve => setTimeout(resolve, 50));
assert_equals(frame.contentWindow.messageData, 0);
frame.remove();
}, "Verify frame gets early messages if setting synchronously message event listener");

promise_test(async (test) => {
const frame = await with_iframe('resources/controlled-frame-postMessage.html?repeatMessages');
let counter = 0;
while (counter++ < 100 && frame.contentWindow.messageData == undefined)
await new Promise(resolve => setTimeout(resolve, 50));
assert_not_equals(frame.contentWindow.messageData, 0);
frame.remove();
}, "Verify frame does not get all messages if not setting event listener early");

promise_test(async (test) => {
const frame = await with_iframe('resources/controlled-frame-postMessage.html?repeatMessages&listener');
let counter = 0;
while (counter++ < 100 && frame.contentWindow.messageData.length < 5)
await new Promise(resolve => setTimeout(resolve, 50));

assert_less_than(counter, 100);
data = frame.contentWindow.messageData;
for (let cptr = 1; cptr < data.length; cptr++)
assert_true(data[cptr - 1] < data[cptr]);
frame.remove();
}, "Verify frame does get messages in order");
</script>
</body>
</html>
@@ -0,0 +1,23 @@
async function doTest(e)
{
if (e.resultingClientId) {
const promise = new Promise(async resolve => {
let counter = 0;
const client = await self.clients.get(e.resultingClientId);
if (client)
client.postMessage(counter++);
if (e.request.url.includes("repeatMessage")) {
setInterval(() => {
if (client)
client.postMessage(counter++);
}, 100);
}
setTimeout(() => {
resolve(fetch(e.request));
}, 1000);
});
e.respondWith(promise);
}
}

self.addEventListener("fetch", e => e.waitUntil(doTest(e)));
@@ -0,0 +1,39 @@
<html>
<body>
<script>
var messageData;
function registerMessage()
{
navigator.serviceWorker.onmessage = (e) => {
if (window.messageData === undefined)
window.messageData = e.data;
}
}

function listenToMessages()
{
messageData = [];
setTimeout(() => {
navigator.serviceWorker.addEventListener("message", (e) => {
messageData.push(e.data);
}, { once:true });
}, 500);
setTimeout(() => {
navigator.serviceWorker.onmessage = (e) => {
messageData.push(e.data);
};
}, 1000);
}

if (window.location.search === "?repeatMessages") {
setTimeout(() => {
registerMessage();
}, 500);
} else if (window.location.search.includes("listener")) {
listenToMessages();
} else {
registerMessage();
}
</script>
</body>
</html>
@@ -0,0 +1,6 @@
setTimeout(() => {
navigator.serviceWorker.onmessage = e => self.postMessage(e.data);
}, 500);
setTimeout(() => {
self.postMessage("No message received");
}, 5000);
@@ -0,0 +1,4 @@
navigator.serviceWorker.onmessage = e => self.postMessage(e.data);
setTimeout(() => {
self.postMessage("No message received");
}, 5000);

0 comments on commit 4a28e3c

Please sign in to comment.