diff options
Diffstat (limited to 'testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js')
-rw-r--r-- | testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js b/testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js new file mode 100644 index 0000000000..c2717bb135 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js @@ -0,0 +1,99 @@ +// To use the functions below, be sure to include the following files in your +// test: +// - "/common/get-host-info.sub.js" to get the different origin values. +// - "common.js" to have the origins easily available. +// - "/common/dispatcher/dispatcher.js" for cross-origin messaging. +// - "/common/utils.js" for token(). + +function getExecutorPath(uuid, origin, headers) { + const executor_path = '/common/dispatcher/executor.html?'; + const coop_header = headers.coop ? + `|header(Cross-Origin-Opener-Policy,${encodeURIComponent(headers.coop)})` : ''; + const coep_header = headers.coep ? + `|header(Cross-Origin-Embedder-Policy,${encodeURIComponent(headers.coep)})` : ''; + return origin + + executor_path + + `uuid=${uuid}` + + '&pipe=' + coop_header + coep_header; +} + +function getPopupHasOpener(popup_token) { + const reply_token = token(); + send(popup_token, `send('${reply_token}', window.opener != null);`); + return receive(reply_token); +} + +// Return true if |object|.|property| can be called without throwing an error. +function canAccessProperty(object, property) { + try { + const unused = object[property]; + return true; + } catch (errors) { + return false; + } +} + +// Verifies that a popup with origin `origin` and headers `headers` has +// the expected `opener_state` after being opened. +async function popup_test(description, origin, headers, expected_opener_state) { + promise_test(async t => { + const popup_token = token(); + const reply_token = token(); + + const popup_url = getExecutorPath( + popup_token, + origin.origin, + headers); + + // We open popup and then ping it, it will respond after loading. + const popup = window.open(popup_url); + send(popup_token, `send('${reply_token}', 'Popup loaded');`); + assert_equals(await receive(reply_token), 'Popup loaded'); + + // Make sure the popup will be closed once the test has run, keeping a clean + // state. + t.add_cleanup(() => { + send(popup_token, `close()`); + }); + + // Give some time for things to settle across processes etc. before + // proceeding with verifications. + await new Promise(resolve => { t.step_timeout(resolve, 500); }); + + // Verify that the opener is in the state we expect it to be in. + switch (expected_opener_state) { + case 'preserved': { + assert_false(popup.closed, 'Popup is closed from opener?'); + assert_true(await getPopupHasOpener(popup_token) === "true", + 'Popup has nulled opener?'); + assert_equals(canAccessProperty(popup, "document"), + origin === SAME_ORIGIN, + 'Main page has dom access to the popup?'); + assert_true(canAccessProperty(popup, "frames"), + 'Main page has cross origin access to the popup?'); + break; + } + case 'restricted': { + assert_false(popup.closed, 'Popup is closed from opener?'); + assert_true(await getPopupHasOpener(popup_token) === "true", + 'Popup has nulled opener?'); + assert_false(canAccessProperty(popup, "document"), + 'Main page has dom access to the popup?'); + assert_false(canAccessProperty(popup, "frames"), + 'Main page has cross origin access to the popup?'); + assert_true(canAccessProperty(popup, "closed"), + 'Main page has limited cross origin access to the popup?'); + break; + } + case 'severed': { + assert_true(popup.closed, 'Popup is closed from opener?'); + assert_false(await getPopupHasOpener(popup_token) === "true", + 'Popup has nulled opener?'); + break; + } + default: + assert_unreached(true, "Unrecognized opener relationship: " + expected_opener_state); + } + }, description); +} + |