Bug 1660447 [wpt PR 25177] - Fix COEP reporting tests, a=testonly
authorYutaka Hirano <yhirano@chromium.org>
Wed, 26 Aug 2020 08:55:06 +0000
changeset 546498 cf7b95e1841c91cfd3a2998f50fcc7692e72fe0d
parent 546497 9a38734fe8144818125b3526b38206fa8cebb704
child 546499 3ab75d9dc47d57e2f4a587a14464836b3a1624c6
push id37735
push userabutkovits@mozilla.com
push dateThu, 27 Aug 2020 21:29:40 +0000
treeherdermozilla-central@109f3a4de567 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1660447, 25177
milestone82.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1660447 [wpt PR 25177] - Fix COEP reporting tests, a=testonly Automatic update from web-platform-tests Fix COEP reporting tests (#25177) This is for https://github.com/whatwg/html/pull/5848. Co-authored-by: Domenic Denicola <d@domenic.me> -- wpt-commits: 8b381a62df79215dfe620cdec5cd8e18f66e099e wpt-pr: 25177
testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-dedicated-worker.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-document.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-service-worker.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-shared-worker.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-navigation.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html
testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-dedicated-worker.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-dedicated-worker.https.html
@@ -18,30 +18,34 @@
 promise_test(async (t) => {
   const worker_url = local(encode(worker_path + header_coep));
   const worker = new Worker(worker_url);
   const mc = new MessageChannel();
   worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "enforce");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP support on DedicatedWorker.")
 
 promise_test(async (t) => {
   const worker_url = local(encode(worker_path + header_coep_report_only));
   const worker = new Worker(worker_url);
   const mc = new MessageChannel();
   worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "reporting");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP-Report-Only support on DedicatedWorker.")
 
 </script>
 </html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-document.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-document.https.html
@@ -27,28 +27,32 @@ async function waitReports(frame) {
 }
 
 promise_test(async (t) => {
   const iframe_url = local(encode(iframe_path + header_coep));
   const iframe = await makeIframe(t, iframe_url);
   const reports = await waitReports(iframe);
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "enforce");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, iframe_url);
 }, "COEP support on document.")
 
 promise_test(async (t) => {
   const iframe_url = local(encode(iframe_path + header_coep_report_only));
   const iframe = await makeIframe(t, iframe_url);
   const reports = await waitReports(iframe);
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "reporting");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, iframe_url);
 }, "COEP-Report-Only support on document.")
 
 </script>
 </html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-service-worker.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-service-worker.https.html
