// META: timeout=long // META: script=/common/utils.js // META: script=/common/get-host-info.sub.js // META: script=/service-workers/service-worker/resources/test-helpers.sub.js const {ORIGIN, REMOTE_ORIGIN} = get_host_info(); const BASE = "/html/cross-origin-embedder-policy/resources"; const REPORTING_FRAME_URL = `${ORIGIN}${BASE}/reporting-empty-frame.html` + '?pipe=header(cross-origin-embedder-policy,credentialless)' + '&token=${token()}'; 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(); }); await receivedEveryReports; // Wait 1000ms more to catch additionnal unexpected reports. await new Promise(r => step_timeout(r, 1000)); return reports; } async function fetchInFrame(t, frameUrl, url, expected_count) { const frame = await with_iframe(frameUrl); t.add_cleanup(() => frame.remove()); const init = { mode: 'no-cors', cache: 'no-store' }; let future_reports = observeReports(frame.contentWindow, expected_count); await frame.contentWindow.fetch(url, init).catch(() => {}); return await future_reports; } 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.blockedURL, blockedUrl); assert_equals(report.body.disposition, disposition); assert_equals(report.body.destination, destination); } // A redirection is used, so that the initial request is same-origin and is // proxyied through the service worker. The ServiceWorker is COEP:unsafe-none, // so it will make the cross-origin request with credentials. The fetch will // succeed, but the response will be blocked by CORP when entering the // COEP:credentialless document. // https://github.com/w3c/ServiceWorker/issues/1592 promise_test(async (t) => { const url = `${ORIGIN}/common/redirect.py?location=` + encodeURIComponent(`${REMOTE_ORIGIN}/common/text-plain.txt`); const WORKER_URL = `${ORIGIN}${BASE}/sw.js`; const reg = await service_worker_unregister_and_register( t, WORKER_URL, REPORTING_FRAME_URL); t.add_cleanup(() => reg.unregister()); const worker = reg.installing || reg.waiting || reg.active; worker.addEventListener('error', t.unreached_func('Worker.onerror')); await wait_for_state(t, worker, 'activated'); const reports = await fetchInFrame(t, REPORTING_FRAME_URL, url, 1); assert_equals(reports.length, 1); checkReport(reports[0], REPORTING_FRAME_URL, url, 'enforce', ''); });