diff options
Diffstat (limited to '')
-rw-r--r-- | testing/web-platform/tests/content-security-policy/support/prefetch-helper.js | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/support/prefetch-helper.js b/testing/web-platform/tests/content-security-policy/support/prefetch-helper.js new file mode 100644 index 0000000000..c0c0be9157 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/support/prefetch-helper.js @@ -0,0 +1,85 @@ +setup(_ => { + assert_implements_optional( + document.createElement('link').relList.supports('prefetch'), + "Browser supports prefetch."); + assert_implements_optional( + "PerformanceResourceTiming" in window, + "Browser supports performance APIs."); +}); + +function assert_resource_not_downloaded(test, url) { + // CSP failures generate resource timing entries, so let's make sure that + // download sizes are 0. + const entries = performance.getEntriesByName(url, 'resource'); + for (const entry of entries) { + assert_equals(entry.transferSize, 0, 'transferSize'); + assert_equals(entry.encodedBodySize, 0, 'encodedBodySize'); + assert_equals(entry.decodedBodySize, 0, 'decodedBodySize'); + } +} + +function assert_link_prefetches(test, link) { + assert_no_csp_event_for_url(test, link.href); + + link.onerror = test.unreached_func('onerror should not fire.'); + + // Test is finished when either the `load` event fires, or we get a performance + // entry showing that the resource loaded successfully. + link.onload = test.step_func(test.step_func_done()); + waitUntilResourceDownloaded(link.href).then(test.step_func_done()); + + document.head.appendChild(link); +} + +function assert_link_does_not_prefetch(test, link) { + let cspEvent = false; + let errorEvent = false; + + waitUntilCSPEventForURL(test, link.href) + .then(test.step_func(e => { + cspEvent = true; + assert_equals(e.violatedDirective, "prefetch-src"); + assert_equals(e.effectiveDirective, "prefetch-src"); + + if (errorEvent) + test.done(); + })); + + link.onerror = test.step_func(e => { + errorEvent = true; + if (cspEvent) + test.done(); + }); + link.onload = test.unreached_func('onload should not fire.'); + + document.head.appendChild(link); +} + +async function try_to_prefetch(href, test) { + const url = new URL(href, location.href); + url.searchParams.set( + 'pipe', + '|header(Cache-Control, max-age=604800)' + + '|header(Access-Control-Allow-Origin, *)' + + '|header(Timing-Allow-Origin, *)'); + url.searchParams.set('uuid', token()); + + const link = document.createElement('link'); + link.rel = 'prefetch'; + link.href = url.toString(); + link.crossOrigin = 'anonymous'; + test.add_cleanup(() => link.remove()); + + const didPrefetch = new Promise(resolve => { + const observer = new PerformanceObserver(list => { + const entries = list.getEntriesByName(link.href); + if (entries.length) { + resolve(entries[0]); + } + }); + observer.observe({entryTypes: ['resource']}) + }); + document.head.appendChild(link); + const entry = await didPrefetch; + return entry.requestStart > 0 && entry.decodedBodySize > 0; +} |