| <!doctype html> |
| <meta name="timeout" content="long"> |
| <title>Cross-Origin-Embedder-Policy header and nested navigable resource without such header</title> |
| <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> <!-- Use token() to allow running tests in parallel --> |
| <div id=log></div> |
| <script> |
| const HOST = get_host_info(); |
| const BASE = "/html/cross-origin-embedder-policy/resources"; |
| |
| // WebKit-specific version of the test because the original WPT test was assuming that REMOTE_ORIGIN was same-site. |
| HOST.SAME_SITE_ORIGIN = "https://" + HOST.ORIGINAL_HOST + ":" + HOST.HTTPS_PORT2; |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| t.add_cleanup(() => frame.remove()); |
| frame.src = "/common/blank.html"; |
| document.body.append(frame); |
| // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a |
| // timeout is used here. Long term all network error handling should be similar and have a |
| // reliable event. |
| assert_equals(frame.contentDocument.body.localName, "body"); |
| t.step_wait_func_done(() => frame.contentDocument === null); |
| }, `"require-corp" top-level: navigating a frame to "none" should fail`); |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| t.add_cleanup(() => frame.remove()); |
| const bc = new BroadcastChannel(token()); |
| bc.onmessage = t.step_func((event) => { |
| let payload = event.data; |
| assert_equals(payload, "loaded"); |
| t.step_wait_func_done(() => frame.contentDocument === null); |
| }); |
| frame.src = `/html/cross-origin-embedder-policy/resources/navigate-require-corp.sub.html?channelName=${bc.name}&to=/common/blank.html`; |
| document.body.append(frame); |
| assert_equals(frame.contentDocument.body.localName, "body"); |
| }, `"require-corp" top-level: navigating a frame from "require-corp" to "none" should fail`); |
| |
| async_test(t => { |
| let pageLoaded = false; |
| const bc = new BroadcastChannel(token()); |
| let finished = false; |
| bc.onmessage = t.step_func((event) => { |
| let payload = event.data; |
| assert_equals(payload, "loaded"); |
| pageLoaded = true; |
| }); |
| |
| const bc2 = new BroadcastChannel(token()); |
| bc2.onmessage = t.step_func_done((event) => { |
| let payload = event.data; |
| assert_equals(payload, "loaded"); |
| assert_equals(pageLoaded, true); |
| }); |
| |
| const win = window.open(`/html/cross-origin-embedder-policy/resources/navigate-none.sub.html?channelName=${bc.name}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", "noopener"); |
| assert_equals(win, null); |
| }, `"require-corp" top-level: creating a noopener "none" popup should succeed`); |
| |
| async_test(t => { |
| let pageLoaded = false; |
| const bc = new BroadcastChannel(token()); |
| bc.onmessage = t.step_func_done((event) => { |
| pageLoaded = true; |
| let payload = event.data; |
| assert_equals(payload, "loaded"); |
| }); |
| |
| const win = window.open(`/html/cross-origin-embedder-policy/resources/navigate-none.sub.html?channelName=${bc.name}&to=/common/blank.html`, "_blank"); |
| t.add_cleanup(() => win.close()); |
| }, `"require-corp" top-level: creating a "none" popup should succeed.`); |
| |
| [ |
| { |
| "name": "", |
| "title": "as popup" |
| }, |
| { |
| "name": "noopener", |
| "title": "as noopener popup" |
| }, |
| { |
| "name": "clear opener", |
| "title": "as popup with opener set to null" |
| } |
| ].forEach(({name, title}) => { |
| async_test(t => { |
| let pageLoaded = false; |
| const bc = new BroadcastChannel(token()); |
| bc.onmessage = t.step_func(event => { |
| pageLoaded = true; |
| const payload = event.data; |
| assert_equals(payload, "loaded"); |
| }); |
| |
| const bc2 = new BroadcastChannel(token()); |
| bc2.onmessage = t.step_func_done(event => { |
| const payload = event.data; |
| assert_equals(payload, "loaded"); |
| assert_equals(pageLoaded, true); |
| }); |
| |
| let clearOpener = ""; |
| if (name === "clear opener") { |
| clearOpener = "&clearOpener=true" |
| } |
| |
| let noopener = undefined; |
| if (name === "noopener") { |
| noopener = "noopener" |
| } |
| |
| const win = window.open(`/html/cross-origin-embedder-policy/resources/navigate-require-corp.sub.html?channelName=${bc.name}${clearOpener}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", noopener); |
| if (name === "noopener") { |
| assert_equals(win, null); |
| } else { |
| t.add_cleanup(() => win.close()); |
| } |
| }, `"require-corp" top-level (${title}): navigating to "none" should succeed`); |
| }); |
| |
| promise_test(async t => { |
| const response = await fetch(HOST.SAME_SITE_ORIGIN+"/html/cross-origin-embedder-policy/resources/nothing-cross-origin-corp.txt", {mode: "no-cors"}); |
| assert_equals(response.type, "opaque"); |
| }, `"require-corp" top-level: fetch() to CORP: cross-origin response should succeed`); |
| |
| promise_test(t => { |
| return promise_rejects_js(t, TypeError, fetch(HOST.SAME_SITE_ORIGIN+"/common/blank.html", {mode: "no-cors"})); |
| }, `"require-corp" top-level: fetch() to response without CORP should fail`); |
| |
| promise_test(t => { |
| const w = window.open(); |
| return promise_rejects_js(t, w.TypeError, w.fetch(HOST.SAME_SITE_ORIGIN+"/common/blank.html", {mode: "no-cors"})); |
| }, `"require-corp" top-level: fetch() to response without CORP through a WindowProxy should fail`); |
| |
| async_test(t => { |
| let w = window.open(); |
| const frame = w.document.createElement("iframe"); |
| t.add_cleanup(() => { |
| w.close(); |
| frame.remove(); |
| }); |
| frame.src = "/common/blank.html"; |
| document.body.append(frame); |
| // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a |
| // timeout is used here. Long term all network error handling should be similar and have a |
| // reliable event. |
| assert_equals(frame.contentDocument.body.localName, "body"); |
| t.step_wait_func_done(() => frame.contentDocument === null); |
| }, `"require-corp" top-level: navigating an iframe to a page without CORP, through a WindowProxy, should fail`); |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| const id = token(); |
| t.add_cleanup(() => frame.remove()); |
| window.addEventListener('message', t.step_func((e) => { |
| if (e.data === id) { |
| // Loaded! |
| t.done(); |
| } |
| })); |
| // REMOTE_ORIGIN is cross-origin, same-site. |
| frame.src = `${HOST.SAME_SITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`; |
| document.body.append(frame); |
| }, 'CORP: same-site is checked and allowed.'); |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| const id = token(); |
| t.add_cleanup(() => frame.remove()); |
| let loaded = false; |
| window.addEventListener('message', t.step_func((e) => { |
| if (e.data === id) { |
| loaded = true; |
| } |
| })); |
| t.step_timeout(() => { |
| // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a |
| // timeout is used here. Long term all network error handling should be similar and have a |
| // reliable event. |
| assert_false(loaded); |
| t.done(); |
| }, 2000); |
| |
| // NOTESAMESITE_ORIGIN is cross-origin, cross-site. |
| frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`; |
| document.body.append(frame); |
| }, 'CORP: same-site is checked and blocked.'); |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| const bc = new BroadcastChannel(token()); |
| t.add_cleanup(() => frame.remove()); |
| bc.onmessage = t.step_func_done((event) => { |
| const payload = event.data; |
| assert_equals(payload, "loaded"); |
| }); |
| |
| const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; |
| // REMOTE_ORIGIN is cross-origin, same-site. |
| frame.src = `${HOST.SAME_SITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?to=${encodeURIComponent(dest)}`; |
| document.body.append(frame); |
| }, 'navigation CORP is checked with the parent frame, not the navigation source - to be allowed'); |
| |
| async_test(t => { |
| const frame = document.createElement("iframe"); |
| const bc = new BroadcastChannel(token()); |
| t.add_cleanup(() => frame.remove()); |
| let loaded = false; |
| bc.onmessage = t.step_func((event) => { |
| loaded = true; |
| }); |
| t.step_timeout(() => { |
| // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a |
| // timeout is used here. Long term all network error handling should be similar and have a |
| // reliable event. |
| assert_false(loaded); |
| t.done(); |
| }, 2000); |
| |
| const dest = `${HOST.REMOTE_ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; |
| // REMOTE_ORIGIN is cross-origin, same-site. |
| frame.src = `${HOST.REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?to=${encodeURIComponent(dest)}`; |
| document.body.append(frame); |
| }, 'navigation CORP is checked with the parent frame, not the navigation source - to be blocked'); |
| |
| async_test(t => { |
| const bc = new BroadcastChannel(token()); |
| let loaded = false; |
| bc.onmessage = t.step_func((event) => { |
| loaded = true; |
| }); |
| t.step_timeout(() => { |
| // Make sure the iframe didn't load. See |
| // https://github.com/whatwg/html/issues/125 for why a timeout is used |
| // here. Long term all network error handling should be similar and have a |
| // reliable event. |
| assert_false(loaded); |
| t.done(); |
| }, 2000); |
| |
| const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; |
| const frame = document.createElement("iframe"); |
| t.add_cleanup(() => frame.remove()); |
| // |dest| is a same-origin URL and hence not blocked by CORP but reidirect.py |
| // is a cross-origin (actually cross-site) URL, so blocked by CORP. |
| frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}/common/redirect.py?location=${encodeURIComponent(dest)}`; |
| document.body.append(frame); |
| }, 'navigation CORP is checked for each redirect'); |
| |
| </script> |