| <!DOCTYPE html> |
| <meta charset=utf-8> |
| <meta name="timeout" content="long"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/get-host-info.sub.js"></script> |
| <script src="/common/utils.js"></script> |
| <script src="/common/dispatcher/dispatcher.js"></script> |
| <!-- Pull in executor_path needed by newPopup / newIframe --> |
| <script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script> |
| <!-- Pull in importScript / newPopup / newIframe --> |
| <script src="/html/anonymous-iframe/resources/common.js"></script> |
| <body> |
| <script> |
| |
| const bc_postmessage_js = (channel_name, message, done_queue_name) => ` |
| const bc = new BroadcastChannel("${channel_name}"); |
| bc.postMessage("${message}"); |
| send("${done_queue_name}", "done"); |
| `; |
| |
| const add_iframe_js = (iframe_origin, response_queue_uuid) => ` |
| const importScript = ${importScript}; |
| await importScript("/html/cross-origin-embedder-policy/credentialless" + |
| "/resources/common.js"); |
| await importScript("/html/anonymous-iframe/resources/common.js"); |
| await importScript("/common/utils.js"); |
| send("${response_queue_uuid}", newIframe("${iframe_origin}")); |
| `; |
| |
| const same_site_origin = get_host_info().HTTPS_ORIGIN; |
| const cross_site_origin = get_host_info().HTTPS_NOTSAMESITE_ORIGIN; |
| |
| async function create_test_iframes(t, response_queue_uuid) { |
| |
| // Create a same-origin iframe in a cross-site popup. |
| const not_same_site_popup_uuid = newPopup(t, cross_site_origin); |
| send(not_same_site_popup_uuid, |
| add_iframe_js(same_site_origin, response_queue_uuid)); |
| const iframe_1_uuid = await receive(response_queue_uuid); |
| |
| // Create a same-origin iframe in a same-site popup. |
| const same_origin_popup_uuid = newPopup(t, same_site_origin); |
| send(same_origin_popup_uuid, |
| add_iframe_js(same_site_origin, response_queue_uuid)); |
| const iframe_2_uuid = await receive(response_queue_uuid); |
| |
| return [iframe_1_uuid, iframe_2_uuid]; |
| } |
| |
| promise_test(t => { |
| return new Promise(async (resolve, reject) => { |
| const response_queue_uuid = token(); |
| |
| const [iframe_1_uuid, iframe_2_uuid] = |
| await create_test_iframes(t, response_queue_uuid); |
| |
| const channel_name = token(); |
| const bc = new BroadcastChannel(channel_name); |
| bc.onmessage = resolve; |
| |
| // Instruct the not-same-top-level-site iframe to send a message on the BC |
| // channel we are listening on. This message should not be received since |
| // the iframe should be in a different partition. |
| send(iframe_1_uuid, |
| bc_postmessage_js(channel_name, "iframe1 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger iframe1 BroadcastChannel message creation"); |
| } |
| |
| // Now instruct the same-top-level-site iframe to send a BC message. By |
| // the time we send the script to execute, have it send the BC message, |
| // and then receive the BC message in our BC instance, it should be |
| // reasonable to assume that the message from the first iframe would have |
| // been delivered if it was going to be. |
| send(iframe_2_uuid, |
| bc_postmessage_js(channel_name, "iframe2 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger iframe2 BroadcastChannel message creation"); |
| } |
| |
| }).then(event => { |
| assert_equals(event.data, "iframe2 msg"); |
| }); |
| |
| }, "BroadcastChannel messages aren't received from a cross-partition iframe"); |
| |
| // Optional Test: Checking for partitioned BroadcastChannels in an A->B->A |
| // (nested-iframe with cross-site ancestor chain) scenario. |
| promise_test(t => { |
| return new Promise(async (resolve, reject) => { |
| const response_queue_uuid = token(); |
| |
| const [cross_site_iframe_uuid, all_same_parent_iframe_uuid] = |
| await create_test_iframes(t, response_queue_uuid); |
| |
| // Create a same-origin iframe in a cross-site iframe in a same-site popup. |
| // Create the same-site child iframe of the cross-site iframe (A->B->A). |
| send(cross_site_iframe_uuid, |
| add_iframe_js(same_site_origin, response_queue_uuid)); |
| const same_site_iframe_uuid = await receive(response_queue_uuid); |
| |
| // Create a same-origin iframe in a same-site iframe in a same-site popup. |
| // Create the same-site child iframe of the same-site parent iframe (A->A->A). |
| send(all_same_parent_iframe_uuid, |
| add_iframe_js(same_site_origin, response_queue_uuid)); |
| const all_same_child_iframe_uuid = await receive(response_queue_uuid); |
| |
| const channel_name = token(); |
| const bc = new BroadcastChannel(channel_name); |
| bc.onmessage = resolve; |
| |
| // Instruct the A->B->A child iframe to send a message on the BC |
| // channel we are listening on. This message should not be received since |
| // the iframe should be in a different partition. |
| send(same_site_iframe_uuid, |
| bc_postmessage_js(channel_name, "iframe1 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger A->B->A BroadcastChannel message creation"); |
| } |
| |
| // Now instruct the A->A->A child iframe to send a BC message. By |
| // the time we send the script to execute, send the BC message, |
| // and receive the BC message in our BC instance, it should be |
| // reasonable to assume that the message from the first iframe would have |
| // been delivered if it was going to be. |
| send(all_same_child_iframe_uuid, |
| bc_postmessage_js(channel_name, "iframe2 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger A->A->A BroadcastChannel message creation"); |
| } |
| |
| }).then(event => { |
| assert_equals(event.data, "iframe2 msg"); |
| }); |
| |
| }, "BroadcastChannel messages aren't received from a nested iframe with a cross-site ancestor"); |
| |
| const newWorker = (origin) => { |
| const worker_token = token(); |
| const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`; |
| const worker = new Worker(worker_url); |
| return worker_token; |
| } |
| |
| promise_test(t => { |
| return new Promise(async (resolve, reject) => { |
| const response_queue_uuid = token(); |
| |
| const create_worker_js = (origin) => ` |
| const importScript = ${importScript}; |
| await importScript("/html/cross-origin-embedder-policy/credentialless" + |
| "/resources/common.js"); |
| await importScript("/html/anonymous-iframe/resources/common.js"); |
| await importScript("/common/utils.js"); |
| const newWorker = ${newWorker}; |
| send("${response_queue_uuid}", newWorker("${origin}")); |
| `; |
| |
| const [iframe_1_uuid, iframe_2_uuid] = |
| await create_test_iframes(t, response_queue_uuid); |
| |
| // Create a dedicated worker in the cross-top-level-site iframe. |
| send(iframe_1_uuid, create_worker_js(same_site_origin)); |
| const worker_1_uuid = await receive(response_queue_uuid); |
| |
| // Create a dedicated worker in the same-top-level-site iframe. |
| send(iframe_2_uuid, create_worker_js(same_site_origin)); |
| const worker_2_uuid = await receive(response_queue_uuid); |
| |
| const channel_name = token(); |
| const bc = new BroadcastChannel(channel_name); |
| bc.onmessage = async (e) => { |
| await send(worker_1_uuid, "self.close();"); |
| await send(worker_2_uuid, "self.close();"); |
| resolve(e); |
| }; |
| |
| // Instruct the not-same-top-level-site worker to send a message on the BC |
| // channel we are listening on. This message should not be received since |
| // the worker should be in a different partition. |
| send(worker_1_uuid, |
| bc_postmessage_js(channel_name, "worker1 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker1 BroadcastChannel message creation"); |
| } |
| |
| // Now instruct the same-top-level-site worker to send a BC message. By |
| // the time we send the script to execute, have it send the BC message, |
| // and then receive the BC message in our BC instance, it should be |
| // reasonable to assume that the message from the first worker would have |
| // been delivered if it was going to be. |
| send(worker_2_uuid, |
| bc_postmessage_js(channel_name, "worker2 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker2 BroadcastChannel message creation"); |
| } |
| |
| }).then(event => { |
| assert_equals(event.data, "worker2 msg"); |
| }); |
| |
| }, "BroadcastChannel messages aren't received from a cross-partition dedicated worker"); |
| |
| const newSharedWorker = (origin) => { |
| const worker_token = token(); |
| const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`; |
| const worker = new SharedWorker(worker_url, worker_token); |
| return worker_token; |
| } |
| |
| promise_test(t => { |
| return new Promise(async (resolve, reject) => { |
| const response_queue_uuid = token(); |
| |
| const create_worker_js = (origin) => ` |
| const importScript = ${importScript}; |
| await importScript("/html/cross-origin-embedder-policy/credentialless" + |
| "/resources/common.js"); |
| await importScript("/html/anonymous-iframe/resources/common.js"); |
| await importScript("/common/utils.js"); |
| const newSharedWorker = ${newSharedWorker}; |
| send("${response_queue_uuid}", newSharedWorker("${origin}")); |
| `; |
| |
| const [iframe_1_uuid, iframe_2_uuid] = |
| await create_test_iframes(t, response_queue_uuid); |
| |
| // Create a shared worker in the cross-top-level-site iframe. |
| send(iframe_1_uuid, create_worker_js(same_site_origin)); |
| const worker_1_uuid = await receive(response_queue_uuid); |
| |
| // Create a shared worker in the same-top-level-site iframe. |
| send(iframe_2_uuid, create_worker_js(same_site_origin)); |
| const worker_2_uuid = await receive(response_queue_uuid); |
| |
| const channel_name = token(); |
| const bc = new BroadcastChannel(channel_name); |
| bc.onmessage = async (e) => { |
| await send(worker_1_uuid, "self.close();"); |
| await send(worker_2_uuid, "self.close();"); |
| resolve(e); |
| }; |
| |
| // Instruct the not-same-top-level-site worker to send a message on the BC |
| // channel we are listening on. This message should not be received since |
| // the worker should be in a different partition. |
| send(worker_1_uuid, |
| bc_postmessage_js(channel_name, "worker1 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker1 BroadcastChannel message creation"); |
| } |
| |
| // Now instruct the same-top-level-site worker to send a BC message. By |
| // the time we send the script to execute, have it send the BC message, |
| // and then receive the BC message in our BC instance, it should be |
| // reasonable to assume that the message from the first worker would have |
| // been delivered if it was going to be. |
| send(worker_2_uuid, |
| bc_postmessage_js(channel_name, "worker2 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker2 BroadcastChannel message creation"); |
| } |
| |
| }).then(event => { |
| assert_equals(event.data, "worker2 msg"); |
| }); |
| |
| }, "BroadcastChannel messages aren't received from a cross-partition shared worker"); |
| |
| const newServiceWorker = async (origin) => { |
| const worker_token = token(); |
| const worker_url = origin + executor_service_worker_path + |
| `&uuid=${worker_token}`; |
| const worker_url_path = executor_service_worker_path.substring(0, |
| executor_service_worker_path.lastIndexOf('/')); |
| const scope = worker_url_path + "/not-used/"; |
| const reg = await navigator.serviceWorker.register(worker_url, |
| {'scope': scope}); |
| return worker_token; |
| } |
| |
| promise_test(t => { |
| return new Promise(async (resolve, reject) => { |
| const response_queue_uuid = token(); |
| |
| const create_worker_js = (origin) => ` |
| const importScript = ${importScript}; |
| await importScript("/html/cross-origin-embedder-policy/credentialless" + |
| "/resources/common.js"); |
| await importScript("/html/anonymous-iframe/resources/common.js"); |
| await importScript("/common/utils.js"); |
| const newServiceWorker = ${newServiceWorker}; |
| send("${response_queue_uuid}", await newServiceWorker("${origin}")); |
| `; |
| |
| const [iframe_1_uuid, iframe_2_uuid] = |
| await create_test_iframes(t, response_queue_uuid); |
| |
| // Create a service worker in the cross-top-level-site iframe. |
| send(iframe_1_uuid, create_worker_js(same_site_origin)); |
| var worker_1_uuid = await receive(response_queue_uuid); |
| |
| const channel_name = token(); |
| const bc = new BroadcastChannel(channel_name); |
| bc.onmessage = async (e) => { |
| if (worker_1_uuid) { |
| await send(worker_1_uuid, "self.registration.unregister();"); |
| } |
| if (worker_2_uuid) { |
| await send(worker_2_uuid, "self.registration.unregister();"); |
| } |
| resolve(e); |
| }; |
| |
| // Instruct the not-same-top-level-site worker to send a message on the BC |
| // channel we are listening on. This message should not be received since |
| // the worker should be in a different partition. |
| send(worker_1_uuid, |
| bc_postmessage_js(channel_name, "worker1 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker1 BroadcastChannel message creation"); |
| } |
| |
| await send(worker_1_uuid, "await self.registration.unregister();"); |
| worker_1_uuid = undefined; |
| |
| // Create a service worker in the same-top-level-site iframe. Note that |
| // if service workers are unpartitioned then this new service worker would |
| // replace the one created above. This is why we wait to create the second |
| // service worker until after we are done with the first one. |
| send(iframe_2_uuid, create_worker_js(same_site_origin)); |
| var worker_2_uuid = await receive(response_queue_uuid); |
| |
| // Now instruct the same-top-level-site worker to send a BC message. By |
| // the time we send the script to execute, have it send the BC message, |
| // and then receive the BC message in our BC instance, it should be |
| // reasonable to assume that the message from the first worker would have |
| // been delivered if it was going to be. |
| send(worker_2_uuid, |
| bc_postmessage_js(channel_name, "worker2 msg", response_queue_uuid)); |
| if (await receive(response_queue_uuid) != "done") { |
| reject("Unable to trigger worker2 BroadcastChannel message creation"); |
| } |
| |
| await send(worker_2_uuid, "await self.registration.unregister();"); |
| worker_2_uuid = undefined; |
| |
| }).then(event => { |
| assert_equals(event.data, "worker2 msg"); |
| }); |
| |
| }, "BroadcastChannel messages aren't received from a cross-partition service worker"); |
| |
| </script> |
| </body> |