summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/client-hints/resources
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/client-hints/resources')
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-different.html11
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-different.html.headers2
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-empty.html11
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-empty.html.headers2
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html11
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html.headers2
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html10
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html.headers5
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-split.html10
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch-split.html.headers3
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch.html10
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch.html.headers2
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html16
-rw-r--r--testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/client-hints/resources/clienthintslist.py40
-rw-r--r--testing/web-platform/tests/client-hints/resources/echo-client-hints-received.py36
-rw-r--r--testing/web-platform/tests/client-hints/resources/echo-ua-client-hints-received.py23
-rw-r--r--testing/web-platform/tests/client-hints/resources/expect-client-hints-headers-iframe.py31
-rw-r--r--testing/web-platform/tests/client-hints/resources/expect-client-hints-headers.html22
-rw-r--r--testing/web-platform/tests/client-hints/resources/expect-different-client-hints-headers.html22
-rw-r--r--testing/web-platform/tests/client-hints/resources/expect-no-client-hints-headers.html24
-rw-r--r--testing/web-platform/tests/client-hints/resources/export.js49
-rw-r--r--testing/web-platform/tests/client-hints/resources/feature-policy-navigation.js72
-rw-r--r--testing/web-platform/tests/client-hints/resources/open-and-add-load-event.js23
-rw-r--r--testing/web-platform/tests/client-hints/resources/script-set-dpr-header.py4
-rw-r--r--testing/web-platform/tests/client-hints/resources/sec-ch-ua.py9
-rw-r--r--testing/web-platform/tests/client-hints/resources/stale-echo-client-hints.py50
-rw-r--r--testing/web-platform/tests/client-hints/resources/viewport-frame.py25
-rw-r--r--testing/web-platform/tests/client-hints/resources/viewport-measurement.html8
-rw-r--r--testing/web-platform/tests/client-hints/resources/viewport.py13
30 files changed, 547 insertions, 0 deletions
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-different.html b/testing/web-platform/tests/client-hints/resources/accept-ch-different.html
new file mode 100644
index 0000000000..05cc0b61b0
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-different.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include only the
+Accept-CH header. Fetching this webpage not cause
+user-agent to persist origin preferences for the client hints
+specified in the Accept-CH header. (This test sends a viewport-width
+preference instead of the device-memory preference)-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-different.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch-different.html.headers
new file mode 100644
index 0000000000..b428fda331
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-different.html.headers
@@ -0,0 +1,2 @@
+Accept-CH: sec-ch-viewport-width,viewport-width
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html b/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html
new file mode 100644
index 0000000000..27393e5a1a
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include only the
+Accept-CH header. Fetching this webpage should cause
+user-agent to persist origin preferences for the client hints
+specified in the Accept-CH header until the origin data is
+cleared.-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html.headers
new file mode 100644
index 0000000000..25215abdf7
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-empty.html.headers
@@ -0,0 +1,2 @@
+Accept-CH:
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html b/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html
new file mode 100644
index 0000000000..70c1c75713
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include only the
+Accept-CH header. Fetching this webpage should cause
+user-agent to persist origin preferences for the client hints
+specified in the Accept-CH header.-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html.headers
new file mode 100644
index 0000000000..83a6a05e54
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-malformed.html.headers
@@ -0,0 +1,2 @@
+Accept-CH: device memory
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html b/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html
new file mode 100644
index 0000000000..bf604dffee
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include empty and full
+Accept-CH headers. Fetching this webpage should cause
+the hint cache to be dropped.-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html.headers
new file mode 100644
index 0000000000..39d4e1935d
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-mixed.html.headers
@@ -0,0 +1,5 @@
+Accept-CH:
+Accept-CH: sec-ch-device-memory
+Accept-CH: device-memory
+Accept-CH:
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-split.html b/testing/web-platform/tests/client-hints/resources/accept-ch-split.html
new file mode 100644
index 0000000000..5038b94013
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-split.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include only
+non-empty Accept-CH headers. Fetching this webpage should cause
+hints to be added to the cache.-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch-split.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch-split.html.headers
new file mode 100644
index 0000000000..261e1e8ee6
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch-split.html.headers
@@ -0,0 +1,3 @@
+Accept-CH: sec-ch-device-memory
+Accept-CH: device-memory
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch.html b/testing/web-platform/tests/client-hints/resources/accept-ch.html
new file mode 100644
index 0000000000..1f1da26ceb
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+
+<!-- An empty webpage whose response headers include only the
+Accept-CH header. Fetching this webpage should cause
+user-agent to persist origin preferences for the client hints
+specified in the Accept-CH header.-->
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch.html.headers b/testing/web-platform/tests/client-hints/resources/accept-ch.html.headers
new file mode 100644
index 0000000000..f5beb4c365
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch.html.headers
@@ -0,0 +1,2 @@
+Accept-CH: sec-ch-device-memory,device-memory
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html b/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html
new file mode 100644
index 0000000000..250a9d9e22
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<script>
+// Step 2 (client-hints/accept-ch.wildcard.https.sub.html)
+const xhr = new XMLHttpRequest();
+xhr.open('POST', "https://{{domains[www2]}}:{{ports[https][0]}}/client-hints/resources/echo-ua-client-hints-received.py");
+xhr.onload = function() {
+ // Step 3 (client-hints/accept-ch.wildcard.https.sub.html)
+ if (xhr.getResponseHeader("sec-ch-ua-platform-received") != null) {
+ window.top.postMessage("HadPlatformVersion", "*");
+ } else {
+ window.top.postMessage("MissingPlatformVersion", "*");
+ }
+};
+xhr.send();
+</script>
diff --git a/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html.sub.headers b/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html.sub.headers
new file mode 100644
index 0000000000..c1c0fcd5c2
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/accept-ch.wildcard.iframe.https.sub.html.sub.headers
@@ -0,0 +1 @@
+Permissions-Policy: ch-ua-platform-version=("https://*.{{domains[]}}:{{ports[https][0]}}") \ No newline at end of file
diff --git a/testing/web-platform/tests/client-hints/resources/clienthintslist.py b/testing/web-platform/tests/client-hints/resources/clienthintslist.py
new file mode 100644
index 0000000000..3d1f7caf46
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/clienthintslist.py
@@ -0,0 +1,40 @@
+def client_hints_list():
+ return [b"device-memory",
+ b"dpr",
+ # b"width", (Only available for images)
+ b"viewport-width",
+ b"rtt",
+ b"downlink",
+ b"ect",
+ b"sec-ch-ua",
+ b"sec-ch-ua-arch",
+ b"sec-ch-ua-platform",
+ b"sec-ch-ua-model",
+ b"sec-ch-ua-mobile",
+ b"sec-ch-ua-full-version",
+ b"sec-ch-ua-platform-version",
+ b"sec-ch-prefers-color-scheme",
+ b"sec-ch-prefers-reduced-motion",
+ b"sec-ch-ua-bitness",
+ b"sec-ch-viewport-height",
+ b"sec-ch-device-memory",
+ b"sec-ch-dpr",
+ # b"sec-ch-width", (Only available for images)
+ b"sec-ch-viewport-width",
+ b"sec-ch-ua-full-version-list",
+ b"sec-ch-ua-wow64",
+ ]
+
+def client_hints_full_list():
+ return client_hints_list() + [b"width", b"sec-ch-width"]
+
+def client_hints_ua_list():
+ return [b"sec-ch-ua",
+ b"sec-ch-ua-arch",
+ b"sec-ch-ua-platform",
+ b"sec-ch-ua-platform-version",
+ b"sec-ch-ua-model",
+ b"sec-ch-ua-full-version",
+ b"sec-ch-ua-full-version-list",
+ b"sec-ch-ua-wow64",
+ ] \ No newline at end of file
diff --git a/testing/web-platform/tests/client-hints/resources/echo-client-hints-received.py b/testing/web-platform/tests/client-hints/resources/echo-client-hints-received.py
new file mode 100644
index 0000000000..190cd86289
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/echo-client-hints-received.py
@@ -0,0 +1,36 @@
+def main(request, response):
+ """
+ Simple handler that sets a response header based on which client hint
+ request headers were received.
+ """
+
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ response.headers.append(b"Access-Control-Allow-Headers", b"*")
+ response.headers.append(b"Access-Control-Expose-Headers", b"*")
+
+ if b"sec-ch-device-memory" in request.headers:
+ response.headers.set(b"device-memory-received", request.headers.get(b"sec-ch-device-memory"))
+ if b"device-memory" in request.headers:
+ response.headers.set(b"device-memory-deprecated-received", request.headers.get(b"device-memory"))
+ if b"sec-ch-dpr" in request.headers:
+ response.headers.set(b"dpr-received", request.headers.get(b"sec-ch-dpr"))
+ if b"dpr" in request.headers:
+ response.headers.set(b"dpr-deprecated-received", request.headers.get(b"dpr"))
+ if b"sec-ch-viewport-width" in request.headers:
+ response.headers.set(b"viewport-width-received", request.headers.get(b"sec-ch-viewport-width"))
+ if b"viewport-width" in request.headers:
+ response.headers.set(b"viewport-width-deprecated-received", request.headers.get(b"viewport-width"))
+ if b"sec-ch-viewport-height" in request.headers:
+ response.headers.set(b"viewport-height-received", request.headers.get(b"sec-ch-viewport-height"))
+ if b"rtt" in request.headers:
+ response.headers.set(b"rtt-received", request.headers.get(b"rtt"))
+ if b"downlink" in request.headers:
+ response.headers.set(b"downlink-received", request.headers.get(b"downlink"))
+ if b"ect" in request.headers:
+ response.headers.set(b"ect-received", request.headers.get(b"ect"))
+ if b"sec-ch-ua-mobile" in request.headers:
+ response.headers.set(b"mobile-received", request.headers.get(b"sec-ch-ua-mobile"))
+ if b"sec-ch-prefers-color-scheme" in request.headers:
+ response.headers.set(b"prefers-color-scheme-received", request.headers.get(b"sec-ch-prefers-color-scheme"))
+ if b"sec-ch-prefers-reduced-motion" in request.headers:
+ response.headers.set(b"prefers-reduced-motion-received", request.headers.get(b"sec-ch-prefers-reduced-motion"))
diff --git a/testing/web-platform/tests/client-hints/resources/echo-ua-client-hints-received.py b/testing/web-platform/tests/client-hints/resources/echo-ua-client-hints-received.py
new file mode 100644
index 0000000000..7982421d07
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/echo-ua-client-hints-received.py
@@ -0,0 +1,23 @@
+import importlib
+client_hints_ua_list = importlib.import_module("client-hints.resources.clienthintslist").client_hints_ua_list
+
+def main(request, response):
+ """
+ Simple handler that sets a response header based on which client hint
+ request headers were received.
+ """
+
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ response.headers.append(b"Access-Control-Allow-Headers", b"*")
+ response.headers.append(b"Access-Control-Expose-Headers", b"*")
+
+ client_hint_headers = client_hints_ua_list()
+ request_client_hints = {i: request.headers.get(i) for i in client_hint_headers}
+
+ for header in client_hint_headers:
+ if request_client_hints[header] is not None:
+ response.headers.set(header + b"-received", request_client_hints[header])
+
+ headers = []
+ content = u""
+ return 200, headers, content
diff --git a/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers-iframe.py b/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers-iframe.py
new file mode 100644
index 0000000000..6a1218264e
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers-iframe.py
@@ -0,0 +1,31 @@
+from wptserve.utils import isomorphic_decode
+
+import importlib
+client_hints_list = importlib.import_module("client-hints.resources.clienthintslist").client_hints_list
+
+def main(request, response):
+ """
+ Simple handler that returns an HTML response that passes when the required
+ Client Hints are received as request headers.
+ """
+
+ result = u"PASS"
+ log = u""
+ for value in client_hints_list():
+ should = (request.GET[value.lower()] == b"true")
+ present = request.headers.get(value.lower()) or request.headers.get(value)
+ if present:
+ log += isomorphic_decode(value) + u" " + str(should) + u" " + isomorphic_decode(present) + u", "
+ else:
+ log += isomorphic_decode(value) + u" " + str(should) + u" " + str(present) + u", "
+ if (should and not present) or (not should and present):
+ if present:
+ result = u"FAIL " + isomorphic_decode(value) + u" " + str(should) + u" " + isomorphic_decode(present)
+ else:
+ result = u"FAIL " + isomorphic_decode(value) + u" " + str(should) + u" " + str(present)
+ break
+
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ body = u"<script>console.log('" + log + u"'); window.parent.postMessage('" + result + u"', '*');</script>"
+
+ response.content = body
diff --git a/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers.html b/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers.html
new file mode 100644
index 0000000000..928a82db45
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/expect-client-hints-headers.html
@@ -0,0 +1,22 @@
+<html>
+<body>
+<script>
+
+// This test checks if browser attaches the device-memory client hint in the
+// HTTP request headers.
+
+// resources/echo-client-hints-received.py sets the response headers depending on the set
+// of client hints it receives in the request headers.
+
+fetch("../resources/echo-client-hints-received.py").then(r => {
+ if(r.status == 200 && r.headers.has("device-memory-received") && r.headers.has("device-memory-deprecated-received")) {
+ window.top.opener.postMessage('PASS', '*');
+ }
+ else {
+ window.top.opener.postMessage('FAIL', '*');
+ }
+});
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/expect-different-client-hints-headers.html b/testing/web-platform/tests/client-hints/resources/expect-different-client-hints-headers.html
new file mode 100644
index 0000000000..19ee394f46
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/expect-different-client-hints-headers.html
@@ -0,0 +1,22 @@
+<html>
+<body>
+<script>
+
+// This test checks if browser attaches the viewport-width client hint in the
+// HTTP request headers.
+
+// resources/echo-client-hints-received.py sets the response headers depending on the set
+// of client hints it receives in the request headers.
+
+fetch("../resources/echo-client-hints-received.py").then(r => {
+ if(r.status == 200 && r.headers.has("viewport-width-received") && r.headers.has("viewport-width-deprecated-received")) {
+ window.top.opener.postMessage('PASS', '*');
+ }
+ else {
+ window.top.opener.postMessage('FAIL', '*');
+ }
+});
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/expect-no-client-hints-headers.html b/testing/web-platform/tests/client-hints/resources/expect-no-client-hints-headers.html
new file mode 100644
index 0000000000..07eb0568d4
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/expect-no-client-hints-headers.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+
+// This test checks if browser attaches the viewport-width client hint in the
+// HTTP request headers.
+
+// resources/echo-client-hints-received.py sets the response headers depending on the set
+// of client hints it receives in the request headers.
+
+fetch("../resources/echo-client-hints-received.py").then(r => {
+ if(r.status == 200 &&
+ !r.headers.has("viewport-width-received") &&
+ !r.headers.has("viewport-width-received")) {
+ window.top.opener.postMessage('PASS', '*');
+ } else {
+ window.top.opener.postMessage('FAIL', '*');
+ }
+});
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/client-hints/resources/export.js b/testing/web-platform/tests/client-hints/resources/export.js
new file mode 100644
index 0000000000..68cea03ce4
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/export.js
@@ -0,0 +1,49 @@
+const client_hints_list = [
+ "device-memory",
+ "dpr",
+ // "width", (only available for images)
+ "viewport-width",
+ "rtt",
+ "downlink",
+ "ect",
+ "sec-ch-ua",
+ "sec-ch-ua-arch",
+ "sec-ch-ua-platform",
+ "sec-ch-ua-model",
+ "sec-ch-ua-mobile",
+ "sec-ch-ua-full-version",
+ "sec-ch-ua-platform-version",
+ "sec-ch-prefers-color-scheme",
+ "sec-ch-prefers-reduced-motion",
+ "sec-ch-ua-bitness",
+ "sec-ch-viewport-height",
+ "sec-ch-device-memory",
+ "sec-ch-dpr",
+ // "sec-ch-width", (Only available for images)
+ "sec-ch-viewport-width",
+ "sec-ch-ua-full-version-list",
+ "sec-ch-ua-wow64",
+];
+
+const client_hints_full_list = client_hints_list.concat(["width", "sec-ch-width"])
+
+const default_on_client_hints = [
+ "sec-ch-ua",
+ "sec-ch-ua-mobile",
+ "sec-ch-ua-platform",
+];
+
+const iframe_src =
+ "/client-hints/resources/expect-client-hints-headers-iframe.py?";
+
+const expect_iframe_no_hints = iframe_src +
+ client_hints_list.map((e) => {
+ if(default_on_client_hints.includes(e)) {
+ return e+"=true";
+ } else {
+ return e+"=false";
+ }
+ }).join("&");
+
+const expect_iframe_hints = iframe_src +
+ client_hints_list.map(e => e+"=true").join("&"); \ No newline at end of file
diff --git a/testing/web-platform/tests/client-hints/resources/feature-policy-navigation.js b/testing/web-platform/tests/client-hints/resources/feature-policy-navigation.js
new file mode 100644
index 0000000000..23782fdfdb
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/feature-policy-navigation.js
@@ -0,0 +1,72 @@
+const meta_name_enabled = [
+ "sec-ch-device-memory",
+ "device-memory",
+ "sec-ch-dpr",
+ "dpr",
+ "sec-ch-viewport-width",
+ "viewport-width",
+ "sec-ch-ua",
+ "sec-ch-ua-mobile",
+ "sec-ch-ua-platform",
+];
+
+const meta_name_client_hints = iframe_src +
+ client_hints_list.map((e) => {
+ if(meta_name_enabled.includes(e)) {
+ return e+"=true";
+ } else {
+ return e+"=false";
+ }
+ }).join("&");
+
+const cross_origin_enabled = [
+ "device-memory",
+ "sec-ch-device-memory",
+ "sec-ch-ua-platform",
+];
+
+const cross_origin_client_hints = iframe_src +
+ client_hints_list.map((e) => {
+ if(cross_origin_enabled.includes(e)) {
+ return e+"=true";
+ } else {
+ return e+"=false";
+ }
+ }).join("&");
+
+const same_origin_disabled = [
+ "dpr",
+ "sec-ch-dpr",
+ "sec-ch-ua-mobile",
+];
+
+const same_origin_client_hints = iframe_src +
+ client_hints_list.map((e) => {
+ if(same_origin_disabled.includes(e)) {
+ return e+"=false";
+ } else {
+ return e+"=true";
+ }
+ }).join("&");
+
+const test_frame = (origin, url, allow, message) => {
+ promise_test(() => {
+ return new Promise((resolve, reject) => {
+ let frame = document.createElement('iframe');
+ frame.allow = allow;
+ window.addEventListener('message', function(e) {
+ try {
+ assert_equals(typeof e.data, "string");
+ assert_equals(e.data, "PASS");
+ } catch {
+ reject(e.data);
+ }
+ resolve();
+ });
+ document.body.appendChild(frame);
+ // Writing to |frame.src| triggers the navigation, so
+ // everything else need to happen first.
+ frame.src = get_host_info()[origin] + url;
+ });
+ }, message);
+}
diff --git a/testing/web-platform/tests/client-hints/resources/open-and-add-load-event.js b/testing/web-platform/tests/client-hints/resources/open-and-add-load-event.js
new file mode 100644
index 0000000000..bd88fcc28e
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/open-and-add-load-event.js
@@ -0,0 +1,23 @@
+function open_and_add_load_event(href) {
+ return new Promise((resolve) => {
+ // While not practically possible, opening "blank" first and setting the
+ // href after allows for the theoretical possibility of registering the event
+ // after the window is loaded.
+ let popup_window = window.open("/resources/blank.html");
+ assert_not_equals(popup_window, null, "Popup windows not allowed?");
+ popup_window.addEventListener('load', resolve, {once: true});
+ popup_window.location.href = href;
+ });
+}
+
+async function open_and_expect_headers(href) {
+ let e = await new Promise(resolve => {
+ let popup_window = window.open("/resources/blank.html");
+ assert_not_equals(popup_window, null, "Popup windows not allowed?");
+ window.addEventListener('message', resolve, false);
+ popup_window.location.href = href;
+ });
+
+ assert_equals(e.data, "PASS");
+ return e;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/client-hints/resources/script-set-dpr-header.py b/testing/web-platform/tests/client-hints/resources/script-set-dpr-header.py
new file mode 100644
index 0000000000..9a65886ed8
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/script-set-dpr-header.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ body = u'dprHeader = "%s";' % request.headers.get(b'sec-ch-dpr', '')
+ return 200, headers, body
diff --git a/testing/web-platform/tests/client-hints/resources/sec-ch-ua.py b/testing/web-platform/tests/client-hints/resources/sec-ch-ua.py
new file mode 100644
index 0000000000..ddeb582a19
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/sec-ch-ua.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ ua = request.headers.get(b'Sec-CH-UA', b'')
+ response.headers.set(b"Content-Type", b"text/html")
+ response.content = b'''
+<script>
+ window.opener.postMessage({ header: '%s' }, "*");
+</script>
+Sec-CH-UA: %s
+''' % (ua, ua)
diff --git a/testing/web-platform/tests/client-hints/resources/stale-echo-client-hints.py b/testing/web-platform/tests/client-hints/resources/stale-echo-client-hints.py
new file mode 100644
index 0000000000..e9832273b8
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/stale-echo-client-hints.py
@@ -0,0 +1,50 @@
+import random
+import string
+
+from wptserve.utils import isomorphic_encode
+import importlib
+client_hints_full_list = importlib.import_module("client-hints.resources.clienthintslist").client_hints_full_list
+
+def id_token():
+ letters = string.ascii_lowercase
+ return u''.join(random.choice(letters) for i in range(20))
+
+def main(request, response):
+ client_hint_headers = client_hints_full_list()
+ client_hints_curr = {i:request.headers.get(i) for i in client_hint_headers}
+
+ token = request.GET.first(b"token", None)
+ is_query = request.GET.first(b"query", None) is not None
+ with request.server.stash.lock:
+ stash = request.server.stash.take(token)
+ if stash != None:
+ (value, client_hints_prev) = stash
+ count = int(value)
+ else:
+ count = 0
+ client_hints_prev = {}
+
+ if is_query:
+ if count < 2:
+ request.server.stash.put(token, (count, client_hints_curr))
+ else:
+ count = count + 1
+ request.server.stash.put(token, (count, client_hints_curr))
+
+ for header in client_hint_headers:
+ if client_hints_curr[header] is not None:
+ response.headers.set(header+b"-recieved", client_hints_curr[header])
+ if (header in client_hints_prev) and (client_hints_prev[header] is not None):
+ response.headers.set(header+b"-previous", client_hints_prev[header])
+
+ if is_query:
+ headers = [(b"Count", count)]
+ content = u""
+ return 200, headers, content
+ else:
+ unique_id = id_token()
+ headers = [(b"Content-Type", b"text/html"),
+ (b"Cache-Control", b"private, max-age=0, stale-while-revalidate=60"),
+ (b"Unique-Id", isomorphic_encode(unique_id))]
+ content = u"report('{}')".format(unique_id)
+ return 200, headers, content
diff --git a/testing/web-platform/tests/client-hints/resources/viewport-frame.py b/testing/web-platform/tests/client-hints/resources/viewport-frame.py
new file mode 100644
index 0000000000..67b592c71a
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/viewport-frame.py
@@ -0,0 +1,25 @@
+def main(request, response):
+ """
+ postMessage with Viewport-Width and Sec-Ch-Viewport-Height headers
+ """
+
+ if b"sec-ch-viewport-width" in request.headers:
+ width = request.headers["sec-ch-viewport-width"]
+ else:
+ width = b"FAIL"
+
+ if b"sec-ch-viewport-height" in request.headers:
+ height = request.headers["sec-ch-viewport-height"]
+ else:
+ height = b"FAIL"
+
+ headers = [(b"Content-Type", b"text/html"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ content = b'''
+<script>
+ let parentOrOpener = window.opener || window.parent;
+ parentOrOpener.postMessage({ viewportWidth: '%s', viewportHeight: '%s' }, "*");
+</script>
+''' % (width, height)
+
+ return 200, headers, content
diff --git a/testing/web-platform/tests/client-hints/resources/viewport-measurement.html b/testing/web-platform/tests/client-hints/resources/viewport-measurement.html
new file mode 100644
index 0000000000..2ac9043af7
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/viewport-measurement.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+(async () => {
+ const response = await fetch("viewport.py");
+ const body = await response.text();
+ parent.postMessage(body, "*");
+})();
+</script>
diff --git a/testing/web-platform/tests/client-hints/resources/viewport.py b/testing/web-platform/tests/client-hints/resources/viewport.py
new file mode 100644
index 0000000000..d5ab6d4eee
--- /dev/null
+++ b/testing/web-platform/tests/client-hints/resources/viewport.py
@@ -0,0 +1,13 @@
+def main(request, response):
+ """
+ Reflect Sec-Ch-Viewport-Width and Sec-Ch-Viewport-Height headers
+ """
+
+ if b"sec-ch-viewport-width" in request.headers and b"sec-ch-viewport-height" in request.headers:
+ result = request.headers["sec-ch-viewport-width"] + b"," + request.headers["sec-ch-viewport-height"]
+ else:
+ result = u"FAIL"
+
+ headers = [(b"Content-Type", b"text/html"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ return 200, headers, result