diff options
Diffstat (limited to 'testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js')
-rw-r--r-- | testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js b/testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js new file mode 100644 index 0000000000..3991e8fe9d --- /dev/null +++ b/testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js @@ -0,0 +1,180 @@ +"use strict"; + +const SAME_ORIGIN = "https://{{host}}:{{ports[h2][0]}}"; +const CROSS_ORIGIN = "https://{{hosts[alt][www]}}:{{ports[h2][0]}}"; + +const RESOURCES_PATH = "/loading/early-hints/resources"; +const SAME_ORIGIN_RESOURCES_URL = SAME_ORIGIN + RESOURCES_PATH; +const CROSS_ORIGIN_RESOURCES_URL = CROSS_ORIGIN + RESOURCES_PATH; + +/** + * Navigate to a test page with an Early Hints response. + * + * @typedef {Object} Preload + * @property {string} url - A URL to preload. Note: This is relative to the + * `test_url` parameter of `navigateToTestWithEarlyHints()`. + * @property {string} as_attr - `as` attribute of this preload. + * + * @param {string} test_url - URL of a test after the Early Hints response. + * @param {Array<Preload>} preloads - Preloads included in the Early Hints response. + */ +function navigateToTestWithEarlyHints(test_url, preloads) { + const params = new URLSearchParams(); + params.set("test_url", test_url); + for (const preload of preloads) { + params.append("preloads", JSON.stringify(preload)); + } + const url = "resources/early-hints-test-loader.h2.py?" + params.toString(); + window.location.replace(new URL(url, window.location)); +} + +/** + * Parses the query string of the current window location and returns preloads + * in the Early Hints response sent via `navigateToTestWithEarlyHints()`. + * + * @returns {Array<Preload>} + */ +function getPreloadsFromSearchParams() { + const params = new URLSearchParams(window.location.search); + const encoded_preloads = params.getAll("preloads"); + const preloads = []; + for (const encoded of encoded_preloads) { + preloads.push(JSON.parse(encoded)); + } + return preloads; +} + +/** + * Fetches a script or an image. + * + * @param {string} element - "script" or "img". + * @param {string} url - URL of the resource. + */ +async function fetchResource(element, url) { + return new Promise((resolve, reject) => { + const el = document.createElement(element); + el.src = url; + el.onload = resolve; + el.onerror = _ => reject(new Error("Failed to fetch resource: " + url)); + document.body.appendChild(el); + }); +} + +/** + * Fetches a script. + * + * @param {string} url + */ +async function fetchScript(url) { + return fetchResource("script", url); +} + +/** + * Fetches an image. + * + * @param {string} url + */ + async function fetchImage(url) { + return fetchResource("img", url); +} + +/** + * Returns true when the resource is preloaded via Early Hints. + * + * @param {string} url + * @returns {boolean} + */ +function isPreloadedByEarlyHints(url) { + const entries = performance.getEntriesByName(url); + if (entries.length === 0) { + return false; + } + assert_equals(entries.length, 1); + return entries[0].initiatorType === "early-hints"; +} + +/** + * Navigate to the referrer policy test page. + * + * @param {string} referrer_policy - A value of Referrer-Policy to test. + */ +function testReferrerPolicy(referrer_policy) { + const params = new URLSearchParams(); + params.set("referrer-policy", referrer_policy); + const same_origin_preload_url = SAME_ORIGIN_RESOURCES_URL + "/fetch-and-record-js.h2.py?id=" + token(); + params.set("same-origin-preload-url", same_origin_preload_url); + const cross_origin_preload_url = CROSS_ORIGIN_RESOURCES_URL + "/fetch-and-record-js.h2.py?id=" + token(); + params.set("cross-origin-preload-url", cross_origin_preload_url); + + const path = "resources/referrer-policy-test-loader.h2.py?" + params.toString(); + const url = new URL(path, window.location); + window.location.replace(url); +} + +/** + * Navigate to the content security policy basic test. The test page sends an + * Early Hints response with a cross origin resource preload. CSP headers are + * configured based on the given policies. A policy should be one of the + * followings: + * "absent" - Do not send Content-Security-Policy header + * "allowed" - Set Content-Security-Policy to allow the cross origin preload + * "disallowed" - Set Content-Security-Policy to disallow the cross origin preload + * + * @param {string} early_hints_policy - The policy for the Early Hints response + * @param {string} final_policy - The policy for the final response + */ +function navigateToContentSecurityPolicyBasicTest( + early_hints_policy, final_policy) { + const params = new URLSearchParams(); + params.set("resource-origin", CROSS_ORIGIN); + params.set("resource-url", + CROSS_ORIGIN_RESOURCES_URL + "/empty.js?" + token()); + params.set("early-hints-policy", early_hints_policy); + params.set("final-policy", final_policy); + + const url = "resources/csp-basic-loader.h2.py?" + params.toString(); + window.location.replace(new URL(url, window.location)); +} + +/** + * Navigate to a test page which sends an Early Hints containing a cross origin + * preload link with/without Content-Security-Policy header. The CSP header is + * configured based on the given policy. The test page disallows the preload + * while the preload is in-flight. The policy should be one of the followings: + * "absent" - Do not send Content-Security-Policy header + * "allowed" - Set Content-Security-Policy to allow the cross origin preload + * + * @param {string} early_hints_policy + */ +function navigateToContentSecurityPolicyDocumentDisallowTest(early_hints_policy) { + const resource_id = token(); + const params = new URLSearchParams(); + params.set("resource-origin", CROSS_ORIGIN); + params.set("resource-url", + CROSS_ORIGIN_RESOURCES_URL + "/delayed-js.h2.py?id=" + resource_id); + params.set("resume-url", + CROSS_ORIGIN_RESOURCES_URL + "/resume-delayed-js.h2.py?id=" + resource_id); + params.set("early-hints-policy", early_hints_policy); + + const url = "resources/csp-document-disallow-loader.h2.py?" + params.toString(); + window.location.replace(new URL(url, window.location)); +} + +/** + * Navigate to a test page which sends different Cross-Origin-Embedder-Policy + * values in an Early Hints response and the final response. + * + * @param {string} early_hints_policy - The policy for the Early Hints response + * @param {string} final_policy - The policy for the final response + */ +function navigateToCrossOriginEmbedderPolicyMismatchTest( + early_hints_policy, final_policy) { + const params = new URLSearchParams(); + params.set("resource-url", + CROSS_ORIGIN_RESOURCES_URL + "/empty-corp-absent.js?" + token()); + params.set("early-hints-policy", early_hints_policy); + params.set("final-policy", final_policy); + + const url = "resources/coep-mismatch.h2.py?" + params.toString(); + window.location.replace(new URL(url, window.location)); +} |