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<!-- Pull in the with_iframe helper function from the service worker tests -->
61cb0ef41Sopenharmony_ci<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
71cb0ef41Sopenharmony_ci<body>
81cb0ef41Sopenharmony_ci<script>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst BC0_FIRST_MSG = 'from BC0 - first';
111cb0ef41Sopenharmony_ciconst BC1_FIRST_MSG = 'from BC1 - first';
121cb0ef41Sopenharmony_ciconst BC2_FIRST_MSG = 'from BC2 - first';
131cb0ef41Sopenharmony_ciconst BC3_FIRST_MSG = 'from BC3 - first';
141cb0ef41Sopenharmony_ciconst BC0_SECOND_MSG = 'from BC0 - second';
151cb0ef41Sopenharmony_ciconst BC1_SECOND_MSG = 'from BC1 - second';
161cb0ef41Sopenharmony_ciconst BC2_SECOND_MSG = 'from BC2 - second';
171cb0ef41Sopenharmony_ciconst BC3_SECOND_MSG = 'done';
181cb0ef41Sopenharmony_ciconst BC0_TARGET_NAME = 'BC1';
191cb0ef41Sopenharmony_ciconst BC1_TARGET_NAME = 'BC1';
201cb0ef41Sopenharmony_ciconst BC2_TARGET_NAME = 'BC2';
211cb0ef41Sopenharmony_ciconst BC3_TARGET_NAME = 'BC3';
221cb0ef41Sopenharmony_ciconst MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME = 'multi-frame-order';
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciconst bc0 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME);
251cb0ef41Sopenharmony_ciconst messages = [];
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cifunction logReceivedMessage(targetname, e) {
281cb0ef41Sopenharmony_ci  messages.push({'target': targetname, 'data': e.data});
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_cifunction postMessagesToChannel() {
321cb0ef41Sopenharmony_ci  return new Promise((resolve) => {
331cb0ef41Sopenharmony_ci    bc0.postMessage(BC0_FIRST_MSG);
341cb0ef41Sopenharmony_ci    bc0.postMessage(BC0_SECOND_MSG);
351cb0ef41Sopenharmony_ci    resolve();
361cb0ef41Sopenharmony_ci  });
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci// Expected flow of messages between the BroadcastChannel objects (based on
401cb0ef41Sopenharmony_ci// the requirement that messages get delivered to BroadcastChannel objects
411cb0ef41Sopenharmony_ci// "in creation order, oldest first") and comments describing the actions
421cb0ef41Sopenharmony_ci// taken in response to each event
431cb0ef41Sopenharmony_ciconst EXPECTED_RESULTS = [
441cb0ef41Sopenharmony_ci  // -> BC0 sends two messages, BC1 and BC2 are connected to the channel
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  {'data': BC0_FIRST_MSG, 'target': BC1_TARGET_NAME},
471cb0ef41Sopenharmony_ci  // -> BC1 Creates BC3 and sends first message
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  {'data': BC0_FIRST_MSG, 'target': BC2_TARGET_NAME},
501cb0ef41Sopenharmony_ci  // -> BC2 sends two messages
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  // BC3 isn't expected to receive the messages sent before it was created, so
531cb0ef41Sopenharmony_ci  // no corresponding entries here for messages from BC0.
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  {'data': BC0_SECOND_MSG, 'target': BC1_TARGET_NAME},
561cb0ef41Sopenharmony_ci  // -> BC1 sends second message
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  {'data': BC0_SECOND_MSG, 'target': BC2_TARGET_NAME},
591cb0ef41Sopenharmony_ci  // -> BC2 closes
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  {'data': BC1_FIRST_MSG, 'target': BC0_TARGET_NAME},
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  {'data': BC1_FIRST_MSG, 'target': BC3_TARGET_NAME},
641cb0ef41Sopenharmony_ci  // -> BC3 sends first message
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  {'data': BC2_FIRST_MSG, 'target': BC0_TARGET_NAME},
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  {'data': BC2_FIRST_MSG, 'target': BC1_TARGET_NAME},
691cb0ef41Sopenharmony_ci  // -> BC1 closes
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  {'data': BC2_FIRST_MSG, 'target': BC3_TARGET_NAME},
721cb0ef41Sopenharmony_ci  // -> BC3 sends second message
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  {'data': BC2_SECOND_MSG, 'target': BC0_TARGET_NAME},
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  {'data': BC2_SECOND_MSG, 'target': BC3_TARGET_NAME},
771cb0ef41Sopenharmony_ci  // -> BC3 closes
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  {'data': BC1_SECOND_MSG, 'target': BC0_TARGET_NAME},
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  {'data': BC3_FIRST_MSG, 'target': BC0_TARGET_NAME},
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  {'data': BC3_SECOND_MSG, 'target': BC0_TARGET_NAME},
841cb0ef41Sopenharmony_ci];
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cifunction testCompletion(t) {
871cb0ef41Sopenharmony_ci  return new Promise((resolve) => {
881cb0ef41Sopenharmony_ci    bc0.onmessage = t.step_func(e => {
891cb0ef41Sopenharmony_ci      logReceivedMessage(BC0_TARGET_NAME, e);
901cb0ef41Sopenharmony_ci      if (e.data == BC3_SECOND_MSG) {
911cb0ef41Sopenharmony_ci        assert_equals(messages.length, EXPECTED_RESULTS.length);
921cb0ef41Sopenharmony_ci        for(var i = 0; i < messages.length; i++) {
931cb0ef41Sopenharmony_ci          assert_equals(messages[i].target, EXPECTED_RESULTS[i].target, `Message ${i+1} has unexpected target`);
941cb0ef41Sopenharmony_ci          assert_equals(messages[i].data, EXPECTED_RESULTS[i].data, `Message ${i+1} has unexpected message contents`);
951cb0ef41Sopenharmony_ci        }
961cb0ef41Sopenharmony_ci        resolve();
971cb0ef41Sopenharmony_ci      }
981cb0ef41Sopenharmony_ci    });
991cb0ef41Sopenharmony_ci  });
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_cipromise_test(async t => {
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  const testResults = testCompletion(t);
1051cb0ef41Sopenharmony_ci  // Await them sequentially because we need the BroadcastChannel object in
1061cb0ef41Sopenharmony_ci  // iframe1 to be created first, we need the BroadcastChannel object in
1071cb0ef41Sopenharmony_ci  // iframe2 to be created second, and then we only want to call
1081cb0ef41Sopenharmony_ci  // postMessagesToChannel once both BroadcastChannels have been created.
1091cb0ef41Sopenharmony_ci  await with_iframe('resources/ordering.html?id=iframe1');
1101cb0ef41Sopenharmony_ci  await with_iframe('resources/ordering.html?id=iframe2');
1111cb0ef41Sopenharmony_ci  await postMessagesToChannel();
1121cb0ef41Sopenharmony_ci  return testResults;
1131cb0ef41Sopenharmony_ci}, "Messages are delivered in port creation order across multiple frames");
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci</script>
1161cb0ef41Sopenharmony_ci</body>
117