summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/cross-origin-opener-policy/resources/popup-test.js
diff options
context:
space:
mode:
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.js99
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);
+}
+