summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/loading/early-hints/resources/early-hints-helpers.sub.js
diff options
context:
space:
mode:
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.js180
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));
+}