@@ -24,18 +24,20 @@ promise_test(async (t) => {
   add_completion_callback(() => reg.unregister());
   const worker = reg.installing || reg.waiting || reg.active;
   const mc = new MessageChannel();
   worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_not_equals(reports, 'TIMEOUT');
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "enforce");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP support on ServiceWorker.");
 
 promise_test(async (t) => {
   const worker_url = local(encode(worker_path + header_coep_report_only));
   // As we don't want the service worker to control any page, generate a
   // one-time scope.
@@ -45,16 +47,18 @@ promise_test(async (t) => {
   add_completion_callback(() => reg.unregister());
   const worker = reg.installing || reg.waiting || reg.active;
   const mc = new MessageChannel();
   worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_not_equals(reports, 'TIMEOUT');
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "reporting");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP-Report-Only support on ServiceWorker.");
 
 </script>
 </html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-shared-worker.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/cache-storage-reporting-shared-worker.https.html
@@ -16,30 +16,34 @@
 promise_test(async (t) => {
   const worker_url = local(encode(worker_path + header_coep));
   const worker = new SharedWorker(worker_url);
   const mc = new MessageChannel();
   worker.port.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "enforce");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP support on SharedWorker.")
 
 promise_test(async (t) => {
   const worker_url = local(encode(worker_path + header_coep_report_only));
   const worker = new SharedWorker(worker_url);
   const mc = new MessageChannel();
   worker.port.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
   const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
   assert_equals(reports.length, 1);
   const report = reports[0];
-  assert_equals(report.body["blocked-url"], image_url);
+  assert_equals(report.body.blockedURL, image_url);
   assert_equals(report.body.type, "corp");
+  assert_equals(report.body.disposition, "reporting");
+  assert_equals(report.body.destination, "");
   assert_equals(report.type, "coep");
   assert_equals(report.url, worker_url);
 }, "COEP-Report-Only support on SharedWorker.")
 
 </script>
 </html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-navigation.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-navigation.https.html
@@ -10,28 +10,31 @@ const {ORIGIN, REMOTE_ORIGIN} = get_host
 const COEP = '|header(cross-origin-embedder-policy,require-corp)';
 const COEP_RO =
   '|header(cross-origin-embedder-policy-report-only,require-corp)';
 const CORP_CROSS_ORIGIN =
   '|header(cross-origin-resource-policy,cross-origin)';
 const FRAME_URL = `${ORIGIN}/common/blank.html?pipe=`;
 const REMOTE_FRAME_URL = `${REMOTE_ORIGIN}/common/blank.html?pipe=`;
 
-function checkCorpReport(report, contextUrl, blockedUrl) {
+function checkCorpReport(report, contextUrl, blockedUrl, disposition) {
   assert_equals(report.type, 'coep');
   assert_equals(report.url, contextUrl);
   assert_equals(report.body.type, 'corp');
-  assert_equals(report.body['blocked-url'], blockedUrl);
+  assert_equals(report.body.blockedURL, blockedUrl);
+  assert_equals(report.body.disposition, disposition);
+  assert_equals(report.body.destination, 'iframe');
 }
 
-function checkCoepMismatchReport(report, contextUrl, blockedUrl) {
+function checkCoepMismatchReport(report, contextUrl, blockedUrl, disposition) {
   assert_equals(report.type, 'coep');
   assert_equals(report.url, contextUrl);
   assert_equals(report.body.type, 'navigation');
-  assert_equals(report.body['blocked-url'], blockedUrl);
+  assert_equals(report.body.blockedURL, blockedUrl);
+  assert_equals(report.body.disposition, disposition);
 }
 
 function loadFrame(document, url) {
   return new Promise((resolve, reject) => {
     const frame = document.createElement('iframe');
     frame.src = url;
     frame.onload = () => resolve(frame);
     frame.onerror = reject;
@@ -77,19 +80,16 @@ async function observeReports(global) {
 // CASES is a list of test case. Each test case consists of:
 //   parent: the suffix of the URL of the parent frame.
 //   target: the suffix of the URL of the target frame.
 //   reports: the expectation of reports to be made. Each report is one of:
 //     'CORP': CORP violation
 //     'CORP-RO' CORP violation (report only)
 //     'NAV': COEP mismatch between the frames.
 //     'NAV-RO': COEP mismatch between the frames (report only).
-//   Currently '-RO' is no-op, e.g., 'CORP' and 'CORP-RO' have the same
-//   expectation. We are planning to introduce "disposition" member in
-//   reports, which will differentiate them each other.
 const CASES = [
   { parent: '', target: '', reports: [] },
   { parent: '', target: COEP, reports: [] },
   { parent: COEP, target: COEP, reports: ['CORP'] },
   { parent: COEP, target: '', reports: ['CORP'] },
 
   { parent: '', target: CORP_CROSS_ORIGIN, reports: [] },
   { parent: COEP, target: CORP_CROSS_ORIGIN, reports: ['NAV'] },
@@ -119,31 +119,35 @@ for (const testcase of CASES) {
         const contextUrl = parent.src ? parent.src : 'about:blank';
         const reports = await observeReports(parent.contentWindow);
         assert_equals(reports.length, testcase.reports.length);
 
         for (let i = 0; i < reports.length; i += 1) {
           const report = reports[i];
           switch (testcase.reports[i]) {
             case 'CORP':
+              checkCorpReport(report, contextUrl, targetUrl, 'enforce');
+              break;
             case 'CORP-RO':
-              checkCorpReport(report, contextUrl, targetUrl);
+              checkCorpReport(report, contextUrl, targetUrl, 'reporting');
               break;
             case 'NAV':
+              checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce');
+              break;
             case 'NAV-RO':
-              checkCoepMismatchReport(report, contextUrl, targetUrl);
+              checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting');
               break;
             default:
               assert_unreached(
                 'Unexpected report expeaction: ' + testcase.reports[i]);
           }
         }
         t.done();
       } catch (e) {
         t.step(() => { throw e; });
       }
     }, `parent: ${desc(testcase.parent)}, target: ${desc(testcase.target)}, ` +
        `with empty frame: ${withEmptyFrame}`);
   }
 }
 
 </script>
-</body></html>
\ No newline at end of file
+</body></html>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html
@@ -16,21 +16,23 @@ const FRAME_URL = `${ORIGIN}/common/blan
 const WORKER_URL = `${ORIGIN}${BASE}/reporting-worker.js` +
   '?pipe=header(cross-origin-embedder-policy,require-corp)' +
   `|header(cross-origin-embedder-policy-report-only,require-corp)`;
 
 function wait(ms) {
   return new Promise(resolve => step_timeout(resolve, ms));
 }
 
-function checkReport(report, contextUrl, blockedUrl) {
+function checkReport(report, contextUrl, blockedUrl, disposition, destination) {
   assert_equals(report.type, 'coep');
   assert_equals(report.url, contextUrl);
   assert_equals(report.body.type, 'corp');
-  assert_equals(report.body['blocked-url'], blockedUrl);
+  assert_equals(report.body.blockedURL, blockedUrl);
+  assert_equals(report.body.disposition, disposition);
+  assert_equals(report.body.destination, destination);
 }
 
 async function fetchInFrame(t, frameUrl, url) {
   const reports = [];
   const frame = await with_iframe(frameUrl);
   t.add_cleanup(() => frame.remove());
 
   const observer = new frame.contentWindow.ReportingObserver((rs) => {
@@ -141,36 +143,59 @@ const CASES = [{
   url: `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt`,
   check: (reports, url, contextUrl) => {
     assert_equals(reports.length, 0);
   }
 }, {
   name: 'blocked due to COEP',
   url: `${REMOTE_ORIGIN}/common/text-plain.txt`,
   check: (reports, contextUrl, url) => {
-    // One for COEP, one for COEP-RO.
     assert_equals(reports.length, 2);
-    checkReport(reports[0], contextUrl, url);
-    checkReport(reports[1], contextUrl, url);
+    checkReport(reports[0], contextUrl, url, 'reporting', '');
+    checkReport(reports[1], contextUrl, url, 'enforce', '');
   }
 }, {
   name: 'blocked during redirect',
   url: `${ORIGIN}/common/redirect.py?location=` +
        encodeURIComponent(`${REMOTE_ORIGIN}/common/text-plain.txt`),
   check: (reports, contextUrl, url) => {
-    // One for COEP, one for COEP-RO.
     assert_equals(reports.length, 2);
-    checkReport(reports[0], contextUrl, url);
-    checkReport(reports[1], contextUrl, url);
+    checkReport(reports[0], contextUrl, url, 'reporting', '');
+    checkReport(reports[1], contextUrl, url, 'enforce', '');
   },
 }];
 
 for (const env of ENVIRONMENTS) {
   for (const testcase of CASES) {
     promise_test(async (t) => {
       const reports = await env.run(t, testcase.url);
 
       testcase.check(reports, env.contextUrl, testcase.url);
     }, `[${env.tag}] ${testcase.name}`);
   }
 }
 
+// A test for a non-empty destination.
+promise_test(async (t) => {
+  const reports = [];
+  const frame = await with_iframe(FRAME_URL);
+  t.add_cleanup(() => frame.remove());
+
+  const observer = new frame.contentWindow.ReportingObserver((rs) => {
+    for (const report of rs) {
+      reports.push(report.toJSON());
+    }
+  });
+  observer.observe();
+  const url = `${REMOTE_ORIGIN}$/common/utils.js`;
+  const script = frame.contentDocument.createElement('script');
+  script.src = url;
+  frame.contentDocument.body.appendChild(script);
+
+  // Wait 200ms for reports to settle.
+  await wait(200);
+
+  assert_equals(reports.length, 2);
+  checkReport(reports[0], FRAME_URL, url, 'reporting', 'script');
+  checkReport(reports[1], FRAME_URL, url, 'enforce', 'script');
+}, 'destination: script');
+
 </script>
--- a/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html
+++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html
@@ -39,44 +39,47 @@ async function pollReports(endpoint, rep
   }
 }
 
 const reports = [];
 const reportsForReportOnly = [];
 pollReports('endpoint', reports);
 pollReports('report-only-endpoint', reportsForReportOnly);
 
-function checkCorpReportExistence(reports, blockedUrl, contextUrl) {
+function checkCorpReportExistence(reports, blockedUrl, contextUrl, disposition) {
   blockedUrl = new URL(blockedUrl, location).href;
   contextUrl = new URL(contextUrl, location).href;
   for (const report of reports) {
     if (report.type !== 'coep' || report.url !== contextUrl ||
         report.body.type !== 'corp') {
       continue;
     }
-    if (report.body['blocked-url'] === blockedUrl) {
+    if (report.body.blockedURL === blockedUrl &&
+        report.body.disposition === disposition) {
+      assert_equals(report.body.destination, '');
       return;
     }
   }
-  assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`);
+  assert_unreached(`A report whose blockedURL is ${blockedUrl} and url is ${contextUrl} is not found.`);
 }
 
-function checkNavigationReportExistence(reports, blockedUrl, contextUrl) {
+function checkNavigationReportExistence(reports, blockedUrl, contextUrl, disposition) {
   blockedUrl = new URL(blockedUrl, location).href;
   contextUrl = new URL(contextUrl, location).href;
   for (const report of reports) {
     if (report.type !== 'coep' || report.url !== contextUrl ||
         report.body.type !== 'navigation') {
       continue;
     }
-    if (report.body['blocked-url'] === blockedUrl) {
+    if (report.body.blockedURL === blockedUrl &&
+        report.body.disposition === disposition) {
       return;
     }
   }
-  assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`);
+  assert_unreached(`A report whose blockedURL is ${blockedUrl} and url is ${contextUrl} is not found.`);
 }
 
 async_test(async (t) => {
   try {
     const iframe = document.createElement('iframe');
     t.add_cleanup(() => iframe.remove());
 
     iframe.src = `resources/reporting-empty-frame.html`
@@ -89,18 +92,19 @@ async_test(async (t) => {
     const init = { mode: 'no-cors', cache: 'no-store' };
     // The response comes from cross-origin, and doesn't have a CORP
     // header, so it is blocked.
     iframe.contentWindow.fetch(url, init).catch(() => {});
 
     // Wait 3 seconds for reports to settle.
     await wait(3000);
 
-    checkCorpReportExistence(reports, url, iframe.src);
-    checkCorpReportExistence(reportsForReportOnly, url, iframe.src);
+    checkCorpReportExistence(reports, url, iframe.src, 'enforce');
+    checkCorpReportExistence(
+      reportsForReportOnly, url, iframe.src, 'reporting');
 
     t.done();
   } catch (e) {
     t.step(() => { throw e });
   }
 }, 'subresource CORP');
 
 async_test(async (t) => {
@@ -125,18 +129,19 @@ async_test(async (t) => {
     const url = `${REMOTE_ORIGIN}/common/blank.html?${token()}`;
     // The nested frame comes from cross-origin and doesn't have a CORP
     // header, so it is blocked.
     attachFrame(url);
 
     // Wait 3 seconds for reports to settle.
     await wait(3000);
 
-    checkCorpReportExistence(reports, url, iframe.src);
-    checkCorpReportExistence(reportsForReportOnly, url, iframe.src);
+    checkCorpReportExistence(reports, url, iframe.src, 'enforce');
+    checkCorpReportExistence(
+      reportsForReportOnly, url, iframe.src, 'reporting');
 
     t.done();
   } catch (e) {
     t.step(() => { throw e });
   }
 }, 'navigation CORP');
 
 async_test(async (t) => {
@@ -153,19 +158,19 @@ async_test(async (t) => {
       iframe.contentDocument.body.appendChild(nested);
     }, {once: true});
 
     document.body.appendChild(iframe);
 
     // Wait 3 seconds for reports to settle.
     await wait(3000);
 
-    checkNavigationReportExistence(reports, targetUrl, iframe.src);
+    checkNavigationReportExistence(reports, targetUrl, iframe.src, 'enforce');
     checkNavigationReportExistence(
-      reportsForReportOnly, targetUrl, iframe.src);
+      reportsForReportOnly, targetUrl, iframe.src, 'reporting');
 
     t.done();
   } catch (e) {
     t.step(() => { throw e });
   }
 }, 'COEP violation on nested frame navigation');
 
 </script>$