test-case.sub.js (3854B)
1 function TestCase(scenarios, sanityChecker) { 2 function runTest(scenario) { 3 sanityChecker.checkScenario(scenario, subresourceMap); 4 5 const urls = getRequestURLs(scenario.subresource, 6 scenario.origin, 7 scenario.redirection); 8 9 /** @type {Subresource} */ 10 const subresource = { 11 subresourceType: scenario.subresource, 12 url: urls.testUrl, 13 policyDeliveries: scenario.subresource_policy_deliveries, 14 }; 15 16 let violationEventResolve; 17 // Resolved with an array of securitypolicyviolation events. 18 const violationEventPromise = new Promise(resolve => { 19 violationEventResolve = resolve; 20 }); 21 22 promise_test(async t => { 23 await xhrRequest(urls.announceUrl); 24 25 // Currently only requests from top-level Documents are tested 26 // (specified by `spec.src.json`) and thus securitypolicyviolation 27 // events are assumed to be fired on the top-level Document here. 28 // When adding non-top-level Document tests, securitypolicyviolation 29 // events should be caught in appropriate contexts. 30 const violationEvents = []; 31 const listener = e => { violationEvents.push(e); }; 32 document.addEventListener('securitypolicyviolation', listener); 33 34 try { 35 // Send out the real resource request. 36 // This should tear down the key if it's not blocked. 37 const mainPromise = invokeRequest(subresource, scenario.source_context_list); 38 if (scenario.expectation === 'allowed') { 39 await mainPromise; 40 } else { 41 await mainPromise 42 .then(t.unreached_func('main promise resolved unexpectedly')) 43 .catch(_ => {}); 44 } 45 } finally { 46 // Always perform post-processing/clean up for 47 // 'securitypolicyviolation' events and resolve 48 // `violationEventPromise`, to prevent timeout of the 49 // promise_test() below. 50 51 // securitypolicyviolation events are fired in a queued task in 52 // https://w3c.github.io/webappsec-csp/#report-violation 53 // so wait for queued tasks to run using setTimeout(). 54 let timeout = 0; 55 if (scenario.subresource.startsWith('worklet-') && 56 navigator.userAgent.includes("Firefox/")) { 57 // https://bugzilla.mozilla.org/show_bug.cgi?id=1808911 58 // In Firefox sometimes violations from Worklets are delayed. 59 timeout = 10; 60 } 61 await new Promise(resolve => setTimeout(resolve, timeout)); 62 63 // Pass violation events to `violationEventPromise` (which will be tested 64 // in the subsequent promise_test()) and clean up the listener. 65 violationEventResolve(violationEvents); 66 document.removeEventListener('securitypolicyviolation', listener); 67 } 68 69 // Send request to check if the key has been torn down. 70 const assertResult = await xhrRequest(urls.assertUrl); 71 72 // Now check if the value has been torn down. If it's still there, 73 // we have blocked the request by content security policy. 74 assert_equals(assertResult.status, scenario.expectation, 75 "The resource request should be '" + scenario.expectation + "'."); 76 77 }, scenario.test_description); 78 79 promise_test(async _ => { 80 const violationEvents = await violationEventPromise; 81 if (scenario.expectation === 'allowed') { 82 assert_array_equals(violationEvents, [], 83 'no violation events should be fired'); 84 } else { 85 assert_equals(violationEvents.length, 1, 86 'One violation event should be fired'); 87 } 88 }, scenario.test_description + ": securitypolicyviolation"); 89 } // runTest 90 91 function runTests() { 92 for (const scenario of scenarios) { 93 runTest(scenario); 94 } 95 } 96 97 return {start: runTests}; 98 }