summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/document-policy
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/document-policy
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/document-policy')
-rw-r--r--testing/web-platform/tests/document-policy/META.yml1
-rw-r--r--testing/web-platform/tests/document-policy/echo-policy-nested.html32
-rw-r--r--testing/web-platform/tests/document-policy/echo-policy-nested.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/echo-policy.py30
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/document-write.tentative.html91
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html40
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html36
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html23
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/layout-animations-enabled-tentative.html30
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/animation-property-height.js3
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/async-script.js1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/common.js90
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/defer-script.js1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/document-policy-image.html13
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/document-write-allowed.html37
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html37
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/image.jpgbin0 -> 570855 bytes
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/image.pngbin0 -> 217 bytes
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/image.svg4
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/parser-blocking-script.js1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/sync-script-test.js9
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/resources/video.ogvbin0 -> 103746 bytes
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html22
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html95
-rw-r--r--testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative-ref.html30
-rw-r--r--testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html46
-rw-r--r--testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html9
-rw-r--r--testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/font-display/resources/font-display-reporting-helper.js81
-rw-r--r--testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html26
-rw-r--r--testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html32
-rw-r--r--testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/image.jpgbin0 -> 2033 bytes
-rw-r--r--testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html26
-rw-r--r--testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html27
-rw-r--r--testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html32
-rw-r--r--testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/oversized.jpgbin0 -> 1655 bytes
-rw-r--r--testing/web-platform/tests/document-policy/reporting/resources/sync-script.js20
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html14
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html28
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html36
-rw-r--r--testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/reporting/unoptimized-image.jpgbin0 -> 43999 bytes
-rw-r--r--testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html24
-rw-r--r--testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/document-policy.html54
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/document-policy.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/no-document-policy.html44
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/required-document-policy-nested.html65
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/required-document-policy.html65
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/required-document-policy.html.headers1
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html64
-rw-r--r--testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html.headers2
-rw-r--r--testing/web-platform/tests/document-policy/resources/document-policy-report-json.js20
89 files changed, 1471 insertions, 0 deletions
diff --git a/testing/web-platform/tests/document-policy/META.yml b/testing/web-platform/tests/document-policy/META.yml
new file mode 100644
index 0000000000..673defaa02
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/META.yml
@@ -0,0 +1 @@
+spec: https://wicg.github.io/document-policy/
diff --git a/testing/web-platform/tests/document-policy/echo-policy-nested.html b/testing/web-platform/tests/document-policy/echo-policy-nested.html
new file mode 100644
index 0000000000..5a01f4e1ec
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/echo-policy-nested.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<body>
+<script>
+// This document will contain an iframe which will either host echo-policy.py,
+// or will host another copy of this document, with the nesting level reduced
+// by one. This way, an arbitrary nesting depth can be achieved, with the
+// final inner-most frame reporting back the advertised required policy.
+
+// The 'id' URL parameter will be passed to the nested document.
+// The 'level' URL paramater will be reduced by 1 and passed to the nested
+// document if it was at least 1. (If it was 0, then echo-policy.py will be
+// nested instead, and the level parameter will not be passed.)
+
+// This document is served with a Document Policy header that should satisfy
+// any requests that include a required policy for the
+// 'lossless-images-max-bpp' feature.
+const params = new URLSearchParams(window.location.search);
+const id = params.get('id');
+const level = params.get('level');
+
+const iframe = document.createElement('iframe');
+var hostname;
+if (level >= 1) {
+ params.set('level',level-1);
+ hostname = document.location.pathname + "?" + params.toString();
+} else {
+ params.delete('level');
+ hostname = "/document-policy/echo-policy.py?" + params.toString();
+}
+iframe.src = hostname;
+document.body.appendChild(iframe);
+</script>
diff --git a/testing/web-platform/tests/document-policy/echo-policy-nested.html.headers b/testing/web-platform/tests/document-policy/echo-policy-nested.html.headers
new file mode 100644
index 0000000000..419a3c3dd1
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/echo-policy-nested.html.headers
@@ -0,0 +1 @@
+Document-Policy: lossless-images-max-bpp=0.0
diff --git a/testing/web-platform/tests/document-policy/echo-policy.py b/testing/web-platform/tests/document-policy/echo-policy.py
new file mode 100644
index 0000000000..2ad326dac7
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/echo-policy.py
@@ -0,0 +1,30 @@
+# This will echo the 'Sec-Required-Document-Policy' request header in the body
+# of the response, as well as in the 'Document-Policy' response header (to
+# ensure the response is loaded by a user agent which is implementing document
+# policy.)
+import json
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ msg = {}
+ headers = [(b'Content-Type', b'text/html')]
+
+ srdp = request.headers.get(b'Sec-Required-Document-Policy')
+ if srdp:
+ msg[u'requiredPolicy'] = isomorphic_decode(srdp)
+ headers.append((b'Document-Policy', srdp))
+
+ frameId = request.GET.first(b'id',None)
+ if frameId:
+ msg[u'id'] = isomorphic_decode(frameId)
+
+ content = u"""<!DOCTYPE html>
+<script>
+top.postMessage(%s, "*");
+</script>
+%s
+""" % (json.dumps(msg), isomorphic_decode(srdp) if srdp != None else srdp)
+
+ return (200, u'OK'), headers, content
+
diff --git a/testing/web-platform/tests/document-policy/experimental-features/document-write.tentative.html b/testing/web-platform/tests/document-policy/experimental-features/document-write.tentative.html
new file mode 100644
index 0000000000..551703c6f5
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/document-write.tentative.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<title>'document-write' tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/document-policy/experimental-features/resources/common.js"></script>
+<style>
+html, body {
+ height: 100%;
+ width: 100%;
+}
+</style>
+<body>
+<script>
+ "use strict";
+
+ function newIframe() {
+ var i = document.createElement("iframe");
+ document.body.appendChild(i);
+ return i;
+ }
+
+ let iframeElement = document.querySelector("iframe");
+ const allowed_url = url_base + "document-write-allowed.html";
+ const disallowed_url = url_base + "document-write-disallowed.html";
+
+ let text_to_write = "<div>FOO<\/div>";
+ let test_cases = [{
+ api: "open",
+ query: "body",
+ expected_value_enabled: false,
+ },
+ {
+ api: "close"
+ },
+ {
+ api: "write",
+ args: text_to_write,
+ query: "div",
+ expected_value_enabled: "FOO"
+ },
+ {
+ api: "writeln",
+ args: text_to_write,
+ query: "div",
+ expected_value_enabled: "FOO"
+ }];
+
+ // The feature 'document-write' is enabled by default and when it
+ // is enabled, all dynamic markup insertion API work as intended.
+ test_cases.forEach((tc) => {
+ promise_test(async() => {
+ let iframeElement = newIframe();
+ await loadUrlInIframe(iframeElement, allowed_url);
+ await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => {
+ assert_false(
+ response.did_throw_exception,
+ `When feature is disabled, invoking 'document.${tc.api}' should not` +
+ " throw an exception.");
+ if (tc.query) {
+ assert_equals(
+ response.value,
+ tc.expected_value_enabled,
+ `The added script tag by 'document.${tc.api}' must have run.`);
+ }
+ });
+ }, `Verify 'document.${tc.api}' is not normally blocked.` );
+ });
+
+
+ // Disabling 'document-write' throws exception on the included API.
+ test_cases.forEach((tc) => {
+ promise_test(async() => {
+ let iframeElement = newIframe();
+ await loadUrlInIframe(iframeElement, disallowed_url);
+ await sendMessageAndGetResponse(iframeElement.contentWindow, tc).then((response) => {
+ assert_true(
+ response.did_throw_exception,
+ `When feature is enabled, invoking 'document.${tc.api}' should ` +
+ " throw an exception.");
+ if (tc.query) {
+ assert_not_equals(
+ response.value,
+ tc.expected_value_enabled,
+ `The added script tag by 'document.${tc.api}' must not have run.`);
+ }
+ });
+ }, `Verify 'document.${tc.api}' is blocked when the feature is disabled.` );
+ });
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html
new file mode 100644
index 0000000000..fd32ace78e
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+<title> 'layout-animations' Policy : Correct behavior for affected and unaffected properties when
+ feature is disabled.
+</title>
+<body>
+<script>
+ // Sanity-check: Properties which are not affected by the policy 'layout-animations' should be
+ // interpolated normally (linearly) when the policy is disabled for the document.
+ test_interpolation(
+ {
+ property: "color",
+ from: "rgba(0, 50, 100, 1)",
+ to: "rgba(200, 150, 200, 1)",
+ test_prefix: 'Testing property "color".'
+ },
+ [
+ {at: 0.00, expect: "rgba(0, 50, 100, 1)"},
+ {at: 0.1, expect: "rgba(20, 60, 110, 1)"},
+ {at: 0.2, expect: "rgba(40, 70, 120, 1)"},
+ {at: 0.4, expect: "rgba(80, 90, 140, 1)"},
+ {at: 0.6, expect: "rgba(120, 110, 160, 1)"},
+ {at: 0.8, expect: "rgba(160, 130, 180, 1)"},
+ {at: 0.9, expect: "rgba(180, 140, 190, 1)"},
+ ]);
+
+ // There is no interpolation for the affected properties when the policy is disabled.
+ ["bottom", "height", "left", "right", "top", "width"].forEach(
+ (p) => test_no_interpolation(
+ {
+ property: p,
+ from: "100px",
+ to: "200px",
+ test_prefix: `Testing property "${p}".`
+ }));
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html.headers b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html.headers
new file mode 100644
index 0000000000..745da550ee
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: layout-animations=?0
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html
new file mode 100644
index 0000000000..ee7c295156
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/document-policy/experimental-features/resources/common.js"></script>
+<title> 'layout-animations' Policy : violation reports from javascript
+</title>
+<body>
+<script>
+ promise_test(async () => {
+ let promise = wait_for_violation_in_file(
+ "layout-animations",
+ "animation-property-height.js");
+ let script = document.createElement("script");
+ script.src = "/document-policy/experimental-features/resources/" +
+ "animation-property-height.js";
+ document.body.appendChild(script);
+ await promise;
+ },
+ "Verify that when 'layout-animations' is disabled, an 'element.animate' " +
+ "API including a keyframe that uses a blocked property generates violation " +
+ "report (linked scripts).");
+
+ promise_test(async () => {
+ let promise = wait_for_violation_in_file(
+ "layout-animations",
+ "layout-animations-disabled-violation-report-js-tentative.html");
+ let div = document.createElement("div");
+ document.body.appendChild(div);
+ div.animate([{width: "100px"}, {width: "200px"}]);
+ await promise;
+ },
+ "Verify that when 'layout-animations' is disabled, an 'element.animate' " +
+ "API including a keyframe that uses a blocked property generates violation " +
+ "report (inline scripts).");
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html.headers b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html.headers
new file mode 100644
index 0000000000..745da550ee
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-js-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: layout-animations=?0
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html
new file mode 100644
index 0000000000..cd9210cc13
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/document-policy/experimental-features/resources/common.js"></script>
+<title> 'layout-animations' Policy : violation reports from CSS keyframes
+</title>
+<body>
+<script>
+ promise_test(async () => {
+ let promise = wait_for_violation_in_file(
+ "layout-animations", null /* source not specified */);
+ let style = document.createElement("style");
+ style.innerHTML = `@keyframes animation_property_top {
+ from { top: 0px }
+ to { top: 100px }
+ }`;
+ document.body.appendChild(style);
+ await promise;
+ },
+ "Verify that when 'layout-animations' is disabled, a keyframes which " +
+ "includes a blocked property generates violation report.");
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html.headers b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html.headers
new file mode 100644
index 0000000000..745da550ee
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-disabled-violation-report-keyframes-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: layout-animations=?0
diff --git a/testing/web-platform/tests/document-policy/experimental-features/layout-animations-enabled-tentative.html b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-enabled-tentative.html
new file mode 100644
index 0000000000..19e405496e
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/layout-animations-enabled-tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+<title> 'layout-animations' Policy : Correct behavior for affected and unaffected properties when
+ feature is enabled.
+</title>
+<body>
+<script>
+ // The expectation for all the following properties could be the same (they are all of type length).
+ let length_expectations_100_to_200 = [
+ {at: 0.00, expect: "100px"},
+ {at: 0.1, expect: "110px"},
+ {at: 0.2, expect: "120px"},
+ {at: 0.4, expect: "140px"},
+ {at: 0.6, expect: "160px"},
+ {at: 0.8, expect: "180px"},
+ {at: 0.9, expect: "190px"},
+ ];
+ // Ensure all the affected animations run normally.
+ ["bottom", "height", "left", "right", "top", "width"].forEach(
+ (p) => test_interpolation({
+ property: p,
+ from: "100px",
+ to: "200px",
+ test_prefix: `Testing property "${p}".`
+ },
+ length_expectations_100_to_200));
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/animation-property-height.js b/testing/web-platform/tests/document-policy/experimental-features/resources/animation-property-height.js
new file mode 100644
index 0000000000..79316cb488
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/animation-property-height.js
@@ -0,0 +1,3 @@
+let div = document.createElement("div");
+document.body.appendChild(div);
+div.animate([{"height": "0px"}, {"height": "100px"}]);
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/async-script.js b/testing/web-platform/tests/document-policy/experimental-features/resources/async-script.js
new file mode 100644
index 0000000000..3c0ee6d023
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/async-script.js
@@ -0,0 +1 @@
+window.didExecuteExternalAsyncScript = true;
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/common.js b/testing/web-platform/tests/document-policy/experimental-features/resources/common.js
new file mode 100644
index 0000000000..639847abf3
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/common.js
@@ -0,0 +1,90 @@
+const url_base = "/document-policy/experimental-features/resources/";
+window.messageResponseCallback = null;
+
+// Returns a promise which is resolved when the <iframe> is navigated to |url|
+// and "load" handler has been called.
+function loadUrlInIframe(iframe, url) {
+ return new Promise((resolve) => {
+ iframe.addEventListener("load", resolve);
+ iframe.src = url;
+ });
+}
+
+// Posts |message| to |target| and resolves the promise with the response coming
+// back from |target|.
+function sendMessageAndGetResponse(target, message) {
+ return new Promise((resolve) => {
+ window.messageResponseCallback = resolve;
+ target.postMessage(message, "*");
+ });
+}
+
+
+function onMessage(e) {
+ if (window.messageResponseCallback) {
+ window.messageResponseCallback(e.data);
+ window.messageResponseCallback = null;
+ }
+}
+
+window.addEventListener("message", onMessage);
+
+// Waits for |load_timeout| before resolving the promise. It will resolve the
+// promise sooner if a message event with |e.data.id| of |id| is received.
+// In such a case the response is the contents of the message |e.data.contents|.
+// Otherwise, returns false (when timeout occurs).
+function waitForMessageOrTimeout(t, id, load_timeout) {
+ return new Promise((resolve) => {
+ window.addEventListener(
+ "message",
+ (e) => {
+ if (!e.data || e.data.id !== id)
+ return;
+ resolve(e.data.contents);
+ }
+ );
+ t.step_timeout(() => { resolve(false); }, load_timeout);
+ });
+}
+
+function createIframe(container, attributes) {
+ var new_iframe = document.createElement("iframe");
+ for (attr_name in attributes)
+ new_iframe.setAttribute(attr_name, attributes[attr_name]);
+ container.appendChild(new_iframe);
+ return new_iframe;
+}
+
+// Returns a promise which is resolved when |load| event is dispatched for |e|.
+function wait_for_load(e) {
+ return new Promise((resolve) => {
+ e.addEventListener("load", resolve);
+ });
+}
+
+setup(() => {
+ window.reporting_observer_instance = new ReportingObserver((reports, observer) => {
+ if (window.reporting_observer_callback) {
+ reports.forEach(window.reporting_observer_callback);
+ }
+ }, {types: ["document-policy-violation"]});
+ window.reporting_observer_instance.observe();
+ window.reporting_observer_callback = null;
+});
+
+// Waits for a violation in |feature| and source file containing |file_name|.
+function wait_for_violation_in_file(feature, file_name) {
+ return new Promise( (resolve) => {
+ assert_equals(null, window.reporting_observer_callback);
+ window.reporting_observer_callback = (report) => {
+ var feature_match = (feature === report.body.featureId);
+ var file_name_match =
+ !file_name ||
+ (report.body.sourceFile.indexOf(file_name) !== -1);
+ if (feature_match && file_name_match) {
+ window.reporting_observer_callback = null;
+ resolve(report);
+ }
+ };
+ });
+}
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/defer-script.js b/testing/web-platform/tests/document-policy/experimental-features/resources/defer-script.js
new file mode 100644
index 0000000000..8d248ee0d0
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/defer-script.js
@@ -0,0 +1 @@
+window.didExecuteExternalDeferredScript = true;
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/document-policy-image.html b/testing/web-platform/tests/document-policy/experimental-features/resources/document-policy-image.html
new file mode 100644
index 0000000000..4e5b919bd1
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/document-policy-image.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<body>
+<script>
+window.addEventListener('load', function() {
+ var img = document.createElement('IMG');
+ img.setAttribute("src", "/document-policy/experimental-features/resources/image.jpg");
+ img.addEventListener('load', function() {
+ parent.postMessage({width: img.width, height: img.height}, '*');
+ });
+ document.body.appendChild(img);
+});
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-allowed.html b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-allowed.html
new file mode 100644
index 0000000000..633fa85e6a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-allowed.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<style>
+#spacer {
+ width: 200%;
+ height: 200%;
+}
+</style>
+<body>
+<script>
+ window.addEventListener("message", onMessageReceived);
+
+ function test(api, args) {
+ let did_throw = false;
+ try {
+ document[api](args);
+ } catch(e) {
+ did_throw = true;
+ }
+ return did_throw;
+ }
+
+ function onMessageReceived(e) {
+ let msg = e.data;
+
+ msg.did_throw_exception = test(msg.api, msg.args);
+ if (msg.query) {
+ let el = document.querySelector(msg.query);
+ msg.value = el ? el.innerHTML : false;
+ }
+ ackMessage(msg, e.source);
+ }
+
+ function ackMessage(msg, source) {
+ source.postMessage(msg, "*");
+ }
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html
new file mode 100644
index 0000000000..633fa85e6a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<style>
+#spacer {
+ width: 200%;
+ height: 200%;
+}
+</style>
+<body>
+<script>
+ window.addEventListener("message", onMessageReceived);
+
+ function test(api, args) {
+ let did_throw = false;
+ try {
+ document[api](args);
+ } catch(e) {
+ did_throw = true;
+ }
+ return did_throw;
+ }
+
+ function onMessageReceived(e) {
+ let msg = e.data;
+
+ msg.did_throw_exception = test(msg.api, msg.args);
+ if (msg.query) {
+ let el = document.querySelector(msg.query);
+ msg.value = el ? el.innerHTML : false;
+ }
+ ackMessage(msg, e.source);
+ }
+
+ function ackMessage(msg, source) {
+ source.postMessage(msg, "*");
+ }
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html.headers b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html.headers
new file mode 100644
index 0000000000..32846f724a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/document-write-disallowed.html.headers
@@ -0,0 +1 @@
+Document-Policy: document-write=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/image.jpg b/testing/web-platform/tests/document-policy/experimental-features/resources/image.jpg
new file mode 100644
index 0000000000..430f5c514a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/image.jpg
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/image.png b/testing/web-platform/tests/document-policy/experimental-features/resources/image.png
new file mode 100644
index 0000000000..556fa72704
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/image.png
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/image.svg b/testing/web-platform/tests/document-policy/experimental-features/resources/image.svg
new file mode 100644
index 0000000000..73ca820915
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/image.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="yes"?>
+
+<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M267.88715 112.77165L267.88715 112.77165C267.88715 93.211205 283.74402 77.35433 303.30447 77.35433L303.30447 77.35433C312.69772 77.35433 321.70627 81.085785 328.3483 87.72782C334.99033 94.36986 338.72177 103.378395 338.72177 112.77165L338.72177 112.77165C338.72177 132.3321 322.8649 148.18898 303.30447 148.18898L303.30447 148.18898C283.74402 148.18898 267.88715 132.3321 267.88715 112.77165Z" fill-rule="nonzero" fill="#cfe2f3" stroke="#073763" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt"></path><path d="M294.15125 114.47782L295.1825 114.61845Q295.01062 115.68095 294.3075 116.29032Q293.60437 116.8997 292.58875 116.8997Q291.3075 116.8997 290.53406 116.06376Q289.76062 115.22782 289.76062 113.66532Q289.76062 112.66532 290.09656 111.90751Q290.4325 111.1497 291.11218 110.7747Q291.79187 110.3997 292.60437 110.3997Q293.60437 110.3997 294.2528 110.90751Q294.90125 111.41532 295.08875 112.36845L294.0575 112.5247Q293.91687 111.8997 293.54187 111.579384Q293.16687 111.25907 292.63562 111.25907Q291.83875 111.25907 291.33875 111.829384Q290.83875 112.3997 290.83875 113.63407Q290.83875 114.8997 291.32312 115.4622Q291.8075 116.0247 292.57312 116.0247Q293.19812 116.0247 293.61218 115.6497Q294.02625 115.2747 294.15125 114.47782ZM296.08875 109.38407L296.08875 108.16532L297.15125 108.16532L297.15125 109.38407L296.08875 109.38407ZM296.08875 116.75907L296.08875 110.54032L297.15125 110.54032L297.15125 116.75907L296.08875 116.75907ZM298.745 116.75907L298.745 110.54032L299.69812 110.54032L299.69812 111.47782Q300.0575 110.82157 300.36218 110.610634Q300.66687 110.3997 301.04187 110.3997Q301.57312 110.3997 302.12 110.72782L301.76062 111.7122Q301.37 111.47782 300.995 111.47782Q300.63562 111.47782 300.36218 111.68876Q300.08875 111.8997 299.97937 112.2747Q299.79187 112.8372 299.79187 113.49345L299.79187 116.75907L298.745 116.75907ZM306.82312 114.47782L307.85437 114.61845Q307.6825 115.68095 306.97937 116.29032Q306.27625 116.8997 305.26062 116.8997Q303.97937 116.8997 303.20593 116.06376Q302.4325 115.22782 302.4325 113.66532Q302.4325 112.66532 302.76843 111.90751Q303.10437 111.1497 303.78406 110.7747Q304.46375 110.3997 305.27625 110.3997Q306.27625 110.3997 306.92468 110.90751Q307.57312 111.41532 307.76062 112.36845L306.72937 112.5247Q306.58875 111.8997 306.21375 111.579384Q305.83875 111.25907 305.3075 111.25907Q304.51062 111.25907 304.01062 111.829384Q303.51062 112.3997 303.51062 113.63407Q303.51062 114.8997 303.995 115.4622Q304.47937 116.0247 305.245 116.0247Q305.87 116.0247 306.28406 115.6497Q306.69812 115.2747 306.82312 114.47782ZM308.72937 116.75907L308.72937 108.16532L309.79187 108.16532L309.79187 116.75907L308.72937 116.75907ZM315.66687 114.75907L316.76062 114.88407Q316.51062 115.8372 315.8075 116.36845Q315.10437 116.8997 314.02625 116.8997Q312.66687 116.8997 311.86218 116.05595Q311.0575 115.2122 311.0575 113.69657Q311.0575 112.13407 311.87 111.266884Q312.6825 110.3997 313.96375 110.3997Q315.21375 110.3997 316.0028 111.24345Q316.79187 112.0872 316.79187 113.63407Q316.79187 113.72782 316.79187 113.91532L312.15125 113.91532Q312.21375 114.94657 312.72937 115.485634Q313.245 116.0247 314.02625 116.0247Q314.60437 116.0247 315.01843 115.72001Q315.4325 115.41532 315.66687 114.75907ZM312.21375 113.05595L315.6825 113.05595Q315.62 112.25907 315.29187 111.86845Q314.77625 111.25907 313.97937 111.25907Q313.245 111.25907 312.7528 111.74345Q312.26062 112.22782 312.21375 113.05595Z" fill-rule="nonzero" fill="#000000"></path></svg>
+
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/parser-blocking-script.js b/testing/web-platform/tests/document-policy/experimental-features/resources/parser-blocking-script.js
new file mode 100644
index 0000000000..c61efee8a0
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/parser-blocking-script.js
@@ -0,0 +1 @@
+window.didExecuteExternalParsingBlockingScript = true;
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/sync-script-test.js b/testing/web-platform/tests/document-policy/experimental-features/resources/sync-script-test.js
new file mode 100644
index 0000000000..65c1b21e6e
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/sync-script-test.js
@@ -0,0 +1,9 @@
+var t = async_test('Test behavior of sync-script feature policy for different script types');
+
+window.onload = t.step_func(function() {
+ assert_equals(undefined, window.didExecuteInlineParsingBlockingScript, 'inline parser blocking script should be blocked');
+ assert_equals(undefined, window.didExecuteExternalParsingBlockingScript, 'external parser blocking script should be blocked');
+ assert_true(window.didExecuteExternalAsyncScript, 'external async script should not be blocked');
+ assert_true(window.didExecuteExternalDeferredScript, 'external defer script should not be blocked');
+ t.done();
+});
diff --git a/testing/web-platform/tests/document-policy/experimental-features/resources/video.ogv b/testing/web-platform/tests/document-policy/experimental-features/resources/video.ogv
new file mode 100644
index 0000000000..c9ee910fc6
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/resources/video.ogv
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html b/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html
new file mode 100644
index 0000000000..a199a4ed3f
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<body>
+<script defer src="/resources/testharness.js"></script>
+<script defer src="/resources/testharnessreport.js"></script>
+<script>
+// The test harness scripts above are loaded as <script defer> because
+// they would be blocked if loaded synchronously.
+// Harness scripts should be evaluated before sync-script-test.js, so it
+// is also loaded as <script defer>
+//
+// The other scripts (both inline and external) are testing whether those
+// scripts are blocked or not.
+// sync-script-test.js asserts the results of the other scripts in onload
+// in order to guarantee that all scripts have either loaded or been blocked
+// before verifying the behavior.
+window.didExecuteInlineParsingBlockingScript = true;
+</script>
+<script src="/document-policy/experimental-features/resources/parser-blocking-script.js"></script>
+<script async src="/document-policy/experimental-features/resources/async-script.js"></script>
+<script defer src="/document-policy/experimental-features/resources/defer-script.js"></script>
+<script defer src="/document-policy/experimental-features/resources/sync-script-test.js"></script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html.headers b/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html.headers
new file mode 100644
index 0000000000..cfe200c27b
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/sync-script.tentative.https.sub.html.headers
@@ -0,0 +1 @@
+Document-Policy: sync-script=?0
diff --git a/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html b/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html
new file mode 100644
index 0000000000..d7bb725249
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe></iframe>
+<script>
+'use strict';
+const default_width = 300;
+const default_height = 150;
+const srcs = [
+ "/document-policy/experimental-features/resources/image.jpg",
+ "/document-policy/experimental-features/resources/image.png",
+ "/document-policy/experimental-features/resources/image.svg"
+];
+const test_cases = [
+// Test when no size is specified, img/video is laid out by the default size.
+{expected_width: default_width, expected_height: default_height},
+// Test when only one dimension is specified, img/video uses the default length for
+// the other dimension.
+{attribute: "width", value: 500, expected_width: 500, expected_height: 500 / 2},
+{attribute: "height", value: 800, expected_width: 800 * 2, expected_height: 800},
+// Test when only one dimension is specified by CSS style, img/video uses the
+// default length for the other dimension.
+{attribute: "style", value: "width:500px;", expected_width: 500, expected_height: 500 / 2},
+{attribute: "style", value: "height:800px;", expected_width: 800 * 2, expected_height: 800},
+// Test when the size of the image is specified, img/video is laid out by the
+// specified size.
+{attribute: "width", value: 500, attribute1: "height", value1: 800, expected_width: 500, expected_height:800},
+{attribute: "style", value: "width:500px;height:800px;", expected_width: 500, expected_height:800}
+];
+
+for (var test of test_cases) {
+ for (var src of srcs) {
+ async_test(t=> {
+ var img = document.createElement('IMG');
+ var expected_width = test.expected_width;
+ var expected_height = test.expected_height;
+ img.setAttribute("src", src);
+ if (typeof test.attribute !== "undefined") {
+ img.setAttribute(test.attribute, test.value);
+ }
+ if (typeof test.attribute1 !== "undefined") {
+ img.setAttribute(test.attribute1, test.value1);
+ }
+ img.addEventListener('load', t.step_func(function() {
+ assert_equals(img.width, expected_width, 'width:');
+ assert_equals(img.height, expected_height, 'height:');
+ t.done();
+ }));
+ document.body.appendChild(img);
+ }, 'Test image with attribute ' + test.attribute + '=' + test.value +
+ ' and attribute ' + test.attribute1 + '=' + test.value1 + ' on src ' + src);
+ }
+ async_test(t=> {
+ var video = document.createElement('video');
+ video.addEventListener('canplaythrough', t.step_func(function() {
+ assert_equals(video.getBoundingClientRect().width, expected_width, 'width:');
+ assert_equals(video.getBoundingClientRect().height, expected_height, 'height:');
+ t.done();
+ }));
+ var expected_width = test.expected_width;
+ var expected_height = test.expected_height;
+ video.setAttribute("src", "/document-policy/experimental-features/resources/video.ogv");
+ if (typeof test.attribute !== "undefined") {
+ video.setAttribute(test.attribute, test.value);
+ }
+ if (typeof test.attribute1 !== "undefined") {
+ video.setAttribute(test.attribute1, test.value1);
+ }
+ document.body.appendChild(video);
+ }, 'Test video with attribute ' + test.attribute + '=' + test.value +
+ ' and attribute ' + test.attribute1 + '=' + test.value1);
+}
+
+// Subframes do not inherit document policy from parent frame.
+// Unsized-Media should not work in subframes.
+var iframe = document.querySelector('iframe');
+var iframe_srcs = [
+ "/document-policy/experimental-features/resources/document-policy-image.html",
+ "https://{{domains[www]}}:{{ports[https][0]}}/document-policy/experimental-features/resources/document-policy-image.html"];
+for (var src of iframe_srcs) {
+ promise_test(function() {
+ iframe.src = src;
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function(e) {
+ resolve(e.data);
+ });
+ }).then(function(data) {
+ assert_not_equals(data.width, default_width, 'width');
+ assert_not_equals(data.height, default_height, 'height');
+ });
+ }, 'Test image size is correctly rendered in iframe of src ' + src);
+}
+</script>
+</body>
diff --git a/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html.headers b/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html.headers
new file mode 100644
index 0000000000..cf59933e8d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/experimental-features/unsized-media.tentative.https.sub.html.headers
@@ -0,0 +1 @@
+Document-Policy: unsized-media=?0
diff --git a/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative-ref.html b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative-ref.html
new file mode 100644
index 0000000000..78bca05b12
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Test for no-font-display-late-swap document policy behavior</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+.ahem {
+ font-family: 'Ahem';
+}
+.arial {
+ font-family: 'Arial';
+}
+</style>
+<p>Tests if font-display is set to optional for each option except for when it is set to fallback</p>
+<table id="container">
+ <tr>
+ <th>not-set</th>
+ <th>auto</th>
+ <th>block</th>
+ <th>swap</th>
+ <th>fallback</th>
+ <th>optional</th>
+ </tr>
+ <tr>
+ <td class="arial">a</td>
+ <td class="arial">a</td>
+ <td class="arial">a</td>
+ <td class="arial">a</td>
+ <td class="ahem">a</td>
+ <td class="arial">a</td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html
new file mode 100644
index 0000000000..26927bb8c6
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>Test for no-font-display-late-swap document policy behavior</title>
+<link rel="help" href="https://github.com/w3c/webappsec-feature-policy/blob/master/policies/font-display-late-swap.md">
+<link rel="match" href="override-to-optional.tentative-ref.html">
+<style>
+</style>
+<p>Tests if font-display is set to optional for each option except for when it is set to fallback</p>
+<table id="container">
+ <tr>
+ <th>not-set</th>
+ <th>auto</th>
+ <th>block</th>
+ <th>swap</th>
+ <th>fallback</th>
+ <th>optional</th>
+ </tr>
+</table>
+<script>
+const fontDisplayValues = ['', 'auto', 'block', 'swap', 'fallback', 'optional'];
+const table = document.getElementById('container');
+
+function makeFontFaceDeclaration(family, display) {
+ url = '/fonts/Ahem.ttf?pipe=trickle(d1)'; // Before the swap period is over
+ return '@font-face { font-family: ' + family + '; src: url("' + url + '"); font-display: ' + display + '; }';
+}
+
+window.onload = () => {
+ let tr = document.createElement('tr');
+ for (let display of fontDisplayValues) {
+ const family = display + '-face';
+ const rule = makeFontFaceDeclaration(family, display);
+ document.styleSheets[0].insertRule(rule, 0);
+ let td = document.createElement('td');
+ td.textContent = 'a';
+ td.style.fontFamily = family + ', Arial';
+ tr.appendChild(td);
+ }
+ table.appendChild(tr);
+ const timeoutMilliSec = 1500; // After the font is loaded
+ setTimeout(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ }, timeoutMilliSec);
+}
+</script>
+</html>
diff --git a/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html.headers
new file mode 100644
index 0000000000..01b8bbccd4
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/override-to-optional.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html
new file mode 100644
index 0000000000..9eea350de4
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'auto'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyReportOnlyGenerated('auto');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-auto.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html
new file mode 100644
index 0000000000..628dbccb4d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value empty</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyReportOnlyGenerated('');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-blank.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html
new file mode 100644
index 0000000000..a383695317
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'block'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyReportOnlyGenerated('block');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-block.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html
new file mode 100644
index 0000000000..a03015e47d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'fallback'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testCompliantWithFontDisplayPolicy('fallback');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-fallback.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html
new file mode 100644
index 0000000000..2a4673f153
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'optional'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testCompliantWithFontDisplayPolicy('optional');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-optional.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html b/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html
new file mode 100644
index 0000000000..ad1f437f8c
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'swap'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyReportOnlyGenerated('swap');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html.headers
new file mode 100644
index 0000000000..1509127277
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/report-only-swap.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html
new file mode 100644
index 0000000000..01857dd90e
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'auto'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyViolationGenerated('auto');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-auto.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html
new file mode 100644
index 0000000000..6521ae131a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value empty</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyViolationGenerated('');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-blank.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html
new file mode 100644
index 0000000000..60403c67a4
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'block'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyViolationGenerated('block');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-block.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html
new file mode 100644
index 0000000000..a03015e47d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'fallback'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testCompliantWithFontDisplayPolicy('fallback');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-fallback.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html
new file mode 100644
index 0000000000..2a4673f153
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'optional'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testCompliantWithFontDisplayPolicy('optional');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-optional.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html b/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html
new file mode 100644
index 0000000000..53d823f178
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Test for font-display-late-swap document policy with font display value 'swap'</title>
+<link rel="help" href="https://github.com/w3c/webappsec-permissions-policy/blob/master/policies/font-display-late-swap.md">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/font-display-reporting-helper.js'></script>
+<script>
+ testFontDisplayPolicyViolationGenerated('swap');
+</script>
diff --git a/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html.headers b/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html.headers
new file mode 100644
index 0000000000..273ca3564d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/reporting-swap.tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: font-display-late-swap=?0 \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/font-display/resources/font-display-reporting-helper.js b/testing/web-platform/tests/document-policy/font-display/resources/font-display-reporting-helper.js
new file mode 100644
index 0000000000..f3c8a22b7a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/font-display/resources/font-display-reporting-helper.js
@@ -0,0 +1,81 @@
+function check_report_format(report, expected_url, expected_disposition) {
+ assert_equals(report.type, 'document-policy-violation');
+ assert_equals(report.url, expected_url);
+ assert_equals(report.body.featureId, 'font-display-late-swap');
+ assert_equals(report.body.disposition, expected_disposition);
+ assert_true('sourceFile' in report.body);
+ assert_true('lineNumber' in report.body);
+ assert_true('columnNumber' in report.body);
+}
+
+function check_violation_report_format(report, expected_url) {
+ check_report_format(report, expected_url, 'enforce');
+}
+
+function check_report_only_report_format(report, expected_url) {
+ check_report_format(report, expected_url, 'report');
+}
+
+function makeFontFaceDeclaration(family, display) {
+ url = '/fonts/Ahem.ttf?pipe=trickle(d1)'; // Before the swap period is over
+ return `@font-face { font-family: ${family}; src: url("${url}"); font-display: ${display}; }`;
+}
+
+/**
+ * Run font-display test with given parameters.
+ *
+ * A violation report is expected with fontDisplayValue set to
+ * ['', 'auto', 'block', 'swap']
+ *
+ * No violation report is expected with fontDisplayValue set to
+ * ['fallback', 'optional']
+
+ * @param {String} fontDisplayValue
+ * @param {(Report, String) => () | undefined} format_check pass a callback to
+ * check report format if a violation report is expected. If no report is
+ * expected to be generated, leave this argument undefined.
+ */
+function runTest(fontDisplayValue, format_check) {
+ window.onload = () => {
+ const family = fontDisplayValue + '-face';
+ const rule = makeFontFaceDeclaration(family, fontDisplayValue);
+
+ const style = document.createElement('style');
+ style.innerHTML = rule;
+ document.body.appendChild(style);
+
+ const div = document.createElement('div');
+ div.textContent = 'a';
+ div.style.fontFamily = family + ', Arial';
+ document.body.appendChild(div);
+ };
+
+ const t = async_test('font-display-late-swap Report Format');
+
+ new ReportingObserver(
+ t.step_func_done((reports, _) => {
+ assert_equals(reports.length, 1);
+ assert_true(!!format_check);
+ format_check(reports[0], document.location.href);
+ }), {
+ types: ['document-policy-violation'],
+ buffered: true
+ }
+ ).observe();
+
+ t.step_timeout(t.step_func_done(() => {
+ assert_false(!!format_check, 'Expected violation report but did not get one.');
+ }), 400); // 400ms should be sufficient to observe the violation report.
+}
+
+function testFontDisplayPolicyViolationGenerated(fontDisplayValue) {
+ runTest(fontDisplayValue, check_violation_report_format);
+}
+
+function testFontDisplayPolicyReportOnlyGenerated(fontDisplayValue) {
+ runTest(fontDisplayValue, check_report_only_report_format);
+}
+
+function testCompliantWithFontDisplayPolicy(fontDisplayValue) {
+ runTest(fontDisplayValue);
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html b/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html
new file mode 100644
index 0000000000..bf17807f4a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <script>
+var check_report_format = ([reports, observer]) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.body.featureId, "document-write");
+ assert_equals(report.body.disposition, "report");
+};
+
+promise_test(async t => {
+ const report = new Promise(resolve => {
+ new ReportingObserver((reports, observer) => resolve([reports, observer]),
+ {types: ['document-policy-violation']}).observe();
+ });
+ document.write("This should be written into the document");
+ check_report_format(await report);
+}, "Document-write report only mode");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html.headers
new file mode 100644
index 0000000000..924dac8e87
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/document-write-report-only-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: document-write=?0
diff --git a/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html b/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html
new file mode 100644
index 0000000000..65a584ce19
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <script>
+var t = async_test("Document-write Report Format");
+
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "document-write");
+ assert_equals(report.body.sourceFile, document.location.href);
+ assert_equals(typeof report.body.lineNumber, "number");
+ assert_equals(typeof report.body.columnNumber, "number");
+ assert_equals(report.body.disposition, "enforce");
+};
+
+new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['document-policy-violation']}).observe();
+
+t.step_func(() => {
+ assert_throws_dom('NotAllowedError',
+ () => document.write("This should not succeed"),
+ "document.write should throw an exception when disabled");
+})();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html.headers
new file mode 100644
index 0000000000..6d05e969b5
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/document-write-reporting-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: document-write=?0
diff --git a/testing/web-platform/tests/document-policy/reporting/image.jpg b/testing/web-platform/tests/document-policy/reporting/image.jpg
new file mode 100644
index 0000000000..c059b96d97
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/image.jpg
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html
new file mode 100644
index 0000000000..85e1349a19
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <script>
+var image = new Image();
+image.src = "./unoptimized-image.jpg";
+
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "lossy-images-max-bpp");
+ assert_equals(report.body.disposition, "enforce");
+};
+
+async_test(t => {
+ new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['document-policy-violation'], buffered: true}).observe();
+}, "unoptimized-images Report Format");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html.headers
new file mode 100644
index 0000000000..cb28d40ec1
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-onload-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: lossy-images-max-bpp=0.5
diff --git a/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html
new file mode 100644
index 0000000000..b6876f4880
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <img src="./unoptimized-image.jpg">
+ <script>
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "lossy-images-max-bpp");
+ assert_equals(report.body.disposition, "enforce");
+ assert_equals(report.body.sourceFile, document.getElementsByTagName('img')[0].src);
+ assert_equals(report.body.lineNumber, null);
+ assert_equals(report.body.columnNumber, null);
+};
+
+async_test(t => {
+ new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['document-policy-violation'], buffered: true}).observe();
+}, "unoptimized-images Report Format");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html.headers
new file mode 100644
index 0000000000..cb28d40ec1
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/lossy-images-max-bpp-reporting-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: lossy-images-max-bpp=0.5
diff --git a/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html b/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html
new file mode 100644
index 0000000000..bef7db27a7
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='../resources/document-policy-report-json.js'></script>
+ </head>
+ <body>
+ <img src="./oversized.jpg" alt="oversized image" width="50" height="50">
+ <script>
+ async_test(t => {
+ new ReportingObserver(
+ t.step_func_done((reports, _) => {
+ assert_greater_than(reports.length, 0);
+ const report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ const rbody = report.body;
+ assert_equals(rbody.featureId, "oversized-images");
+ assert_equals(rbody.sourceFile, document.getElementsByTagName('img')[0].src);
+ assert_equals(rbody.lineNumber, null);
+ assert_equals(rbody.columnNumber, null);
+ check_report_json(reports[0]);
+ }),
+ {types: ['document-policy-violation'], buffered: true}
+ ).observe();
+ },
+ "oversized-images Report Format")
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html.headers
new file mode 100644
index 0000000000..10f5be1c33
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/oversized-images-reporting-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: oversized-images=2.0
diff --git a/testing/web-platform/tests/document-policy/reporting/oversized.jpg b/testing/web-platform/tests/document-policy/reporting/oversized.jpg
new file mode 100644
index 0000000000..497ed770bf
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/oversized.jpg
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/reporting/resources/sync-script.js b/testing/web-platform/tests/document-policy/reporting/resources/sync-script.js
new file mode 100644
index 0000000000..10d582cb0e
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/resources/sync-script.js
@@ -0,0 +1,20 @@
+// This is deliberately split from sync-script-reporting.html so that it will
+// not be blocked by policy, and can actuall be executed.
+
+var t = async_test("Sync-script Report Format");
+
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "sync-script");
+ assert_equals(report.body.sourceFile, null);
+ assert_equals(report.body.lineNumber, null);
+ assert_equals(report.body.columnNumber, null);
+ assert_equals(report.body.disposition, "enforce");
+ check_report_json(report);
+};
+
+new ReportingObserver(t.step_func_done(check_report_format),
+ { types: ['document-policy-violation'],
+ buffered: true}).observe();
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html b/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html
new file mode 100644
index 0000000000..45e1b8fc3c
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script defer src='/resources/testharness.js'></script>
+ <script defer src='/resources/testharnessreport.js'></script>
+ <script defer src='../resources/document-policy-report-json.js'></script>
+ <script defer src="resources/sync-script.js"></script>
+ </head>
+ <body>
+ <!-- The presence of this script will violate the sync-script policy,
+ and will trigger a report. -->
+ <script>var newGlobal = true;</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html.headers b/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html.headers
new file mode 100644
index 0000000000..cfe200c27b
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-script-reporting.html.headers
@@ -0,0 +1 @@
+Document-Policy: sync-script=?0
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html b/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html
new file mode 100644
index 0000000000..a68cf713ee
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <script>
+const check_report_format = ([reports, observer]) => {
+ const report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.body.featureId, "sync-xhr");
+ assert_equals(report.body.disposition, "report");
+};
+
+promise_test(async t => {
+ const report = new Promise(resolve => {
+ new ReportingObserver((reports, observer) => resolve([reports, observer]),
+ {types: ['document-policy-violation']}).observe();
+ });
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", document.location.href, false);
+ xhr.send();
+ check_report_format(await report);
+}, "Sync-xhr report only mode");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html.headers b/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html.headers
new file mode 100644
index 0000000000..8de201c750
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-xhr-report-only.html.headers
@@ -0,0 +1 @@
+Document-Policy-Report-Only: sync-xhr=?0
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html b/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html
new file mode 100644
index 0000000000..3bcb63459d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='../resources/document-policy-report-json.js'></script>
+ </head>
+ <body>
+ <script>
+var t = async_test("Sync-xhr Report Format");
+
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "sync-xhr");
+ assert_equals(report.body.sourceFile, document.location.href);
+ assert_equals(typeof report.body.lineNumber, "number");
+ assert_equals(typeof report.body.columnNumber, "number");
+ assert_equals(report.body.disposition, "enforce");
+ check_report_json(report);
+};
+
+new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['document-policy-violation']}).observe();
+
+t.step_func(() => {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", document.location.href, false);
+ assert_throws_dom('NetworkError',
+ () => xhr.send(),
+ "Synchronous XHR.send should throw an exception when disabled");
+})();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html.headers b/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html.headers
new file mode 100644
index 0000000000..ab319fc4ce
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/sync-xhr-reporting.html.headers
@@ -0,0 +1 @@
+Document-Policy: sync-xhr=?0
diff --git a/testing/web-platform/tests/document-policy/reporting/unoptimized-image.jpg b/testing/web-platform/tests/document-policy/reporting/unoptimized-image.jpg
new file mode 100644
index 0000000000..599137a55d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/unoptimized-image.jpg
Binary files differ
diff --git a/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html b/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html
new file mode 100644
index 0000000000..47a3643646
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <img src="image.jpg">
+ <script>
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "document-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "unsized-media");
+ assert_equals(report.body.disposition, "enforce");
+};
+
+async_test(t => {
+ new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['document-policy-violation'], buffered: true}).observe();
+}, "Unsized-media Report Format");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html.headers b/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html.headers
new file mode 100644
index 0000000000..cf59933e8d
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/reporting/unsized-media-reporting-tentative.html.headers
@@ -0,0 +1 @@
+Document-Policy: unsized-media=?0
diff --git a/testing/web-platform/tests/document-policy/required-policy/document-policy.html b/testing/web-platform/tests/document-policy/required-policy/document-policy.html
new file mode 100644
index 0000000000..aaa8d69200
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/document-policy.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test advertised required document policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script> </head>
+ <body>
+ <h1>Test advertised required document policy</h1>
+<script>
+// The top-level document has a document policy, but not a required document
+// policy. A request for a document in a frame should not include a
+// `Sec-Required-Document-Policy` header, unless that frame requires it
+// explicitly through the `policy` attribute.
+
+callbacks = {};
+
+window.addEventListener('message', ev => {
+ var id = ev.data.id;
+ if (id && callbacks[id]) {
+ callbacks[id](ev.data.requiredPolicy || null);
+ }
+});
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=1";
+ callbacks["1"] = t.step_func_done(result => {
+ assert_equals(result, null);
+ });
+ document.body.appendChild(iframe);
+}, "Top-level document's policy should not affect child frame requests");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=2";
+ iframe.policy = "font-display-late-swap=?0";
+ callbacks["2"] = t.step_func_done(result => {
+ assert_equals(result, "font-display-late-swap=?0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame can have a required policy independent of the parent document.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=3";
+ iframe.policy = "lossless-images-max-bpp=4";
+ callbacks["3"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=4.0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame can have a required policy which is less strict than the parent document's policy.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/required-policy/document-policy.html.headers b/testing/web-platform/tests/document-policy/required-policy/document-policy.html.headers
new file mode 100644
index 0000000000..20629ac15f
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/document-policy.html.headers
@@ -0,0 +1 @@
+Document-Policy: lossless-images-max-bpp=1.1
diff --git a/testing/web-platform/tests/document-policy/required-policy/no-document-policy.html b/testing/web-platform/tests/document-policy/required-policy/no-document-policy.html
new file mode 100644
index 0000000000..8a3624440f
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/no-document-policy.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test advertised required document policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script> </head>
+ <body>
+ <h1>Test advertised required document policy</h1>
+<script>
+// The top-level document does not have any document-policy-related headers.
+// A request for a document in a frame should not include a
+// `Sec-Required-Document-Policy` header, unless that frame requires it
+// explicitly through the `policy` attribute.
+
+callbacks = {};
+
+window.addEventListener('message', ev => {
+ var id = ev.data.id;
+ if (id && callbacks[id]) {
+ callbacks[id](ev.data.requiredPolicy || null);
+ }
+});
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=1";
+ callbacks["1"] = t.step_func_done(result => {
+ assert_equals(result, null);
+ });
+ document.body.appendChild(iframe);
+}, "Child frame should have no required policy by default.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=2";
+ iframe.policy = "font-display-late-swap=?0";
+ callbacks["2"] = t.step_func_done(result => {
+ assert_equals(result, "font-display-late-swap=?0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame can have an explicit required policy.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/required-policy/required-document-policy-nested.html b/testing/web-platform/tests/document-policy/required-policy/required-document-policy-nested.html
new file mode 100644
index 0000000000..33de2533a2
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/required-document-policy-nested.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test advertised required document policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script> </head>
+ <body>
+ <h1>Test advertised required document policy</h1>
+<script>
+// The top-level document has no required document policy. Its child frames may,
+// though, and those policies should be set for any subframes.
+
+callbacks = {};
+
+window.addEventListener('message', ev => {
+ var id = ev.data.id;
+ if (id && callbacks[id]) {
+ callbacks[id](ev.data.requiredPolicy || null);
+ }
+});
+
+// Frame tree should be:
+// Top:
+// <iframe>
+// <iframe>
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy-nested.html?id=1";
+ callbacks["1"] = t.step_func_done(result => {
+ assert_equals(result, null);
+ });
+ document.body.appendChild(iframe);
+}, "test nested required document policy");
+
+// Frame tree should be:
+// Top:
+// <iframe policy="lossless-images-max-bpp=1.1">
+// <iframe>
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy-nested.html?id=2";
+ iframe.policy = "lossless-images-max-bpp=1.1";
+ callbacks["2"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.1");
+ });
+ document.body.appendChild(iframe);
+}, "test nested required document policy when set by nested frame");
+
+// Frame tree should be:
+// Top:
+// <iframe policy="lossless-images-max-bpp=1.1">
+// <iframe>
+// <iframe>
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy-nested.html?id=3&level=1";
+ iframe.policy = "lossless-images-max-bpp=1.1";
+ callbacks["3"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.1");
+ });
+ document.body.appendChild(iframe);
+}, "test nested required document policy when set by intermediate nested frame");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html b/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html
new file mode 100644
index 0000000000..1058e3582a
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test advertised required document policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script> </head>
+ <body>
+ <h1>Test advertised required document policy</h1>
+<script>
+// The top-level document has a required document policy. Any requests for
+// documents in child frames must be sent with a required policy header
+// indicating a required policy at least as strict. (In this case, "at least as
+// strict" means that the 'bpp' parameter must be less than or equal to the
+// parent document's required value.)
+
+callbacks = {};
+
+window.addEventListener('message', ev => {
+ var id = ev.data.id;
+ if (id && callbacks[id]) {
+ callbacks[id](ev.data.requiredPolicy || null);
+ }
+});
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=1";
+ callbacks["1"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.1");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame with no explicit policy should have the same required policy as its parent.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=2";
+ iframe.policy = "lossless-images-max-bpp=4";
+ callbacks["2"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.1");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame with a less strict required policy should have the stricter value from the parent's policy applied.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=3";
+ iframe.policy = "lossless-images-max-bpp=1.0";
+ callbacks["3"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame may have a stricter policy than the parent.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=4";
+ iframe.policy = "font-display-late-swap=?0";
+ callbacks["4"] = t.step_func_done(result => {
+ assert_equals(result, "font-display-late-swap=?0, lossless-images-max-bpp=1.1");
+ });
+ document.body.appendChild(iframe);
+}, "Any unrelated policy directives should combine with the parent's required policy.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html.headers b/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html.headers
new file mode 100644
index 0000000000..ac1bf268b5
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/required-document-policy.html.headers
@@ -0,0 +1 @@
+Require-Document-Policy: lossless-images-max-bpp=1.1
diff --git a/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html b/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html
new file mode 100644
index 0000000000..1ed94a81e7
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test advertised required document policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script> </head>
+ <body>
+ <h1>Test advertised required document policy</h1>
+<script>
+// The top-level document has a document policy, as well as a required document
+// policy (for subframes) which is stricter. This test should load (the required
+// policy should not block this page,) but the requirements should be applied to
+// nested content.
+
+callbacks = {};
+
+window.addEventListener('message', ev => {
+ var id = ev.data.id;
+ if (id && callbacks[id]) {
+ callbacks[id](ev.data.requiredPolicy || null);
+ }
+});
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=1";
+ callbacks["1"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame with no explicit policy should have the same required policy as its parent.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=2";
+ iframe.policy = "lossless-images-max-bpp=4";
+ callbacks["2"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=1.0");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame with a less strict required policy should have the stricter value from the parent's policy applied.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=3";
+ iframe.policy = "lossless-images-max-bpp=0.9";
+ callbacks["3"] = t.step_func_done(result => {
+ assert_equals(result, "lossless-images-max-bpp=0.9");
+ });
+ document.body.appendChild(iframe);
+}, "Child frame may have a stricter policy than the parent.");
+
+async_test(t => {
+ var iframe = document.createElement('iframe');
+ iframe.src = "/document-policy/echo-policy.py?id=4";
+ iframe.policy = "no-font-display-late-swap";
+ callbacks["4"] = t.step_func_done(result => {
+ assert_equals(result, "no-font-display-late-swap, lossless-images-max-bpp=1.0");
+ });
+ document.body.appendChild(iframe);
+}, "Any unrelated policy directives should combine with the parent's required policy.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html.headers b/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html.headers
new file mode 100644
index 0000000000..3c593a32aa
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/required-policy/separate-document-policies.html.headers
@@ -0,0 +1,2 @@
+Document-Policy: lossless-images-max-bpp=1.1
+Require-Document-Policy: lossless-images-max-bpp=1.0
diff --git a/testing/web-platform/tests/document-policy/resources/document-policy-report-json.js b/testing/web-platform/tests/document-policy/resources/document-policy-report-json.js
new file mode 100644
index 0000000000..035857ba39
--- /dev/null
+++ b/testing/web-platform/tests/document-policy/resources/document-policy-report-json.js
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview functions for ensuring document policy report is serializable
+ */
+
+const check_report_json = (report) => {
+ // Ensures toJSON method exists on report.
+ assert_equals(typeof report.toJSON, "function");
+ const report_json = report.toJSON();
+ // Ensures toJSON() call is successful.
+ assert_equals(report.type, report_json.type);
+ assert_equals(report.url, report_json.url);
+ assert_equals(report.body.featureId, report_json.body.featureId);
+ assert_equals(report.body.disposition, report_json.body.disposition);
+ assert_equals(report.body.sourceFile, report_json.body.sourceFile);
+ assert_equals(report.body.lineNumber, report_json.body.lineNumber);
+ assert_equals(report.body.columnNumber, report_json.body.columnNumber);
+ // Ensures JSON.stringify() serializes the report correctly.
+ assert_false(JSON.stringify(report) === "{}");
+ assert_equals(JSON.stringify(report), JSON.stringify(report_json));
+} \ No newline at end of file