diff --git a/webmessaging/broadcastchannel/detached-iframe.tentative.html b/webmessaging/broadcastchannel/detached-iframe.tentative.html new file mode 100644 index 000000000000000..b9b06c3a46463bf --- /dev/null +++ b/webmessaging/broadcastchannel/detached-iframe.tentative.html @@ -0,0 +1,174 @@ + + + + + + + + + + diff --git a/webmessaging/broadcastchannel/resources/service-worker.js b/webmessaging/broadcastchannel/resources/service-worker.js index fc37aede84586e2..a3d17b9c650adb5 100644 --- a/webmessaging/broadcastchannel/resources/service-worker.js +++ b/webmessaging/broadcastchannel/resources/service-worker.js @@ -9,6 +9,7 @@ bc3.onmessage = e => { }; bc3.postMessage('from worker'); +// Ensure that the worker stays alive for the duration of the test self.addEventListener('install', evt => { evt.waitUntil(promise); }); diff --git a/webmessaging/broadcastchannel/resources/worker.js b/webmessaging/broadcastchannel/resources/worker.js index 9364c602756385c..df23072bc99f95d 100644 --- a/webmessaging/broadcastchannel/resources/worker.js +++ b/webmessaging/broadcastchannel/resources/worker.js @@ -16,6 +16,12 @@ function handler(e, reply) { c = new BroadcastChannel(e.data.channel); let messages = []; c.onmessage = e => { + if (e.data === 'ready') { + // Ignore any 'ready' messages from the other thread since there could + // be some race conditions between this BroadcastChannel instance + // being created / ready to receive messages and the message being sent. + return; + } messages.push(e.data); if (e.data == 'done') reply(messages); diff --git a/webmessaging/broadcastchannel/workers.html b/webmessaging/broadcastchannel/workers.html index 1d05feb7edbf0e9..16fea069309f573 100644 --- a/webmessaging/broadcastchannel/workers.html +++ b/webmessaging/broadcastchannel/workers.html @@ -80,11 +80,14 @@ let worker = new Worker('resources/worker.js'); worker.onmessage = t.step_func(e => { - assert_array_equals(events, ['c1: from worker', 'c2: echo'], + assert_array_equals(events, + ['c1: from worker', 'c2: ready', 'c2: echo'], 'messages in document'); assert_array_equals(e.data, ['done'], 'messages in worker'); t.done(); }); + worker.onmessagerror = + t.unreached_func('Worker\'s onmessageerror handler called'); c.addEventListener('message', e => { if (e.data == 'from worker') { @@ -94,48 +97,30 @@ let c2 = new BroadcastChannel('worker-close'); c2.onmessage = e => { events.push('c2: ' + e.data); - c2.postMessage('done'); + if (e.data === 'ready') { + worker.postMessage({ping: 'echo'}); + } else { + c2.postMessage('done'); + c2.close(); + } }; - worker.postMessage({ping: 'echo'}); + // For some implementations there may be a race condition between + // when the BroadcastChannel instance above is created / ready to + // receive messages and when the worker calls postMessage on it's + // BroadcastChannel instance. To avoid this, confirm that our + // instance can receive a message before indicating to the other + // thread that we are ready. For more details, see: + // https://github.com/whatwg/html/issues/7267 + let c3 = new BroadcastChannel('worker-close'); + c3.postMessage('ready'); + c3.close(); }, 1); } }); worker.postMessage({channel: 'worker-close'}); + t.add_cleanup(() => worker.terminate()); }, 'Closing and re-opening a channel works.'); -async_test(t => { - function workerCode() { - close(); - var bc = new BroadcastChannel('worker-test'); - postMessage(true); - } - - var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"}); - - var w = new Worker(URL.createObjectURL(workerBlob)); - w.onmessage = function(e) { - assert_true(e.data, "BroadcastChannel created on worker shutdown."); - t.done(); - } -}, 'BroadcastChannel created after a worker self.close()'); - -async_test(t => { - function workerCode() { - close(); - var bc = new BroadcastChannel('worker-test-after-close'); - bc.postMessage(true); - } - - var bc = new BroadcastChannel('worker-test-after-close'); - bc.onmessage = function(e) { - assert_true(e.data, "BroadcastChannel created on worker shutdown."); - t.done(); - } - - var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"}); - new Worker(URL.createObjectURL(workerBlob)); -}, 'BroadcastChannel used after a worker self.close()'); - diff --git a/webmessaging/broadcastchannel/workers.tentative.html b/webmessaging/broadcastchannel/workers.tentative.html new file mode 100644 index 000000000000000..e72fa365fd78613 --- /dev/null +++ b/webmessaging/broadcastchannel/workers.tentative.html @@ -0,0 +1,256 @@ + + + + +