summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/cross-origin-opener-policy/reporting
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/cross-origin-opener-policy/reporting')
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml6
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html82
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html85
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html63
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html63
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html92
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html93
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html77
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html79
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html67
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html68
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html82
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html83
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html66
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers1
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html71
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers1
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html13
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html124
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html275
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html86
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers6
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html124
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html111
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html130
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html86
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers6
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html71
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers1
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html96
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers3
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html32
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers3
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html32
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers3
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html73
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers2
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html67
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html85
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers2
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html126
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers3
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html173
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers4
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html216
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers3
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html110
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers1
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html126
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers2
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html111
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js422
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js65
-rw-r--r--testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js20
68 files changed, 4074 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml
new file mode 100644
index 0000000000..0db28208a6
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml
@@ -0,0 +1,6 @@
+suggested_reviewers:
+ - ArthurSonzogni
+ - ParisMeuleman
+ - camillelamy
+ - hemeryar
+ - mikewest
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html
new file mode 100644
index 0000000000..a7e83cc0d9
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html
@@ -0,0 +1,82 @@
+<title>
+ COOP reports are to the opener when the opener used COOP-RO+COEP and then it
+ tries to access a same-origin openee.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_report_token= token();
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(opener_report_token);
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This is same origin with the "opener".
+ const openee_report_token = token();
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens it openee.
+ send(opener_token, `
+ openee = window.open("${openee_requested_url}");
+ send("${this_window_token}", "ACK 1");
+ `);
+ assert_equals("ACK 1", await receive(this_window_token));
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. Ensure the openee's document to be loaded.
+ send(openee_token, `
+ send("${this_window_token}", "ACK 2");
+ `);
+ assert_equals("ACK 2", await receive(this_window_token));
+
+ // 4. The opener tries to access its openee.
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee);")
+ );
+ // 5. Check a report sent to the opener.
+ let report =
+ await receiveReport(opener_report_token, "access-from-coop-page-to-openee")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, openee_url);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, openee_requested_url);
+}, name);
+
+runTest(false, "access-from-coop-page-to-openee, same-origin");
+runTest(true , "access-from-coop-page-to-openee, same-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..fe72a2299f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html
@@ -0,0 +1,85 @@
+<title>
+ COOP reports are to the opener when the opener used COOP-RO+COEP and then it
+ tries to access a cross-origin openee.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_report_token= token();
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(opener_report_token);
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This is cross origin with the "opener".
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_url = cross_origin + executor_path + `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens it openee.
+ send(opener_token, `
+ openee = window.open("${openee_requested_url}");
+ send("${this_window_token}", "ACK 1");
+ `);
+ assert_equals("ACK 1", await receive(this_window_token));
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. Ensure the openee's document to be loaded.
+ send(openee_token, `
+ send("${this_window_token}", "ACK 2");
+ `);
+ assert_equals("ACK 2", await receive(this_window_token));
+
+ // 4. The opener tries to access its openee.
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee);")
+ );
+
+
+ // 5. Check a report sent to the opener.
+ let report =
+ await receiveReport(opener_report_token, "access-from-coop-page-to-openee")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, "");
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, openee_requested_url);
+}, name);
+
+runTest(false, "access-from-coop-page-to-openee, cross-origin");
+runTest(true , "access-from-coop-page-to-openee, cross-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html
new file mode 100644
index 0000000000..005339a06e
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html
@@ -0,0 +1,63 @@
+<title>
+ COOP reports are sent when the openee used COOP-RO+COEP and then tries to
+ access its same-origin opener.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ const report_token = token();
+ const openee_token = token();
+
+ const opener_url = location.href;
+
+ const reportTo = reportToHeaders(report_token);
+ const openee_url = same_origin + executor_path +
+ reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ const openee = window.open(openee_requested_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Try to access the opener. A report is sent, because of COOP-RO+COEP.
+
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ // 2. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-from-coop-page-to-opener")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, opener_url);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, opener_url);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, name);
+
+runTest(false, "access-from-coop-page-to-opener, same-origin");
+runTest(true , "access-from-coop-page-to-opener, same-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..eedfaa557f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html
@@ -0,0 +1,63 @@
+<title>
+ COOP reports are sent when the openee used COOP-RO+COEP and then tries to
+ access its cross-origin opener.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ const report_token = token();
+ const openee_token = token();
+
+ const opener_origin = location.origin + '/';
+
+ const reportTo = reportToHeaders(report_token);
+ const openee_url = cross_origin + executor_path +
+ reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ const openee = window.open(openee_requested_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Try to access the opener. A report is sent, because of COOP-RO+COEP.
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ // 2. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-from-coop-page-to-opener")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, "");
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, opener_origin);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, name);
+
+runTest(false, "access-from-coop-page-to-opener, cross-origin");
+runTest(true , "access-from-coop-page-to-opener, cross-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html
new file mode 100644
index 0000000000..90df0e4e99
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html
@@ -0,0 +1,92 @@
+<title>
+ One window accesses a second one. They are aren't related by an opener/openee
+ relationship. The first window has set
+ Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a
+ "access-from-coop-page-to-other" report.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+promise_test(async t => {
+ const report_token= token();
+ const report_to = reportToHeaders(report_token);
+
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. With COOP:same-origin + reporter.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + report_to.header +
+ report_to.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. With COOP:same-origin + reporter.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + report_to.header +
+ report_to.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // The "other" window.
+ const other_token = token();
+ const other_url = same_origin + executor_path + report_to.header +
+ `&uuid=${other_token}`;
+
+ t.add_cleanup(() => {
+ send(opener_token, "window.close()")
+ send(openee_token, "window.close()")
+ send(other_token, "window.close()")
+ })
+
+ // 1. Create the "opener" window.
+ let opener_window_proxy = window.open(opener_url);
+
+ // 2. Create the "openee" window.
+ send(opener_token, `
+ window.openee = window.open('${escapeComma(openee_url)}');
+ `);
+
+ // 3. Create the "other" window.
+ send(openee_token, `
+ window.other = window.open('${escapeComma(other_url)}');
+ `);
+
+ // 4. Wait for "other" to load its document.
+ send(other_token, `send('${this_window_token}', "Loaded");`);
+ assert_equals(await receive(this_window_token), "Loaded");
+
+ // 5. "opener" accesses "other" window, through "openee".
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee.other);")
+ );
+
+ // 6. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-from-coop-page-to-other")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, other_url.replace(/"/g, '%22'));
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, "access-from-coop-page-to-other (COOP-RO)");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..f0d60c2531
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html
@@ -0,0 +1,93 @@
+<title>
+ One window accesses a second one. They are aren't related by an opener/openee
+ relationship. The first window has set
+ Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a
+ "access-from-coop-page-to-other" report.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin= get_host_info().HTTPS_ORIGIN;
+const cross_origin= get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+promise_test(async t => {
+ const report_token= token();
+ const report_to = reportToHeaders(report_token);
+
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. With COOP:same-origin + reporter.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + report_to.header +
+ report_to.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. With COOP:same-origin + reporter.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + report_to.header +
+ report_to.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // The "other" window.
+ const other_token = token();
+ const other_url = cross_origin + executor_path + report_to.header +
+ `&uuid=${other_token}`;
+
+ t.add_cleanup(() => {
+ send(opener_token, "window.close()")
+ send(openee_token, "window.close()")
+ send(other_token, "window.close()")
+ })
+
+ // 1. Create the "opener" window.
+ let opener_window_proxy = window.open(opener_url);
+
+ // 2. Create the "openee" window.
+ send(opener_token, `
+ window.openee = window.open('${escapeComma(openee_url)}');
+ `);
+
+ // 3. Create the "other" window.
+ send(openee_token, `
+ window.other = window.open('${escapeComma(other_url)}');
+ `);
+
+ // 4. Wait for "other" to load its document.
+ send(other_token, `send('${this_window_token}', "Loaded");`);
+ assert_equals(await receive(this_window_token), "Loaded");
+
+ // 5. "opener" accesses "other" window, through "openee".
+
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee.other);")
+ );
+
+ // 6. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-from-coop-page-to-other")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_found(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, "");
+ assert_equals(report.body.referrer, undefined);
+}, "access-from-coop-page-to-other (COOP-RO)");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html
new file mode 100644
index 0000000000..9f0a8821a4
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html
@@ -0,0 +1,77 @@
+<title>
+ COOP reports are to the opener when the opener used COOP-RO+COEP and then its
+ same-origin openee tries to access it.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_report_token= token();
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(opener_report_token);
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This is same origin with the "opener".
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `
+ openee = window.open("${openee_requested_url}");
+ send("${this_window_token}", "ACK 1");
+ `);
+ assert_equals("ACK 1", await receive(this_window_token));
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. The openee tries to access its opener.
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ // 4. Check a report sent to the opener.
+ let report =
+ await receiveReport(opener_report_token, "access-to-coop-page-from-openee")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, openee_url);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, openee_requested_url);
+}, name);
+
+runTest(false, "access-to-coop-page-from-openee, same-origin");
+runTest(true , "access-to-coop-page-from-openee, same-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..d9577836d9
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html
@@ -0,0 +1,79 @@
+<title>
+ COOP reports are to the opener when the opener used COOP-RO+COEP and then its
+ cross-origin openee tries to access it.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+const cross_origin= get_host_info().HTTPS_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_report_token= token();
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(opener_report_token);
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This is cross origin with the "opener".
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_url = cross_origin + executor_path + `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `
+ openee = window.open("${openee_requested_url}");
+ send("${this_window_token}", "ACK 1");
+ `);
+ assert_equals("ACK 1", await receive(this_window_token));
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. The openee tries to access its opener.
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ // 4. Check a report sent to the opener.
+ let report =
+ await receiveReport(opener_report_token, "access-to-coop-page-from-openee")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, "");
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, openee_requested_url);
+}, name);
+
+runTest(false, "access-to-coop-page-from-openee, cross-origin");
+runTest(true , "access-to-coop-page-from-openee, cross-origin + redirect)");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html
new file mode 100644
index 0000000000..8a643d762c
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html
@@ -0,0 +1,67 @@
+<title>
+ COOP reports are sent when the openee used COOP-RO+COEP and then its
+ same-origin opener tries to access it.
+</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/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ const report_token = token();
+ const openee_token = token();
+ const opener_token = token(); // The current test window.
+
+ const opener_url = location.href;
+
+ const reportTo = reportToHeaders(report_token);
+ const openee_url = same_origin + executor_path + reportTo.header +
+ reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+
+ const openee = window.open(openee_requested_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Make sure the new document to be loaded.
+ send(openee_token, `
+ send("${opener_token}", "Ready");
+ `);
+ let reply = await receive(opener_token);
+ assert_equals(reply, "Ready");
+
+ // 2. Try to access the openee. A report is sent, because of COOP-RO+COEP.
+ tryAccess(openee);
+
+ // 3. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-to-coop-page-from-opener")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, opener_url);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, opener_url);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, name);
+
+runTest(false, "access-to-coop-page-from-opener, same-origin");
+runTest(true , "access-to-coop-page-from-opener, same-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..7e1ae870a7
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html
@@ -0,0 +1,68 @@
+<title>
+ COOP reports are sent when the openee used COOP-RO+COEP and then its
+ cross-origin opener tries to access it.
+</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/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const redirect_path = directory + "/resources/redirect.py?";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let runTest = (openee_redirect, name) => promise_test(async t => {
+ const report_token = token();
+ const openee_token = token();
+ const opener_token = token(); // The current test window.
+
+ const opener_origin = location.origin + '/';
+
+ const reportTo = reportToHeaders(report_token);
+ const openee_url = cross_origin + executor_path +
+ reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+ const openee_redirect_url = same_origin + redirect_path + openee_url
+ const openee_requested_url = openee_redirect ? openee_redirect_url
+ : openee_url;
+
+
+ const openee = window.open(openee_requested_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Make sure the new document to be loaded.
+ send(openee_token, `
+ send("${opener_token}", "Ready");
+ `);
+ let reply = await receive(opener_token);
+ assert_equals(reply, "Ready");
+
+ // 2. Try to access the openee. A report is sent, because of COOP-RO+COEP.
+ tryAccess(openee);
+
+ // 3. Check a report is sent to the openee.
+ let report =
+ await receiveReport(report_token, "access-to-coop-page-from-opener")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, "");
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, undefined);
+ assert_equals(report.body.referrer, opener_origin);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, name);
+
+runTest(false, "access-to-coop-page-from-opener, cross-origin");
+runTest(true , "access-to-coop-page-from-opener, cross-origin + redirect");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html
new file mode 100644
index 0000000000..b73bab8610
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html
@@ -0,0 +1,82 @@
+<title>
+ One window accesses a second one. They are aren't related by an opener/openee
+ relationship. The second window has set
+ Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a
+ "access-to-coop-page-from-other" report.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + `&uuid=${opener_token}`;
+
+ // The "openee" window. With COOP:same-origin + reporter.
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_reportTo = reportToHeaders(openee_report_token);
+ const openee_url = same_origin + executor_path + openee_reportTo.header +
+ openee_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // The "other" window.
+ const other_token = token();
+ const other_url = same_origin + executor_path + `&uuid=${other_token}`;
+
+ t.add_cleanup(() => {
+ send(opener_token, "window.close()")
+ send(openee_token, "window.close()")
+ send(other_token, "window.close()")
+ })
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+
+ // 2. The opener opens its openee and the other window.
+ send(opener_token, `
+ window.openee = window.open('${openee_url.replace(/,/g, '\\,')}');
+ window.other = window.open('${other_url}');
+ `);
+
+ // 3. Make sure the openee is loaded.
+ send(openee_token, `send("${this_window_token}", "Loaded");`);
+ assert_equals(await receive(this_window_token), "Loaded");
+
+ // 4. The "other" window attempts to access the openee though the opener.
+ send(other_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener.openee);")
+ );
+
+ // 4. Check a report sent to the openee.
+ let report =
+ await receiveReport(openee_report_token, "access-to-coop-page-from-other")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, other_url);
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, "access-to-coop-page-from-other (COOP-RO)");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html
new file mode 100644
index 0000000000..c86daa3dca
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html
@@ -0,0 +1,83 @@
+<title>
+ One window accesses a second one. They are aren't related by an opener/openee
+ relationship. The second window has set
+ Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a
+ "access-to-coop-page-from-other" report.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + `&uuid=${opener_token}`;
+
+ // The "openee" window. With COOP:same-origin + reporter.
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_reportTo = reportToHeaders(openee_report_token);
+ const openee_url = cross_origin + executor_path + openee_reportTo.header +
+ openee_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // The "other" window.
+ const other_token = token();
+ const other_url = same_origin + executor_path + `&uuid=${other_token}`;
+
+ t.add_cleanup(() => {
+ send(opener_token, "window.close()")
+ send(openee_token, "window.close()")
+ send(other_token, "window.close()")
+ })
+
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+
+ // 2. The opener opens its openee and the other window.
+ send(opener_token, `
+ window.openee = window.open('${openee_url.replace(/,/g, '\\,')}');
+ window.other = window.open('${other_url}');
+ `);
+
+ // 3. Make sure the openee is loaded.
+ send(openee_token, `send("${this_window_token}", "Loaded");`);
+ assert_equals(await receive(this_window_token), "Loaded");
+
+ // 4. The "other" window attempts to access the openee though the opener.
+ send(other_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener.openee);")
+ );
+
+ // 4. Check a report sent to the openee.
+ let report =
+ await receiveReport(openee_report_token, "access-to-coop-page-from-other")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, openee_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+ assert_source_location_missing(report);
+ assert_equals(report.body.openerURL, undefined);
+ assert_equals(report.body.openeeURL, undefined);
+ assert_equals(report.body.otherDocumentURL, "");
+ assert_equals(report.body.referrer, undefined);
+ assert_equals(report.body.initialPopupURL, undefined);
+}, "access-to-coop-page-from-other (COOP-RO)");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html
new file mode 100644
index 0000000000..849bf6579a
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.blur() access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("blur", w => w.blur());
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html
new file mode 100644
index 0000000000..7696600488
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.close() access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("close", w => w.close());
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html
new file mode 100644
index 0000000000..c678d18a80
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.closed access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("closed", w => w.closed);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html
new file mode 100644
index 0000000000..363c0d294f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.focus() access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("focus", w => w.focus());
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html
new file mode 100644
index 0000000000..fc1925045f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.frames access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("frames", w => w.frames);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html
new file mode 100644
index 0000000000..b6c5f5acb1
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html
@@ -0,0 +1,66 @@
+<title> Check reports are sent for the indexed getter</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>
+
+const directory = "/html/cross-origin-opener-policy";
+const executor_path = "/common/dispatcher/executor.html?pipe=";
+const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
+
+let origin = [
+ ["cross-origin" , get_host_info().HTTPS_REMOTE_ORIGIN ] ,
+ ["same-site" , get_host_info().HTTPS_ORIGIN ] ,
+];
+
+let testCase = [
+//[operation , expectReport ] ,
+ [w => w[0] , true ], // Existing iframe.
+ [w => w[1] , false ], // Out of bounds (positive).
+ [w => w[-1] , false ], // Out of bounds (negative).
+];
+
+origin.forEach(([origin_name, origin]) => {
+ testCase.forEach(([op, expectReport]) => {
+ promise_test(async t => {
+ const opener_token = token();
+ const openee_token = token();
+
+ const openee_url = origin+ executor_path + `&uuid=${openee_token}`;
+ const openee = window.open(openee_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Create an iframe in the openee.
+ send(openee_token, `
+ let iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+
+ send("${opener_token}", "openee loaded");
+ `);
+ let reply = await receive(opener_token);
+ assert_equals(reply, "openee loaded");
+
+ // 2. Try to access the openee.
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ try {op(openee)} catch(e) {}
+ let reports = observer.takeRecords();
+ observer.disconnect();
+
+ // 3. Check the received reports.
+ if (expectReport) {
+ assert_equals(reports.length, 1);
+ assert_equals(reports[0].type, "coop-access-violation");
+ assert_equals(reports[0].body.property, "indexed");
+ } else {
+ assert_equals(reports.length, 0);
+ }
+
+ }, `${origin_name} > ${op}`);
+});
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers
new file mode 100644
index 0000000000..64f4d5fedf
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="none"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html
new file mode 100644
index 0000000000..a9f3614cb5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.length access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("length", w => w.length);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html
new file mode 100644
index 0000000000..442817748d
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.location access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("location", w => w.location);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html
new file mode 100644
index 0000000000..e42f084821
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.location access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("location", w => w.location = "#");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html
new file mode 100644
index 0000000000..27be9a48d1
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html
@@ -0,0 +1,71 @@
+<title> Check reports are sent for the indexed getter</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>
+
+const executor_path = "/common/dispatcher/executor.html?pipe=";
+let crossOrigin = ["cross-origin" , get_host_info().HTTPS_REMOTE_ORIGIN ];
+let sameOrigin = ["same-site" , get_host_info().HTTPS_ORIGIN ];
+
+let testCase = [
+//[ operation , origin , expectReport ],
+ [ w => w["iframeName"] , sameOrigin , true ],
+ [ w => w["iframeName"] , crossOrigin , true ],
+ [ w => w["divID"] , sameOrigin , true ],
+ [ w => w["divID"] , crossOrigin , false ],
+ [ w => w["existingGlobal"] , sameOrigin , false ],
+ [ w => w["existingGlobal"] , crossOrigin , false ],
+ [ w => w["missingGlobal"] , sameOrigin , false ],
+ [ w => w["missingGlobal"] , crossOrigin , false ],
+];
+
+testCase.forEach(([op, [origin_name, origin], expectReport]) => {
+ promise_test(async t => {
+ const opener_token = token();
+ const openee_token = token();
+
+ const openee_url = origin + executor_path + `&uuid=${openee_token}`;
+ const openee = window.open(openee_url);
+ t.add_cleanup(() => send(openee_token, "window.close()"))
+
+ // 1. Make sure the new document to be loaded. Populate the document.
+ send(openee_token, `
+ let iframe = document.createElement("iframe");
+ iframe.name = "iframeName";
+ document.body.appendChild(iframe);
+
+ let div = document.createElement("div");
+ div.id = "divID";
+ document.body.appendChild(div);
+
+ window.existingGlobal = "test";
+
+ send("${opener_token}", "Ready");
+ `);
+ let reply = await receive(opener_token);
+ assert_equals(reply, "Ready");
+
+ // 2. Try to access the openee.
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ try {op(openee)} catch(e) {}
+ let reports = observer.takeRecords();
+ observer.disconnect();
+
+ // 3. Check the received reports.
+ if (expectReport) {
+ assert_equals(reports.length, 1);
+ assert_equals(reports[0].type, "coop-access-violation");
+ assert_equals(reports[0].body.property, "named");
+ } else {
+ assert_equals(reports.length, 0);
+ }
+
+ }, `${origin_name} > ${op}`);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers
new file mode 100644
index 0000000000..64f4d5fedf
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="none"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html
new file mode 100644
index 0000000000..b99dfdc562
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.opener access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("opener", w => w.opener);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html
new file mode 100644
index 0000000000..10c251140b
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.opener access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("opener", w => w.opener = "", /* expectReport = */false);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html
new file mode 100644
index 0000000000..a9168fdaa5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.postMessage(arg1, arg2) access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("postMessage", w => w.postMessage("", ""));
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html
new file mode 100644
index 0000000000..4341f245d5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.postMessage(arg1) access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("postMessage", w => w.postMessage(""));
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html
new file mode 100644
index 0000000000..7a7d5a3fec
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.self access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("self", w => w.self);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html
new file mode 100644
index 0000000000..1b75ecc105
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.top access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("top", w => w.top);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html
new file mode 100644
index 0000000000..07278b4a11
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html
@@ -0,0 +1,13 @@
+<title> Check openee.window access is checked</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script>
+<script>
+
+testAccessProperty("window", w => w.window);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html
new file mode 100644
index 0000000000..46cdc6eb27
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html
@@ -0,0 +1,124 @@
+<title>
+ Both the openee and the opener have a COOP reporter. The report are sent to
+ both side.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const origin_opener = get_host_info().HTTPS_ORIGIN;
+const origin_openee = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+let genericSetup = async function(test) {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_report_token= token();
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(opener_report_token);
+ const opener_url = origin_opener+ executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This has COOP and a reporter.
+ const openee_report_token= token();
+ const openee_token = token();
+ const openee_reportTo = reportToHeaders(openee_report_token);
+ const openee_url = origin_openee + executor_path + openee_reportTo.header +
+ openee_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // Cleanup at the end of the test.
+ test.add_cleanup(() => {
+ send(openee_token, 'window.close()');
+ send(opener_token, 'window.close()');
+ });
+
+ // 1. Spawn the opener and the openee windows.
+ window.open(opener_url);
+ send(opener_token, `
+ openee = window.open('${escapeComma(openee_url)}');
+ `);
+
+ // 2. Wait for both to be loaded.
+ send(openee_token, `send('${this_window_token}', 'ACK');`);
+ assert_equals(await receive(this_window_token), 'ACK');
+
+ return [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ];
+}
+
+let assert_generic_coop_report = function(report) {
+ assert_equals(report.type, "coop");
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+}
+
+promise_test(async test => {
+ let [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ] = await genericSetup(test);
+
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee);")
+ );
+
+ let report_opener =
+ await receiveReport(opener_report_token, "access-from-coop-page-to-openee")
+ let report_openee =
+ await receiveReport(openee_report_token, "access-to-coop-page-from-opener")
+
+ assert_generic_coop_report(report_openee);
+ assert_generic_coop_report(report_opener);
+
+ assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
+ assert_source_location_found(report_opener);
+ assert_source_location_missing(report_openee);
+}, "Access from opener")
+
+promise_test(async test => {
+ let [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ] = await genericSetup(test);
+
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ let report_opener =
+ await receiveReport(opener_report_token, "access-to-coop-page-from-openee")
+ let report_openee =
+ await receiveReport(openee_report_token, "access-from-coop-page-to-opener")
+
+ assert_generic_coop_report(report_openee);
+ assert_generic_coop_report(report_opener);
+
+ assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
+ assert_source_location_missing(report_opener);
+ assert_source_location_found(report_openee);
+}, "Access from openee")
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html
new file mode 100644
index 0000000000..375c627d27
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html
@@ -0,0 +1,275 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>
+ Check the ReportingObserver(s) are notified about the coop-access-violation
+ events.
+</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_site = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;
+const corp_header = '|header(Cross-Origin-Resource-Policy,cross-origin)';
+
+promise_test(async t => {
+ // This test window.
+ const this_window_token = token();
+
+ // The "opener" window, using COOP-Report-Only and a reporter.
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(token());
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window, NOT using COOP.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + `&uuid=${openee_token}`;
+
+ // 1. Create the opener window.
+ window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close();"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `openee = window.open('${openee_url}');`);
+ t.add_cleanup(() => send(openee_token, `window.close();`));
+
+ // 3. Wait for the openee to load its document.
+ send(openee_token, `send("${this_window_token}", "Ready");`);
+ assert_equals(await receive(this_window_token), "Ready");
+
+ // 4. The opener tries to access its openee. All reports for blocked access
+ // from the COOP page should notify the ReportingObservers.
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ tryAccess(openee);
+ let reports = observer.takeRecords();
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ `));
+
+ let report_access_from = JSON.parse(await receive(this_window_token));
+ assert_equals(report_access_from.length, 1, "No report received.");
+ assert_equals(report_access_from[0].type, "coop-access-violation");
+ assert_equals(report_access_from[0].url, opener_url.replace(/"/g, '%22'));
+ assert_source_location_found(report_access_from[0])
+ assert_equals(report_access_from[0].body.type,
+ "access-from-coop-page-to-openee");
+ assert_equals(report_access_from[0].body.openeeURL, openee_url);
+ assert_equals(report_access_from[0].body.openerURL, undefined);
+ assert_equals(report_access_from[0].body.otherDocumentURL, undefined);
+
+ // 5. The openee tries to access its opener. No reports for blocked access
+ // to the COOP page should be dispatched.
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ tryAccess(opener);
+ let reports = observer.takeRecords();
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ `));
+ let report_access_to = JSON.parse(await receive(this_window_token));
+ assert_equals(report_access_to.length, 0, "Unexpected report received.");
+}, "Opener COOP");
+
+promise_test(async t => {
+ // This test window.
+ const this_window_token = token();
+
+ // The "opener" window, NOT using COOP.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + `&uuid=${opener_token}`;
+
+ // The "openee" window, using COOP-Report-Only and a reporter.
+ const openee_token = token();
+ const openee_reportTo = reportToHeaders(token());
+ const openee_url = same_origin + executor_path + openee_reportTo.header +
+ openee_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // 1. Create the opener window.
+ window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close();"));
+
+ // 2. The opener opens its openee.
+ send(opener_token,
+ `openee = window.open('${openee_url.replace(/,/g, '\\,')}');`);
+ t.add_cleanup(() => send(openee_token, `window.close();`));
+
+ // 3. The openee tries to access its opener. All reports for blocked access
+ // from the COOP page should notify the ReportingObservers.
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ tryAccess(opener);
+ let reports = observer.takeRecords();
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ `));
+ let report_access_from = JSON.parse(await receive(this_window_token));
+ assert_equals(report_access_from.length, 1, "No report received.");
+ assert_equals(report_access_from[0].type, "coop-access-violation");
+ assert_equals(report_access_from[0].url, openee_url.replace(/"/g, '%22'));
+ assert_true(report_access_from[0].body.sourceFile.includes("try-access.js"));
+ assert_source_location_found(report_access_from[0])
+ assert_equals(report_access_from[0].body.type,
+ "access-from-coop-page-to-opener");
+ assert_equals(report_access_from[0].body.openeeURL, undefined);
+ assert_equals(report_access_from[0].body.openerURL, opener_url);
+ assert_equals(report_access_from[0].body.otherDocumentURL, undefined);
+
+ // 4. The opener tries to access its openee. No reports for blocked access
+ // to the COOP page should be dispatched.
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `
+ let observer = new ReportingObserver(()=>{});
+ observer.observe();
+ tryAccess(openee);
+ let reports = observer.takeRecords();
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ `));
+ let report_access_to = JSON.parse(await receive(this_window_token));
+ assert_equals(report_access_to.length, 0, "Unexpected report received.");
+}, "Openee COOP");
+
+promise_test(async t => {
+ // This test window.
+ const this_window_token = token();
+
+ // The "opener" window, using COOP-Report-Only and a reporter.
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(token());
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "opener's iframe", same-origin with its parent.
+ const opener_iframe_token = token();
+ const opener_iframe_url = same_origin + executor_path + coep_header +
+ `&uuid=${opener_iframe_token}`;
+
+ // The "openee" window, NOT using COOP.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + coep_header +
+ `&uuid=${openee_token}`;
+
+ // 1. Create the opener window.
+ window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close();"));
+
+ // 2. The opener opens an iframe, and install a ReportingObserver to catch
+ // future accesses.
+ send(opener_token, `
+ iframe = document.createElement("iframe");
+ iframe.src = "${opener_iframe_url}";
+ document.body.appendChild(iframe);
+
+ let observer = new ReportingObserver(reports => {
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ });
+ observer.observe();
+ `);
+
+ // 3. The iframe opens the openee.
+ send(opener_iframe_token, `openee = window.open('${openee_url}');`);
+ t.add_cleanup(() => send(openee_token, `window.close();`));
+
+ // 4. Wait for the openee to load its document.
+ send(openee_token, `send("${this_window_token}", "Ready");`);
+ assert_equals(await receive(this_window_token), "Ready");
+
+ // 4. The opener's iframe tries to access the openee. This is an
+ // "access-from-coop-page" from a same-origin iframe, so the
+ // ReportingObserver(s) are notified.
+ send(opener_iframe_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `tryAccess(openee);`));
+
+ let reports = await receive(this_window_token);
+ reports = JSON.parse(reports);
+ assert_equals(reports.length, 1, "No report received.");
+ assert_equals(reports[0].type, "coop-access-violation");
+ assert_equals(reports[0].url, opener_url.replace(/"/g, '%22'));
+ assert_true(reports[0].body.sourceFile.includes("try-access.js"));
+ assert_source_location_found(reports[0]);
+ assert_equals(reports[0].body.type,
+ "access-from-coop-page-to-openee");
+ assert_equals(reports[0].body.openeeURL, openee_url);
+ assert_equals(reports[0].body.openerURL, undefined);
+ assert_equals(reports[0].body.otherDocumentURL, undefined);
+}, "Access from same-origin iframe")
+
+promise_test(async t => {
+ // This test window.
+ const this_window_token = token();
+
+ // The "opener" window, using COOP-Report-Only and a reporter.
+ const opener_token = token();
+ const opener_reportTo = reportToHeaders(token());
+ const opener_url = same_origin + executor_path + opener_reportTo.header +
+ opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "opener's iframe", same-origin with its parent.
+ const opener_iframe_token = token();
+ const opener_iframe_url = cross_site + executor_path + coep_header +
+ corp_header +
+ `&uuid=${opener_iframe_token}`;
+
+ // The "openee" window, NOT using COOP.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + coep_header +
+ `&uuid=${openee_token}`;
+
+ // 1. Create the opener window.
+ window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close();"));
+
+ // 2. The opener opens an iframe, and install a ReportingObserver to catch
+ // future accesses.
+ send(opener_token, `
+ iframe = document.createElement("iframe");
+ iframe.src = "${opener_iframe_url}";
+ document.body.appendChild(iframe);
+
+ let observer = new ReportingObserver(reports => {
+ send("${this_window_token}", JSON.stringify(reports));
+ observer.disconnect();
+ });
+ observer.observe();
+ `);
+
+ // 3. The iframe opens the openee.
+ send(opener_iframe_token, `openee = window.open('${openee_url}');`);
+ t.add_cleanup(() => send(openee_token, `window.close();`));
+
+ // 4. Wait for the openee to load its document.
+ send(openee_token, `send("${this_window_token}", "Ready");`);
+ assert_equals(await receive(this_window_token), "Ready");
+
+ // 5. The opener's iframe tries to access the openee. This is an
+ // "access-from-coop-page" from a cross-site iframe. The ReportingObservers
+ // from the main document aren't notified.
+ send(opener_iframe_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js", `tryAccess(openee);`));
+
+ let reports = await receive(this_window_token, 2000);
+ assert_equals(reports, "timeout", "Unexpected report received.");
+}, "Access from cross-site iframe")
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html
new file mode 100644
index 0000000000..7bfdab1330
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html
@@ -0,0 +1,86 @@
+
+<meta name=timeout content=long>
+<title>A test with both COOP and COOP report only setup using Reporting-Endpoints 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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=2aee31d2-cd11-43bd-b34d-5f081ca3b2b4&report_only_id=d18f1779-e2ab-4a7a-8b1c-44e3a6f440f5"></script>
+
+<script>
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup with both normal and report-only COOP. Four
+ // reports are sent.
+ [
+ CROSS_ORIGIN,
+ `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "require-corp",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": reportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ]
+];
+
+runNavigationDocumentReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers
new file mode 100644
index 0000000000..de48445f38
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers
@@ -0,0 +1,6 @@
+Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint"
+Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint"
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Embedder-Policy-Report-Only: require-corp
+Referrer-Policy: origin
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=2aee31d2-cd11-43bd-b34d-5f081ca3b2b4", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d18f1779-e2ab-4a7a-8b1c-44e3a6f440f5"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html
new file mode 100644
index 0000000000..409628c15c
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html
@@ -0,0 +1,124 @@
+<title>
+ Both the openee and the opener have a COOP reporter. The report are sent to
+ both side.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const origin_opener = get_host_info().HTTPS_ORIGIN;
+const origin_openee = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+let genericSetup = async function(test) {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP and a reporter.
+ const opener_token = token();
+ const opener_report_token = reportToken();
+ const opener_reporting = reportingEndpointsHeaders(opener_report_token);
+ const opener_url = origin_opener+ executor_path + opener_reporting.header +
+ opener_reporting.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window. This has COOP and a reporter.
+ const openee_token = token();
+ const openee_report_token = reportToken();
+ const openee_reporting = reportingEndpointsHeaders(openee_report_token);
+ const openee_url = origin_openee + executor_path + openee_reporting.header +
+ openee_reporting.coopReportOnlySameOriginHeader + coep_header +
+ `&uuid=${openee_token}`;
+
+ // Cleanup at the end of the test.
+ test.add_cleanup(() => {
+ send(openee_token, 'window.close()');
+ send(opener_token, 'window.close()');
+ });
+
+ // 1. Spawn the opener and the openee windows.
+ window.open(opener_url);
+ send(opener_token, `
+ openee = window.open('${escapeComma(openee_url)}');
+ `);
+
+ // 2. Wait for both to be loaded.
+ send(openee_token, `send('${this_window_token}', 'ACK');`);
+ assert_equals(await receive(this_window_token), 'ACK');
+
+ return [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ];
+}
+
+let assert_generic_coop_report = function(report) {
+ assert_equals(report.type, "coop");
+ assert_equals(report.body.disposition, "reporting");
+ assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
+ assert_equals(report.body.property, "blur");
+}
+
+promise_test(async test => {
+ let [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ] = await genericSetup(test);
+
+ send(opener_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(openee);")
+ );
+
+ let report_opener =
+ await receiveReport(opener_report_token, "access-from-coop-page-to-openee")
+ let report_openee =
+ await receiveReport(openee_report_token, "access-to-coop-page-from-opener")
+
+ assert_generic_coop_report(report_openee);
+ assert_generic_coop_report(report_opener);
+
+ assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
+ assert_source_location_found(report_opener);
+ assert_source_location_missing(report_openee);
+}, "Access from opener")
+
+promise_test(async test => {
+ let [
+ this_window_token,
+ opener_token, opener_report_token, opener_url,
+ openee_token, openee_report_token, openee_url,
+ ] = await genericSetup(test);
+
+ send(openee_token, addScriptAndTriggerOnload(
+ directory + "/reporting/resources/try-access.js",
+ "tryAccess(opener);")
+ );
+
+ let report_opener =
+ await receiveReport(opener_report_token, "access-to-coop-page-from-openee")
+ let report_openee =
+ await receiveReport(openee_report_token, "access-from-coop-page-to-opener")
+
+ assert_generic_coop_report(report_openee);
+ assert_generic_coop_report(report_opener);
+
+ assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
+ assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
+ assert_source_location_missing(report_opener);
+ assert_source_location_found(report_openee);
+}, "Access from openee")
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
new file mode 100644
index 0000000000..b2ff818d56
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
@@ -0,0 +1,111 @@
+<title>
+ Tests the redirect interaction with COOP same-origin-allow-popups.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script>
+
+const same_origin = {
+ host: get_host_info().HTTPS_ORIGIN,
+ name: "Same origin"
+};
+const cross_origin = {
+ host: get_host_info().HTTPS_REMOTE_ORIGIN,
+ name: "Cross origin"
+};
+
+// Tests the redirect interaction with COOP same-origin-allow-popups and
+// reporting:
+// 1 - open the opener document on origin same_origin wit COOP
+// same-origin-allow-popups.
+// 2 - opener opens popup with document on origin popup_origin, no COOP and a
+// redirect header (HTTP 302, location).
+// 3 - redirection to a document with origin same_origin and COOP
+// same-origin-allow-popups.
+//
+// The navigation (2) to the first document of the popup stays in the same
+// browsing context group due to the same-origin-allow-popups COOP of the
+// opener.
+// The redirect (3) to the final document does since it compares the
+// popup_origin/unsafe-none document with the
+// same-origin/same-origin-allow-popups document.
+//
+// A opens B, B redirects to C.
+//
+// Document Origin COOP
+// -------- ------------ ------------------------
+// A same-origin same-origin-allow-popups
+// B popup-origin unsafe-none
+// C same-origin same-origin-allow-popups
+function redirect_test(popup_origin) {
+ promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP same-origin-allow-popups and a
+ // reporter.
+ const opener_token = token();
+ const opener_report_token = reportToken();
+ const opener_reporting = reportingEndpointsHeaders(opener_report_token);
+ const opener_url = same_origin.host + executor_path +
+ opener_reporting.header + opener_reporting.coopSameOriginAllowPopupsHeader +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window.
+ // The initial document does not have COOP and is on popup_origin, it
+ // redirects to a same-origin (with the opener) document with COOP
+ // same-origin-allow-popups.
+ const openee_token = token();
+ const openee_redirect_url = same_origin.host + executor_path +
+ opener_reporting.header + opener_reporting.coopSameOriginAllowPopupsHeader +
+ `&uuid=${openee_token}`;
+ const redirect_header = 'status(302)' +
+ `|header(Location,${encodeURIComponent(
+ openee_redirect_url
+ .replace(/,/g, "\\,")
+ .replace(/\\\\,/g, "\\\\\\,")
+ .replace(/\(/g, "%28")
+ .replace(/\)/g, "%29"))})`;
+ const openee_url = popup_origin.host + executor_path + redirect_header +
+ `&uuid=${openee_token}`;
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `
+ openee = window.open("${openee_url}");
+ `);
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. Check the opener status on the openee.
+ send(openee_token, `
+ send("${this_window_token}", opener !== null);
+ `);
+ assert_equals(await receive(this_window_token), "false", "opener");
+
+ // 4. Check the openee status on the opener.
+ send(opener_token, `
+ send("${this_window_token}", openee.closed);
+ `);
+ assert_equals(await receive(this_window_token), "true", "openee.closed");
+
+ // 5. Check a report sent to the openee.
+ let report = await receiveReport(
+ opener_report_token,
+ "navigation-to-response");
+ assert_equals(report.type, "coop");
+ assert_equals(report.body.disposition, "enforce");
+ assert_equals(report.body.effectivePolicy, "same-origin-allow-popups");
+ }, `${popup_origin.name} openee redirected to same-origin with same-origin-allow-popups`);
+}
+
+redirect_test(same_origin);
+redirect_test(cross_origin);
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html
new file mode 100644
index 0000000000..bd89856305
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html
@@ -0,0 +1,130 @@
+<title>
+ Tests the redirect interaction with COOP unsafe-none.
+</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>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+<script>
+
+const same_origin = {
+ host: get_host_info().HTTPS_ORIGIN,
+ name: "Same origin"
+};
+const cross_origin = {
+ host: get_host_info().HTTPS_REMOTE_ORIGIN,
+ name: "Cross origin"
+};
+
+// Repeated call receive() to fetch all reports received within 1 second.
+async function fetchReportsByID(uuid){
+ let timeStart = new Date().getTime();
+ const reports = [];
+ while(new Date().getTime() - timeStart < 1000) {
+ // Promise.race is used to timeout since receive() has no timeout mechanism.
+ reports.push(...await Promise.race([
+ receive(uuid).then(JSON.parse),
+ new Promise(resolve => step_timeout(resolve, 1000, []))
+ ]));
+ }
+ return reports;
+}
+
+function fetchReportByType(reports, type){
+ return reports.filter((report)=> (report.body.type === type));
+}
+
+ // Tests the redirect interaction with COOP unsafe-none and reporting:
+ // 1 - open the opener document on origin same_origin with COOP
+ // unsafe-none.
+ // 2 - opener opens popup with document on origin popup_origin, with COOP
+ // same-origin, Reporting-Endpoints header and a redirect header
+ // (HTTP 302, location).
+ // 3 - redirection to a document with origin same-origin and COOP
+ // unsafe-none.
+ //
+ // Navigation 2) should generate a report sent to B's reporter(navigation-to).
+ // Navigation 3) should generate a report sent to B's reporter(navigation-from).
+ //
+ // A opens B, B redirects to C.
+ //
+ // Document Origin COOP
+ // -------- ------------ ------------------------
+ // A same-origin unsafe-none
+ // B popup-origin same-origin
+ // C same-origin unsafe-none
+function redirect_test(popup_origin) {
+ promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP unsafe-none and no reporter.
+ const opener_token = token();
+ const opener_url = same_origin.host + executor_path +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window.
+ // The initial document have COOP, reporter and is on popup_origin, it
+ // redirects to a same-origin (with the opener) document with no COOP.
+ const openee_token = token();
+ const openee_report_token = reportToken();
+ const openee_reporting = reportingEndpointsHeaders(openee_report_token);
+ const openee_redirect_url = same_origin.host + executor_path +
+ `&uuid=${openee_token}`;
+ const redirect_header = '|status(302)' +
+ `|header(Location,${encodeURIComponent(
+ openee_redirect_url)})`;
+ const openee_url = (popup_origin.host + executor_path
+ + openee_reporting.header + openee_reporting.coopSameOriginHeader
+ + redirect_header + `&uuid=${openee_token}`)
+ .replace(/,/g, "\\,")
+ .replace(/\\\\,/g, "\\\\\\,")
+ .replace(/\(/g, "%28")
+ .replace(/\)/g, "%29");
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `
+ openee = window.open(\`${openee_url}\`);
+ `);
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. Check the opener status on the openee.
+ send(openee_token, `
+ send("${this_window_token}", opener !== null);
+ `);
+ assert_equals(await receive(this_window_token), "false", "opener");
+
+ // 4. Check the openee status on the opener.
+ send(opener_token, `
+ send("${this_window_token}", openee.closed);
+ `);
+ assert_equals(await receive(this_window_token), "true", "openee.closed");
+
+ // 5. Check a report sent to B's reporting endpoint when A opens B.
+ const reports = await fetchReportsByID(openee_report_token);
+ const navigationToReport = fetchReportByType(
+ reports, "navigation-to-response");
+ assert_equals(navigationToReport.length, 1);
+ assert_equals(navigationToReport[0].type, "coop");
+ assert_equals(navigationToReport[0].body.disposition, "enforce");
+ assert_equals(navigationToReport[0].body.effectivePolicy, "same-origin");
+ // 6. Check a report sent to B's reporting endpoint when B redirects to C.
+ const navigationFromReport = fetchReportByType(
+ reports, "navigation-from-response");
+ assert_equals(navigationFromReport.length, 1);
+ assert_equals(navigationFromReport[0].type, "coop");
+ assert_equals(navigationFromReport[0].body.disposition, "enforce");
+ assert_equals(navigationFromReport[0].body.effectivePolicy, "same-origin");
+ }, `${popup_origin.name} openee redirected to same-origin with unsafe-none`);
+}
+
+redirect_test(same_origin);
+redirect_test(cross_origin);
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html
new file mode 100644
index 0000000000..ca1471ccc0
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html
@@ -0,0 +1,86 @@
+<meta name=timeout content=long>
+<title>A test with both COOP and COOP report only setup</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=47b45e17-51c5-4691-bdd5-8f343bbfcf42&report_only_id=3eb3ad1d-872e-4ea8-8b40-0e98783a0683"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup with both normal and report-only COOP. Four
+ // reports are sent.
+ [
+ CROSS_ORIGIN,
+ `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "require-corp",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": reportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ]
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers
new file mode 100644
index 0000000000..50c3045bb6
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers
@@ -0,0 +1,6 @@
+Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint"
+Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint"
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Embedder-Policy-Report-Only: require-corp
+Referrer-Policy: origin
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=47b45e17-51c5-4691-bdd5-8f343bbfcf42", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=3eb3ad1d-872e-4ea8-8b40-0e98783a0683" \ No newline at end of file
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html
new file mode 100644
index 0000000000..cca2e7e1ae
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html
@@ -0,0 +1,71 @@
+
+<meta name=timeout content=long>
+<title>Report only tests for an opener without any COOP/COOP report only set</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a same-origin popup with a same-origin COOP report-only value, which
+ // would cause a browsing context group swap, hence a report is sent.
+ [
+ SAME_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ [
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": `${location.href}`, // previous documnent url
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP report-only value, which
+ // would cause a browsing context group swap, hence a report is sent.
+ [
+ CROSS_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ [
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers
new file mode 100644
index 0000000000..5b29739bbd
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers
@@ -0,0 +1 @@
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html
new file mode 100644
index 0000000000..52b1f2a09f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html
@@ -0,0 +1,96 @@
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=380ca360-d1ae-4329-b1dd-69cea49cd705&report_only_id=cf9ac91d-6c5d-4489-a420-10be9402ef84"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup without any COOP setup, the current document
+ // (opener) report-only would cause a browsing context group swap, hence a
+ // report is sent to the corresponding endpoint.
+ [
+ CROSS_ORIGIN,
+ "",
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP report-only value, which
+ // would cause a browsing context group swap, hence a report is sent to both
+ // endpoints.
+ [
+ CROSS_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ [
+ {
+ "endpoint": reportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a same-origin COOP report-only value, the two
+ // COOP-report-only values match, hence no virtual browsing context group swap
+ // happens and no report is sent.
+ [
+ SAME_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ []
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers
new file mode 100644
index 0000000000..04bc49906b
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers
@@ -0,0 +1,3 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint"
+Referrer-Policy: origin
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=380ca360-d1ae-4329-b1dd-69cea49cd705", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=cf9ac91d-6c5d-4489-a420-10be9402ef84"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html
new file mode 100644
index 0000000000..148c700ee5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html
@@ -0,0 +1,32 @@
+
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup with COOP report-only with coep, which mismatches
+ // with the current document (opener) COOP (unsafe-none) and COOP report-only
+ // (same-origin) values.
+ [
+ SAME_ORIGIN,
+ "",
+ "require-corp",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ []
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers
new file mode 100644
index 0000000000..58ab03394a
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers
@@ -0,0 +1,3 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin
+Cross-Origin-Embedder-Policy-Report-Only: require-corp
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html
new file mode 100644
index 0000000000..148c700ee5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html
@@ -0,0 +1,32 @@
+
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup with COOP report-only with coep, which mismatches
+ // with the current document (opener) COOP (unsafe-none) and COOP report-only
+ // (same-origin) values.
+ [
+ SAME_ORIGIN,
+ "",
+ "require-corp",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ []
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers
new file mode 100644
index 0000000000..2ba7ffb592
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers
@@ -0,0 +1,3 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin
+Cross-Origin-Embedder-Policy: require-corp
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html
new file mode 100644
index 0000000000..8a63682c69
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html
@@ -0,0 +1,73 @@
+
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports
+
+ // Open a cross-origin popup with COOP report-only with coep, which mismatches
+ // with the current document (opener) COOP (unsafe-none) and COOP report-only
+ // (same-origin) values.
+ [
+ SAME_ORIGIN,
+ "",
+ "require-corp",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ [
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": `${location.href}`,
+ "referrer": `${location.origin}/`,
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with COOP report-only with coep report-only,
+ // which mismatches with the current document (opener) COOP (unsafe-none) and
+ // COOP report-only (same-origin) values.
+ [
+ SAME_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "require-corp",
+ [
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": `${location.href}`,
+ "referrer": `${location.origin}/`,
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers
new file mode 100644
index 0000000000..9a8445a43e
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy-Report-Only: same-origin
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html
new file mode 100644
index 0000000000..893dfa20b8
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html
@@ -0,0 +1,67 @@
+<title>
+ Reports a browsing context group switch when an opener with COOP navigates.
+</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/reporting/resources/reporting-common.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window.
+ const opener_token = token();
+ const opener_url = same_origin + executor_path + `&uuid=${opener_token}`;
+
+ // The "openee" window.
+ const openee_token = token();
+ const openee_url = same_origin + executor_path + `&uuid=${openee_token}`;
+
+ // The "final" url the opener will navigate to. It has COOP and a reporter.
+ const final_report_token = reportToken();
+ const final_token = token();
+ const final_reportTo = reportingEndpointsHeaders(final_report_token);
+ const final_url = same_origin + executor_path + final_reportTo.header +
+ final_reportTo.coopSameOriginHeader +`&uuid=${final_token}`;
+
+ // 1. Create the opener window and ensure it doesn't have an opener.
+ let opener_window_proxy = window.open(opener_url, '_blank', 'noopener');
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens a window.
+ send(opener_token, `
+ openee = window.open('${escapeComma(openee_url)}');
+ `);
+
+ // 3. Ensure the openee loads.
+ send(openee_token, `
+ send("${this_window_token}", "ACK");
+ `);
+ assert_equals("ACK", await receive(this_window_token));
+
+ // 4. The opener navigates.
+ send(opener_token, `
+ location.replace('${escapeComma(final_url)}');
+ `);
+
+ // 5. Check a report was sent to the opener.
+ let report =
+ await receiveReport(final_report_token, "navigation-to-response")
+ assert_equals(report.type, "coop");
+ assert_equals(report.url, final_url.replace(/"/g, '%22'));
+ assert_equals(report.body.disposition, "enforce");
+ assert_equals(report.body.effectivePolicy, "same-origin");
+ assert_equals(report.body.previousResponseURL, opener_url.replace(/"/g, '%22'));
+}, "navigation-report-from-opener-navigation");
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html
new file mode 100644
index 0000000000..b625b285cf
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html
@@ -0,0 +1,85 @@
+<title>Cross-Origin-Opener-Policy: a navigated popup with reporting</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel -->
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=df3cde15-b00b-4a59-b6e2-498b67a6146e&report_only_id=ebf3a415-7a74-42e1-92d1-e600b1bbe22e"></script>
+
+<script>
+
+// This test does the following:
+// 1 - This document has COOP: same-origin-allow-popups; report-to="coop-report-endpoint"
+// 2 - Open a popup on a same-origin page without COOP, with the coop-popup-report-endpoint
+// 3 - Navigate the popup to a same-origin page with COOP, with the coop-redirect-report-endpoint
+// it verifies that the reports are properly send for the browsing context switch
+// during the navigation in the popup (step 3). The current document (the opener)
+// endpoint should not receive any report as no switch ocurred on 2.
+promise_test( async t => {
+ const callbackToken = token();
+ const noCoopToken = token();
+ const coopToken= token();
+ await reportingTest(async resolve => {
+ const noCOOPUrl = executor_path +
+ convertToWPTHeaderPipe(getReportingEndpointsHeader(location.origin)) +
+ `|header(Cross-Origin-Opener-Policy,${encodeURIComponent(`unsafe-none; report-to="${popupReportEndpoint.name}"`)})` +
+ `&uuid=${noCoopToken}`;
+ const coopUrl = executor_path +
+ convertToWPTHeaderPipe(getReportingEndpointsHeader(location.origin)) +
+ `|header(Cross-Origin-Opener-Policy,${encodeURIComponent(`same-origin; report-to="${redirectReportEndpoint.name}"`)})` +
+ `&uuid=${coopToken}`;
+
+ // 1. Open a popup without COOP and with reporting. COOP does not trigger
+ // a browsing context group switch because the current document is
+ // same-origin-allow-popups
+ const popup = window.open(noCOOPUrl);
+ t.add_cleanup(() => send(noCoopToken, "window.close()"));
+
+ // 2. Navigate the popup to a COOP document, which switches the browsing
+ // context group.
+ send(noCoopToken, `window.location = "${coopUrl}";`);
+ t.add_cleanup(() => send(coopToken, "window.close()"));
+
+ // 3. Make sure the new document is loaded.
+ send(coopToken, `
+ send("${callbackToken}", "Ready");
+ `);
+ let reply = await receive(callbackToken);
+ resolve();
+ },
+ "", // executor token for the report replacements, unused in this test
+ [
+ // Reports expected for the navigation from "noCOOP" to "coop"
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "nextResponseURL": RegExp(`uuid=${coopToken}$`),
+ "type": "navigation-from-response"
+ },
+ "url": RegExp(`uuid=${noCoopToken}$`),
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": redirectReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": RegExp(`uuid=${noCoopToken}$`),
+ "referrer": RegExp(`uuid=${noCoopToken}$`),
+ "type": "navigation-to-response"
+ },
+ "url": RegExp(`uuid=${coopToken}$`),
+ "type": "coop"
+ }
+ },
+ ]);
+}, "Open a popup to a document without COOP, then navigate it to a document with");
+
+verifyRemainingReports();
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers
new file mode 100644
index 0000000000..a6a27c2d3e
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint"
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=df3cde15-b00b-4a59-b6e2-498b67a6146e", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=ebf3a415-7a74-42e1-92d1-e600b1bbe22e"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html
new file mode 100644
index 0000000000..d674e2e449
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html
@@ -0,0 +1,126 @@
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=6a739c25-0ec5-4832-b4a3-847281006857&report_only_id=f91209ee-b3a3-474b-b337-d663533745fb"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports
+
+ // Open a same-origin popup with a same-origin COOP and no COEP. Produces two
+ // reports (one from and one to). Both pages being same origin, the
+ // next/pervious document urls are available.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": `${location.href}`, // previous documnent url
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin-allow-popup COOP and noCOEP.
+ // Produces two reports (one from and one to). Both pages being cross origin,
+ // the next/pervious document urls are not available and the initial document
+ // url/referrer are used instead.
+ [
+ CROSS_ORIGIN,
+ `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "previousResponseURL": ``,
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP and COEP, and no reporting.
+ // Produces one navigation-from-report for this document (the opener). The
+ // pages being cross origin, the next/pervious document urls are not available
+ // and the initial document url/referrer are used instead.
+ [
+ CROSS_ORIGIN,
+ `same-origin`,
+ "require-corp",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-allow-popups",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers
new file mode 100644
index 0000000000..3e213a95a3
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers
@@ -0,0 +1,3 @@
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6a739c25-0ec5-4832-b4a3-847281006857", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=f91209ee-b3a3-474b-b337-d663533745fb"
+Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint"
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html
new file mode 100644
index 0000000000..88b180702f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html
@@ -0,0 +1,173 @@
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=edbbace3-40ca-4640-8d50-dc6e52acc1da&report_only_id=f65cf51a-ca6f-4028-a2c3-0c06183faa13"></script>
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports
+
+ // Open and navigate a popup to a same-origin page with the same COOP-COEP
+ // settings: no browsing context group switch hence no report expected.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ "",
+ "",
+ []
+ ],
+ // Open a same-origin popup with a same-origin COOP but no COEP. Produces two
+ // reports (one from and one to). The from report has an effectivePolicy of
+ // same-origin-plus-coep, both pages being same origin, the entire
+ // next/pervious document urls are available.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next destination url
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": `${location.href}`, // previous document url
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP and COEP. Produces two
+ // reports (one from and one to). The from report has an effectivePolicy of
+ // same-origin-plus-coep, both pages being cross origin, the next/pervious
+ // document urls are not available and the initial document url/referrer are
+ // used instead.
+ [
+ CROSS_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": ``,
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a same-origin COOP report only. One report
+ // is sent to this page's endpoint, but none to the report-only endpoint.
+ [
+ SAME_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "require-corp",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP report only. A report is
+ // sent to both this page's endpoint and the popup's.
+ [
+ CROSS_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "require-corp",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportOnlyEndpoint,
+ "report": {
+ "body": {
+ "disposition": "reporting",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": ``,
+ "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers
new file mode 100644
index 0000000000..0f78bdb2d0
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers
@@ -0,0 +1,4 @@
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=edbbace3-40ca-4640-8d50-dc6e52acc1da", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=f65cf51a-ca6f-4028-a2c3-0c06183faa13"
+Cross-Origin-Opener-Policy: same-origin; report-to="coop-report-endpoint"
+Cross-Origin-Embedder-Policy: require-corp
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html
new file mode 100644
index 0000000000..47bb67cc4b
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html
@@ -0,0 +1,216 @@
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=6aad9729-8642-4894-91d9-a4d44707cd4a&report_only_id=69eb1838-6a03-4cda-97b0-c126ffcb9e8a"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports
+
+ // Open a popup on a same-origin page, with a compatible COOP.
+ // This is a sanity check that no report are produced.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ []
+ ],
+ // Open a cross-origin popup with a same-origin COOP. Produces two
+ // reports (one from and one to). The from report has an effectivePolicy of
+ // same-origin (corresponding to the current document), both pages being
+ // cross origin, the next/pervious document urls are not available and the
+ // initial document url/referrer are used instead.
+ [
+ CROSS_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/,
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": "",
+ "referrer": '', // referrer (empty due to the Referrer Policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a unsafe-none COOP and no COEP. COOP switches
+ // the browsing context group and hence produces two reports (one from and one
+ // to). This test verifies that unsafe-none properly sends report.
+ [
+ SAME_ORIGIN,
+ `unsafe-none; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/,
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "previousResponseURL": `${location.href}`,
+ "referrer": '', // referrer (empty due to the Referrer Policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a same-origin COOP and COEP. The difference
+ // of COEP values leads to the browsing context group switch and produces two
+ // reports. This verifies that the navigation-to-document report has an
+ // effectivePolicy of same-origin-plus-coep.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "require-corp",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/,
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin-plus-coep",
+ "previousResponseURL": `${location.href}`,
+ "referrer": '', // referrer (empty due to the Referrer Policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with no COOP (but reporting) and no COEP.
+ // Produces two reports. The pages being cross origin, the next/pervious
+ // document urls are not available and the initial document url/referrer are
+ // used instead.
+ [
+ CROSS_ORIGIN,
+ `unsafe-none; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/,
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "previousResponseURL": "",
+ "referrer": '', // referrer (empty due to the Referrer Policy)
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with no COOP (without reporting) and no COEP.
+ // Produces one report to this page (opener) endpoint.
+ // This verifies that the navigated-to-document's COOP report values do not
+ // impact the navigated-from-document's COOP.
+ [
+ SAME_ORIGIN,
+ "unsafe-none",
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/,
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ }
+ ]
+ ]
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers
new file mode 100644
index 0000000000..79c851a86c
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers
@@ -0,0 +1,3 @@
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6aad9729-8642-4894-91d9-a4d44707cd4a", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=69eb1838-6a03-4cda-97b0-c126ffcb9e8a"
+Cross-Origin-Opener-Policy: same-origin; report-to="coop-report-endpoint"
+Referrer-Policy: no-referrer
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html
new file mode 100644
index 0000000000..3a8f343f37
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html
@@ -0,0 +1,110 @@
+<meta name=timeout content=long>
+<title>reporting same origin</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports
+
+ // Open a cross-origin popup with a same-origin COOP and no COEP. COOP
+ // switches the browsing context group and hence produces one report.
+ // This test verifies that the navigated to document properly sends a
+ // navigation-to report. The navigationURI is the referrer.
+ [
+ CROSS_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a unsafe-none COOP and no COEP. COOP switches
+ // the browsing context group and hence produces one report.
+ // This test verifies that having different policies on same origin documents
+ // still properly produces report to the navigated-to-document.
+ [
+ SAME_ORIGIN,
+ `unsafe-none; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "previousResponseURL": `${location.href}`,
+ "referrer": `${location.href}`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a unsafe-none COOP (with reporting) and no
+ // COEP. COOP switches the browsing context group and hence produces one
+ // reports to the unsafe-none document. This test verifies that unsafe-none
+ // properly sends report in that configuration.
+ [
+ CROSS_ORIGIN,
+ `unsafe-none; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "previousResponseURL": "",
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a same-origin COOP Report only value, the
+ // report only matches the previous document COOP value, no report is sent.
+ [
+ SAME_ORIGIN,
+ "",
+ "",
+ `same-origin; report-to="${popupReportOnlyEndpoint.name}"`,
+ "",
+ []
+ ],
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers
new file mode 100644
index 0000000000..46ad58d83b
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-origin
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html
new file mode 100644
index 0000000000..2563dbb01f
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html
@@ -0,0 +1,126 @@
+<meta name=timeout content=long>
+<title>reporting same origin with report-to</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>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/cross-origin-opener-policy/resources/common.js"></script>
+<script
+ src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=1f79b0d5-c2a2-4e0b-8e8c-651af2321964&report_only_id=c50700c8-db1e-4224-b06f-4c6a95a5f4be"></script>
+
+<script>
+
+let tests = [
+ // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports
+
+ // Open a same-origin popup with a same-origin COOP with reporting and no COEP.
+ // COOP switches the browsing context group and hence produces two reports
+ // (one from and one to). This test verifies that unsafe-none (from the opener)
+ // properly sends a report.
+ [
+ SAME_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": `${location.href}`, // previous document url
+ "referrer": `${location.href}`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a same-origin popup with a same-origin COOP (no reporting)and no COEP.
+ // COOP switches the browsing context group and hence produces one report for
+ // the navigated from document (this page, the opener). This test differs with
+ // the previous one as it assert that the navigated to document's COOP reporting
+ // values do not interfere.
+ [
+ SAME_ORIGIN,
+ `same-origin`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ }
+ ]
+ ],
+ // Open a cross-origin popup with a same-origin COOP and no COEP. COOP switches
+ // the browsing context group and hence produces two reports.
+ [
+ CROSS_ORIGIN,
+ `same-origin; report-to="${popupReportEndpoint.name}"`,
+ "",
+ "",
+ "",
+ [
+ {
+ "endpoint": reportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "unsafe-none",
+ "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL
+ "type": "navigation-from-response"
+ },
+ "url": `${location.href}`,
+ "type": "coop"
+ }
+ },
+ {
+ "endpoint": popupReportEndpoint,
+ "report": {
+ "body": {
+ "disposition": "enforce",
+ "effectivePolicy": "same-origin",
+ "previousResponseURL": ``,
+ "referrer": `${location.origin}/`, // referrer
+ "type": "navigation-to-response"
+ },
+ "url": /uuid=EXECUTOR_UUID$/,
+ "type": "coop"
+ }
+ }
+ ]
+ ]
+];
+
+runNavigationReportingTests(document.title, tests);
+
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers
new file mode 100644
index 0000000000..f1f18d6708
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers
@@ -0,0 +1,2 @@
+Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=1f79b0d5-c2a2-4e0b-8e8c-651af2321964", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=c50700c8-db1e-4224-b06f-4c6a95a5f4be"
+Cross-Origin-Opener-Policy: unsafe-none; report-to="coop-report-endpoint"
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
new file mode 100644
index 0000000000..cd2f6b67b3
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
@@ -0,0 +1,111 @@
+<title>
+ Tests the redirect interaction with COOP same-origin-allow-popups.
+</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/reporting/resources/reporting-common.js"></script>
+<script>
+
+const directory = "/html/cross-origin-opener-policy";
+const same_origin = {
+ host: get_host_info().HTTPS_ORIGIN,
+ name: "Same origin"
+};
+const cross_origin = {
+ host: get_host_info().HTTPS_REMOTE_ORIGIN,
+ name: "Cross origin"
+};
+
+// Tests the redirect interaction with COOP same-origin-allow-popups and
+// reporting:
+// 1 - open the opener document on origin same_origin with COOP
+// same-origin-allow-popups.
+// 2 - opener opens popup with document on origin popup_origin, no COOP and a
+// redirect header (HTTP 302, location).
+// 3 - redirection to a document with origin same_origin and COOP
+// same-origin-allow-popups.
+//
+// The navigation (2) to the first document of the popup stays in the same
+// browsing context group due to the same-origin-allow-popups COOP of the
+// opener.
+// The redirect (3) to the final document does since it compares the
+// popup_origin/unsafe-none document with the
+// same-origin/same-origin-allow-popups document.
+//
+// A opens B, B redirects to C.
+//
+// Document Origin COOP
+// -------- ------------ ------------------------
+// A same-origin same-origin-allow-popups
+// B popup-origin unsafe-none
+// C same-origin same-origin-allow-popups
+function redirect_test( popup_origin ) {
+ promise_test(async t => {
+ // The test window.
+ const this_window_token = token();
+
+ // The "opener" window. This has COOP same-origin-allow-popups and a
+ // reporter.
+ const opener_report_token = reportToken();
+ const opener_token = token();
+ const opener_reportTo = reportingEndpointsHeaders(opener_report_token);
+ const opener_url = same_origin.host + executor_path +
+ opener_reportTo.header + opener_reportTo.coopSameOriginAllowPopupsHeader +
+ `&uuid=${opener_token}`;
+
+ // The "openee" window.
+ // The initial document does not have COOP and is on popup_origin, it
+ // redirects to a same-origin (with the opener) document with COOP
+ // same-origin-allow-popups.
+ const openee_token = token();
+ const openee_redirect_url = same_origin.host + executor_path +
+ opener_reportTo.header + opener_reportTo.coopSameOriginAllowPopupsHeader +
+ `&uuid=${openee_token}`;
+ const redirect_header = 'status(302)' +
+ `|header(Location,${encodeURIComponent(
+ openee_redirect_url
+ .replace(/,/g, "\\,")
+ .replace(/\\\\,/g, "\\\\\\,")
+ .replace(/\(/g, "%28")
+ .replace(/\)/g, "%29"))})`;
+ const openee_url = popup_origin.host + executor_path + redirect_header +
+ `&uuid=${openee_token}`;
+ // 1. Create the opener window.
+ let opener_window_proxy = window.open(opener_url);
+ t.add_cleanup(() => send(opener_token, "window.close()"));
+
+ // 2. The opener opens its openee.
+ send(opener_token, `
+ openee = window.open("${openee_url}");
+ `);
+ t.add_cleanup(() => send(openee_token, "window.close()"));
+
+ // 3. Check the opener status on the openee.
+ send(openee_token, `
+ send("${this_window_token}", opener !== null);
+ `);
+ assert_equals(await receive(this_window_token), "false", "opener");
+
+ // 4. Check the openee status on the opener.
+ send(opener_token, `
+ send("${this_window_token}", openee.closed);
+ `);
+ assert_equals(await receive(this_window_token), "true", "openee.closed");
+
+ // 5. Check a report sent to the openee.
+ let report = await receiveReport(
+ opener_report_token,
+ "navigation-to-response");
+ assert_equals(report.type, "coop");
+ assert_equals(report.body.disposition, "enforce");
+ assert_equals(report.body.effectivePolicy, "same-origin-allow-popups");
+ }, `${popup_origin.name} openee redirected to same-origin with same-origin-allow-popups`);
+}
+
+redirect_test(same_origin);
+redirect_test(cross_origin);
+</script>
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js
new file mode 100644
index 0000000000..70bb4897f5
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js
@@ -0,0 +1,422 @@
+const executor_path = "/common/dispatcher/executor.html?pipe=";
+const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
+
+// Report endpoint keys must start with a lower case alphabet character.
+// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-15#section-4.2.3.3
+const reportToken = () => {
+ return token().replace(/./, 'a');
+}
+
+const isWPTSubEnabled = "{{GET[pipe]}}".includes("sub");
+
+const getReportEndpointURL = (reportID) =>
+ `/reporting/resources/report.py?reportID=${reportID}`;
+
+const reportEndpoint = {
+ name: "coop-report-endpoint",
+ reportID: isWPTSubEnabled ? "{{GET[report_id]}}" : token(),
+ reports: []
+};
+const reportOnlyEndpoint = {
+ name: "coop-report-only-endpoint",
+ reportID: isWPTSubEnabled ? "{{GET[report_only_id]}}" : token(),
+ reports: []
+};
+const popupReportEndpoint = {
+ name: "coop-popup-report-endpoint",
+ reportID: token(),
+ reports: []
+};
+const popupReportOnlyEndpoint = {
+ name: "coop-popup-report-only-endpoint",
+ reportID: token(),
+ reports: []
+};
+const redirectReportEndpoint = {
+ name: "coop-redirect-report-endpoint",
+ reportID: token(),
+ reports: []
+};
+const redirectReportOnlyEndpoint = {
+ name: "coop-redirect-report-only-endpoint",
+ reportID: token(),
+ reports: []
+};
+
+const reportEndpoints = [
+ reportEndpoint,
+ reportOnlyEndpoint,
+ popupReportEndpoint,
+ popupReportOnlyEndpoint,
+ redirectReportEndpoint,
+ redirectReportOnlyEndpoint
+];
+
+// Allows RegExps to be pretty printed when printing unmatched expected reports.
+Object.defineProperty(RegExp.prototype, "toJSON", {
+ value: RegExp.prototype.toString
+});
+
+function wait(ms) {
+ return new Promise(resolve => step_timeout(resolve, ms));
+}
+
+// Check whether a |report| is a "opener breakage" COOP report.
+function isCoopOpenerBreakageReport(report) {
+ if (report.type != "coop")
+ return false;
+
+ if (report.body.type != "navigation-from-response" &&
+ report.body.type != "navigation-to-response") {
+ return false;
+ }
+
+ return true;
+}
+
+async function clearReportsOnServer(host) {
+ const res = await fetch(
+ '/reporting/resources/report.py', {
+ method: "POST",
+ body: JSON.stringify({
+ op: "DELETE",
+ reportIDs: reportEndpoints.map(endpoint => endpoint.reportID)
+ })
+ });
+ assert_equals(res.status, 200, "reports cleared");
+}
+
+async function pollReports(endpoint) {
+ const res = await fetch(getReportEndpointURL(endpoint.reportID),
+ { cache: 'no-store' });
+ if (res.status !== 200) {
+ return;
+ }
+ for (const report of await res.json()) {
+ if (isCoopOpenerBreakageReport(report))
+ endpoint.reports.push(report);
+ }
+}
+
+// Recursively check that all members of expectedReport are present or matched
+// in report.
+// Report may have members not explicitly expected by expectedReport.
+function isObjectAsExpected(report, expectedReport) {
+ if (( report === undefined || report === null
+ || expectedReport === undefined || expectedReport === null )
+ && report !== expectedReport ) {
+ return false;
+ }
+ if (expectedReport instanceof RegExp && typeof report === "string") {
+ return expectedReport.test(report);
+ }
+ // Perform this check now, as RegExp and strings above have different typeof.
+ if (typeof report !== typeof expectedReport)
+ return false;
+ if (typeof expectedReport === 'object') {
+ return Object.keys(expectedReport).every(key => {
+ return isObjectAsExpected(report[key], expectedReport[key]);
+ });
+ }
+ return report == expectedReport;
+}
+
+async function checkForExpectedReport(expectedReport) {
+ return new Promise( async (resolve, reject) => {
+ const polls = 20;
+ const waitTime = 200;
+ for (var i=0; i < polls; ++i) {
+ pollReports(expectedReport.endpoint);
+ for (var j=0; j<expectedReport.endpoint.reports.length; ++j){
+ if (isObjectAsExpected(expectedReport.endpoint.reports[j],
+ expectedReport.report)){
+ expectedReport.endpoint.reports.splice(j,1);
+ resolve();
+ return;
+ }
+ };
+ await wait(waitTime);
+ }
+ reject(
+ replaceTokensInReceivedReport(
+ "No report matched the expected report for endpoint: "
+ + expectedReport.endpoint.name
+ + ", expected report: " + JSON.stringify(expectedReport.report)
+ + ", within available reports: "
+ + JSON.stringify(expectedReport.endpoint.reports)
+ ));
+ });
+}
+
+function replaceFromRegexOrString(str, match, value) {
+ if (str instanceof RegExp) {
+ return RegExp(str.source.replace(match, value));
+ }
+ return str.replace(match, value);
+}
+
+// Replace generated values in regexes and strings of an expected report:
+// EXECUTOR_UUID: the uuid generated with token().
+function replaceValuesInExpectedReport(expectedReport, executorUuid) {
+ if (expectedReport.report.body !== undefined) {
+ if (expectedReport.report.body.nextResponseURL !== undefined) {
+ expectedReport.report.body.nextResponseURL = replaceFromRegexOrString(
+ expectedReport.report.body.nextResponseURL, "EXECUTOR_UUID",
+ executorUuid);
+ }
+ if (expectedReport.report.body.previousResponseURL !== undefined) {
+ expectedReport.report.body.previousResponseURL = replaceFromRegexOrString(
+ expectedReport.report.body.previousResponseURL, "EXECUTOR_UUID",
+ executorUuid);
+ }
+ if (expectedReport.report.body.referrer !== undefined) {
+ expectedReport.report.body.referrer = replaceFromRegexOrString(
+ expectedReport.report.body.referrer, "EXECUTOR_UUID",
+ executorUuid);
+ }
+ }
+ if (expectedReport.report.url !== undefined) {
+ expectedReport.report.url = replaceFromRegexOrString(
+ expectedReport.report.url, "EXECUTOR_UUID", executorUuid);
+ }
+ return expectedReport;
+}
+
+function replaceTokensInReceivedReport(str) {
+ return str.replace(/.{8}-.{4}-.{4}-.{4}-.{12}/g, `(uuid)`);
+}
+
+// Run a test then check that all expected reports are present.
+async function reportingTest(testFunction, executorToken, expectedReports) {
+ await new Promise(testFunction);
+ expectedReports = Array.from(
+ expectedReports,
+ report => replaceValuesInExpectedReport(report, executorToken) );
+ await Promise.all(Array.from(expectedReports, checkForExpectedReport));
+}
+
+function convertToWPTHeaderPipe([name, value]) {
+ return `header(${name}, ${encodeURIComponent(value)})`;
+}
+
+function getReportToHeader(host) {
+ return [
+ "Report-To",
+ reportEndpoints.map(
+ reportEndpoint => {
+ const reportToJSON = {
+ 'group': `${reportEndpoint.name}`,
+ 'max_age': 3600,
+ 'endpoints': [{
+ 'url': `${host}${getReportEndpointURL(reportEndpoint.reportID)}`
+ }]
+ };
+ // Escape comma as required by wpt pipes.
+ return JSON.stringify(reportToJSON)
+ .replace(/,/g, '\\,')
+ .replace(/\(/g, '\\\(')
+ .replace(/\)/g, '\\\)=');
+ }
+ ).join("\\, ")];
+}
+
+function getReportingEndpointsHeader(host) {
+ return [
+ "Reporting-Endpoints",
+ reportEndpoints.map(reportEndpoint => {
+ return `${reportEndpoint.name}="${host}${getReportEndpointURL(reportEndpoint.reportID)}"`;
+ }).join("\\, ")];
+}
+
+// Return Report and Report-Only policy headers.
+function getPolicyHeaders(coop, coep, coopRo, coepRo) {
+ return [
+ [`Cross-Origin-Opener-Policy`, coop],
+ [`Cross-Origin-Embedder-Policy`, coep],
+ [`Cross-Origin-Opener-Policy-Report-Only`, coopRo],
+ [`Cross-Origin-Embedder-Policy-Report-Only`, coepRo]];
+}
+
+function navigationReportingTest(testName, host, coop, coep, coopRo, coepRo,
+ expectedReports) {
+ const executorToken = token();
+ const callbackToken = token();
+ promise_test(async t => {
+ await reportingTest(async resolve => {
+ const openee_headers = [
+ getReportingEndpointsHeader(host.origin),
+ ...getPolicyHeaders(coop, coep, coopRo, coepRo)
+ ].map(convertToWPTHeaderPipe);
+ const openee_url = host.origin + executor_path +
+ openee_headers.join('|') + `&uuid=${executorToken}`;
+ const openee = window.open(openee_url);
+ const uuid = token();
+ t.add_cleanup(() => send(uuid, "window.close()"));
+
+ // 1. Make sure the new document is loaded.
+ send(executorToken, `
+ send("${callbackToken}", "Ready");
+ `);
+ let reply = await receive(callbackToken);
+ assert_equals(reply, "Ready");
+ resolve();
+ }, executorToken, expectedReports);
+ }, `coop reporting test ${testName} to ${host.name} with ${coop}, ${coep}, ${coopRo}, ${coepRo}`);
+}
+
+function navigationDocumentReportingTest(testName, host, coop, coep, coopRo,
+ coepRo, expectedReports) {
+ const executorToken = token();
+ const callbackToken = token();
+ promise_test(async t => {
+ const openee_headers = [
+ getReportingEndpointsHeader(host.origin),
+ ...getPolicyHeaders(coop, coep, coopRo, coepRo)
+ ].map(convertToWPTHeaderPipe);
+ const openee_url = host.origin + executor_path +
+ openee_headers.join('|') + `&uuid=${executorToken}`;
+ window.open(openee_url);
+ t.add_cleanup(() => send(executorToken, "window.close()"));
+ // Have openee window send a message through dispatcher, once we receive
+ // the Ready message from dispatcher it means the openee is fully loaded.
+ send(executorToken, `
+ send("${callbackToken}", "Ready");
+ `);
+ let reply = await receive(callbackToken);
+ assert_equals(reply, "Ready");
+
+ await wait(1000);
+
+ expectedReports = expectedReports.map(
+ (report) => replaceValuesInExpectedReport(report, executorToken));
+ return Promise.all(expectedReports.map(
+ async ({ endpoint, report: expectedReport }) => {
+ await pollReports(endpoint);
+ for (let report of endpoint.reports) {
+ assert_true(isObjectAsExpected(report, expectedReport),
+ `report received for endpoint: ${endpoint.name} ${JSON.stringify(report)} should match ${JSON.stringify(expectedReport)}`);
+ }
+ assert_equals(endpoint.reports.length, 1, `has exactly one report for ${endpoint.name}`)
+ }));
+ }, `coop document reporting test ${testName} to ${host.name} with ${coop}, ${coep}, ${coopRo}, ${coepRo}`);
+}
+
+// Run an array of reporting tests then verify there's no reports that were not
+// expected.
+// Tests' elements contain: host, coop, coep, coop-report-only,
+// coep-report-only, expectedReports.
+// See isObjectAsExpected for explanations regarding the matching behavior.
+async function runNavigationReportingTests(testName, tests) {
+ await clearReportsOnServer();
+ tests.forEach(test => {
+ navigationReportingTest(testName, ...test);
+ });
+ verifyRemainingReports();
+}
+
+// Run an array of reporting tests using Reporting-Endpoints header then
+// verify there's no reports that were not expected.
+// Tests' elements contain: host, coop, coep, coop-report-only,
+// coep-report-only, expectedReports.
+// See isObjectAsExpected for explanations regarding the matching behavior.
+function runNavigationDocumentReportingTests(testName, tests) {
+ clearReportsOnServer();
+ tests.forEach(test => {
+ navigationDocumentReportingTest(testName, ...test);
+ });
+}
+
+function verifyRemainingReports() {
+ promise_test(t => {
+ return Promise.all(reportEndpoints.map(async (endpoint) => {
+ await pollReports(endpoint);
+ assert_equals(endpoint.reports.length, 0, `${endpoint.name} should be empty`);
+ }));
+ }, "verify remaining reports");
+}
+
+const receiveReport = async function(uuid, type) {
+ while(true) {
+ let reports = await Promise.race([
+ receive(uuid),
+ new Promise(resolve => {
+ step_timeout(resolve, 1000, "timeout");
+ })
+ ]);
+ if (reports == "timeout")
+ return "timeout";
+ reports = JSON.parse(reports);
+ for(report of reports) {
+ if (report?.body?.type == type)
+ return report;
+ }
+ }
+}
+
+const coopHeaders = function (uuid) {
+ // Use a custom function instead of convertToWPTHeaderPipe(), to avoid
+ // encoding double quotes as %22, which messes with the reporting endpoint
+ // registration.
+ let getHeader = (uuid, coop_value, is_report_only) => {
+ const header_name =
+ is_report_only ?
+ "Cross-Origin-Opener-Policy-Report-Only":
+ "Cross-Origin-Opener-Policy";
+ return `|header(${header_name},${coop_value}%3Breport-to="${uuid}")`;
+ }
+
+ return {
+ coopSameOriginHeader:
+ getHeader(uuid, "same-origin", is_report_only = false),
+ coopSameOriginAllowPopupsHeader:
+ getHeader(uuid, "same-origin-allow-popups", is_report_only = false),
+ coopRestrictPropertiesHeader:
+ getHeader(uuid, "restrict-properties", is_report_only = false),
+ coopReportOnlySameOriginHeader:
+ getHeader(uuid, "same-origin", is_report_only = true),
+ coopReportOnlySameOriginAllowPopupsHeader:
+ getHeader(uuid, "same-origin-allow-popups", is_report_only = true),
+ coopReportOnlyRestrictPropertiesHeader:
+ getHeader(uuid, "restrict-properties", is_report_only = true),
+ };
+}
+
+// Build a set of headers to tests the reporting API. This defines a set of
+// matching 'Report-To', 'Cross-Origin-Opener-Policy' and
+// 'Cross-Origin-Opener-Policy-Report-Only' headers.
+const reportToHeaders = function(uuid) {
+ const report_endpoint_url = dispatcher_path + `?uuid=${uuid}`;
+ let reportToJSON = {
+ 'group': `${uuid}`,
+ 'max_age': 3600,
+ 'endpoints': [
+ {'url': report_endpoint_url.toString()},
+ ]
+ };
+ reportToJSON = JSON.stringify(reportToJSON)
+ .replace(/,/g, '\\,')
+ .replace(/\(/g, '\\\(')
+ .replace(/\)/g, '\\\)=');
+
+ return {
+ header: `|header(report-to,${reportToJSON})`,
+ ...coopHeaders(uuid)
+ };
+};
+
+// Build a set of headers to tests the reporting API. This defines a set of
+// matching 'Reporting-Endpoints', 'Cross-Origin-Opener-Policy' and
+// 'Cross-Origin-Opener-Policy-Report-Only' headers.
+const reportingEndpointsHeaders = function (uuid) {
+ // Report endpoint keys must start with a lower case alphabet:
+ // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-15#section-4.2.3.3
+ assert_true(uuid.match(/^[a-z].*/) != null, 'Use reportToken() instead.');
+
+ const report_endpoint_url = dispatcher_path + `?uuid=${uuid}`;
+ const reporting_endpoints_header = `${uuid}="${report_endpoint_url}"`;
+
+ return {
+ header: `|header(Reporting-Endpoints,${reporting_endpoints_header})`,
+ ...coopHeaders(uuid)
+ };
+};
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js
new file mode 100644
index 0000000000..a405202431
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js
@@ -0,0 +1,65 @@
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+const origin = [
+ ["same-origin" , same_origin ],
+ ["cross-origin", cross_origin],
+];
+let escapeComma = url => url.replace(/,/g, '\\,');
+
+let testAccessProperty = (
+ property,
+ op,
+ expectReport = true,
+ use_restrict_properties = false,
+) => {
+ origin.forEach(([origin_name, origin]) => {
+ promise_test(async t => {
+ const this_window_token = token();
+
+ // The opener window:
+ const opener_token = token();
+ const opener_url = get_host_info().HTTP_ORIGIN + executor_path +
+ `&uuid=${opener_token}`;
+
+ // The openee window:
+ const openee_token = token();
+ const openee_report_token = token();
+ const openee_report_to = reportToHeaders(openee_report_token);
+ const coop_ro_header =
+ use_restrict_properties
+ ? openee_report_to.coopReportOnlyRestrictPropertiesHeader
+ : openee_report_to.coopReportOnlySameOriginHeader;
+ const openee_url = origin + executor_path + openee_report_to.header +
+ coop_ro_header + coep_header + `&uuid=${openee_token}`;
+
+ t.add_cleanup(() => {
+ send(opener_token, "window.close()")
+ send(openee_token, "window.close()")
+ });
+
+ // Open the two windows. Wait for them to be loaded.
+ window.open(opener_url);
+ send(opener_token, `
+ window.openee = window.open('${escapeComma(openee_url)}');
+ `);
+ send(openee_token, `send("${this_window_token}", "Ready");`);
+ assert_equals(await receive(this_window_token), "Ready");
+
+ // 2. Try to access the openee.
+ send(opener_token, `(${op})(openee);`);
+
+ // 3. Fetch reports sent to the openee.
+ let report = await receiveReport(openee_report_token,
+ "access-to-coop-page-from-opener");
+ if (expectReport) {
+ assert_equals(report.body.property, property);
+ } else {
+ // "timeout" should be returned if no such reports are received.
+ assert_equals(report, "timeout");
+ }
+
+
+ }, `${origin_name} > ${op}`);
+ })
+};
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js
new file mode 100644
index 0000000000..a06cb07904
--- /dev/null
+++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js
@@ -0,0 +1,20 @@
+// A function trying to access to |w| through a "CrossOrigin" attribute (blur).
+// This function is kept in its own file to ensure the source location of the
+// call stays constant.
+function tryAccess(w) {
+ try {
+ w.blur();
+ } catch(e) {}
+}
+
+function assert_source_location_found(report) {
+ assert_true(report.body.sourceFile.includes("try-access.js"));
+ assert_equals(report.body.lineNumber, 6);
+ assert_equals(report.body.columnNumber, 7);
+}
+
+function assert_source_location_missing(report) {
+ assert_equals(report.body.sourceFile, undefined);
+ assert_equals(report.body.lineNumber, undefined);
+ assert_equals(report.body.columnNumber, undefined);
+}