11cb0ef41Sopenharmony_ci<!DOCTYPE html>
21cb0ef41Sopenharmony_ci<meta charset=utf-8>
31cb0ef41Sopenharmony_ci<script src="/resources/testharness.js"></script>
41cb0ef41Sopenharmony_ci<script src="/resources/testharnessreport.js"></script>
51cb0ef41Sopenharmony_ci<script>
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciasync_test(t => {
81cb0ef41Sopenharmony_ci    let c1 = new BroadcastChannel('worker');
91cb0ef41Sopenharmony_ci    let c2 = new BroadcastChannel('worker');
101cb0ef41Sopenharmony_ci    let events = [];
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci    c1.onmessage = e => events.push(e);
131cb0ef41Sopenharmony_ci    c2.onmessage = e => events.push(e);
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci    let doneCount = 0;
161cb0ef41Sopenharmony_ci    c2.addEventListener('message', t.step_func(e => {
171cb0ef41Sopenharmony_ci        if (e.data == 'from worker') {
181cb0ef41Sopenharmony_ci          c2.postMessage('from c2');
191cb0ef41Sopenharmony_ci          c1.postMessage('done');
201cb0ef41Sopenharmony_ci        } else if (e.data == 'done') {
211cb0ef41Sopenharmony_ci          assert_equals(events.length, 4);
221cb0ef41Sopenharmony_ci          assert_equals(events[0].data, 'from worker');
231cb0ef41Sopenharmony_ci          assert_equals(events[0].target, c1);
241cb0ef41Sopenharmony_ci          assert_equals(events[1].data, 'from worker');
251cb0ef41Sopenharmony_ci          assert_equals(events[1].target, c2);
261cb0ef41Sopenharmony_ci          assert_equals(events[2].data, 'from c2');
271cb0ef41Sopenharmony_ci          assert_equals(events[3].data, 'done');
281cb0ef41Sopenharmony_ci          if (++doneCount == 2) t.done();
291cb0ef41Sopenharmony_ci        }
301cb0ef41Sopenharmony_ci      }));
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci    let worker = new Worker('resources/worker.js');
331cb0ef41Sopenharmony_ci    worker.onmessage = t.step_func(e => {
341cb0ef41Sopenharmony_ci        assert_array_equals(e.data, ['from c2', 'done']);
351cb0ef41Sopenharmony_ci        if (++doneCount == 2) t.done();
361cb0ef41Sopenharmony_ci      });
371cb0ef41Sopenharmony_ci    worker.postMessage({channel: 'worker'});
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  }, 'BroadcastChannel works in workers');
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciasync_test(t => {
421cb0ef41Sopenharmony_ci    let c1 = new BroadcastChannel('shared worker');
431cb0ef41Sopenharmony_ci    let c2 = new BroadcastChannel('shared worker');
441cb0ef41Sopenharmony_ci    let events = [];
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci    c1.onmessage = e => events.push(e);
471cb0ef41Sopenharmony_ci    c2.onmessage = e => events.push(e);
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    let doneCount = 0;
501cb0ef41Sopenharmony_ci    c2.addEventListener('message', t.step_func(e => {
511cb0ef41Sopenharmony_ci        if (e.data == 'from worker') {
521cb0ef41Sopenharmony_ci          c2.postMessage('from c2');
531cb0ef41Sopenharmony_ci          c1.postMessage('done');
541cb0ef41Sopenharmony_ci        } else if (e.data == 'done') {
551cb0ef41Sopenharmony_ci          assert_equals(events.length, 4);
561cb0ef41Sopenharmony_ci          assert_equals(events[0].data, 'from worker');
571cb0ef41Sopenharmony_ci          assert_equals(events[0].target, c1);
581cb0ef41Sopenharmony_ci          assert_equals(events[1].data, 'from worker');
591cb0ef41Sopenharmony_ci          assert_equals(events[1].target, c2);
601cb0ef41Sopenharmony_ci          assert_equals(events[2].data, 'from c2');
611cb0ef41Sopenharmony_ci          assert_equals(events[3].data, 'done');
621cb0ef41Sopenharmony_ci          if (++doneCount == 2) t.done();
631cb0ef41Sopenharmony_ci        }
641cb0ef41Sopenharmony_ci      }));
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    let worker = new SharedWorker('resources/worker.js');
671cb0ef41Sopenharmony_ci    worker.port.onmessage = t.step_func(e => {
681cb0ef41Sopenharmony_ci        assert_array_equals(e.data, ['from c2', 'done']);
691cb0ef41Sopenharmony_ci        if (++doneCount == 2) t.done();
701cb0ef41Sopenharmony_ci      });
711cb0ef41Sopenharmony_ci    worker.port.postMessage({channel: 'shared worker'});
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  }, 'BroadcastChannel works in shared workers');
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ciasync_test(t => {
761cb0ef41Sopenharmony_ci    let c = new BroadcastChannel('worker-close');
771cb0ef41Sopenharmony_ci    let events = [];
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci    c.onmessage = e => events.push('c1: ' + e.data);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    let worker = new Worker('resources/worker.js');
821cb0ef41Sopenharmony_ci    worker.onmessage = t.step_func(e => {
831cb0ef41Sopenharmony_ci        assert_array_equals(events,
841cb0ef41Sopenharmony_ci                            ['c1: from worker', 'c2: ready', 'c2: echo'],
851cb0ef41Sopenharmony_ci                            'messages in document');
861cb0ef41Sopenharmony_ci        assert_array_equals(e.data, ['done'], 'messages in worker');
871cb0ef41Sopenharmony_ci        t.done();
881cb0ef41Sopenharmony_ci      });
891cb0ef41Sopenharmony_ci    worker.onmessagerror =
901cb0ef41Sopenharmony_ci        t.unreached_func('Worker\'s onmessageerror handler called');
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    c.addEventListener('message', e => {
931cb0ef41Sopenharmony_ci        if (e.data == 'from worker') {
941cb0ef41Sopenharmony_ci          c.close();
951cb0ef41Sopenharmony_ci          if (self.gc) self.gc();
961cb0ef41Sopenharmony_ci          window.setTimeout(() => {
971cb0ef41Sopenharmony_ci              let c2 = new BroadcastChannel('worker-close');
981cb0ef41Sopenharmony_ci              c2.onmessage = e => {
991cb0ef41Sopenharmony_ci                  events.push('c2: ' + e.data);
1001cb0ef41Sopenharmony_ci                  if (e.data === 'ready') {
1011cb0ef41Sopenharmony_ci                    worker.postMessage({ping: 'echo'});
1021cb0ef41Sopenharmony_ci                  } else {
1031cb0ef41Sopenharmony_ci                    c2.postMessage('done');
1041cb0ef41Sopenharmony_ci                    c2.close();
1051cb0ef41Sopenharmony_ci                  }
1061cb0ef41Sopenharmony_ci                };
1071cb0ef41Sopenharmony_ci              // For some implementations there may be a race condition between
1081cb0ef41Sopenharmony_ci              // when the BroadcastChannel instance above is created / ready to
1091cb0ef41Sopenharmony_ci              // receive messages and when the worker calls postMessage on it's
1101cb0ef41Sopenharmony_ci              // BroadcastChannel instance. To avoid this, confirm that our
1111cb0ef41Sopenharmony_ci              // instance can receive a message before indicating to the other
1121cb0ef41Sopenharmony_ci              // thread that we are ready. For more details, see:
1131cb0ef41Sopenharmony_ci              // https://github.com/whatwg/html/issues/7267
1141cb0ef41Sopenharmony_ci              let c3 = new BroadcastChannel('worker-close');
1151cb0ef41Sopenharmony_ci              c3.postMessage('ready');
1161cb0ef41Sopenharmony_ci              c3.close();
1171cb0ef41Sopenharmony_ci            }, 1);
1181cb0ef41Sopenharmony_ci        }
1191cb0ef41Sopenharmony_ci      });
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci    worker.postMessage({channel: 'worker-close'});
1221cb0ef41Sopenharmony_ci    t.add_cleanup(() => worker.terminate());
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  }, 'Closing and re-opening a channel works.');
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciasync_test(t => {
1271cb0ef41Sopenharmony_ci  function workerCode() {
1281cb0ef41Sopenharmony_ci    close();
1291cb0ef41Sopenharmony_ci    try {
1301cb0ef41Sopenharmony_ci      var bc = new BroadcastChannel('worker-create-after-close');
1311cb0ef41Sopenharmony_ci    } catch (e) {
1321cb0ef41Sopenharmony_ci      postMessage(e);
1331cb0ef41Sopenharmony_ci      return;
1341cb0ef41Sopenharmony_ci    }
1351cb0ef41Sopenharmony_ci    postMessage(true);
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  var workerBlob = new Blob(
1391cb0ef41Sopenharmony_ci      [workerCode.toString() + ';workerCode();'],
1401cb0ef41Sopenharmony_ci      {type: 'application/javascript'});
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  var w = new Worker(URL.createObjectURL(workerBlob));
1431cb0ef41Sopenharmony_ci  w.onmessage = t.step_func_done(function(e) {
1441cb0ef41Sopenharmony_ci    assert_equals(
1451cb0ef41Sopenharmony_ci        e.data, true,
1461cb0ef41Sopenharmony_ci        'BroadcastChannel creation in closed worker triggered exception: ' +
1471cb0ef41Sopenharmony_ci            e.data.message);
1481cb0ef41Sopenharmony_ci  });
1491cb0ef41Sopenharmony_ci  t.add_cleanup(() => w.terminate());
1501cb0ef41Sopenharmony_ci}, 'BroadcastChannel created after a worker self.close()');
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_cifunction postMessageFromWorkerWorkerCode(workerName, channelName) {
1541cb0ef41Sopenharmony_ci  if (workerName === 'close-before-create-worker') {
1551cb0ef41Sopenharmony_ci    close();
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci  let bc = new BroadcastChannel(channelName);
1581cb0ef41Sopenharmony_ci  if (workerName === 'close-after-create-worker') {
1591cb0ef41Sopenharmony_ci    close();
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci  bc.postMessage(workerName + ' done');
1621cb0ef41Sopenharmony_ci  postMessage(true);
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_cifunction doPostMessageFromWorkerTest(t, workerName, channelName) {
1661cb0ef41Sopenharmony_ci  var bc = new BroadcastChannel(channelName);
1671cb0ef41Sopenharmony_ci  bc.onmessage = t.step_func_done(function(e) {
1681cb0ef41Sopenharmony_ci    assert_equals(
1691cb0ef41Sopenharmony_ci        e.data, 'done-worker done',
1701cb0ef41Sopenharmony_ci        'BroadcastChannel message should only be received from the second worker');
1711cb0ef41Sopenharmony_ci  });
1721cb0ef41Sopenharmony_ci  t.add_cleanup(() => bc.close());
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  var testMessageHandler = t.step_func(function(e) {
1751cb0ef41Sopenharmony_ci    assert_equals(
1761cb0ef41Sopenharmony_ci        e.data, true,
1771cb0ef41Sopenharmony_ci        'Worker sent postMessage indicating it sent a BroadcastChannel message');
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci    var w = createWorker(
1801cb0ef41Sopenharmony_ci        postMessageFromWorkerWorkerCode, 'done-worker', channelName);
1811cb0ef41Sopenharmony_ci    t.add_cleanup(() => w.terminate());
1821cb0ef41Sopenharmony_ci  });
1831cb0ef41Sopenharmony_ci  createWorker(
1841cb0ef41Sopenharmony_ci      postMessageFromWorkerWorkerCode, workerName, channelName,
1851cb0ef41Sopenharmony_ci      testMessageHandler);
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  // To avoid calling t.step_timeout here, have the worker postMessage(true)
1881cb0ef41Sopenharmony_ci  // once it is finished and then we'll instantiate another worker that
1891cb0ef41Sopenharmony_ci  // performs the same test steps but doesn't close. By the time the
1901cb0ef41Sopenharmony_ci  // BroadcastChannel message in that worker gets sent successfully it should
1911cb0ef41Sopenharmony_ci  // be safe to assume that any BroadcastChannel messages from the previous
1921cb0ef41Sopenharmony_ci  // worker would have been sent if they were going to be.
1931cb0ef41Sopenharmony_ci}
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_cifunction createWorker(workerCode, workerName, channelName, handler = null) {
1961cb0ef41Sopenharmony_ci  var workerCodeStr = workerCode.toString() +
1971cb0ef41Sopenharmony_ci      `;${workerCode.name}("${workerName}", "${channelName}");`;
1981cb0ef41Sopenharmony_ci  var workerBlob = new Blob([workerCodeStr], {type: 'application/javascript'});
1991cb0ef41Sopenharmony_ci  var w = new Worker(URL.createObjectURL(workerBlob));
2001cb0ef41Sopenharmony_ci  if (handler !== null) {
2011cb0ef41Sopenharmony_ci    w.onmessage = handler;
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci  return w;
2041cb0ef41Sopenharmony_ci}
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ciasync_test(t => {
2071cb0ef41Sopenharmony_ci  const workerName = 'close-after-create-worker';
2081cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-from-worker';
2091cb0ef41Sopenharmony_ci  doPostMessageFromWorkerTest(t, workerName, channelName);
2101cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages from closed worker to parent should be ignored (BC created before closing)');
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ciasync_test(t => {
2131cb0ef41Sopenharmony_ci  const workerName = 'close-before-create-worker';
2141cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-from-worker';
2151cb0ef41Sopenharmony_ci  doPostMessageFromWorkerTest(t, workerName, channelName);
2161cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages from closed worker to parent should be ignored (BC created after closing)');
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_cifunction postMessageToWorkerWorkerCode(workerName, channelName) {
2201cb0ef41Sopenharmony_ci  self.addEventListener('message', () => {
2211cb0ef41Sopenharmony_ci    if (workerName === 'close-before-create-worker') {
2221cb0ef41Sopenharmony_ci      close();
2231cb0ef41Sopenharmony_ci    }
2241cb0ef41Sopenharmony_ci    try {
2251cb0ef41Sopenharmony_ci      let bc1 = new BroadcastChannel(channelName);
2261cb0ef41Sopenharmony_ci      bc1.onmessage = e => {
2271cb0ef41Sopenharmony_ci        if (e.data === 'ready') {
2281cb0ef41Sopenharmony_ci          postMessage(e.data);
2291cb0ef41Sopenharmony_ci        } else if (e.data === 'test') {
2301cb0ef41Sopenharmony_ci          postMessage(workerName + ' done');
2311cb0ef41Sopenharmony_ci        }
2321cb0ef41Sopenharmony_ci      };
2331cb0ef41Sopenharmony_ci      bc1.onmessageerror = () => {
2341cb0ef41Sopenharmony_ci        postMessage('onmessageerror called from worker BroadcastChannel');
2351cb0ef41Sopenharmony_ci      };
2361cb0ef41Sopenharmony_ci      if (workerName === 'close-after-create-worker') {
2371cb0ef41Sopenharmony_ci        close();
2381cb0ef41Sopenharmony_ci      }
2391cb0ef41Sopenharmony_ci    } catch (e) {
2401cb0ef41Sopenharmony_ci      postMessage(e);
2411cb0ef41Sopenharmony_ci      return;
2421cb0ef41Sopenharmony_ci    }
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci    if (workerName === 'done-worker') {
2451cb0ef41Sopenharmony_ci      // For some implementations there may be a race condition between when
2461cb0ef41Sopenharmony_ci      // the BroadcastChannel instance above is created / ready to receive
2471cb0ef41Sopenharmony_ci      // messages and when the parent calls postMessage on it's
2481cb0ef41Sopenharmony_ci      // BroadcastChannel instance. To avoid this, confirm that our instance
2491cb0ef41Sopenharmony_ci      // can receive a message before indicating to the other thread that we
2501cb0ef41Sopenharmony_ci      // are ready. For more details, see:
2511cb0ef41Sopenharmony_ci      // https://github.com/whatwg/html/issues/7267
2521cb0ef41Sopenharmony_ci      let bc2 = new BroadcastChannel(channelName);
2531cb0ef41Sopenharmony_ci      bc2.postMessage('ready');
2541cb0ef41Sopenharmony_ci      bc2.close();
2551cb0ef41Sopenharmony_ci    } else {
2561cb0ef41Sopenharmony_ci      // Since the worker has closed, it's not expected that the
2571cb0ef41Sopenharmony_ci      // BroadcastChannel will receive messages (there's a separate test for
2581cb0ef41Sopenharmony_ci      // that), so just indicate directly that it's ready to test receiving
2591cb0ef41Sopenharmony_ci      // a message from the parent dispite the possibility of a race condition.
2601cb0ef41Sopenharmony_ci      postMessage('ready');
2611cb0ef41Sopenharmony_ci    }
2621cb0ef41Sopenharmony_ci  });
2631cb0ef41Sopenharmony_ci  self.addEventListener('messageerror', () => {
2641cb0ef41Sopenharmony_ci    postMessage('onmessageerror called from worker');
2651cb0ef41Sopenharmony_ci  });
2661cb0ef41Sopenharmony_ci}
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_cifunction doPostMessageToWorkerTest(t, workerName, channelName) {
2691cb0ef41Sopenharmony_ci  var bc = new BroadcastChannel(channelName);
2701cb0ef41Sopenharmony_ci  t.add_cleanup(() => bc.close());
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  var doneMessageHandler = t.step_func(function(e) {
2731cb0ef41Sopenharmony_ci    if (e.data === 'ready') {
2741cb0ef41Sopenharmony_ci      bc.postMessage('test');
2751cb0ef41Sopenharmony_ci    } else if (e.data === 'done-worker done') {
2761cb0ef41Sopenharmony_ci      t.done();
2771cb0ef41Sopenharmony_ci    } else {
2781cb0ef41Sopenharmony_ci      assert_unreached(
2791cb0ef41Sopenharmony_ci          'BroadcastChannel.postMessage triggered exception within second worker: ' +
2801cb0ef41Sopenharmony_ci          e.data.message);
2811cb0ef41Sopenharmony_ci    }
2821cb0ef41Sopenharmony_ci  });
2831cb0ef41Sopenharmony_ci  var testMessageHandler = t.step_func(function(e) {
2841cb0ef41Sopenharmony_ci    assert_equals(
2851cb0ef41Sopenharmony_ci        e.data, 'ready',
2861cb0ef41Sopenharmony_ci        'Worker sent postMessage indicating its BroadcastChannel instance is ready');
2871cb0ef41Sopenharmony_ci    bc.postMessage('test');
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci    var doneWorker = createWorker(
2901cb0ef41Sopenharmony_ci        postMessageToWorkerWorkerCode, 'done-worker', channelName,
2911cb0ef41Sopenharmony_ci        doneMessageHandler);
2921cb0ef41Sopenharmony_ci    t.add_cleanup(() => {
2931cb0ef41Sopenharmony_ci      doneWorker.terminate();
2941cb0ef41Sopenharmony_ci    });
2951cb0ef41Sopenharmony_ci    doneWorker.postMessage('start');
2961cb0ef41Sopenharmony_ci  });
2971cb0ef41Sopenharmony_ci  var testWorker = createWorker(
2981cb0ef41Sopenharmony_ci      postMessageToWorkerWorkerCode, workerName, channelName,
2991cb0ef41Sopenharmony_ci      testMessageHandler);
3001cb0ef41Sopenharmony_ci  testWorker.postMessage('start');
3011cb0ef41Sopenharmony_ci}
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ciasync_test(t => {
3041cb0ef41Sopenharmony_ci  const workerName = 'close-after-create-worker';
3051cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-to-worker';
3061cb0ef41Sopenharmony_ci  doPostMessageToWorkerTest(t, workerName, channelName);
3071cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages from parent to closed worker should be ignored (BC created before closing)');
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ciasync_test(t => {
3101cb0ef41Sopenharmony_ci  const workerName = 'close-before-create-worker';
3111cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-to-worker';
3121cb0ef41Sopenharmony_ci  doPostMessageToWorkerTest(t, workerName, channelName);
3131cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages from parent to closed worker should be ignored (BC created after closing)');
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_cifunction postMessageWithinWorkerWorkerCode(workerName, channelName) {
3171cb0ef41Sopenharmony_ci  if (workerName === 'close-before-create-worker') {
3181cb0ef41Sopenharmony_ci    close();
3191cb0ef41Sopenharmony_ci  }
3201cb0ef41Sopenharmony_ci  try {
3211cb0ef41Sopenharmony_ci    let bc1 = new BroadcastChannel(channelName);
3221cb0ef41Sopenharmony_ci    let bc2 = new BroadcastChannel(channelName);
3231cb0ef41Sopenharmony_ci    bc1.onmessage = e => {
3241cb0ef41Sopenharmony_ci      postMessage(workerName + ' done')
3251cb0ef41Sopenharmony_ci    };
3261cb0ef41Sopenharmony_ci    if (workerName === 'close-after-create-worker') {
3271cb0ef41Sopenharmony_ci      close();
3281cb0ef41Sopenharmony_ci    }
3291cb0ef41Sopenharmony_ci    bc2.postMessage(true);
3301cb0ef41Sopenharmony_ci    postMessage(true);
3311cb0ef41Sopenharmony_ci  } catch (e) {
3321cb0ef41Sopenharmony_ci    postMessage(e);
3331cb0ef41Sopenharmony_ci  }
3341cb0ef41Sopenharmony_ci}
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_cifunction doPostMessageWithinWorkerTest(t, workerName, channelName) {
3371cb0ef41Sopenharmony_ci  var doneMessageHandler = t.step_func(function(e) {
3381cb0ef41Sopenharmony_ci    if (e.data === true) {
3391cb0ef41Sopenharmony_ci      // Done worker has finished - no action needed
3401cb0ef41Sopenharmony_ci    } else if (e.data === 'done-worker done') {
3411cb0ef41Sopenharmony_ci      t.done();
3421cb0ef41Sopenharmony_ci    } else {
3431cb0ef41Sopenharmony_ci      assert_unreached(
3441cb0ef41Sopenharmony_ci          'BroadcastChannel.postMessage triggered exception within second worker: ' +
3451cb0ef41Sopenharmony_ci          e.data.message);
3461cb0ef41Sopenharmony_ci    }
3471cb0ef41Sopenharmony_ci  });
3481cb0ef41Sopenharmony_ci  var testMessageHandler = t.step_func(function(e) {
3491cb0ef41Sopenharmony_ci    assert_equals(
3501cb0ef41Sopenharmony_ci        e.data, true,
3511cb0ef41Sopenharmony_ci        'Worker indicated that the test procedures were executed successfully');
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci    var w = createWorker(
3541cb0ef41Sopenharmony_ci        postMessageWithinWorkerWorkerCode, 'done-worker', channelName,
3551cb0ef41Sopenharmony_ci        doneMessageHandler);
3561cb0ef41Sopenharmony_ci    t.add_cleanup(() => w.terminate());
3571cb0ef41Sopenharmony_ci  });
3581cb0ef41Sopenharmony_ci  createWorker(
3591cb0ef41Sopenharmony_ci      postMessageWithinWorkerWorkerCode, workerName, channelName,
3601cb0ef41Sopenharmony_ci      testMessageHandler);
3611cb0ef41Sopenharmony_ci}
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ciasync_test(t => {
3641cb0ef41Sopenharmony_ci  const workerName = 'close-after-create-worker';
3651cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-within-worker';
3661cb0ef41Sopenharmony_ci  doPostMessageWithinWorkerTest(t, workerName, channelName);
3671cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages within closed worker should be ignored (BCs created before closing)');
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ciasync_test(t => {
3701cb0ef41Sopenharmony_ci  const workerName = 'close-before-create-worker';
3711cb0ef41Sopenharmony_ci  const channelName = workerName + '-postmessage-within-worker';
3721cb0ef41Sopenharmony_ci  doPostMessageWithinWorkerTest(t, workerName, channelName);
3731cb0ef41Sopenharmony_ci}, 'BroadcastChannel messages within closed worker should be ignored (BCs created after closing)');
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci</script>
376