174 lines
5.6 KiB
HTML
174 lines
5.6 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset=utf-8>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/common/get-host-info.sub.js"></script>
|
|
<!-- Pull in the with_iframe helper function from the service worker tests -->
|
|
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
|
<body>
|
|
<script>
|
|
const TEST_IFRAME_CLASS_NAME = 'test-iframe';
|
|
const events = [];
|
|
var bc1;
|
|
const DONE_MSG = 'done';
|
|
|
|
function DetachedIframeTestCheckForOneMessage(t) {
|
|
return new Promise((resolve) => {
|
|
bc1.onmessage = t.step_func(e => {
|
|
events.push(e);
|
|
if (e.data == DONE_MSG) {
|
|
assert_equals(events.length, 1);
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
const IframeAction = {
|
|
REMOVE_BEFORE_CREATION: 'remove-before-creation',
|
|
REMOVE_AFTER_CREATION: 'remove-after-creation',
|
|
};
|
|
|
|
async function doMessageSentTest(t, channelName, action) {
|
|
await with_iframe('about:blank');
|
|
const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
|
|
const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
|
|
|
|
if (action === IframeAction.REMOVE_BEFORE_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
events.length = 0;
|
|
|
|
bc1 = new BroadcastChannel(channelName);
|
|
const bc2 = new BroadcastChannel(channelName);
|
|
const iframe_bc = new iframe_BroadcastChannel(channelName);
|
|
|
|
if (action === IframeAction.REMOVE_AFTER_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
const testResultsPromise = DetachedIframeTestCheckForOneMessage(t);
|
|
|
|
iframe_bc.postMessage('test');
|
|
bc2.postMessage(DONE_MSG);
|
|
|
|
bc2.close();
|
|
iframe_bc.close();
|
|
t.add_cleanup(() => bc1.close());
|
|
|
|
return testResultsPromise;
|
|
}
|
|
|
|
promise_test(async t => {
|
|
return doMessageSentTest(
|
|
t, 'postMessage-from-detached-iframe-pre',
|
|
IframeAction.REMOVE_AFTER_CREATION);
|
|
}, 'BroadcastChannel messages from detached iframe to parent should be ignored (BC created before detaching)');
|
|
|
|
promise_test(async t => {
|
|
return doMessageSentTest(
|
|
t, 'postMessage-from-detached-iframe-post',
|
|
IframeAction.REMOVE_BEFORE_CREATION);
|
|
}, 'BroadcastChannel messages from detached iframe to parent should be ignored (BC created after detaching)');
|
|
|
|
|
|
async function doMessageReceivedTest(t, channelName, action) {
|
|
await with_iframe('about:blank');
|
|
const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
|
|
const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
|
|
|
|
if (action === IframeAction.REMOVE_BEFORE_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
events.length = 0;
|
|
|
|
// `iframe_bc` must be created first so that it receives messages before
|
|
// `bc1`. That way we can tell whether `iframe_bc` received a message by
|
|
// inspecting `events` in the `bc1` message handler.
|
|
const iframe_bc = new iframe_BroadcastChannel(channelName);
|
|
iframe_bc.onmessage = e => {
|
|
events.push(e)
|
|
};
|
|
bc1 = new BroadcastChannel(channelName);
|
|
const bc2 = new BroadcastChannel(channelName);
|
|
|
|
if (action === IframeAction.REMOVE_AFTER_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
const testResultsPromise = DetachedIframeTestCheckForOneMessage(t);
|
|
bc2.postMessage(DONE_MSG);
|
|
|
|
bc2.close();
|
|
iframe_bc.close();
|
|
t.add_cleanup(() => bc1.close());
|
|
}
|
|
|
|
promise_test(async t => {
|
|
return doMessageReceivedTest(
|
|
t, 'postMessage-to-detached-iframe-pre',
|
|
IframeAction.REMOVE_AFTER_CREATION);
|
|
}, 'BroadcastChannel messages from parent to detached iframe should be ignored (BC created before detaching)');
|
|
|
|
promise_test(async t => {
|
|
return doMessageReceivedTest(
|
|
t, 'postMessage-to-detached-iframe-post',
|
|
IframeAction.REMOVE_BEFORE_CREATION);
|
|
}, 'BroadcastChannel messages from parent to detached iframe should be ignored (BC created after detaching)');
|
|
|
|
|
|
async function doMessageSendReceiveTest(t, channelName, action) {
|
|
await with_iframe('about:blank');
|
|
const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
|
|
const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
|
|
|
|
if (action === IframeAction.REMOVE_BEFORE_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
const iframe_bc1 = new iframe_BroadcastChannel(channelName);
|
|
const iframe_bc2 = new iframe_BroadcastChannel(channelName);
|
|
iframe_bc1.onmessage = t.unreached_func(
|
|
'Detached iframe BroadcastChannel instance received message unexpectedly');
|
|
|
|
if (action === IframeAction.REMOVE_AFTER_CREATION) {
|
|
iframe.remove();
|
|
}
|
|
|
|
iframe_bc2.postMessage(DONE_MSG);
|
|
|
|
iframe_bc2.close();
|
|
t.add_cleanup(() => iframe_bc1.close());
|
|
|
|
// To avoid calling t.step_timeout here, instead just create two new
|
|
// BroadcastChannel instances and complete the test when a message is passed
|
|
// between them. Per the spec, all "BroadcastChannel objects whose relevant
|
|
// agents are the same" must have messages delivered to them in creation
|
|
// order, so if we get this message then it's safe to assume the earlier
|
|
// message would have been delivered if it was going to be.
|
|
const bc1 = new BroadcastChannel(channelName);
|
|
const bc2 = new BroadcastChannel(channelName);
|
|
return new Promise((resolve) => {
|
|
bc1.onmessage = t.step_func(e => {
|
|
resolve();
|
|
});
|
|
bc2.postMessage(DONE_MSG);
|
|
});
|
|
}
|
|
|
|
promise_test(async t => {
|
|
return doMessageSendReceiveTest(
|
|
t, 'postMessage-within-detached-iframe-pre',
|
|
IframeAction.REMOVE_AFTER_CREATION);
|
|
}, 'BroadcastChannel messages within detached iframe should be ignored (BCs created before detaching)');
|
|
|
|
promise_test(async t => {
|
|
return doMessageSendReceiveTest(
|
|
t, 'postMessage-within-detached-iframe-post',
|
|
IframeAction.REMOVE_BEFORE_CREATION);
|
|
}, 'BroadcastChannel messages within detached iframe should be ignored (BCs created after detaching)');
|
|
|
|
</script>
|
|
</body>
|