function assert_no_csp_event_for_url(test, url) { self.addEventListener("securitypolicyviolation", test.step_func(e => { if (e.blockedURI !== url) return; assert_unreached("SecurityPolicyViolation event fired for " + url); })); } function assert_no_event(test, obj, name) { obj.addEventListener(name, test.unreached_func("The '" + name + "' event should not have fired.")); } function waitUntilCSPEventForURLOrLine(test, url, line) { return new Promise((resolve, reject) => { self.addEventListener("securitypolicyviolation", test.step_func(e => { if (e.blockedURI == url && (!line || line == e.lineNumber)) resolve(e); })); }); } function waitUntilCSPEventForURL(test, url) { return waitUntilCSPEventForURLOrLine(test, url); } function waitUntilCSPEventForEval(test, line) { return waitUntilCSPEventForURLOrLine(test, "eval", line); } function waitUntilCSPEventForTrustedTypes(test) { return waitUntilCSPEventForURLOrLine(test, "trusted-types-sink"); } function waitUntilEvent(obj, name) { return new Promise((resolve, reject) => { obj.addEventListener(name, resolve); }); } // Given the URL of a worker that pings its opener upon load, this // function builds a test that asserts that the ping is received, // and that no CSP event fires. function assert_worker_is_loaded(url, description, expected_message = "ping") { async_test(t => { assert_no_csp_event_for_url(t, url); var w = new Worker(url); assert_no_event(t, w, "error"); waitUntilEvent(w, "message") .then(t.step_func_done(e => { assert_equals(e.data, expected_message); })); }, description); } function assert_shared_worker_is_loaded(url, description, expected_message = "ping") { async_test(t => { assert_no_csp_event_for_url(t, url); var w = new SharedWorker(url); assert_no_event(t, w, "error"); waitUntilEvent(w.port, "message") .then(t.step_func_done(e => { assert_equals(e.data, expected_message); })); w.port.start(); }, description); } function assert_service_worker_is_loaded(url, description) { promise_test(t => { assert_no_csp_event_for_url(t, url); return Promise.all([ waitUntilEvent(navigator.serviceWorker, "message") .then(e => { assert_equals(e.data, "ping"); }), navigator.serviceWorker.register(url, { scope: url }) .then(r => { var sw = r.active || r.installing || r.waiting; t.add_cleanup(_ => r.unregister()); sw.postMessage("pong?"); }) ]); }, description); } // Given the URL of a worker that pings its opener upon load, this // function builds a test that asserts that the constructor throws // a SecurityError, and that a CSP event fires. function assert_worker_is_blocked(url, description) { async_test(t => { // If |url| is a blob, it will be stripped down to "blob" for reporting. var reportedURL = new URL(url).protocol == "blob:" ? "blob" : url; waitUntilCSPEventForURL(t, reportedURL) .then(t.step_func_done(e => { assert_equals(e.blockedURI, reportedURL); assert_equals(e.violatedDirective, "worker-src"); assert_equals(e.effectiveDirective, "worker-src"); })); // TODO(mkwst): We shouldn't be throwing here. We should be firing an // `error` event on the Worker. https://crbug.com/663298 assert_throws_dom("SecurityError", function () { var w = new Worker(url); }); }, description); } function assert_shared_worker_is_blocked(url, description) { async_test(t => { // If |url| is a blob, it will be stripped down to "blob" for reporting. var reportedURL = new URL(url).protocol == "blob:" ? "blob" : url; waitUntilCSPEventForURL(t, reportedURL) .then(t.step_func_done(e => { assert_equals(e.blockedURI, reportedURL); assert_equals(e.violatedDirective, "worker-src"); assert_equals(e.effectiveDirective, "worker-src"); })); // TODO(mkwst): We shouldn't be throwing here. We should be firing an // `error` event on the SharedWorker. https://crbug.com/663298 assert_throws_dom("SecurityError", function () { var w = new SharedWorker(url); }); }, description); } function assert_service_worker_is_blocked(url, description) { promise_test(t => { assert_no_event(t, navigator.serviceWorker, "message"); // If |url| is a blob, it will be stripped down to "blob" for reporting. var reportedURL = new URL(url).protocol == "blob:" ? "blob" : url; return Promise.all([ waitUntilCSPEventForURL(t, reportedURL) .then(t.step_func_done(e => { assert_equals(e.blockedURI, reportedURL); assert_equals(e.violatedDirective, "worker-src"); assert_equals(e.effectiveDirective, "worker-src"); })), promise_rejects_dom(t, "SecurityError", navigator.serviceWorker.register(url, { scope: url })) ]); }, description); }