summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/generic/test-case.sub.js
diff options
context:
space:
mode:
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.js98
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};
+}