| <title> |
| This tests the inheritance of COOP for navigations of the top document to about:blank. |
| </title> |
| <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> |
| <script src="/html/cross-origin-opener-policy/resources/common.js"></script> |
| |
| |
| <p>Non-initial empty documents (about:blank) should inherit their |
| cross-origin-opener-policy from the navigation's initiator top level document, |
| if the initiator and its top level document are same-origin, or default (to |
| unsafe-none) otherwise. |
| </p> |
| |
| <ol> |
| <li>Create the opener popup with a given COOP <code>openerCOOP</code>.</li> |
| <li>Add iframe to the opener popup that is either same-origin or |
| cross-origin. |
| </li> |
| <li>Opener opens a new window, to a network document with the same origin and |
| COOP value as opener.</li> |
| <li>Opener's iframe navigates its parent frame (opener) to about:blank.</li> |
| <li>Verify the openee still has access to its opener.</li> |
| </ol> |
| |
| <script> |
| const executor_path = "/common/dispatcher/executor.html?pipe="; |
| const same_origin = get_host_info().HTTPS_ORIGIN; |
| const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; |
| const coop_same_origin_header = |
| '|header(Cross-Origin-Opener-Policy,same-origin)'; |
| const coop_same_origin_allow_popups_header = |
| '|header(Cross-Origin-Opener-Policy,same-origin-allow-popups)'; |
| const coop_unsafe_none_header = |
| '|header(Cross-Origin-Opener-Policy,unsafe-none)'; |
| |
| function navigateToAboutBlankTest( |
| COOP_header, |
| iframe_origin, |
| expect_opener_closed |
| ){ |
| return promise_test(async t => { |
| const this_window_token = token(); |
| const opener_token = token(); |
| const openee_token = token(); |
| const iframe_token = token(); |
| |
| const opener_url = same_origin + executor_path + COOP_header + |
| `&uuid=${opener_token}`; |
| const openee_url = same_origin + executor_path + COOP_header + |
| `&uuid=${openee_token}`; |
| const iframe_url = iframe_origin + executor_path + `&uuid=${iframe_token}`; |
| |
| t.add_cleanup(() => { |
| send(opener_token, "window.close()"); |
| send(openee_token, "window.close()"); |
| }); |
| |
| // 1. Create the opener window. |
| let opener_window_proxy = window.open(opener_url, opener_token); |
| |
| // 2. Create the iframe. |
| send(opener_token, ` |
| iframe = document.createElement('iframe'); |
| iframe.src = "${iframe_url}"; |
| document.body.appendChild(iframe); |
| `); |
| |
| // 3. The opener opens openee window. |
| send(opener_token, ` |
| window.openee = window.open( |
| '${openee_url.replace(/,/g, '\\,')}' |
| ); |
| `); |
| |
| // 4. Ensure the popup is fully loaded. |
| send(openee_token, `send("${this_window_token}", "Ack");`); |
| assert_equals(await receive(this_window_token), "Ack"); |
| |
| // 5. The iframe navigates its top-level document to about:blank. It needs |
| // to receive a user action as it may be cross-origin and it navigates top |
| // to a cross-origin document. |
| // https://github.com/WICG/interventions/issues/16 |
| send(iframe_token, addScriptAndTriggerOnload( |
| "/resources/testdriver.js", |
| `${addScriptAndTriggerOnload("/resources/testdriver-vendor.js", |
| ` |
| test_driver.bless('navigate top to about:blank', () => { |
| open("about:blank", "_top"); |
| }); |
| `)} |
| `)); |
| |
| // 6. Ensure opener is fully loaded and then retrieve the results. |
| send(openee_token, ` |
| (async function() { |
| const timeout = 2000; |
| const retry_delay = 100; |
| for(let i = 0; i * retry_delay < timeout; ++i) { |
| // A try-catch block is used, because of same-origin policy, |
| // which may prevent the access to the opener if its origin changed, |
| // after a navigation to about:blank from the cross origin iframe. |
| try { |
| if ( |
| window.opener === null || |
| window.opener.closed || |
| window.opener.document.location.href == "about:blank") { |
| send("${this_window_token}", "about:blank loaded"); |
| return; |
| } |
| } catch(e) { |
| // The exception is thrown when about:blank is loaded and is |
| // cross-origin with openee. |
| send("${this_window_token}", "about:blank loaded"); |
| return; |
| } |
| await new Promise(resolve => setTimeout(resolve, retry_delay)); |
| } |
| send("${this_window_token}", "about:blank NOT loaded"); |
| })() |
| `); |
| assert_equals(await receive(this_window_token), "about:blank loaded"); |
| |
| // 7. Retrieve and check the results. |
| send(openee_token, ` |
| send( |
| "${this_window_token}", |
| window.opener === null || window.opener.closed); |
| `); |
| |
| assert_equals(await receive(this_window_token), `${expect_opener_closed}`); |
| }, `Navigate top to about:blank from iframe with \ |
| opener COOP: ${COOP_header}, iframe origin: ${iframe_origin}`); |
| }; |
| |
| // iframe same-origin with its top-level embedder: |
| // initial empty document and about:blank navigations initiated from the |
| // same-origin iframe will inherit COOP from the iframe's top-level embedder. |
| |
| // Opener's navigation to about:blank stays in the same browsing context group. |
| navigateToAboutBlankTest( |
| coop_same_origin_header, |
| same_origin, |
| false |
| ); |
| |
| // iframe cross-origin with its top-level embedder: |
| // initial empty document and about:blank navigations initiated from the |
| // cross-origin iframe will default COOP to unsafe-none. |
| |
| // Opener's navigation to about:blank doesn't inherit COOP, leading to a |
| // browsing context group switch. |
| navigateToAboutBlankTest( |
| coop_same_origin_header, |
| cross_origin, |
| true |
| ); |
| |
| // Same origin allow popups allows the navigation of top to the cross-origin |
| // about:blank (origin inherited from the iframe) page, which does not have COOP |
| // (initiator is a cross origin iframe). |
| navigateToAboutBlankTest( |
| coop_same_origin_allow_popups_header, |
| cross_origin, |
| false |
| ); |
| </script> |