diff options
Diffstat (limited to '')
-rw-r--r-- | testing/web-platform/tests/webmessaging/broadcastchannel/detached-iframe.html | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webmessaging/broadcastchannel/detached-iframe.html b/testing/web-platform/tests/webmessaging/broadcastchannel/detached-iframe.html new file mode 100644 index 0000000000..b9b06c3a46 --- /dev/null +++ b/testing/web-platform/tests/webmessaging/broadcastchannel/detached-iframe.html @@ -0,0 +1,174 @@ +<!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> |