Skip to content

Commit c59dd98

Browse files
bnoordhuisbengl
authored andcommitted
test: run webmessaging/broadcastchannel WPT
Refs: #38803 PR-URL: #41962 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Mestery <[email protected]>
1 parent 53e2e8c commit c59dd98

20 files changed

+1353
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
async_test(t => {
2+
let c1 = new BroadcastChannel('eventType');
3+
let c2 = new BroadcastChannel('eventType');
4+
5+
c2.onmessage = t.step_func(e => {
6+
assert_true(e instanceof MessageEvent);
7+
assert_equals(e.target, c2);
8+
assert_equals(e.type, 'message');
9+
assert_equals(e.origin, location.origin, 'origin');
10+
assert_equals(e.data, 'hello world');
11+
assert_equals(e.source, null, 'source');
12+
t.done();
13+
});
14+
c1.postMessage('hello world');
15+
}, 'postMessage results in correct event');
16+
17+
async_test(t => {
18+
let c1 = new BroadcastChannel('order');
19+
let c2 = new BroadcastChannel('order');
20+
let c3 = new BroadcastChannel('order');
21+
22+
let events = [];
23+
let doneCount = 0;
24+
let handler = t.step_func(e => {
25+
events.push(e);
26+
if (e.data == 'done') {
27+
doneCount++;
28+
if (doneCount == 2) {
29+
assert_equals(events.length, 6);
30+
assert_equals(events[0].target, c2, 'target for event 0');
31+
assert_equals(events[0].data, 'from c1');
32+
assert_equals(events[1].target, c3, 'target for event 1');
33+
assert_equals(events[1].data, 'from c1');
34+
assert_equals(events[2].target, c1, 'target for event 2');
35+
assert_equals(events[2].data, 'from c3');
36+
assert_equals(events[3].target, c2, 'target for event 3');
37+
assert_equals(events[3].data, 'from c3');
38+
assert_equals(events[4].target, c1, 'target for event 4');
39+
assert_equals(events[4].data, 'done');
40+
assert_equals(events[5].target, c3, 'target for event 5');
41+
assert_equals(events[5].data, 'done');
42+
t.done();
43+
}
44+
}
45+
});
46+
c1.onmessage = handler;
47+
c2.onmessage = handler;
48+
c3.onmessage = handler;
49+
50+
c1.postMessage('from c1');
51+
c3.postMessage('from c3');
52+
c2.postMessage('done');
53+
}, 'messages are delivered in port creation order');
54+
55+
async_test(t => {
56+
let c1 = new BroadcastChannel('closed');
57+
let c2 = new BroadcastChannel('closed');
58+
let c3 = new BroadcastChannel('closed');
59+
60+
c2.onmessage = t.unreached_func();
61+
c2.close();
62+
c3.onmessage = t.step_func(() => t.done());
63+
c1.postMessage('test');
64+
}, 'messages aren\'t delivered to a closed port');
65+
66+
async_test(t => {
67+
let c1 = new BroadcastChannel('closed');
68+
let c2 = new BroadcastChannel('closed');
69+
let c3 = new BroadcastChannel('closed');
70+
71+
c2.onmessage = t.unreached_func();
72+
c3.onmessage = t.step_func(() => t.done());
73+
c1.postMessage('test');
74+
c2.close();
75+
}, 'messages aren\'t delivered to a port closed after calling postMessage.');
76+
77+
async_test(t => {
78+
let c1 = new BroadcastChannel('create-in-onmessage');
79+
let c2 = new BroadcastChannel('create-in-onmessage');
80+
81+
c2.onmessage = t.step_func(e => {
82+
assert_equals(e.data, 'first');
83+
c2.close();
84+
let c3 = new BroadcastChannel('create-in-onmessage');
85+
c3.onmessage = t.step_func(event => {
86+
assert_equals(event.data, 'done');
87+
t.done();
88+
});
89+
c1.postMessage('done');
90+
});
91+
c1.postMessage('first');
92+
c2.postMessage('second');
93+
}, 'closing and creating channels during message delivery works correctly');
94+
95+
async_test(t => {
96+
let c1 = new BroadcastChannel('close-in-onmessage');
97+
let c2 = new BroadcastChannel('close-in-onmessage');
98+
let c3 = new BroadcastChannel('close-in-onmessage');
99+
let events = [];
100+
c1.onmessage = e => events.push('c1: ' + e.data);
101+
c2.onmessage = e => events.push('c2: ' + e.data);
102+
c3.onmessage = e => events.push('c3: ' + e.data);
103+
104+
// c2 closes itself when it receives the first message
105+
c2.addEventListener('message', e => {
106+
c2.close();
107+
});
108+
109+
c3.addEventListener('message', t.step_func(e => {
110+
if (e.data == 'done') {
111+
assert_array_equals(events, [
112+
'c2: first',
113+
'c3: first',
114+
'c3: done']);
115+
t.done();
116+
}
117+
}));
118+
c1.postMessage('first');
119+
c1.postMessage('done');
120+
}, 'Closing a channel in onmessage prevents already queued tasks from firing onmessage events');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<!DOCTYPE html>
2+
<meta charset=utf-8>
3+
<script src="/resources/testharness.js"></script>
4+
<script src="/resources/testharnessreport.js"></script>
5+
<script>
6+
async_test(t => {
7+
const c1 = new BroadcastChannel('blob');
8+
const c2 = new BroadcastChannel('blob');
9+
const c3 = new BroadcastChannel('blob');
10+
11+
let readCount = 0;
12+
c2.onmessage = t.step_func(e => {
13+
// check blob
14+
assert_true('blob' in e.data);
15+
assert_true(e.data.blob instanceof Blob);
16+
assert_equals(e.data.blob.size, 6);
17+
const reader = new FileReader();
18+
reader.onerror = t.unreached_func();
19+
reader.onload = t.step_func(() => {
20+
assert_equals(reader.result, 'foobar');
21+
if (++readCount == 2)
22+
t.done();
23+
});
24+
reader.readAsText(e.data.blob);
25+
});
26+
c3.onmessage = c2.onmessage;
27+
(() => {
28+
c1.postMessage({blob: new Blob(['foo', 'bar'])});
29+
})();
30+
// TODO(https://github.com/web-platform-tests/wpt/issues/7899): Change to
31+
// some sort of cross-browser GC trigger.
32+
if (self.gc) self.gc();
33+
}, 'Blobs work on BroadcastChannel');
34+
35+
async_test(t => {
36+
const c1 = new BroadcastChannel('blobworker');
37+
const c2 = new BroadcastChannel('blobworker');
38+
const events = [];
39+
40+
const verifyEvents = function() {
41+
assert_equals(events.length, 5);
42+
assert_equals(events[0], 'from worker');
43+
assert_equals(events[1], 'from worker');
44+
assert_true(events[2].blob instanceof Blob);
45+
assert_equals(events[2].blob.size, 11);
46+
assert_true(events[3].blob instanceof Blob);
47+
assert_equals(events[3].blob.size, 11);
48+
assert_equals(events[4], 'done');
49+
const reader = new FileReader();
50+
reader.onerror = t.unreached_func();
51+
reader.onload = t.step_func(() => {
52+
assert_equals(reader.result, 'hello-world');
53+
t.done();
54+
});
55+
reader.readAsText(events[3].blob);
56+
};
57+
58+
let receivedDone = false;
59+
let receivedWorkerDone = false;
60+
61+
c1.onmessage = e => events.push(e.data);
62+
c2.onmessage = e => events.push(e.data);
63+
c2.addEventListener('message', t.step_func(e => {
64+
if (e.data.blob)
65+
c1.postMessage('done');
66+
if (e.data === 'done')
67+
receivedDone = true;
68+
if (receivedDone && receivedWorkerDone)
69+
verifyEvents();
70+
}));
71+
72+
const worker = new Worker('resources/worker.js');
73+
worker.onmessage = t.step_func(e => {
74+
receivedWorkerDone = true;
75+
if (receivedDone && receivedWorkerDone)
76+
verifyEvents();
77+
});
78+
worker.postMessage({channel: 'blobworker'});
79+
worker.postMessage({blob: ['hello-world']});
80+
81+
}, 'Blobs work with workers on BroadcastChannel');
82+
83+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<meta charset=utf-8>
3+
<script src="/resources/testharness.js"></script>
4+
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/common/get-host-info.sub.js"></script>
6+
<!-- Pull in the with_iframe helper function from the service worker tests -->
7+
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
8+
<body>
9+
<script>
10+
11+
const events = [];
12+
13+
function testCompletion(t) {
14+
return new Promise((resolve) => {
15+
window.addEventListener("message", t.step_func(e => {
16+
if (e.data == 'done') {
17+
assert_equals(events.length, 0);
18+
resolve();
19+
}
20+
}));
21+
});
22+
}
23+
24+
promise_test(async t => {
25+
26+
const bc0 = new BroadcastChannel('no-cross-origin-messages');
27+
bc0.onmessage = e => {window.events.push(e);};
28+
29+
const testResults = testCompletion(t);
30+
const url = get_host_info().HTTPS_NOTSAMESITE_ORIGIN +
31+
'/webmessaging/broadcastchannel/resources/cross-origin.html';
32+
await with_iframe(url);
33+
34+
return testResults;
35+
}, "Messages aren't delivered across origins");
36+
37+
</script>
38+
</body>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!DOCTYPE html>
2+
<meta charset=utf-8>
3+
<script src="/resources/testharness.js"></script>
4+
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/common/get-host-info.sub.js"></script>
6+
<script src="/common/utils.js"></script>
7+
<script src="/common/dispatcher/dispatcher.js"></script>
8+
<!-- Pull in executor_path needed by newPopup / newIframe -->
9+
<script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script>
10+
<!-- Pull in newPopup / newIframe -->
11+
<script src="/html/cross-origin-embedder-policy/anonymous-iframe/resources/common.js"></script>
12+
<body>
13+
<script>
14+
15+
const emit_script = (channel_name, message, done_queue_name) => `
16+
const bc = new BroadcastChannel("${channel_name}");
17+
bc.postMessage("${message}");
18+
send("${done_queue_name}", "done");
19+
`;
20+
21+
promise_test(async t => {
22+
const origin = get_host_info().HTTPS_ORIGIN;
23+
const not_same_site_origin = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;
24+
const response_queue_uuid = token();
25+
26+
const popup_init_script = `
27+
const importScript = ${importScript};
28+
await importScript("/html/cross-origin-embedder-policy/credentialless" +
29+
"/resources/common.js");
30+
await importScript("/html/cross-origin-embedder-policy/anonymous-iframe" +
31+
"/resources/common.js");
32+
await importScript("/common/utils.js");
33+
send("${response_queue_uuid}", newIframe("${origin}"));
34+
`;
35+
36+
// Create a same-origin iframe in a cross-site popup.
37+
const not_same_site_popup_uuid = newPopup(t, not_same_site_origin);
38+
send(not_same_site_popup_uuid, popup_init_script);
39+
const iframe_1_uuid = await receive(response_queue_uuid);
40+
41+
// Create a same-origin iframe in a same-site popup.
42+
const same_origin_popup_uuid = newPopup(t, origin);
43+
send(same_origin_popup_uuid, popup_init_script);
44+
const iframe_2_uuid = await receive(response_queue_uuid);
45+
46+
const channel_name = token();
47+
const bc = new BroadcastChannel(channel_name);
48+
bc.onmessage = t.step_func(e => {
49+
assert_equals(e.data, "msg from iframe2");
50+
t.done();
51+
});
52+
53+
// Instruct the not-same-top-level-site iframe to send a message on the BC
54+
// channel we are listening on. This message should not be received since
55+
// the iframe should be in a different partition.
56+
send(iframe_1_uuid,
57+
emit_script(channel_name, "msg from iframe1", response_queue_uuid));
58+
assert_equals(await receive(response_queue_uuid), "done");
59+
60+
// Now instruct the same-top-level-site iframe to send a BC message. By
61+
// the time we send the script to execute, have it send the BC message,
62+
// and then receive the BC message in our BC instance, it should be
63+
// reasonable to assume that the message from the first iframe would have
64+
// been delivered if it was going to be.
65+
send(iframe_2_uuid,
66+
emit_script(channel_name, "msg from iframe2", response_queue_uuid));
67+
assert_equals(await receive(response_queue_uuid), "done");
68+
69+
}, "BroadcastChannel messages aren't received from a cross-partition iframe");
70+
71+
</script>
72+
</body>

0 commit comments

Comments
 (0)