diff options
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/support/testharness-helper.js')
-rw-r--r-- | testing/web-platform/tests/content-security-policy/support/testharness-helper.js | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/support/testharness-helper.js b/testing/web-platform/tests/content-security-policy/support/testharness-helper.js new file mode 100644 index 0000000000..5c36e286da --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/support/testharness-helper.js @@ -0,0 +1,142 @@ +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); +} |