summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-fonts/parsing
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/css/css-fonts/parsing
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-fonts/parsing')
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-computed.html251
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-face-src-format.html68
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-face-src-list.html43
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-face-src-local.html41
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-face-src-tech.html92
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-family-computed.html29
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-family-invalid.html24
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-family-valid.html29
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-computed.html28
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-invalid.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-valid.html28
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-invalid.html35
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-kerning-computed.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-kerning-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-kerning-valid.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-language-override-computed.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-language-override-invalid.html22
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-language-override-valid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-computed.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-invalid.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-valid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-palette-computed.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-palette-invalid.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-palette-valid.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-invalid.html288
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-valid.html390
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-shorthand-variant.html30
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-computed.html24
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-invalid.html22
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-valid.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-computed.html73
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-invalid.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-size-valid.html35
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-stretch-computed.html28
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-stretch-invalid.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-stretch-valid.html27
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html26
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-style-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-computed.html25
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-invalid.html22
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-valid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-valid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-valid.html26
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-valid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-valid.html205
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-invalid.html57
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-valid.html34
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-computed.html24
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-valid.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-computed.html35
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-invalid.html29
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-valid.html34
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-computed.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-invalid.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-valid.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-invalid.html62
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-computed.html35
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-invalid.html27
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-valid.html34
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-computed.html38
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-invalid.html30
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-valid.html39
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-computed.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-valid.html19
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-serialization.html59
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variant-valid.html106
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-computed.html29
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-invalid.html38
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-valid.html26
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-weight-computed.html61
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-weight-invalid.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/parsing/font-weight-valid.html29
78 files changed, 3362 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html
new file mode 100644
index 0000000000..ab2694d211
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().font</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop">
+<meta name="assert" content="font computed value round-trips.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<style>
+ #container {
+ font-weight: 800;
+ font-size: 40px;
+ }
+</style>
+</head>
+<body>
+<div id="container">
+ <div id="target"></div>
+</div>
+<script>
+'use strict';
+
+// Firefox and Edge 18 serialize these as supplied.
+// Blink and Safari have implementation-dependent or platform-dependent serializations.
+function test_system_font(keyword) {
+ test(() => {
+ const target = document.getElementById('target');
+ const previousValue = 'italic xx-large/0px fantasy';
+ target.style.font = previousValue;
+ target.style.font = keyword;
+ const readValue = getComputedStyle(target).font;
+ assert_not_equals(readValue, '', 'font should be set');
+ assert_not_equals(readValue, previousValue, 'font should be updated');
+ target.style.font = previousValue;
+ target.style.font = readValue;
+ assert_equals(getComputedStyle(target).font, readValue, "serialization should round-trip");
+ }, keyword + ' should be a supported system font.');
+}
+
+test_system_font('caption');
+test_system_font('icon');
+test_system_font('menu');
+test_system_font('message-box');
+test_system_font('small-caption');
+test_system_font('status-bar');
+
+// a value other than normal
+const generate_style = () => 'italic';
+
+// value other than normal
+const generate_variant = () => 'small-caps';
+
+// values other than normal
+const generate_weight = (() => {
+ const alternatives = [
+ 'bold',
+ 'bolder',
+ 'lighter',
+ '100',
+ '900'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const compute_weight = (() => {
+ const cache = {}
+ return (weight) => {
+ if (!(weight in cache)) {
+ const weight_reference = document.createElement('div');
+ document.getElementById('container').appendChild(weight_reference);
+ weight_reference.style.fontWeight = weight;
+ cache[weight] = getComputedStyle(weight_reference).fontWeight;
+ weight_reference.remove();
+ }
+ return cache[weight];
+ }
+})();
+
+// values other than normal
+const generate_stretch = (() => {
+ const alternatives = [
+ 'ultra-condensed',
+ 'extra-condensed',
+ 'condensed',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'expanded',
+ 'extra-expanded',
+ 'ultra-expanded'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_size = (() => {
+ const alternatives = [
+ // <absolute-size>
+ 'xx-small',
+ 'medium',
+ 'xx-large',
+
+ // <relative-size>
+ 'larger',
+ 'smaller',
+
+ // <length-percentage>
+ '10px',
+ '20%',
+ 'calc(30% - 40px)',
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_line_height = (() => {
+ const alternatives = [
+ null,
+ 'normal',
+ '1.2',
+ 'calc(120% + 1.2em)'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_family = (() => {
+ const alternatives = [
+ 'serif',
+ 'sans-serif',
+ 'cursive',
+ 'fantasy',
+ 'monospace',
+ 'Menu',
+ '"Non-Generic Example Family Name"'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+function test_specific(prefix) {
+ const reference = document.createElement('div');
+ document.getElementById('container').appendChild(reference);
+
+ let parts = [];
+ let canonical = [];
+ let style = null;
+ let variant = null;
+ let weight = null;
+ let stretch = null;
+ for (let entry of prefix) {
+ if (entry === 'style') {
+ style = generate_style();
+ parts.push(style);
+ } else if (entry === 'variant') {
+ variant = generate_variant();
+ parts.push(variant);
+ } else if (entry === 'weight') {
+ weight = generate_weight();
+ parts.push(weight);
+ } else if (entry === 'stretch') {
+ stretch = generate_stretch();
+ parts.push(stretch);
+ } else {
+ // normal
+ parts.push('normal');
+ }
+ }
+
+ if (style) {
+ canonical.push(style);
+ reference.style.fontStyle = style;
+ }
+
+ if (variant) {
+ canonical.push(variant);
+ reference.style.fontVariant = style;
+ }
+ if (weight) {
+ canonical.push(compute_weight(weight));
+ reference.style.fontWeight = style;
+ }
+ if (stretch) {
+ canonical.push(stretch);
+ reference.style.fontStretch = style;
+ }
+
+ const size = generate_size();
+ reference.style.fontSize = size;
+ const line_height = generate_line_height();
+ if (line_height) {
+ parts.push(size + '/' + line_height);
+ reference.style.lineHeight = line_height;
+ } else {
+ parts.push(size);
+ }
+
+ const family = generate_family();
+ parts.push(family);
+ reference.style.fontFamily = family;
+
+ if (!line_height || line_height === 'normal') {
+ canonical.push(getComputedStyle(reference).fontSize);
+ } else {
+ // Implementations differ on adjacent space when serializing '/'
+ // https://github.com/w3c/csswg-drafts/issues/4282
+ canonical.push(getComputedStyle(reference).fontSize + ' / ' + getComputedStyle(reference).lineHeight);
+ }
+
+ canonical.push(family);
+
+ reference.remove();
+
+ test_computed_value('font', parts.join(' '), canonical.join(' '));
+}
+
+// Font style, variant, weight and stretch may appear in any order.
+// Any or all may be omitted. Each accepts the keyword 'normal'.
+// We generate every permutation of these four properties, treating
+// the cases of a property value being omitted or being explicitly
+// 'normal' as being distinct permutations from when the property
+// has a value other than 'normal'.
+function test_various(prefix) {
+ test_specific(prefix);
+ if (prefix.length === 4) {
+ // Font style, variant, weight and stretch may not appear
+ // more than once.
+ return;
+ }
+
+ const alternatives = [
+ 'normal',
+ 'style',
+ 'variant',
+ 'weight',
+ 'stretch'
+ ];
+ for (let alternative of alternatives) {
+ // Since this is called recursively, check prefix for existing
+ // alternatives, otherwise we may have two styles or two variants, etc.
+ if (alternative === 'normal' || !prefix.includes(alternative))
+ test_various(prefix.concat(alternative));
+ }
+}
+
+test_various([]);
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-format.html b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-format.html
new file mode 100644
index 0000000000..36abbb44dc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-format.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<title>CSS Fonts 4 test: parsing the format() function in the src descriptor</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-src-parsing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="testStyle">
+</style>
+<script>
+ const sheet = testStyle.sheet;
+ tests = [
+ // No format() function
+ { src: 'url("foo.ttf")', valid: true },
+ { src: 'url("foo.ttf"), url("bar.ttf")', valid: true },
+ // Empty format() is not valid
+ { src: 'url("foo.ttf") format()', valid: false },
+ // Quoted strings in format()
+ { src: 'url("foo.ttf") format("collection")', valid: true },
+ { src: 'url("foo.ttf") format("opentype")', valid: true },
+ { src: 'url("foo.ttf") format("truetype")', valid: true },
+ { src: 'url("foo.ttf") format("woff")', valid: true },
+ { src: 'url("foo.ttf") format("woff2")', valid: true },
+ // Multiple strings (was valid in CSS Fonts 3, but not allowed in Fonts 4)
+ { src: 'url("foo.ttf") format("opentype", "truetype")', valid: false },
+ // Keywords (new in Fonts 4)
+ { src: 'url("foo.ttf") format(collection)', valid: true },
+ { src: 'url("foo.ttf") format(opentype)', valid: true },
+ { src: 'url("foo.ttf") format(truetype)', valid: true },
+ { src: 'url("foo.ttf") format(woff)', valid: true },
+ { src: 'url("foo.ttf") format(woff2)', valid: true },
+ // Multiple keywords are not accepted
+ { src: 'url("foo.ttf") format(opentype, truetype)', valid: false },
+ { src: 'url("foo.ttf") format(opentype truetype)', valid: false },
+ // Invalid format keywords should be a parse error
+ { src: 'url("foo.ttf") format(auto)', valid: false },
+ { src: 'url("foo.ttf") format(default)', valid: false },
+ { src: 'url("foo.ttf") format(inherit)', valid: false },
+ { src: 'url("foo.ttf") format(initial)', valid: false },
+ { src: 'url("foo.ttf") format(none)', valid: false },
+ { src: 'url("foo.ttf") format(normal)', valid: false },
+ { src: 'url("foo.ttf") format(xyzzy)', valid: false },
+ // Unknown format string still matches the grammar, although it won't be
+ // loaded. UAs may choose to either not load it, or not add unsupported
+ // entries to the list, ensure that subsequent component of the list are
+ // still recognized.
+ { src: 'url("foo.ttf") format("embedded-opentype"), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format(embedded-opentype), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format("svg"), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format(svg), url("bar.html")', valid: true },
+ // A parsing error in one component does not make the entire descriptor invalid.
+ { src: 'url("foo.ttf") format(xyzz 200px), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format(xyzz), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") dummy(xyzzy), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format(), url("bar.html")', valid: true },
+ { src: 'url("foo.ttf") format(none), url("bar.html")', valid: true },
+ ];
+
+ for (let t of tests) {
+ test(() => {
+ assert_equals(sheet.cssRules.length, 0, "testSheet should initially be empty");
+ sheet.insertRule("@font-face { src: " + t.src + "}");
+ try {
+ assert_equals(sheet.cssRules[0].style.getPropertyValue("src") != "", t.valid);
+ } finally {
+ sheet.deleteRule(0);
+ }
+ }, "Check that src: " + t.src + " is " + (t.valid ? "valid" : "invalid"));
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-list.html b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-list.html
new file mode 100644
index 0000000000..c87705109f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-list.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<title>CSS Fonts 4 test: parsing the src descriptor list</title>
+<meta name="assert" content="A parse error in one component of the source list does not invalidate the entire descriptor">
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-src-parsing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="testStyle">
+</style>
+<script>
+ const sheet = testStyle.sheet;
+ tests = [
+ // A component with a parse error does not invalidate the entire descriptor
+ // if there's some other valid component present.
+ { src: 'local(inherit), url(foo.ttf)', valid: true },
+ { src: 'local("myfont"), local(unset)', valid: true },
+ { src: 'local(), url(foo.ttf)', valid: true },
+ { src: 'local(12px monospace), url(foo.ttf)', valid: true },
+ { src: 'local("myfont") format(opentype), url(foo.ttf)', valid: true },
+ { src: 'url(not a valid url/bar.ttf), url(foo.ttf)', valid: true },
+ { src: 'url(foo.ttf) format(bad), url(foo.ttf)', valid: true },
+ { src: 'url(foo.ttf) tech(unknown), url(foo.ttf)', valid: true },
+ { src: 'url(foo.ttf), url(something.ttf) format(broken)', valid: true },
+ { src: '/* an empty component */, url(foo.ttf)', valid: true },
+ { src: 'local(""), url(foo.ttf), unparseable-garbage, local("another font name")', valid: true },
+ // But if all components are bad, the descriptor is invalid.
+ { src: 'local(), local(initial)', valid: false },
+ { src: 'local("textfont") format(opentype), local("emoji") tech(color-COLRv0)', valid: false },
+ { src: 'local(), /*empty*/, url(should be quoted.ttf), junk', valid: false },
+ { src: 'url(foo.ttf) format(unknown), url(bar.ttf) tech(broken)', valid: false },
+ ];
+
+ for (let t of tests) {
+ test(() => {
+ assert_equals(sheet.cssRules.length, 0, "testSheet should initially be empty");
+ sheet.insertRule("@font-face { src: " + t.src + "}");
+ try {
+ assert_equals(sheet.cssRules[0].style.getPropertyValue("src") != "", t.valid);
+ } finally {
+ sheet.deleteRule(0);
+ }
+ }, "Check that src: " + t.src + " is " + (t.valid ? "valid" : "invalid"));
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-local.html b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-local.html
new file mode 100644
index 0000000000..d7c8cba18c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-local.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>CSS Fonts Module Level 4: parsing @font-face src:local()</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#local-font-fallback">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="testStyle">
+</style>
+<script>
+ const sheet = testStyle.sheet;
+ tests = [
+ // Unquoted collapsing space
+ { src:'local( A )', valid:true },
+ { src:'local(A B)', valid:true },
+ { src:'local(A B)', valid:true },
+ { src:'local( A B )', valid:true },
+ // Unquoted local() with invalid CSS-wide keywords excluded from <custom-ident>
+ { src:'local(default)', valid:false },
+ { src:'local(inherit)', valid:false },
+ { src:'local(revert)', valid:false },
+ { src:'local(unset)', valid:false },
+ // Unquoted local() with CSS-wide keywords as part of the name
+ { src:'local(default A)', valid:true },
+ { src:'local(inherit A)', valid:true },
+ { src:'local(revert A)', valid:true },
+ { src:'local(unset A)', valid:true },
+ // Quoted local() with CSS-wide keywords
+ { src:'local("default")', valid:true },
+ { src:'local("inherit")', valid:true },
+ { src:'local("revert")', valid:true },
+ { src:'local("unset")', valid:true }
+ ];
+
+ for (let t of tests) {
+ test(() => {
+ assert_equals(sheet.cssRules.length, 0, "testSheet should initially be empty");
+ sheet.insertRule("@font-face { src: " + t.src + "}");
+ assert_equals(sheet.cssRules[0].style.getPropertyValue("src") != "", t.valid);
+ sheet.deleteRule(0);
+ }, "Check that src: " + t.src + " is " + (t.valid ? "valid" : "invalid"));
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-tech.html b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-tech.html
new file mode 100644
index 0000000000..fb7d92f8e4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-face-src-tech.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<title>CSS Fonts 4 test: parsing the tech() function in the src descriptor</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-src-parsing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="testStyle">
+</style>
+<script>
+ const sheet = testStyle.sheet;
+ tests = [
+ // No tech() function
+ { src: 'url("foo.ttf")', valid: true },
+ // Empty tech() is not valid
+ { src: 'url("foo.ttf") tech()', valid: false },
+ // Check that each valid keyword is accepted
+ { src: 'url("foo.ttf") tech(features-opentype)', valid: true },
+ { src: 'url("foo.ttf") tech(features-aat)', valid: true },
+ { src: 'url("foo.ttf") tech(color-COLRv0)', valid: true },
+ { src: 'url("foo.ttf") tech(color-COLRv1)', valid: true },
+ { src: 'url("foo.ttf") tech(color-sbix)', valid: true },
+ { src: 'url("foo.ttf") tech(color-CBDT)', valid: true },
+ { src: 'url("foo.ttf") tech(variations)', valid: true },
+ { src: 'url("foo.ttf") tech(palettes)', valid: true },
+ // tech() does not accept strings (unlike format()!)
+ { src: 'url("foo.ttf") tech("features-opentype")', valid: false },
+ { src: 'url("foo.ttf") tech("color-COLRv0")', valid: false },
+ { src: 'url("foo.ttf") tech("variations")', valid: false },
+ // tech() accepts a comma-separated list of keywords
+ { src: 'url("foo.ttf") tech(features-opentype, color-COLRv0, variations, palettes)', valid: true },
+ { src: 'url("foo.ttf") tech(features-opentype color-COLRv0 variations palettes)', valid: false },
+ // Invalid font-tech keywords should be a parse error
+ { src: 'url("foo.ttf") tech(feature-opentype)', valid: false },
+ { src: 'url("foo.ttf") tech(feature-aat)', valid: false },
+ { src: 'url("foo.ttf") tech(feature-graphite)', valid: false },
+ { src: 'url("foo.ttf") tech(auto)', valid: false },
+ { src: 'url("foo.ttf") tech(default)', valid: false },
+ { src: 'url("foo.ttf") tech(inherit)', valid: false },
+ { src: 'url("foo.ttf") tech(initial)', valid: false },
+ { src: 'url("foo.ttf") tech(none)', valid: false },
+ { src: 'url("foo.ttf") tech(normal)', valid: false },
+ { src: 'url("foo.ttf") tech(xyzzy)', valid: false },
+ // format() function must precede tech() if both are present
+ { src: 'url("foo.ttf") format(opentype) tech(features-opentype)', valid: true },
+ { src: 'url("foo.ttf") tech(features-opentype) format(opentype)', valid: false },
+ // Unsupported technology (for example: no browser has incremental transfer yet), might be
+ // dropped from the list, next component of the list should be accepted.
+ { src: 'url("foo.ttf") tech(incremental), url("bar.html")', dontcomparetech: true, valid: true },
+ { src: 'url("foo.ttf") tech(incremental, color-SVG, features-graphite, features-aat), url("bar.html")', dontcomparetech: true, valid: true },
+ { src: 'url("foo.ttf") tech(color-SVG, features-graphite), url("bar.html")', dontcomparetech: true, valid: true },
+ { src: 'url("foo.ttf") tech(color-SVG), url("bar.html")', dontcomparetech: true, valid: true },
+ { src: 'url("foo.ttf") tech(features-graphite), url("bar.html")', dontcomparetech: true, valid: true },
+ // No invalid functions.
+ { src: 'url("foo.ttf") dummy("opentype") tech(variations)', valid: false },
+ { src: 'url("foo.ttf") dummy("opentype") dummy(variations)', valid: false },
+ { src: 'url("foo.ttf") format(opentype) tech(features-opentype) dummy(something)', valid: false },
+ // A parsing error in one component does not make the entire descriptor invalid.
+ { src: 'url("foo.ttf") format(dummy), url("foo.ttf") tech(variations)', valid: true },
+ // check_same_tech isn't currently smart enough to handle this.
+ { src: 'url("foo.ttf") tech(color), url("bar.html")', dontcomparetech: true, valid: true },
+ ];
+
+ // Assert that the two arguments have the same set of keywords in the tech() function,
+ // (although their ordering may differ).
+ function check_same_tech(serialized, specified) {
+ if (!specified.includes("tech(")) {
+ assert_false(serialized.includes("tech("), "expected no tech() function");
+ return;
+ }
+ // Extract the lists of tech() keywords and sort them for comparison.
+ const tech = /tech\((.+)\)/;
+ var specified_techs = tech.exec(specified)[1].split(/,\s*/).sort().join(", ");
+ var serialized_techs = tech.exec(serialized)[1].split(/,\s*/).sort().join(", ");
+ // Per CSSOM spec, keywords are serialized in ASCII-lowercase form:
+ // https://drafts.csswg.org/cssom/#serialize-a-css-component-value
+ assert_equals(serialized_techs, specified_techs.toLowerCase(), "expected matching tech() lists");
+ }
+
+ for (let t of tests) {
+ test(() => {
+ assert_equals(sheet.cssRules.length, 0, "testSheet should initially be empty");
+ sheet.insertRule("@font-face { src: " + t.src + "}");
+ try {
+ assert_equals(sheet.cssRules[0].style.getPropertyValue("src") != "", t.valid);
+ if (t.valid && !t.dontcomparetech) {
+ check_same_tech(sheet.cssRules[0].style.getPropertyValue("src"), t.src);
+ }
+ } finally {
+ sheet.deleteRule(0);
+ }
+ }, "Check that src: " + t.src + " is " + (t.valid ? "valid" : "invalid"));
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-family-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-family-computed.html
new file mode 100644
index 0000000000..2f5f7dd91c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-family-computed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontFamily</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-family-prop">
+<meta name="assert" content="font-family computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-family', 'serif');
+test_computed_value('font-family', 'sans-serif');
+test_computed_value('font-family', 'cursive');
+test_computed_value('font-family', 'fantasy');
+test_computed_value('font-family', 'monospace');
+test_computed_value('font-family', 'serif, sans-serif, cursive, fantasy, monospace');
+
+test_computed_value('font-family', 'Helvetica, Verdana, sans-serif');
+test_computed_value('font-family', '"New Century Schoolbook", serif');
+test_computed_value('font-family', '"21st Century", fantasy');
+
+test_computed_value('font-family', '"inherit", "serif"');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-family-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-family-invalid.html
new file mode 100644
index 0000000000..f4403e7e64
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-family-invalid.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-family with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-family-prop">
+<meta name="assert" content="font-family supports only the grammar '[ <family-name> | <generic-family> ] #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-family', 'cursive serif');
+
+test_invalid_value('font-family', 'Red/Black, sans-serif');
+test_invalid_value('font-family', '"Lucida" Grande, sans-serif');
+test_invalid_value('font-family', 'Ahem!, sans-serif');
+test_invalid_value('font-family', 'test@foo, sans-serif');
+test_invalid_value('font-family', '#POUND, sans-serif');
+test_invalid_value('font-family', 'Hawaii 5-0, sans-serif');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-family-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-family-valid.html
new file mode 100644
index 0000000000..ceaa9a0d14
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-family-valid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-family with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-family-prop">
+<meta name="assert" content="font-family supports the full grammar '[ <family-name> | <generic-family> ] #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-family', 'Serif', 'serif');
+test_valid_value('font-family', 'Sans-Serif', 'sans-serif');
+test_valid_value('font-family', 'Cursive', 'cursive');
+test_valid_value('font-family', 'Fantasy', 'fantasy');
+test_valid_value('font-family', 'Monospace', 'monospace');
+test_valid_value('font-family', 'System-UI', 'system-ui');
+test_valid_value('font-family', 'serif, sans-serif, cursive, fantasy, monospace, system-ui');
+
+test_valid_value('font-family', 'Helvetica, Verdana, sans-serif');
+test_valid_value('font-family', '"New Century Schoolbook", serif');
+test_valid_value('font-family', "'21st Century', fantasy", '"21st Century", fantasy');
+
+test_valid_value('font-family', '"inherit", "serif"');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-computed.html
new file mode 100644
index 0000000000..8fa2eda821
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-computed.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontFeatureSettings</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop">
+<meta name="assert" content="font-feature-settings computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-feature-settings', 'normal');
+
+test_computed_value('font-feature-settings', '"dlig"');
+test_computed_value('font-feature-settings', '"smcp"');
+test_computed_value('font-feature-settings', '"c2sc"');
+test_computed_value('font-feature-settings', '"liga" 0');
+test_computed_value('font-feature-settings', '"tnum", "hist"');
+
+test_computed_value('font-feature-settings', '"PKRN"');
+
+test_computed_value('font-feature-settings', '"dlig", "smcp", "dlig" 0');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-invalid.html
new file mode 100644
index 0000000000..37689ce705
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-invalid.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-feature-settings with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop">
+<meta name="assert" content="font-feature-settings supports only the grammar 'normal | <feature-tag-value> #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-feature-settings', 'normal "dlig"');
+test_invalid_value('font-feature-settings', '"c2sc", normal');
+
+test_invalid_value('font-feature-settings', '"tnum" "hist"');
+test_invalid_value('font-feature-settings', '"silly" off');
+
+test_invalid_value('font-feature-settings', 'dlig');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-valid.html
new file mode 100644
index 0000000000..9ed4b5cde2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-feature-settings-valid.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-feature-settings with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop">
+<meta name="assert" content="font-feature-settings supports the full grammar 'normal | <feature-tag-value> #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-feature-settings', 'normal');
+
+// <feature-tag-value> = <string> [ <integer> | on | off ]?
+test_valid_value('font-feature-settings', '"dlig" 1', '"dlig"');
+test_valid_value('font-feature-settings', '"smcp" on', '"smcp"');
+test_valid_value('font-feature-settings', "'c2sc'", '"c2sc"');
+test_valid_value('font-feature-settings', '"liga" off', '"liga" 0');
+test_valid_value('font-feature-settings', '"tnum", \'hist\'', '"tnum", "hist"');
+
+test_valid_value('font-feature-settings', '"PKRN"');
+
+test_valid_value('font-feature-settings', '"dlig" 1, "smcp" on, "dlig" 0', '"dlig", "smcp", "dlig" 0');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-invalid.html
new file mode 100644
index 0000000000..4262750b0e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-invalid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop">
+<meta name="assert" content="font supports only the grammar '[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-stretch-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font', 'menu icon');
+
+test_invalid_value('font', 'italic oblique xx-small serif');
+test_invalid_value('font', 'small-caps small-caps medium/normal sans-serif');
+test_invalid_value('font', 'bold bolder xx-large/1.2 cursive');
+test_invalid_value('font', 'ultra-condensed extra-condensed larger/calc(120% + 1.2em) fantasy');
+test_invalid_value('font', 'italic small-caps lighter condensed normal smaller monospace');
+test_invalid_value('font', 'normal 100 semi-condensed oblique small-caps 10px/normal Menu');
+test_invalid_value('font', 'normal normal normal normal normal 20%/1.2 \"FB Armada\"');
+
+test_invalid_value('font', 'italic small-caps lighter condensed smaller');
+test_invalid_value('font', 'normal 100 semi-condensed oblique small-caps Menu');
+test_invalid_value('font', '100% larger / 2 fantasy');
+
+test_invalid_value('font', 'oldstyle-nums medium serif');
+test_invalid_value('font', 'common-ligatures medium serif');
+test_invalid_value('font', 'normal full-width medium serif');
+test_invalid_value('font', 'italic titling-caps medium serif');
+test_invalid_value('font', 'petite-caps medium serif');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-computed.html
new file mode 100644
index 0000000000..8abd71b03b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-computed.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontKerning</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-kerning-prop">
+<meta name="assert" content="font-kerning computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-kerning', 'auto');
+test_computed_value('font-kerning', 'normal');
+test_computed_value('font-kerning', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-invalid.html
new file mode 100644
index 0000000000..46e94b0a76
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-kerning with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-kerning-prop">
+<meta name="assert" content="font-kerning supports only the grammar 'auto | normal | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-kerning', 'normal auto');
+test_invalid_value('font-kerning', 'none, auto');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-valid.html
new file mode 100644
index 0000000000..623f860dd7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-kerning-valid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-kerning with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-kerning-prop">
+<meta name="assert" content="font-kerning supports the full grammar 'auto | normal | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-kerning', 'auto');
+test_valid_value('font-kerning', 'normal');
+test_valid_value('font-kerning', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-computed.html
new file mode 100644
index 0000000000..76601b9728
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-computed.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontLanguageOverride</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-language-override">
+<meta name="assert" content="font-language-override computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-language-override', 'normal');
+test_computed_value('font-language-override', '"ksw"');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-invalid.html
new file mode 100644
index 0000000000..f69e551658
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-invalid.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-language-override with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-language-override">
+<meta name="assert" content="font-language-override supports only the grammar 'normal | <string>'.">
+<meta name="assert" content="font-language-override string has three letters.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-language-override', 'auto');
+test_invalid_value('font-language-override', 'normal "ksw"');
+
+test_invalid_value('font-language-override', '"tr"');
+test_invalid_value('font-language-override', '"1 %"');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-valid.html
new file mode 100644
index 0000000000..27246f46ba
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-language-override-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-language-override with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-language-override">
+<meta name="assert" content="font-language-override supports the full grammar 'normal | <string>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-language-override', 'normal');
+test_valid_value('font-language-override', '"ksw"');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-computed.html
new file mode 100644
index 0000000000..9e0719b12c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-computed.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontOpticalSizing</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-optical-sizing">
+<meta name="assert" content="font-optical-sizing computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-optical-sizing', 'auto');
+test_computed_value('font-optical-sizing', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-invalid.html
new file mode 100644
index 0000000000..efd0f6257c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-invalid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-optical-sizing with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-optical-sizing">
+<meta name="assert" content="font-optical-sizing supports only the grammar 'auto | none'.">
+<meta name="assert" content="font-optical-sizing string has three letters.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-optical-sizing', 'normal');
+test_invalid_value('font-optical-sizing', 'auto none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-valid.html
new file mode 100644
index 0000000000..f9545d8920
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-optical-sizing-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-optical-sizing with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-optical-sizing">
+<meta name="assert" content="font-optical-sizing supports the full grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-optical-sizing', 'auto');
+test_valid_value('font-optical-sizing', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-palette-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-computed.html
new file mode 100644
index 0000000000..1de3364979
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-computed.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontPalette</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-prop">
+<meta name="assert" content="font-palette computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-palette', 'normal');
+test_computed_value('font-palette', 'light');
+test_computed_value('font-palette', 'dark');
+test_computed_value('font-palette', '--pitchfork');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-palette-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-invalid.html
new file mode 100644
index 0000000000..d9c9b1adbf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-invalid.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-palette with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-prop">
+<meta name="assert" content="font-palette supports only the grammar 'normal | light | dark | <palette-identifier>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-palette', 'normal none');
+test_invalid_value('font-palette', 'none, light');
+test_invalid_value('font-palette', 'A');
+test_invalid_value('font-palette', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-palette-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-valid.html
new file mode 100644
index 0000000000..516da172ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-valid.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-palette with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-prop">
+<meta name="assert" content="font-palette supports the full grammar 'normal | light | dark | <palette-identifier>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-palette', 'normal');
+test_valid_value('font-palette', 'light');
+test_valid_value('font-palette', 'dark');
+test_valid_value('font-palette', '--pitchfork');
+test_valid_value('font-palette', '--');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-invalid.html
new file mode 100644
index 0000000000..2056055f34
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-invalid.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing @font-palette-values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-values">
+<meta name="assert" content="@font-palette-values is parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="style">
+@font-palette-values {
+}
+
+@font-palette-values A {
+}
+
+@font-palette-values --A --B {
+}
+
+/* 0 */
+@font-palette-values --A {
+ font-family: a, serif; /* multiple families are allowed, but not generics */
+}
+
+/* 1 */
+@font-palette-values --A {
+ font-family: 1;
+}
+
+/* 2 */
+@font-palette-values --A {
+ font: 12px a;
+}
+
+/* 3 */
+@font-palette-values --A {
+ base-palette: 1 2;
+}
+
+/* 4 */
+@font-palette-values --A {
+ base-palette: ident;
+}
+
+/* 5 */
+@font-palette-values --A {
+ base-palette: "a" "b";
+}
+
+/* 6 */
+@font-palette-values --A {
+ base-palette: ;
+}
+
+/* 7 */
+@font-palette-values --A {
+ override-colors: ident #123;
+}
+
+/* 8 */
+@font-palette-values --A {
+ override-colors: 0 "red";
+}
+
+/* 9 */
+@font-palette-values --A {
+ override-colors: 0 #123, 1;
+}
+
+/* 10 */
+@font-palette-values --A {
+ override-colors: ;
+}
+
+/* 11 */
+@font-palette-values --A {
+ override-colors: 0 #123 1;
+}
+
+/* 12 */
+@font-palette-values --A {
+ override-colors: 0;
+}
+
+/* 13 */
+@font-palette-values --A {
+ font-family: "";
+}
+
+/* 14 */
+@font-palette-values --A {
+ base-palette: initial;
+ override-colors: initial;
+}
+
+/* 15 */
+@font-palette-values --A {
+ base-palette: inherit;
+ override-colors: inherit;
+}
+
+/* 16 */
+@font-palette-values --A {
+ base-palette: unset;
+ override-colors: unset;
+}
+
+/* 17 */
+@font-palette-values --A {
+ base-palette: -1;
+ override-color: -1 #123;
+}
+
+/* 18 */
+@font-palette-values --A {
+ override-colors: 0 canvas;
+}
+</style>
+</head>
+<body>
+<script>
+let rules = document.getElementById("style").sheet.cssRules;
+test(function() {
+ assert_equals(rules.length, 19);
+});
+
+test(function() {
+ let text = rules[0].cssText;
+ let rule = rules[0];
+ assert_equals(text.indexOf("font-family"), -1);
+ assert_equals(rule.fontFamily, "");
+ rule.fontFamily = "SomeFontFamily";
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ rule.basePalette = "7";
+ assert_equals(rule.basePalette, "");
+ assert_throws_js(TypeError, function() {
+ rule.clear();
+ });
+ assert_throws_js(TypeError, function() {
+ rule.delete(4);
+ });
+ assert_throws_js(TypeError, function() {
+ rule.set(4, "0 #123");
+ });
+});
+
+test(function() {
+ let text = rules[1].cssText;
+ let rule = rules[1];
+ assert_equals(text.indexOf("font-family"), -1);
+ assert_equals(rule.fontFamily, "");
+});
+
+test(function() {
+ let text = rules[2].cssText;
+ let rule = rules[2];
+ assert_equals(text.indexOf("font:"), -1);
+ assert_equals(rule.fontFamily, "");
+});
+
+test(function() {
+ let text = rules[3].cssText;
+ let rule = rules[3];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+ let text = rules[4].cssText;
+ let rule = rules[4];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+ let text = rules[5].cssText;
+ let rule = rules[5];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+ let text = rules[6].cssText;
+ let rule = rules[6];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+ let text = rules[7].cssText;
+ let rule = rules[7];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[8].cssText;
+ let rule = rules[8];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[9].cssText;
+ let rule = rules[9];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[10].cssText;
+ let rule = rules[10];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[11].cssText;
+ let rule = rules[11];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[12].cssText;
+ let rule = rules[12];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[13].cssText;
+ let rule = rules[13];
+ // I see nothing in the spec that indicates an empty string is a parse error.
+ assert_not_equals(text.indexOf("font-family"), -1);
+});
+
+test(function() {
+ let text = rules[14].cssText;
+ let rule = rules[14];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[15].cssText;
+ let rule = rules[15];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[16].cssText;
+ let rule = rules[16];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ assert_equals(CSSRule.FONT_PALETTE_VALUES_RULE, undefined);
+});
+
+test(function() {
+ let text = rules[17].cssText;
+ let rule = rules[17];
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(text.indexOf("override-color"), -1);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[18].cssText;
+ let rule = rules[18];
+ assert_equals(text.indexOf("override-colors"), -1);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-valid.html
new file mode 100644
index 0000000000..3c0c0626f5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-palette-values-valid.html
@@ -0,0 +1,390 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing @font-palette-values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-values">
+<meta name="assert" content="@font-palette-values is parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="style">
+/* 0 */
+@font-palette-values --A {
+}
+
+/* 1 */
+@font-palette-values --B {
+ font-weight: 400;
+}
+
+/* 2 */
+@font-palette-values --C {
+ font-family: foo;
+ font-family: bar;
+ base-palette: 1;
+ base-palette: "baz";
+ base-palette: 2;
+ override-colors: "a" #123;
+ override-colors: 3 #123;
+ override-colors: "b" #123;
+}
+
+/* 3 */
+@font-palette-values --D {
+ base-palette: "foo";
+ base-palette: 1;
+ base-palette: "bar";
+ override-colors: 3 #123;
+ override-colors: "baz" #123;
+ override-colors: 4 #123;
+}
+
+/* 4 */
+@font-palette-values --E {
+ override-colors: 3 rgb(17, 34, 51);
+ override-colors: 3 rgb(68, 85, 102);
+}
+
+/* 5 */
+@font-palette-values --F {
+ font-family: "foo";
+}
+
+/* 6 */
+@font-palette-values --G {
+ override-colors: 3 rgb(17, 34, 51), 4 rgb(68, 85, 102);
+}
+
+/* 7 */
+@font-palette-values --H {
+ override-colors: 3 rgb(17, 34, 51), 3 rgb(68, 85, 102);
+}
+
+/* 8 */
+@font-palette-values --I {
+ override-colors: 0 #0000FF;
+}
+
+/* 9 */
+@font-palette-values --J {
+ override-colors: 0 green;
+}
+
+/* 10 */
+@font-palette-values --K {
+ override-colors: 0 transparent;
+}
+
+/* 11 */
+@font-palette-values --L {
+ override-colors: 0 rgba(1 2 3 / 4);
+}
+
+/* 12 */
+@font-palette-values --M {
+ override-colors: 0 lab(29.2345% 39.3825 20.0664);
+}
+
+/* 13 */
+@font-palette-values --N {
+ override-colors: 0 color(display-p3 100% 100% 100%);
+}
+
+/* 14 */
+@font-palette-values --O {
+ override-colors: 0 transparent;
+}
+
+/* 15 */
+@font-palette-values -- {
+}
+
+/* 16 */
+@font-palette-values --P {
+ font-family: foo, bar, baz;
+}
+</style>
+</head>
+<body>
+<script>
+let rules = document.getElementById("style").sheet.cssRules;
+let supports_lab = CSS.supports('color', 'lab(29.2345% 39.3825 20.0664)');
+let supports_display_p3_color_space =
+ CSS.supports('color', 'color(display-p3 100% 100% 100%)');
+
+test(function() {
+ let text = rules[0].cssText;
+ assert_not_equals(text.indexOf("@font-palette-values "), -1);
+ assert_not_equals(text.indexOf(" --A "), -1);
+ assert_not_equals(text.indexOf("{"), -1);
+ assert_not_equals(text.indexOf("}"), -1);
+ assert_equals(text.indexOf("font-family"), -1);
+ assert_equals(text.indexOf("base-palette"), -1);
+ assert_equals(text.indexOf("override-colors"), -1);
+});
+
+test(function() {
+ let rule = rules[0];
+ assert_equals(rule.constructor.name, "CSSFontPaletteValuesRule");
+ assert_equals(rule.name, "--A");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[1].cssText;
+ assert_equals(text.indexOf("font-weight"), -1);
+});
+
+test(function() {
+ let rule = rules[1];
+ assert_equals(rule.name, "--B");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[2].cssText;
+ assert_equals(text.indexOf("font-family: foo;"), -1);
+ assert_not_equals(text.indexOf("font-family: bar;"), -1);
+ assert_equals(text.indexOf("base-palette: 1;"), -1);
+ assert_equals(text.indexOf("base-palette: \"baz\""), -1);
+ assert_not_equals(text.indexOf("base-palette: 2;"), -1);
+ assert_equals(text.indexOf("override-colors: \"a\""), -1);
+ assert_not_equals(text.indexOf("override-colors: 3"), -1);
+ assert_equals(text.indexOf("override-colors: \"b\""), -1);
+});
+
+test(function() {
+ let rule = rules[2];
+ assert_equals(rule.name, "--C");
+ assert_equals(rule.fontFamily, "bar");
+ assert_equals(rule.basePalette, "2");
+ assert_equals(rule.overrideColors, "3 rgb(17, 34, 51)");
+});
+
+test(function() {
+ let text = rules[3].cssText;
+ assert_equals(text.indexOf("base-palette: \"foo\";"), -1);
+ assert_not_equals(text.indexOf("base-palette: 1"), -1);
+ assert_equals(text.indexOf("base-palette: \"bar\";"), -1);
+ assert_equals(text.indexOf("override-colors: 3"), -1);
+ assert_equals(text.indexOf("override-colors: \"baz\""), -1);
+ assert_not_equals(text.indexOf("override-colors: 4"), -1);
+});
+
+test(function() {
+ let rule = rules[3];
+ assert_equals(rule.name, "--D");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "1");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_equals(rule.overrideColors.indexOf("4 "), 0);
+ assert_not_equals(rule.overrideColors.indexOf("rgb"), -1);
+});
+
+test(function() {
+ let text = rules[4].cssText;
+ assert_equals(text.indexOf("51"), -1);
+ assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+ let rule = rules[4];
+ assert_equals(rule.name, "--E");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_equals(rule.overrideColors.indexOf("3 "), 0);
+ assert_not_equals(rule.overrideColors.indexOf("102"), -1);
+});
+
+test(function() {
+ let text = rules[5].cssText;
+ assert_not_equals(text.indexOf("foo"), -1);
+});
+
+test(function() {
+ let rule = rules[5];
+ assert_equals(rule.name, "--F");
+ assert_in_array(rule.fontFamily, ["foo", "\"foo\""]);
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[6].cssText;
+ assert_not_equals(text.indexOf("51"), -1);
+ assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+ let rule = rules[6];
+ assert_equals(rule.name, "--G");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.split("),").length, 2);
+ assert_equals(rule.overrideColors.indexOf("3 "), 0);
+ assert_not_equals(rule.overrideColors.indexOf("), 4 "), -1);
+ assert_not_equals(rule.overrideColors.indexOf("51"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("102"), -1);
+});
+
+test(function() {
+ let text = rules[7].cssText;
+ assert_not_equals(text.indexOf("51"), -1);
+ assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+ let rule = rules[7];
+ assert_equals(rule.name, "--H");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_not_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_equals(rule.overrideColors.indexOf("3 "), 0);
+ assert_not_equals(rule.overrideColors.indexOf("), 3 "), -1);
+ assert_not_equals(rule.overrideColors.indexOf("51"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("102"), -1);
+});
+
+test(function() {
+ let text = rules[8].cssText;
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_not_equals(text.indexOf("rgb(0, 0, 255)"), -1);
+});
+
+test(function() {
+ let rule = rules[8];
+ assert_equals(rule.name, "--I");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("rgb(0, 0, 255)"), -1);
+});
+
+test(function() {
+ let text = rules[9].cssText;
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_true(text.includes("rgb(0, 128, 0)") ||
+ text.includes("green"));
+});
+
+test(function() {
+ let rule = rules[9];
+ assert_equals(rule.name, "--J");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_true(rule.overrideColors.includes("rgb(0, 128, 0)") ||
+ rule.overrideColors.includes("green"))
+});
+
+test(function() {
+ let text = rules[10].cssText;
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_true(text.includes("rgba(0, 0, 0, 0)") ||
+ text.includes("transparent"));
+});
+
+test(function() {
+ let rule = rules[10];
+ assert_equals(rule.name, "--K");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_true(rule.overrideColors.includes("rgba(0, 0, 0, 0)") ||
+ rule.overrideColors.includes("transparent"));
+});
+
+test(function() {
+ let text = rules[11].cssText;
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_not_equals(text.indexOf("2"), -1);
+});
+
+test(function() {
+ let rule = rules[11];
+ assert_equals(rule.name, "--L");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("2"), -1);
+});
+
+test(function() {
+ let text = rules[12].cssText;
+ if (supports_lab) {
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_not_equals(text.indexOf("29"), -1);
+ }
+});
+
+test(function() {
+ let rule = rules[12];
+ assert_equals(rule.name, "--M");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ if (supports_lab) {
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("lab"), -1);
+ }
+});
+
+test(function() {
+ let text = rules[13].cssText;
+ if (supports_display_p3_color_space) {
+ assert_not_equals(text.indexOf("override-colors"), -1);
+ assert_not_equals(text.indexOf("display-p3"), -1);
+ }
+});
+
+test(function() {
+ let rule = rules[13];
+ assert_equals(rule.name, "--N");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ if (supports_display_p3_color_space) {
+ assert_equals(rule.overrideColors.indexOf("),"), -1);
+ assert_not_equals(rule.overrideColors.indexOf("display-p3"), -1);
+ }
+});
+
+test(function() {
+ let text = rules[14].cssText;
+ assert_not_equals(text.indexOf("override-colors"), -1);
+});
+
+test(function() {
+ let rule = rules[14];
+ assert_equals(rule.name, "--O");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_not_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let text = rules[15].cssText;
+ assert_not_equals(text.indexOf("--"), -1);
+});
+
+test(function() {
+ let rule = rules[15];
+ assert_equals(rule.name, "--");
+ assert_equals(rule.fontFamily, "");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+
+test(function() {
+ let rule = rules[16];
+ assert_equals(rule.name, "--P");
+ assert_equals(rule.fontFamily, "foo, bar, baz");
+ assert_equals(rule.basePalette, "");
+ assert_equals(rule.overrideColors, "");
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-shorthand-variant.html b/testing/web-platform/tests/css/css-fonts/parsing/font-shorthand-variant.html
new file mode 100644
index 0000000000..98a02ff9bb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-shorthand-variant.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: font-variant vs font shorthand</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop">
+<meta name="assert" content="Only the CSS2 font-variant values (normal | small-caps) are supported by the font shorthand.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="container">
+ <div id="target"></div>
+</div>
+<script>
+test(() => {
+ const target = document.getElementById('target');
+ target.style.font = "medium serif";
+ target.style.fontVariant = "small-caps";
+ assert_equals(target.style.font, "small-caps medium serif", "font should be updated");
+ target.style.fontVariant = "titling-caps";
+ assert_equals(target.style.font, "", "font should be empty");
+ target.style.fontVariant = "normal";
+ assert_equals(target.style.font, "medium serif", "font should be reset");
+ target.style.fontVariant = "full-width";
+ assert_equals(target.style.font, "", "font should be empty");
+}, "font shorthand returns only CSS2 font-variant values");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-computed.html
new file mode 100644
index 0000000000..a4c8212b98
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-computed.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontSizeAdjust</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
+<meta name="assert" content="font-size-adjust computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-size-adjust', 'none');
+test_computed_value('font-size-adjust', '0.5');
+test_computed_value('font-size-adjust', 'ex-height 0.5', '0.5'); // default basis 'ex-height' omitted from serialization
+test_computed_value('font-size-adjust', 'cap-height 0.8');
+test_computed_value('font-size-adjust', 'ch-width 0.4');
+test_computed_value('font-size-adjust', 'ic-width 0.9');
+test_computed_value('font-size-adjust', 'ic-height 1.1');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-invalid.html
new file mode 100644
index 0000000000..8f1dfb1582
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-invalid.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-size-adjust with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
+<meta name="assert" content="font-size-adjust supports only the grammar 'none | [basis] <number>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-size-adjust', 'auto');
+test_invalid_value('font-size-adjust', '-10');
+test_invalid_value('font-size-adjust', '0.5 ex-height');
+test_invalid_value('font-size-adjust', 'em 1.0');
+test_invalid_value('font-size-adjust', 'ch 0.5'); // it's 'ch-width', not 'ch'
+test_invalid_value('font-size-adjust', 'ic 1.0'); // it's 'ic-width' or 'ic-height', not 'ic'
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-valid.html
new file mode 100644
index 0000000000..bb46daf4be
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-adjust-valid.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-size-adjust with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
+<meta name="assert" content="font-size-adjust supports the full grammar 'none | [basis] <number>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-size-adjust', 'none');
+test_valid_value('font-size-adjust', '0.5');
+test_valid_value('font-size-adjust', 'ex-height 0.5', '0.5'); // default basis 'ex' omitted from serialization
+test_valid_value('font-size-adjust', 'cap-height 0.8');
+test_valid_value('font-size-adjust', 'ch-width 0.4');
+test_valid_value('font-size-adjust', 'ic-width 0.9');
+test_valid_value('font-size-adjust', 'ic-height 0.9');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-computed.html
new file mode 100644
index 0000000000..3a98c75c25
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-computed.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontSize</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-size-prop">
+<meta name="assert" content="font-size computed value is an absolute length.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<style>
+ #container {
+ font-size: 40px;
+ }
+</style>
+</head>
+<body>
+<div id="container">
+ <div id="target"></div>
+</div>
+<font id="reference"></font>
+<script>
+function test_relative_size(first, second) {
+ test(() => {
+ const target = document.getElementById('target');
+ target.style.fontSize = first;
+ const firstResult = Number(getComputedStyle(target).fontSize.replace('px', ''));
+ target.style.fontSize = second;
+ const secondResult = Number(getComputedStyle(target).fontSize.replace('px', ''));
+ assert_less_than_equal(firstResult, secondResult);
+ }, first + ' <= ' + second);
+}
+
+test_relative_size('xx-small', 'x-small');
+test_relative_size('x-small', 'small');
+test_relative_size('small', 'medium');
+test_relative_size('medium', 'large');
+test_relative_size('large', 'x-large');
+test_relative_size('x-large', 'xx-large');
+// Added in Fonts level 4: https://github.com/w3c/csswg-drafts/issues/3907
+test_relative_size('xx-large', 'xxx-large');
+
+// <relative-size>
+test_relative_size('inherit', 'larger');
+test_relative_size('smaller', 'inherit');
+
+// <length-percentage>
+test_computed_value('font-size', '10px');
+test_computed_value('font-size', '20%', '8px');
+test_computed_value('font-size', 'calc(30% - 40px)', '0px');
+test_computed_value('font-size', 'calc(30% + 40px)', '52px');
+test_computed_value('font-size', 'calc(10px - 0.5em)', '0px');
+test_computed_value('font-size', 'calc(10px + 0.5em)', '30px');
+
+function test_font_size(attribute, keyword) {
+ test(() => {
+ const reference = document.getElementById('reference');
+ reference.setAttribute('size', attribute);
+ const target = document.getElementById('target');
+ target.style.fontSize = keyword;
+ assert_equals(getComputedStyle(target).fontSize, getComputedStyle(reference).fontSize);
+ }, '<font size="' + attribute + '"> is font-size: ' + keyword);
+}
+
+test_font_size('2', 'small');
+test_font_size('3', 'medium');
+test_font_size('4', 'large');
+test_font_size('5', 'x-large');
+test_font_size('6', 'xx-large');
+test_font_size('7', 'xxx-large');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-invalid.html
new file mode 100644
index 0000000000..b3bccc289f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-invalid.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-size with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-prop">
+<meta name="assert" content="font-size supports only the grammar '<absolute-size> | <relative-size> | <length-percentage>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-size', 'auto');
+test_invalid_value('font-size', 'medium small');
+
+test_invalid_value('font-size', '-10px');
+test_invalid_value('font-size', '-20%');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-size-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-size-valid.html
new file mode 100644
index 0000000000..72cf605302
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-size-valid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-size with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-size-prop">
+<meta name="assert" content="font-size supports the full grammar '<absolute-size> | <relative-size> | <length-percentage>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+// <absolute-size>
+test_valid_value('font-size', 'xx-small');
+test_valid_value('font-size', 'x-small');
+test_valid_value('font-size', 'small');
+test_valid_value('font-size', 'medium');
+test_valid_value('font-size', 'large');
+test_valid_value('font-size', 'x-large');
+test_valid_value('font-size', 'xx-large');
+// Added in Fonts level 4: https://github.com/w3c/csswg-drafts/issues/3907
+test_valid_value('font-size', 'xxx-large');
+
+// <relative-size>
+test_valid_value('font-size', 'larger');
+test_valid_value('font-size', 'smaller');
+
+// <length-percentage>
+test_valid_value('font-size', '10px');
+test_valid_value('font-size', '20%');
+test_valid_value('font-size', 'calc(30% - 40px)');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-computed.html
new file mode 100644
index 0000000000..9d1136ef69
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-computed.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontStretch</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-stretch-prop">
+<meta name="assert" content="font-stretch computed value is a percentage.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-stretch', 'ultra-condensed', '50%');
+test_computed_value('font-stretch', 'extra-condensed', '62.5%');
+test_computed_value('font-stretch', 'condensed', '75%');
+test_computed_value('font-stretch', 'semi-condensed', '87.5%');
+test_computed_value('font-stretch', 'normal', '100%');
+test_computed_value('font-stretch', 'semi-expanded', '112.5%');
+test_computed_value('font-stretch', 'expanded', '125%');
+test_computed_value('font-stretch', 'extra-expanded', '150%');
+test_computed_value('font-stretch', 'ultra-expanded', '200%');
+
+test_computed_value('font-stretch', '234.5%');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-invalid.html
new file mode 100644
index 0000000000..9ff8fa5dcf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-invalid.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-stretch with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-stretch-prop">
+<meta name="assert" content="font-stretch supports only the grammar 'normal | <percentage> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded'.">
+<meta name="assert" content="Values less than 0% are invalid.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-stretch', 'auto');
+test_invalid_value('font-stretch', 'normal, ultra-condensed');
+test_invalid_value('font-stretch', 'condensed expanded');
+test_invalid_value('font-stretch', '-50%');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-valid.html
new file mode 100644
index 0000000000..38452c2699
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-stretch-valid.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-stretch with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-stretch-prop">
+<meta name="assert" content="font-stretch supports the full grammar 'normal | <percentage> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-stretch', 'normal');
+test_valid_value('font-stretch', 'ultra-condensed');
+test_valid_value('font-stretch', 'extra-condensed');
+test_valid_value('font-stretch', 'condensed');
+test_valid_value('font-stretch', 'semi-condensed');
+test_valid_value('font-stretch', 'semi-expanded');
+test_valid_value('font-stretch', 'expanded');
+test_valid_value('font-stretch', 'extra-expanded');
+test_valid_value('font-stretch', 'ultra-expanded');
+
+test_valid_value('font-stretch', '234.5%');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html
new file mode 100644
index 0000000000..46074c4219
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontStyle</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-style-prop">
+<meta name="assert" content="font-style computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ #target {
+ font-family: Ahem;
+ }
+</style>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-style', 'normal');
+test_computed_value('font-style', 'italic');
+test_computed_value('font-style', 'oblique');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-style-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-style-invalid.html
new file mode 100644
index 0000000000..4542c29cf2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-style-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-style with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-style-prop">
+<meta name="assert" content="font-style supports only the grammar 'normal | italic | oblique'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-style', 'auto');
+test_invalid_value('font-style', 'italic oblique');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html
new file mode 100644
index 0000000000..b61864478b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-style with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-style-prop">
+<meta name="assert" content="font-style supports the full grammar 'normal | italic | oblique'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-style', 'normal');
+test_valid_value('font-style', 'italic');
+test_valid_value('font-style', 'oblique');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-computed.html
new file mode 100644
index 0000000000..eba354927a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-computed.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module: getComputedStyle().fontSynthesis</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-synthesis">
+<meta name="assert" content="font-synthesis computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-synthesis', 'none');
+test_computed_value('font-synthesis', 'weight');
+test_computed_value('font-synthesis', 'style');
+test_computed_value('font-synthesis', 'small-caps');
+test_computed_value('font-synthesis', 'style small-caps');
+test_computed_value('font-synthesis', 'weight small-caps');
+test_computed_value('font-synthesis', 'weight style');
+test_computed_value('font-synthesis', 'weight style small-caps');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-invalid.html
new file mode 100644
index 0000000000..8d647997d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-invalid.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module: parsing font-synthesis with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-synthesis">
+<meta name="assert" content="font-synthesis supports only the grammar 'none | [ weight || style || small-caps ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-synthesis', 'auto');
+test_invalid_value('font-synthesis', 'none weight');
+test_invalid_value('font-synthesis', 'none style');
+test_invalid_value('font-synthesis', 'style none');
+test_invalid_value('font-synthesis', 'none small-caps');
+test_invalid_value('font-synthesis', 'small-caps none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-invalid.html
new file mode 100644
index 0000000000..aa0e3e4029
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-small-caps with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-small-caps">
+<meta name="assert" content="font-synthesis-small-caps supports only the grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-synthesis-small-caps', 'normal');
+test_invalid_value('font-synthesis-small-caps', 'auto none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-valid.html
new file mode 100644
index 0000000000..064fc88161
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-small-caps-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-small-caps with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-small-caps">
+<meta name="assert" content="font-synthesis-small-caps supports the full grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-synthesis-small-caps', 'auto');
+test_valid_value('font-synthesis-small-caps', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html
new file mode 100644
index 0000000000..e0fc0f4a2a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-style with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-style">
+<meta name="assert" content="font-synthesis-style supports only the grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-synthesis-style', 'normal');
+test_invalid_value('font-synthesis-style', 'auto none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-valid.html
new file mode 100644
index 0000000000..5b1c01561a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-style-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-style with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-style">
+<meta name="assert" content="font-synthesis-style supports the full grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-synthesis-style', 'auto');
+test_valid_value('font-synthesis-style', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-valid.html
new file mode 100644
index 0000000000..4c91fb9b44
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-valid.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module: parsing font-synthesis with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-synthesis">
+<meta name="assert" content="font-synthesis supports the full grammar 'none | [ weight || style || small-caps ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-synthesis', 'none');
+test_valid_value('font-synthesis', 'weight');
+test_valid_value('font-synthesis', 'style');
+test_valid_value('font-synthesis', 'small-caps');
+test_valid_value('font-synthesis', 'style weight', 'weight style');
+test_valid_value('font-synthesis', 'small-caps weight', 'weight small-caps');
+test_valid_value('font-synthesis', 'small-caps style', 'style small-caps');
+test_valid_value('font-synthesis', 'style weight small-caps', 'weight style small-caps');
+test_valid_value('font-synthesis', 'style small-caps weight ', 'weight style small-caps');
+test_valid_value('font-synthesis', 'small-caps style weight ', 'weight style small-caps');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-invalid.html
new file mode 100644
index 0000000000..292a21ef97
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-weight with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-weight">
+<meta name="assert" content="font-synthesis-weight supports only the grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-synthesis-weight', 'normal');
+test_invalid_value('font-synthesis-weight', 'auto none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-valid.html
new file mode 100644
index 0000000000..8a70fa4fd3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-synthesis-weight-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-synthesis-weight with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-synthesis-weight">
+<meta name="assert" content="font-synthesis-weight supports the full grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-synthesis-weight', 'auto');
+test_valid_value('font-synthesis-weight', 'none');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-valid.html
new file mode 100644
index 0000000000..896be89741
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-valid.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop">
+<meta name="assert" content="font supports the full grammar '[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-stretch-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+'use strict';
+
+// Firefox and Edge 18 serialize these as supplied.
+// Blink and Safari have implementation-dependent or platform-dependent serializations.
+function test_system_font(keyword) {
+ test(() => {
+ const target = document.getElementById('target');
+ const previousValue = 'italic xx-large/0px fantasy';
+ target.style.font = previousValue;
+ target.style.font = keyword;
+ const readValue = target.style.getPropertyValue('font');
+ assert_not_equals(readValue, '', 'font should be set');
+ assert_not_equals(readValue, previousValue, 'font should be updated');
+ target.style.font = previousValue;
+ target.style.font = readValue;
+ assert_equals(target.style.getPropertyValue('font'), readValue, "serialization should round-trip");
+ }, keyword + ' should be a supported system font.');
+}
+
+test_system_font('caption');
+test_system_font('icon');
+test_system_font('menu');
+test_system_font('message-box');
+test_system_font('small-caption');
+test_system_font('status-bar');
+
+// values other than normal
+const generate_style = (() => {
+ const alternatives = [
+ 'italic',
+ 'oblique'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+// value other than normal
+const generate_variant = () => 'small-caps';
+
+// values other than normal
+const generate_weight = (() => {
+ const alternatives = [
+ 'bold',
+ 'bolder',
+ 'lighter',
+ '100',
+ '900'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+// values other than normal
+const generate_stretch = (() => {
+ const alternatives = [
+ 'ultra-condensed',
+ 'extra-condensed',
+ 'condensed',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'expanded',
+ 'extra-expanded',
+ 'ultra-expanded'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_size = (() => {
+ const alternatives = [
+ // <absolute-size>
+ 'xx-small',
+ 'medium',
+ 'xx-large',
+
+ // <relative-size>
+ 'larger',
+ 'smaller',
+
+ // <length-percentage>
+ '10px',
+ '20%',
+ 'calc(30% - 40px)',
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_line_height = (() => {
+ const alternatives = [
+ null,
+ 'normal',
+ '1.2',
+ 'calc(120% + 1.2em)'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+const generate_family = (() => {
+ const alternatives = [
+ 'serif',
+ 'sans-serif',
+ 'cursive',
+ 'fantasy',
+ 'monospace',
+ 'Menu',
+ '"FB Armada"'
+ ];
+ let counter = 0;
+ return () => alternatives[counter++ % alternatives.length];
+})();
+
+function test_specific(prefix) {
+ let parts = [];
+ let canonical = [];
+ let style = null;
+ let variant = null;
+ let weight = null;
+ let stretch = null;
+ for (let entry of prefix) {
+ if (entry === 'style') {
+ style = generate_style();
+ parts.push(style);
+ } else if (entry === 'variant') {
+ variant = generate_variant();
+ parts.push(variant);
+ } else if (entry === 'weight') {
+ weight = generate_weight();
+ parts.push(weight);
+ } else if (entry === 'stretch') {
+ stretch = generate_stretch();
+ parts.push(stretch);
+ } else {
+ // normal
+ parts.push('normal');
+ }
+ }
+
+ if (style)
+ canonical.push(style);
+ if (variant)
+ canonical.push(variant);
+ if (weight)
+ canonical.push(weight);
+ if (stretch)
+ canonical.push(stretch);
+
+ const size = generate_size();
+ const lineHeight = generate_line_height();
+ if (lineHeight) {
+ parts.push(size + '/' + lineHeight);
+ if (lineHeight === 'normal')
+ canonical.push(size);
+ else
+ canonical.push(size + ' / ' + lineHeight);
+ } else {
+ parts.push(size);
+ canonical.push(size);
+ }
+
+ const family = generate_family();
+ parts.push(family);
+ canonical.push(family);
+
+ test_valid_value('font', parts.join(' '), canonical.join(' '));
+}
+
+function test_various(prefix) {
+ test_specific(prefix);
+ if (prefix.length === 4)
+ return;
+
+ const alternatives = [
+ 'normal',
+ 'style',
+ 'variant',
+ 'weight',
+ 'stretch'
+ ];
+ for (let alternative of alternatives) {
+ if (alternative === 'normal' || !prefix.includes(alternative))
+ test_various(prefix.concat(alternative));
+ // else we would have two styles or two variants, etc.
+ }
+}
+
+test_various([]);
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-invalid.html
new file mode 100644
index 0000000000..8cd17d0849
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-invalid.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>
+ CSS Fonts Module Level 4: parsing font-variant-alternates with invalid values
+ </title>
+ <link
+ rel="help"
+ href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variant-alternates"
+ />
+ <meta
+ name="assert"
+ content="font-variant-alternates supports only the grammar normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]"
+ />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/parsing-testcommon.js"></script>
+ </head>
+ <body>
+ <script>
+ test_invalid_value(
+ "font-variant-alternates",
+ "swash(several,different,aliases)"
+ );
+ test_invalid_value("font-variant-alternates", "stylistic(more,than,one)");
+ test_invalid_value("font-variant-alternates", "ornaments(more,than,one)");
+ test_invalid_value("font-variant-alternates", "swash(more,than,one)");
+ test_invalid_value(
+ "font-variant-alternates",
+ "annotation(more,than,one)"
+ );
+ test_invalid_value(
+ "font-variant-alternates",
+ "historical-forms(argument)"
+ );
+ test_invalid_value("font-variant-alternates", "annotation()");
+ test_invalid_value("font-variant-alternates", "annotation");
+ test_invalid_value("font-variant-alternates", "swash");
+ test_invalid_value("font-variant-alternates", "ornaments stylistic");
+ test_invalid_value("font-variant-alternates", "swash(one) swash(two)");
+ test_invalid_value(
+ "font-variant-alternates",
+ "unkown(one) myfunction(two)"
+ );
+ test_invalid_value(
+ "font-variant-alternates",
+ "styleset(thisone) styleset(something,else)"
+ );
+ test_invalid_value(
+ "font-variant-alternates",
+ "swash(foo) swash(bar)"
+ );
+ test_invalid_value("font-variant-alternates", "ornaments(one historical-forms");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-valid.html
new file mode 100644
index 0000000000..43cc6f5244
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-alternates-valid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>
+ CSS Fonts Module Level 4: parsing font-variant-alternates with valid
+ values
+ </title>
+ <link
+ rel="help"
+ href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variant-alternates"
+ />
+ <meta
+ name="assert"
+ content="font-variant-alternates supports only the grammar normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]"
+ />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/parsing-testcommon.js"></script>
+ </head>
+ <body>
+ <script>
+ test_valid_value(
+ "font-variant-alternates",
+ "character-variant(more, than, one)"
+ );
+ test_valid_value("font-variant-alternates", "styleset(more, than, one)");
+ test_valid_value(
+ "font-variant-alternates",
+ "styleset(more, than, one) character-variant(more, than, one)"
+ );
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-computed.html
new file mode 100644
index 0000000000..01b890df20
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-computed.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariantCaps</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-caps-prop">
+<meta name="assert" content="font-variant-caps computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-caps', 'normal');
+test_computed_value('font-variant-caps', 'small-caps');
+test_computed_value('font-variant-caps', 'all-small-caps');
+test_computed_value('font-variant-caps', 'petite-caps');
+test_computed_value('font-variant-caps', 'all-petite-caps');
+test_computed_value('font-variant-caps', 'unicase');
+test_computed_value('font-variant-caps', 'titling-caps');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-invalid.html
new file mode 100644
index 0000000000..4c538ad5eb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-caps with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-caps-prop">
+<meta name="assert" content="font-variant-caps supports only the grammar 'normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-caps', 'auto');
+test_invalid_value('font-variant-caps', 'normal unicase');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-valid.html
new file mode 100644
index 0000000000..f34595a9f2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-caps-valid.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-caps with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-caps-prop">
+<meta name="assert" content="font-variant-caps supports the full grammar 'normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-caps', 'normal');
+test_valid_value('font-variant-caps', 'small-caps');
+test_valid_value('font-variant-caps', 'all-small-caps');
+test_valid_value('font-variant-caps', 'petite-caps');
+test_valid_value('font-variant-caps', 'all-petite-caps');
+test_valid_value('font-variant-caps', 'unicase');
+test_valid_value('font-variant-caps', 'titling-caps');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-computed.html
new file mode 100644
index 0000000000..5f820cd386
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-computed.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariantEastAsian</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-east-asian-prop">
+<meta name="assert" content="font-variant-east-asian computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-east-asian', 'normal');
+
+// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
+test_computed_value('font-variant-east-asian', 'jis78');
+test_computed_value('font-variant-east-asian', 'jis83');
+test_computed_value('font-variant-east-asian', 'jis90');
+test_computed_value('font-variant-east-asian', 'jis04');
+test_computed_value('font-variant-east-asian', 'simplified');
+test_computed_value('font-variant-east-asian', 'traditional');
+
+// <east-asian-width-values> = [ full-width | proportional-width ]
+test_computed_value('font-variant-east-asian', 'full-width');
+test_computed_value('font-variant-east-asian', 'proportional-width');
+
+test_computed_value('font-variant-east-asian', 'ruby');
+
+test_computed_value('font-variant-east-asian', 'jis78 proportional-width');
+test_computed_value('font-variant-east-asian', 'simplified full-width ruby');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-invalid.html
new file mode 100644
index 0000000000..c61a4b9b13
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-invalid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-east-asian with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-east-asian-prop">
+<meta name="assert" content="font-variant-east-asian supports only the grammar 'normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-east-asian', 'normal ruby');
+
+test_invalid_value('font-variant-east-asian', 'jis78 jis83');
+
+test_invalid_value('font-variant-east-asian', 'full-width proportional-width');
+
+test_invalid_value('font-variant-east-asian', 'normal garbage');
+test_invalid_value('font-variant-east-asian', 'normal none');
+test_invalid_value('font-variant-east-asian', 'normal 30px');
+
+test_invalid_value('font-variant-east-asian', 'full-width garbage');
+test_invalid_value('font-variant-east-asian', 'full-width none');
+test_invalid_value('font-variant-east-asian', 'full-width 30px');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-valid.html
new file mode 100644
index 0000000000..0f16ceccfe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-east-asian-valid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-east-asian with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-east-asian-prop">
+<meta name="assert" content="font-variant-east-asian supports the full grammar 'normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-east-asian', 'normal');
+
+// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
+test_valid_value('font-variant-east-asian', 'jis78');
+test_valid_value('font-variant-east-asian', 'jis83');
+test_valid_value('font-variant-east-asian', 'jis90');
+test_valid_value('font-variant-east-asian', 'jis04');
+test_valid_value('font-variant-east-asian', 'simplified');
+test_valid_value('font-variant-east-asian', 'traditional');
+
+// <east-asian-width-values> = [ full-width | proportional-width ]
+test_valid_value('font-variant-east-asian', 'full-width');
+test_valid_value('font-variant-east-asian', 'proportional-width');
+
+test_valid_value('font-variant-east-asian', 'ruby');
+
+test_valid_value('font-variant-east-asian', 'jis78 proportional-width');
+test_valid_value('font-variant-east-asian', 'ruby full-width simplified', 'simplified full-width ruby');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-computed.html
new file mode 100644
index 0000000000..5d24a1dfee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-computed.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: getComputedStyle().fontVariantEmoji</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-variant-emoji-prop">
+<meta name="assert" content="font-variant-emoji computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-emoji', 'normal');
+test_computed_value('font-variant-emoji', 'text');
+test_computed_value('font-variant-emoji', 'emoji');
+test_computed_value('font-variant-emoji', 'unicode');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-invalid.html
new file mode 100644
index 0000000000..afbf2c4878
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-invalid.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variant-emoji with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-variant-emoji-prop">
+<meta name="assert" content="font-variant-emoji supports only the grammar 'normal | text | emoji | unicode'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-emoji', 'auto');
+test_invalid_value('font-variant-emoji', 'none');
+test_invalid_value('font-variant-emoji', 'color');
+test_invalid_value('font-variant-emoji', 'normal text');
+test_invalid_value('font-variant-emoji', 'text emoji');
+test_invalid_value('font-variant-emoji', 'normal, unicode');
+test_invalid_value('font-variant-emoji', 'unicode, emoji');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-valid.html
new file mode 100644
index 0000000000..f3bf80bb52
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-emoji-valid.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variant-emoji with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-variant-emoji-prop">
+<meta name="assert" content="font-variant-emoji supports the full grammar 'normal | text | emoji | unicode'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-emoji', 'normal');
+test_valid_value('font-variant-emoji', 'text');
+test_valid_value('font-variant-emoji', 'emoji');
+test_valid_value('font-variant-emoji', 'unicode');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-invalid.html
new file mode 100644
index 0000000000..c591acc3fc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-invalid.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variant with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variant">
+<meta name="assert" content="font-variant supports only the grammar 'normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero || <east-asian-variant-values> || <east-asian-width-values> || ruby || [ sub | super ] ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant', 'normal none');
+
+// <common-lig-values>
+test_invalid_value('font-variant', 'common-ligatures no-common-ligatures');
+
+// <discretionary-lig-values>
+test_invalid_value('font-variant', 'discretionary-ligatures no-discretionary-ligatures');
+
+// <historical-lig-values>
+test_invalid_value('font-variant', 'historical-ligatures no-historical-ligatures');
+
+// <contextual-alt-values>
+test_invalid_value('font-variant', 'contextual no-contextual');
+
+// [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ]
+test_invalid_value('font-variant', 'small-caps all-small-caps');
+
+// [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]
+test_invalid_value('font-variant', 'stylistic(flowing) stylistic(flowing)');
+
+// <numeric-figure-values>
+test_invalid_value('font-variant', 'lining-nums oldstyle-nums');
+
+// <numeric-spacing-values>
+test_invalid_value('font-variant', 'proportional-nums tabular-nums');
+
+// <numeric-fraction-values>
+test_invalid_value('font-variant', 'diagonal-fractions stacked-fractions');
+
+// ordinal
+test_invalid_value('font-variant', 'ordinal slashed-zero ordinal');
+
+// slashed-zero
+test_invalid_value('font-variant', 'slashed-zero jis78 slashed-zero');
+
+// <east-asian-variant-values>
+test_invalid_value('font-variant', 'jis78 jis83');
+
+// <east-asian-width-values>
+test_invalid_value('font-variant', 'full-width proportional-width');
+
+// ruby
+test_invalid_value('font-variant', 'ruby sub ruby');
+
+// [ sub | super ]
+test_invalid_value('font-variant', 'sub super');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-computed.html
new file mode 100644
index 0000000000..a9dfac54e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-computed.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariantLigatures</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-ligatures-prop">
+<meta name="assert" content="font-variant-ligatures computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-ligatures', 'normal');
+test_computed_value('font-variant-ligatures', 'none');
+
+// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
+test_computed_value('font-variant-ligatures', 'common-ligatures');
+test_computed_value('font-variant-ligatures', 'no-common-ligatures');
+
+// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
+test_computed_value('font-variant-ligatures', 'discretionary-ligatures');
+test_computed_value('font-variant-ligatures', 'no-discretionary-ligatures');
+
+// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
+test_computed_value('font-variant-ligatures', 'historical-ligatures');
+test_computed_value('font-variant-ligatures', 'no-historical-ligatures');
+
+// <contextual-alt-values> = [ contextual | no-contextual ]
+test_computed_value('font-variant-ligatures', 'contextual');
+test_computed_value('font-variant-ligatures', 'no-contextual');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-invalid.html
new file mode 100644
index 0000000000..69af66b9b0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-invalid.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-ligatures with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-ligatures-prop">
+<meta name="assert" content="font-variant-ligatures supports only the grammar 'normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-ligatures', 'none normal');
+
+test_invalid_value('font-variant-ligatures', 'normal common-ligatures');
+
+test_invalid_value('font-variant-ligatures', 'common-ligatures no-common-ligatures');
+
+test_invalid_value('font-variant-ligatures', 'discretionary-ligatures no-discretionary-ligatures');
+
+test_invalid_value('font-variant-ligatures', 'historical-ligatures no-historical-ligatures');
+
+test_invalid_value('font-variant-ligatures', 'contextual no-contextual');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-valid.html
new file mode 100644
index 0000000000..2fdd99e226
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-ligatures-valid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-ligatures with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-ligatures-prop">
+<meta name="assert" content="font-variant-ligatures supports the full grammar 'normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-ligatures', 'normal');
+test_valid_value('font-variant-ligatures', 'none');
+
+// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
+test_valid_value('font-variant-ligatures', 'common-ligatures');
+test_valid_value('font-variant-ligatures', 'no-common-ligatures');
+
+// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
+test_valid_value('font-variant-ligatures', 'discretionary-ligatures');
+test_valid_value('font-variant-ligatures', 'no-discretionary-ligatures');
+
+// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
+test_valid_value('font-variant-ligatures', 'historical-ligatures');
+test_valid_value('font-variant-ligatures', 'no-historical-ligatures');
+
+// <contextual-alt-values> = [ contextual | no-contextual ]
+test_valid_value('font-variant-ligatures', 'contextual');
+test_valid_value('font-variant-ligatures', 'no-contextual');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-computed.html
new file mode 100644
index 0000000000..ae3fbecefe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-computed.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariantNumeric</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-numeric-prop">
+<meta name="assert" content="font-variant-numeric computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-numeric', 'normal');
+
+// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
+test_computed_value('font-variant-numeric', 'lining-nums');
+test_computed_value('font-variant-numeric', 'oldstyle-nums');
+
+// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
+test_computed_value('font-variant-numeric', 'proportional-nums');
+test_computed_value('font-variant-numeric', 'tabular-nums');
+
+// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
+test_computed_value('font-variant-numeric', 'diagonal-fractions');
+test_computed_value('font-variant-numeric', 'stacked-fractions');
+
+test_computed_value('font-variant-numeric', 'ordinal');
+
+test_computed_value('font-variant-numeric', 'slashed-zero');
+
+test_computed_value('font-variant-numeric', 'oldstyle-nums tabular-nums diagonal-fractions');
+
+test_computed_value('font-variant-numeric', 'lining-nums proportional-nums stacked-fractions ordinal slashed-zero');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-invalid.html
new file mode 100644
index 0000000000..97f9e14840
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-invalid.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-numeric with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-numeric-prop">
+<meta name="assert" content="font-variant-numeric supports only the grammar 'normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-numeric', 'auto');
+
+test_invalid_value('font-variant-numeric', 'normal lining-nums');
+test_invalid_value('font-variant-numeric', 'lining-nums oldstyle-nums');
+
+test_invalid_value('font-variant-numeric', 'proportional-nums normal');
+test_invalid_value('font-variant-numeric', 'tabular-nums proportional-nums');
+
+test_invalid_value('font-variant-numeric', 'normal diagonal-fractions');
+test_invalid_value('font-variant-numeric', 'diagonal-fractions stacked-fractions');
+
+test_invalid_value('font-variant-numeric', 'ordinal normal');
+
+test_invalid_value('font-variant-numeric', 'normal slashed-zero');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-valid.html
new file mode 100644
index 0000000000..c7a9fd252c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-numeric-valid.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-numeric with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-numeric-prop">
+<meta name="assert" content="font-variant-numeric supports the full grammar 'normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-numeric', 'normal');
+
+// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
+test_valid_value('font-variant-numeric', 'lining-nums');
+test_valid_value('font-variant-numeric', 'oldstyle-nums');
+
+// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
+test_valid_value('font-variant-numeric', 'proportional-nums');
+test_valid_value('font-variant-numeric', 'tabular-nums');
+
+// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
+test_valid_value('font-variant-numeric', 'diagonal-fractions');
+test_valid_value('font-variant-numeric', 'stacked-fractions');
+
+test_valid_value('font-variant-numeric', 'ordinal');
+
+test_valid_value('font-variant-numeric', 'slashed-zero');
+
+test_valid_value('font-variant-numeric', 'oldstyle-nums tabular-nums diagonal-fractions');
+
+// Blink gives "slashed-zero ordinal stacked-fractions proportional-nums lining-nums".
+// Also accept specified order as correct serialization.
+test_valid_value('font-variant-numeric', 'slashed-zero ordinal stacked-fractions proportional-nums lining-nums', ['slashed-zero ordinal stacked-fractions proportional-nums lining-nums', 'lining-nums proportional-nums stacked-fractions ordinal slashed-zero']);
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-computed.html
new file mode 100644
index 0000000000..24bac43e79
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-computed.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariantPosition</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-position-prop">
+<meta name="assert" content="font-variant-position computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variant-position', 'normal');
+test_computed_value('font-variant-position', 'sub');
+test_computed_value('font-variant-position', 'super');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-invalid.html
new file mode 100644
index 0000000000..11110ce53b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-position with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-position-prop">
+<meta name="assert" content="font-variant-position supports only the grammar 'normal | sub | super'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variant-position', 'auto');
+test_invalid_value('font-variant-position', 'super sub');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-valid.html
new file mode 100644
index 0000000000..3887ab0cc4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-position-valid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-variant-position with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-variant-position-prop">
+<meta name="assert" content="font-variant-position supports the full grammar 'normal | sub | super'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant-position', 'normal');
+test_valid_value('font-variant-position', 'sub');
+test_valid_value('font-variant-position', 'super');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-serialization.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-serialization.html
new file mode 100644
index 0000000000..04e4d92681
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-serialization.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: serialization of font-variant</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variant">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1797146">
+<meta name="assert" content="re-setting font-variant to its serialization should be idempotent">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id=target style=""></div>
+<script>
+test(function(){
+ let div = document.getElementById("target");
+ let sty = div.style;
+
+ sty.font = "12px serif";
+ v = sty.fontVariant;
+ assert_in_array(v, ["", "normal"]); // Accept either explicit 'normal' or empty.
+ sty.fontVariant = v;
+ assert_equals(sty.fontVariant, v);
+
+ sty.font = "menu";
+ v = sty.fontVariant;
+ assert_in_array(v, ["", "normal"]);
+
+ sty.font = "12px serif"
+ sty.fontVariantNumeric = "tabular-nums";
+ v = sty.fontVariant;
+ assert_equals(v, "tabular-nums");
+ sty.fontVariant = v;
+ assert_equals(sty.fontVariant, v);
+
+ sty.font = "menu"
+ sty.fontVariantNumeric = "tabular-nums";
+ v = sty.fontVariant;
+ assert_equals(v, "tabular-nums");
+ sty.fontVariant = v;
+ assert_equals(sty.fontVariant, v);
+
+ sty.font = "12px serif"
+ sty.fontVariantNumeric = "tabular-nums";
+ sty.fontVariantCaps = "small-caps";
+ v = sty.fontVariant;
+ sty.fontVariant = v;
+ assert_equals(sty.fontVariant, v);
+
+ sty.font = "menu"
+ sty.fontVariantNumeric = "tabular-nums";
+ sty.fontVariantCaps = "small-caps";
+ v = sty.fontVariant;
+ sty.fontVariant = v;
+ assert_equals(sty.fontVariant, v);
+}, "checking serialized value of font-variant");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variant-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-valid.html
new file mode 100644
index 0000000000..19d858189a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variant-valid.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variant with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variant">
+<meta name="assert" content="font-variant supports the full grammar 'normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero || <east-asian-variant-values> || <east-asian-width-values> || ruby || [ sub | super ] ]'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variant', 'normal');
+test_valid_value('font-variant', 'none');
+
+// <common-lig-values>
+test_valid_value('font-variant', 'common-ligatures');
+test_valid_value('font-variant', 'no-common-ligatures');
+
+// <discretionary-lig-values>
+test_valid_value('font-variant', 'discretionary-ligatures');
+test_valid_value('font-variant', 'no-discretionary-ligatures');
+
+// <historical-lig-values>
+test_valid_value('font-variant', 'historical-ligatures');
+test_valid_value('font-variant', 'no-historical-ligatures');
+
+// <contextual-alt-values>
+test_valid_value('font-variant', 'contextual');
+test_valid_value('font-variant', 'no-contextual');
+
+// [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ]
+test_valid_value('font-variant', 'small-caps');
+test_valid_value('font-variant', 'all-small-caps');
+test_valid_value('font-variant', 'petite-caps');
+test_valid_value('font-variant', 'all-petite-caps');
+test_valid_value('font-variant', 'unicase');
+test_valid_value('font-variant', 'titling-caps');
+
+// [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]
+test_valid_value('font-variant', 'stylistic(flowing)');
+test_valid_value('font-variant', 'historical-forms');
+test_valid_value('font-variant', 'styleset(flowing)');
+test_valid_value('font-variant', 'character-variant(flowing)');
+test_valid_value('font-variant', 'swash(flowing)');
+test_valid_value('font-variant', 'ornaments(flowing)');
+test_valid_value('font-variant', 'annotation(flowing)');
+
+test_valid_value('font-variant', 'stylistic(flowing) historical-forms styleset(flowing) character-variant(flowing) swash(flowing) ornaments(flowing) annotation(flowing)');
+
+test_valid_value('font-variant', 'annotation(flowing) ornaments(flowing) swash(flowing) character-variant(flowing) styleset(flowing) historical-forms stylistic(flowing)', 'stylistic(flowing) historical-forms styleset(flowing) character-variant(flowing) swash(flowing) ornaments(flowing) annotation(flowing)');
+
+// <numeric-figure-values>
+test_valid_value('font-variant', 'lining-nums');
+test_valid_value('font-variant', 'oldstyle-nums');
+
+// <numeric-spacing-values>
+test_valid_value('font-variant', 'proportional-nums');
+test_valid_value('font-variant', 'tabular-nums');
+
+// <numeric-fraction-values>
+test_valid_value('font-variant', 'diagonal-fractions');
+test_valid_value('font-variant', 'stacked-fractions');
+
+// ordinal
+test_valid_value('font-variant', 'ordinal');
+
+// slashed-zero
+test_valid_value('font-variant', 'slashed-zero');
+
+// <east-asian-variant-values>
+test_valid_value('font-variant', 'jis78');
+test_valid_value('font-variant', 'jis83');
+test_valid_value('font-variant', 'jis90');
+test_valid_value('font-variant', 'jis04');
+test_valid_value('font-variant', 'simplified');
+test_valid_value('font-variant', 'traditional');
+
+// <east-asian-width-values>
+test_valid_value('font-variant', 'full-width');
+test_valid_value('font-variant', 'proportional-width');
+
+// ruby
+test_valid_value('font-variant', 'ruby');
+
+// [ sub | super ]
+test_valid_value('font-variant', 'sub');
+test_valid_value('font-variant', 'super');
+
+
+test_valid_value('font-variant',
+ 'common-ligatures discretionary-ligatures historical-ligatures contextual' +
+ ' small-caps stylistic(flowing) lining-nums proportional-nums diagonal-fractions' +
+ ' ordinal slashed-zero jis78 full-width ruby sub');
+
+test_valid_value('font-variant',
+ 'super proportional-width jis83 stacked-fractions tabular-nums oldstyle-nums historical-forms all-small-caps no-contextual no-historical-ligatures no-discretionary-ligatures no-common-ligatures',
+ [
+ 'no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual all-small-caps historical-forms oldstyle-nums tabular-nums stacked-fractions jis83 proportional-width super',
+ 'no-contextual no-historical-ligatures no-discretionary-ligatures no-common-ligatures all-small-caps historical-forms stacked-fractions tabular-nums oldstyle-nums jis83 proportional-width super'
+ ]
+);
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-computed.html
new file mode 100644
index 0000000000..521461657e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-computed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontVariationSettings</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-variation-settings">
+<meta name="assert" content="font-variation-settings computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('font-variation-settings', 'normal');
+
+test_computed_value('font-variation-settings', '"wght" 700');
+test_computed_value('font-variation-settings', '"AB@D" 0.5');
+
+test_computed_value('font-variation-settings', '"wght" 700, "wght" 500', '"wght" 500',
+ "duplicate values should be removed, keeping the rightmost occurrence.");
+
+test_computed_value('font-variation-settings', '"wght" 700, "XHGT" 0.7',
+ ['"wght" 700, "XHGT" 0.7', '"XHGT" 0.7, "wght" 700']);
+
+test_computed_value('font-variation-settings', '"XHGT" calc(0.4 + 0.3)', '"XHGT" 0.7');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-invalid.html
new file mode 100644
index 0000000000..bd9370b350
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-invalid.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variation-settings with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-variation-settings">
+<meta name="assert" content="font-variation-settings supports only the grammar 'normal | [ <string> <number>] #'.">
+<meta name="assert" content="font-variation-settings strings must have 4 characters.">
+ <script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-variation-settings', '700');
+test_invalid_value('font-variation-settings', '"XHGT"');
+test_invalid_value('font-variation-settings', 'wght 700');
+test_invalid_value('font-variation-settings', 'normal, "wght" 700');
+
+test_invalid_value('font-variation-settings', '"wgt" 700');
+test_invalid_value('font-variation-settings', '"XHGTX" 0.7');
+test_invalid_value('font-variation-settings', '"abc\1F" 0.5');
+test_invalid_value('font-variation-settings', '"abc\7F" 0.5');
+test_invalid_value('font-variation-settings', '"abc\A9" 0.5');
+
+test_invalid_value('font-variation-settings', "'wght' 200 'abcd' 400");
+test_invalid_value('font-variation-settings', "'a' 1234");
+test_invalid_value('font-variation-settings', "'abcde' 1234");
+test_invalid_value('font-variation-settings', "'wght' 200, ");
+test_invalid_value('font-variation-settings', "'abcd\" 123");
+
+test_invalid_value('font-variation-settings', "'wght' 100px");
+test_invalid_value('font-variation-settings', "'wght' calc(100px + 200px)");
+test_invalid_value('font-variation-settings', "'wght' 42%");
+test_invalid_value('font-variation-settings', "'wght' calc(100%)");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-valid.html
new file mode 100644
index 0000000000..fc0c3ef703
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-variation-settings-valid.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing font-variation-settings with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-variation-settings">
+<meta name="assert" content="font-variation-settings supports the full grammar 'normal | [ <string> <number>] #'.">
+<meta name="assert" content="font-variation-settings strings are case sensitive.">
+ <script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-variation-settings', 'normal');
+
+test_valid_value('font-variation-settings', '"wght" 700');
+test_valid_value('font-variation-settings', "'wght' 700", '"wght" 700');
+test_valid_value('font-variation-settings', '"wght" 700, "XHGT" 0.7');
+
+test_valid_value('font-variation-settings', '"a cd" 0.5');
+test_valid_value('font-variation-settings', '"ab@d" 0.5');
+test_valid_value('font-variation-settings', "'wght' 1e3, 'slnt' -450.0e-1", '"wght" 1000, "slnt" -45');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-weight-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-computed.html
new file mode 100644
index 0000000000..08208e5dd4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-computed.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: getComputedStyle().fontWeight</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-weight-prop">
+<meta name="assert" content="font-weight computed value is a number.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="container">
+ <div id="target"></div>
+</div>
+<script>
+'use strict';
+test_computed_value('font-weight', 'normal', '400');
+test_computed_value('font-weight', 'bold', '700');
+test_computed_value('font-weight', '100');
+test_computed_value('font-weight', '200');
+test_computed_value('font-weight', '300');
+test_computed_value('font-weight', '400');
+test_computed_value('font-weight', '500');
+test_computed_value('font-weight', '600');
+test_computed_value('font-weight', '700');
+test_computed_value('font-weight', '800');
+test_computed_value('font-weight', '900');
+
+function test_relative(specified, inherited, computed) {
+ test(() => {
+ const container = document.getElementById('container');
+ const target = document.getElementById('target');
+ container.style.fontWeight = inherited;
+ target.style.fontWeight = specified;
+ assert_equals(getComputedStyle(target).fontWeight, computed);
+ }, inherited + ' made ' + specified + ' computes to ' + computed);
+}
+
+test_relative('bolder', '100', '400');
+test_relative('bolder', '200', '400');
+test_relative('bolder', '300', '400');
+test_relative('bolder', '400', '700');
+test_relative('bolder', '500', '700');
+test_relative('bolder', '600', '900');
+test_relative('bolder', '700', '900');
+test_relative('bolder', '800', '900');
+test_relative('bolder', '900', '900');
+
+test_relative('lighter', '100', '100');
+test_relative('lighter', '200', '100');
+test_relative('lighter', '300', '100');
+test_relative('lighter', '400', '100');
+test_relative('lighter', '500', '100');
+test_relative('lighter', '600', '400');
+test_relative('lighter', '700', '400');
+test_relative('lighter', '800', '700');
+test_relative('lighter', '900', '700');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-weight-invalid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-invalid.html
new file mode 100644
index 0000000000..af81569306
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-weight with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-weight-prop">
+<meta name="assert" content="font-weight supports only the grammar 'normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value('font-weight', 'auto');
+test_invalid_value('font-weight', 'bold 900');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-weight-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-valid.html
new file mode 100644
index 0000000000..090729287b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/parsing/font-weight-valid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 3: parsing font-weight with valid values</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-weight-prop">
+<meta name="assert" content="font-weight supports the full grammar 'normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value('font-weight', 'normal');
+test_valid_value('font-weight', 'bold');
+test_valid_value('font-weight', 'bolder');
+test_valid_value('font-weight', 'lighter');
+test_valid_value('font-weight', '100');
+test_valid_value('font-weight', '200');
+test_valid_value('font-weight', '300');
+test_valid_value('font-weight', '400');
+test_valid_value('font-weight', '500');
+test_valid_value('font-weight', '600');
+test_valid_value('font-weight', '700');
+test_valid_value('font-weight', '800');
+test_valid_value('font-weight', '900');
+</script>
+</body>
+</html>