CSS: more pseudo-element tests

Test ::-webkit-autofill in @supports and add more getComputedStyle() coverage.
diff --git a/css/css-conditional/at-supports-selector-webkit-slider-thumb.tentative.html b/css/css-conditional/at-supports-selector-webkit-slider-thumb.tentative.html
new file mode 100644
index 0000000..3f777a7
--- /dev/null
+++ b/css/css-conditional/at-supports-selector-webkit-slider-thumb.tentative.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>CSS Test (Conditional Rules): In @supports, known -webkit- pseudo elements can be parsed successfully</title>
+<link rel="help" href="https://drafts.csswg.org/css-conditional-3/#at-supports">
+<link rel="match" href="at-supports-001-ref.html">
+<style>
+  div {
+    background:red;
+    height:100px;
+    width:100px;
+  }
+  /* This matches in user agents supporting ::-webkit-slider-thumb. */
+  @supports selector(input::-webkit-slider-thumb) {
+    div { background-color:green; }
+  }
+  /* This should never match. */
+  @supports selector(input::-webkit-asdf) {
+    div { background-color:red; }
+  }
+</style>
+<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+<div></div>
diff --git a/css/cssom/getComputedStyle-pseudo.html b/css/cssom/getComputedStyle-pseudo.html
index 35c5efe..c07347a 100644
--- a/css/cssom/getComputedStyle-pseudo.html
+++ b/css/cssom/getComputedStyle-pseudo.html
@@ -105,24 +105,62 @@
   <ul><li id="pseudo-invalid">Item</li></ul>
 </div>
 <script>
-test(function() {
-  var div = document.getElementById('test');
-  [":before", ":after"].forEach(function(pseudo) {
+test(() => {
+  const div = document.getElementById('test');
+  ["before", "after"].forEach(pseudo => {
+    assert_equals(getComputedStyle(div, pseudo).width, "100px");
+  });
+}, "Resolution of width is correct when pseudo-element argument is ignored (due to no colon)");
+
+test(() => {
+  const div = document.getElementById('test');
+  [
+    ":before ",
+    "::before ",
+    "::before\t",
+    "::before\f",
+    "::before\n",
+    "::before,",
+    "::before,::after",
+    "::before@after",
+    "::before#after",
+    "::\"before\"",
+    "::before\u0000",
+    "::before-->",
+    "::before0",
+  ].forEach(pseudo => {
+    assert_equals(getComputedStyle(div, pseudo).width, "", pseudo);
+  });
+}, "Resolution of width is correct when pseudo-element argument is invalid (due to a trailing token)");
+
+test(() => {
+  const div = document.getElementById('test');
+  [":before", ":after"].forEach(pseudo => {
     assert_equals(getComputedStyle(div, pseudo).width, "50px");
   });
-}, "Resolution of width is correct for ::before and ::after pseudo-elements");
+}, "Resolution of width is correct for ::before and ::after pseudo-elements (single-colon)");
+
+test(() => {
+  const div = document.getElementById('test');
+  ["::before", "::after"].forEach(pseudo => {
+    assert_equals(getComputedStyle(div, pseudo).width, "50px");
+  });
+}, "Resolution of width is correct for ::before and ::after pseudo-elements (double-colon)");
+
 test(function() {
   const div = document.getElementById('test');
   [":bef\\oRE", "::\\000041fter"].forEach(pseudo => {
     assert_equals(getComputedStyle(div, pseudo).width, "50px");
   });
 }, "Pseudo-elements can use the full range of CSS syntax");
+
 test(function() {
   var contents = document.getElementById('contents');
   [":before", ":after"].forEach(function(pseudo) {
     assert_equals(getComputedStyle(contents, pseudo).width, "50px");
   });
 }, "Resolution of width is correct for ::before and ::after pseudo-elements of display: contents elements");
+
 test(function() {
   var has_no_pseudos = document.body;
   has_no_pseudos.style.position = "relative";
@@ -135,6 +173,7 @@
                   "definite size");
   });
 }, "Resolution of nonexistent pseudo-element styles");
+
 test(function() {
   var none = document.getElementById('none');
   [":before", ":after"].forEach(function(pseudo) {
@@ -142,6 +181,7 @@
                   "Pseudo-styles of display: none elements should be correct");
   });
 }, "Resolution of pseudo-element styles in display: none elements");
+
 test(function() {
   var flex = document.getElementById('flex');
   [":before", ":after"].forEach(function(pseudo) {
@@ -149,6 +189,7 @@
                   "Pseudo-styles of display: flex elements should get blockified");
   });
 }, "Item-based blockification of pseudo-elements");
+
 test(function() {
   var flexNoPseudo = document.getElementById('flex-no-pseudo');
   [":before", ":after"].forEach(function(pseudo) {
@@ -156,6 +197,7 @@
                   "Pseudo-styles of display: flex elements should get blockified");
   });
 }, "Item-based blockification of nonexistent pseudo-elements");
+
 test(function() {
   var contentsPseudos = document.getElementById('contents-pseudos');
   [":before", ":after"].forEach(function(pseudo) {
@@ -167,6 +209,7 @@
                   "display: contents in " + pseudo + " should reflect other non-inherited properties in CSSOM");
   });
 }, "display: contents on pseudo-elements");
+
 test(function() {
   var contentsPseudosDynamic = document.getElementById('contents-pseudos-dynamic');
   [":before", ":after"].forEach(function(pseudo) {
@@ -183,8 +226,9 @@
                   "display: contents in " + pseudo + " should reflect other non-inherited properties in CSSOM");
   });
 }, "Dynamically change to display: contents on pseudo-elements");
-test(function() {
-  var div = document.getElementById('test');
+
+test(() => {
+  const div = document.getElementById('test');
   // Note that these assertions deliberately avoid assert_[not_]equals to
   // avoid gCS().length in the failure output.
   assert_true(
@@ -198,6 +242,22 @@
     "Should return an empty style for unknown pseudo-elements starting with colon");
 }, "Unknown pseudo-elements");
 
+test(() => {
+  const div = document.getElementById('test');
+
+  const style1 = getComputedStyle(div, "totallynotapseudo");
+  assert_throws_dom("NoModificationAllowedError", () => style1.color = "1");
+  assert_throws_dom("NoModificationAllowedError", () => style1.margin = "10px");
+
+  const style2 = getComputedStyle(div, "::totallynotapseudo");
+  assert_throws_dom("NoModificationAllowedError", () => style2.color = "1");
+  assert_throws_dom("NoModificationAllowedError", () => style2.margin = "10px");
+
+  const style3 = getComputedStyle(div, ":totallynotapseudo");
+  assert_throws_dom("NoModificationAllowedError", () => style3.color = "1");
+  assert_throws_dom("NoModificationAllowedError", () => style3.margin = "10px");
+}, "CSSStyleDeclaration is immutable");
+
 // If you add a pseudo-element identifier here, don't forget to add the corresponding style rule in
 // <style> above.
 [
@@ -214,7 +274,7 @@
   "view-transition-old(name)",
   "view-transition-new(name)"
 ].forEach(pseudoIdentifier => {
-  test(function() {
+  test(() => {
     assert_implements_optional(CSS.supports(`selector(::${pseudoIdentifier})`), `::${pseudoIdentifier}`);
     const li = document.querySelector('li');
     assert_true(