1<!DOCTYPE html> 2<meta charset=utf-8> 3<script src="/resources/testharness.js"></script> 4<script src="/resources/testharnessreport.js"></script> 5<!-- Pull in the with_iframe helper function from the service worker tests --> 6<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> 7<body> 8<script> 9 10const BC0_FIRST_MSG = 'from BC0 - first'; 11const BC1_FIRST_MSG = 'from BC1 - first'; 12const BC2_FIRST_MSG = 'from BC2 - first'; 13const BC3_FIRST_MSG = 'from BC3 - first'; 14const BC0_SECOND_MSG = 'from BC0 - second'; 15const BC1_SECOND_MSG = 'from BC1 - second'; 16const BC2_SECOND_MSG = 'from BC2 - second'; 17const BC3_SECOND_MSG = 'done'; 18const BC0_TARGET_NAME = 'BC1'; 19const BC1_TARGET_NAME = 'BC1'; 20const BC2_TARGET_NAME = 'BC2'; 21const BC3_TARGET_NAME = 'BC3'; 22const MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME = 'multi-frame-order'; 23 24const bc0 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME); 25const messages = []; 26 27function logReceivedMessage(targetname, e) { 28 messages.push({'target': targetname, 'data': e.data}); 29} 30 31function postMessagesToChannel() { 32 return new Promise((resolve) => { 33 bc0.postMessage(BC0_FIRST_MSG); 34 bc0.postMessage(BC0_SECOND_MSG); 35 resolve(); 36 }); 37} 38 39// Expected flow of messages between the BroadcastChannel objects (based on 40// the requirement that messages get delivered to BroadcastChannel objects 41// "in creation order, oldest first") and comments describing the actions 42// taken in response to each event 43const EXPECTED_RESULTS = [ 44 // -> BC0 sends two messages, BC1 and BC2 are connected to the channel 45 46 {'data': BC0_FIRST_MSG, 'target': BC1_TARGET_NAME}, 47 // -> BC1 Creates BC3 and sends first message 48 49 {'data': BC0_FIRST_MSG, 'target': BC2_TARGET_NAME}, 50 // -> BC2 sends two messages 51 52 // BC3 isn't expected to receive the messages sent before it was created, so 53 // no corresponding entries here for messages from BC0. 54 55 {'data': BC0_SECOND_MSG, 'target': BC1_TARGET_NAME}, 56 // -> BC1 sends second message 57 58 {'data': BC0_SECOND_MSG, 'target': BC2_TARGET_NAME}, 59 // -> BC2 closes 60 61 {'data': BC1_FIRST_MSG, 'target': BC0_TARGET_NAME}, 62 63 {'data': BC1_FIRST_MSG, 'target': BC3_TARGET_NAME}, 64 // -> BC3 sends first message 65 66 {'data': BC2_FIRST_MSG, 'target': BC0_TARGET_NAME}, 67 68 {'data': BC2_FIRST_MSG, 'target': BC1_TARGET_NAME}, 69 // -> BC1 closes 70 71 {'data': BC2_FIRST_MSG, 'target': BC3_TARGET_NAME}, 72 // -> BC3 sends second message 73 74 {'data': BC2_SECOND_MSG, 'target': BC0_TARGET_NAME}, 75 76 {'data': BC2_SECOND_MSG, 'target': BC3_TARGET_NAME}, 77 // -> BC3 closes 78 79 {'data': BC1_SECOND_MSG, 'target': BC0_TARGET_NAME}, 80 81 {'data': BC3_FIRST_MSG, 'target': BC0_TARGET_NAME}, 82 83 {'data': BC3_SECOND_MSG, 'target': BC0_TARGET_NAME}, 84]; 85 86function testCompletion(t) { 87 return new Promise((resolve) => { 88 bc0.onmessage = t.step_func(e => { 89 logReceivedMessage(BC0_TARGET_NAME, e); 90 if (e.data == BC3_SECOND_MSG) { 91 assert_equals(messages.length, EXPECTED_RESULTS.length); 92 for(var i = 0; i < messages.length; i++) { 93 assert_equals(messages[i].target, EXPECTED_RESULTS[i].target, `Message ${i+1} has unexpected target`); 94 assert_equals(messages[i].data, EXPECTED_RESULTS[i].data, `Message ${i+1} has unexpected message contents`); 95 } 96 resolve(); 97 } 98 }); 99 }); 100} 101 102promise_test(async t => { 103 104 const testResults = testCompletion(t); 105 // Await them sequentially because we need the BroadcastChannel object in 106 // iframe1 to be created first, we need the BroadcastChannel object in 107 // iframe2 to be created second, and then we only want to call 108 // postMessagesToChannel once both BroadcastChannels have been created. 109 await with_iframe('resources/ordering.html?id=iframe1'); 110 await with_iframe('resources/ordering.html?id=iframe2'); 111 await postMessagesToChannel(); 112 return testResults; 113}, "Messages are delivered in port creation order across multiple frames"); 114 115</script> 116</body> 117