diff options
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/generic/test-case.sub.js')
-rw-r--r-- | testing/web-platform/tests/content-security-policy/generic/test-case.sub.js | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/generic/test-case.sub.js b/testing/web-platform/tests/content-security-policy/generic/test-case.sub.js new file mode 100644 index 0000000000..d9a6494dd3 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/generic/test-case.sub.js @@ -0,0 +1,98 @@ +function TestCase(scenarios, sanityChecker) { + function runTest(scenario) { + sanityChecker.checkScenario(scenario, subresourceMap); + + const urls = getRequestURLs(scenario.subresource, + scenario.origin, + scenario.redirection); + + /** @type {Subresource} */ + const subresource = { + subresourceType: scenario.subresource, + url: urls.testUrl, + policyDeliveries: scenario.subresource_policy_deliveries, + }; + + let violationEventResolve; + // Resolved with an array of securitypolicyviolation events. + const violationEventPromise = new Promise(resolve => { + violationEventResolve = resolve; + }); + + promise_test(async t => { + await xhrRequest(urls.announceUrl); + + // Currently only requests from top-level Documents are tested + // (specified by `spec.src.json`) and thus securitypolicyviolation + // events are assumed to be fired on the top-level Document here. + // When adding non-top-level Document tests, securitypolicyviolation + // events should be caught in appropriate contexts. + const violationEvents = []; + const listener = e => { violationEvents.push(e); }; + document.addEventListener('securitypolicyviolation', listener); + + try { + // Send out the real resource request. + // This should tear down the key if it's not blocked. + const mainPromise = invokeRequest(subresource, scenario.source_context_list); + if (scenario.expectation === 'allowed') { + await mainPromise; + } else { + await mainPromise + .then(t.unreached_func('main promise resolved unexpectedly')) + .catch(_ => {}); + } + } finally { + // Always perform post-processing/clean up for + // 'securitypolicyviolation' events and resolve + // `violationEventPromise`, to prevent timeout of the + // promise_test() below. + + // securitypolicyviolation events are fired in a queued task in + // https://w3c.github.io/webappsec-csp/#report-violation + // so wait for queued tasks to run using setTimeout(). + let timeout = 0; + if (scenario.subresource.startsWith('worklet-') && + navigator.userAgent.includes("Firefox/")) { + // https://bugzilla.mozilla.org/show_bug.cgi?id=1808911 + // In Firefox sometimes violations from Worklets are delayed. + timeout = 10; + } + await new Promise(resolve => setTimeout(resolve, timeout)); + + // Pass violation events to `violationEventPromise` (which will be tested + // in the subsequent promise_test()) and clean up the listener. + violationEventResolve(violationEvents); + document.removeEventListener('securitypolicyviolation', listener); + } + + // Send request to check if the key has been torn down. + const assertResult = await xhrRequest(urls.assertUrl); + + // Now check if the value has been torn down. If it's still there, + // we have blocked the request by content security policy. + assert_equals(assertResult.status, scenario.expectation, + "The resource request should be '" + scenario.expectation + "'."); + + }, scenario.test_description); + + promise_test(async _ => { + const violationEvents = await violationEventPromise; + if (scenario.expectation === 'allowed') { + assert_array_equals(violationEvents, [], + 'no violation events should be fired'); + } else { + assert_equals(violationEvents.length, 1, + 'One violation event should be fired'); + } + }, scenario.test_description + ": securitypolicyviolation"); + } // runTest + + function runTests() { + for (const scenario of scenarios) { + runTest(scenario); + } + } + + return {start: runTests}; +} |