diff options
Diffstat (limited to 'testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/reporting-navigation.https.window.js')
-rw-r--r-- | testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/reporting-navigation.https.window.js | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/reporting-navigation.https.window.js b/testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/reporting-navigation.https.window.js new file mode 100644 index 0000000000..1d62996e38 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/reporting-navigation.https.window.js @@ -0,0 +1,139 @@ +// META: timeout=long +// META: script=/common/get-host-info.sub.js +// META: script=./resources/common.js +const {ORIGIN, REMOTE_ORIGIN} = get_host_info(); +const COEP = '|header(cross-origin-embedder-policy,credentialless)'; +const COEP_RO = + '|header(cross-origin-embedder-policy-report-only,credentialless)'; +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, disposition) { + assert_equals(report.type, 'coep'); + assert_equals(report.url, contextUrl); + assert_equals(report.body.type, 'corp'); + assert_equals(report.body.blockedURL, blockedUrl); + assert_equals(report.body.disposition, disposition); + assert_equals(report.body.destination, 'iframe'); +} + +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.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; + document.body.appendChild(frame); + }); +} + +// |parentSuffix| is a suffix for the parent frame URL. +// |targetUrl| is a URL for the target frame. +async function loadFrames(test, parentSuffix, targetUrl) { + const frame = await loadFrame(document, FRAME_URL + parentSuffix); + test.add_cleanup(() => frame.remove()); + // Here we don't need "await". This loading may or may not succeed, and + // we're not interested in the result. + loadFrame(frame.contentDocument, targetUrl); + + return frame; +} + +async function observeReports(global, expected_count) { + const reports = []; + const receivedEveryReports = new Promise(resolve => { + if (expected_count == 0) + resolve(); + + const observer = new global.ReportingObserver((rs) => { + for (const r of rs) { + reports.push(r.toJSON()); + } + if (expected_count <= reports.length) + resolve(); + }); + observer.observe(); + + }); + + // Wait 500ms more to catch additionnal unexpected reports. + await receivedEveryReports; + await new Promise(r => step_timeout(r, 500)); + return reports; +} + +function desc(headers) { + return headers === '' ? '(none)' : headers; +} + +// CASES is a list of test case. Each test case consists of: +// parent_headers: the suffix of the URL of the parent frame. +// target_headers: the suffix of the URL of the target frame. +// expected_reports: 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). +const reportingTest = function( + parent_headers, target_headers, expected_reports) { + // These tests are very slow, so they must be run in parallel using + // async_test. + promise_test_parallel(async t => { + const targetUrl = REMOTE_FRAME_URL + target_headers; + const parent = await loadFrames(t, parent_headers, targetUrl); + const contextUrl = parent.src ? parent.src : 'about:blank'; + const reports = await observeReports( + parent.contentWindow, + expected_reports.length + ); + assert_equals(reports.length, expected_reports.length); + for (let i = 0; i < reports.length; i += 1) { + const report = reports[i]; + switch (expected_reports[i]) { + case 'CORP': + checkCorpReport(report, contextUrl, targetUrl, 'enforce'); + break; + case 'CORP-RO': + checkCorpReport(report, contextUrl, targetUrl, 'reporting'); + break; + case 'NAV': + checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce'); + break; + case 'NAV-RO': + checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting'); + break; + default: + assert_unreached( + 'Unexpected report exception: ' + expected_reports[i]); + } + } + }, `parent: ${desc(parent_headers)}, target: ${desc(target_headers)}, `); +} + +reportingTest('', '', []); +reportingTest('', COEP, []); +reportingTest(COEP, COEP, ['CORP']); +reportingTest(COEP, '', ['CORP']); + +reportingTest('', CORP_CROSS_ORIGIN, []); +reportingTest(COEP, CORP_CROSS_ORIGIN, ['NAV']); + +reportingTest('', COEP + CORP_CROSS_ORIGIN, []); +reportingTest(COEP, COEP + CORP_CROSS_ORIGIN, []); + +reportingTest(COEP_RO, COEP, ['CORP-RO']); +reportingTest(COEP_RO, '', ['CORP-RO', 'NAV-RO']); +reportingTest(COEP_RO, CORP_CROSS_ORIGIN, ['NAV-RO']); +reportingTest(COEP_RO, COEP + CORP_CROSS_ORIGIN, []); + +reportingTest(COEP, COEP_RO + CORP_CROSS_ORIGIN, ['NAV']); |