diff --git a/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini b/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini
index 3a3d15b8406..947e223fb28 100644
--- a/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini
+++ b/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini
@@ -14,9 +14,6 @@
   [Revoke blob URL after creating Request, will fetch]
     expected: FAIL
 
-  [Revoke blob URL after calling fetch, fetch should succeed]
-    expected: FAIL
-
 
 [url-with-fetch.any.html]
   [Untitled]
@@ -37,6 +34,3 @@
   [Revoke blob URL after creating Request, will fetch]
     expected: FAIL
 
-  [Revoke blob URL after calling fetch, fetch should succeed]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 5b8ebce0eb8..53405b9febb 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -110749,6 +110749,18 @@
      {}
     ]
    ],
+   "css/css-contain/contain-size-fieldset-001.html": [
+    [
+     "/css/css-contain/contain-size-fieldset-001.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-fieldset-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-contain/contain-size-flexbox-001.html": [
     [
      "/css/css-contain/contain-size-flexbox-001.html",
@@ -127713,6 +127725,18 @@
      {}
     ]
    ],
+   "css/css-multicol/multicol-under-vertical-rl-scroll.html": [
+    [
+     "/css/css-multicol/multicol-under-vertical-rl-scroll.html",
+     [
+      [
+       "/css/css-multicol/multicol-under-vertical-rl-scroll-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-multicol/multicol-width-001.xht": [
     [
      "/css/css-multicol/multicol-width-001.xht",
@@ -137329,6 +137353,18 @@
      {}
     ]
    ],
+   "css/css-text/tab-size/tab-min-rendered-width-1.html": [
+    [
+     "/css/css-text/tab-size/tab-min-rendered-width-1.html",
+     [
+      [
+       "/css/css-text/tab-size/tab-min-rendered-width-1-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/tab-size/tab-size-integer-001.html": [
     [
      "/css/css-text/tab-size/tab-size-integer-001.html",
@@ -185989,6 +186025,18 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html": [
+    [
+     "/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html",
+     [
+      [
+       "/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html": [
     [
      "/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html",
@@ -186157,6 +186205,18 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html": [
+    [
+     "/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html",
+     [
+      [
+       "/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html": [
     [
      "/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html",
@@ -221103,6 +221163,21 @@
      {}
     ]
    ],
+   "content-security-policy/generic/support/load_img_and_post_result_header.html": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/generic/support/load_img_and_post_result_header.html.sub.headers": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/generic/support/load_img_and_post_result_meta.sub.html": [
+    [
+     {}
+    ]
+   ],
    "content-security-policy/generic/support/log-pass.html": [
     [
      {}
@@ -248288,6 +248363,11 @@
      {}
     ]
    ],
+   "css/css-contain/reference/contain-size-fieldset-001-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-contain/reference/contain-size-flexbox-001-ref.html": [
     [
      {}
@@ -260128,6 +260208,11 @@
      {}
     ]
    ],
+   "css/css-multicol/multicol-under-vertical-rl-scroll-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-multicol/multicol-width-001-ref.xht": [
     [
      {}
@@ -264688,6 +264773,11 @@
      {}
     ]
    ],
+   "css/css-text/tab-size/tab-min-rendered-width-1-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/tab-size/tab-size-integer-001-ref.html": [
     [
      {}
@@ -288928,6 +289018,11 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html": [
+    [
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml": [
     [
      {}
@@ -289018,6 +289113,11 @@
      {}
     ]
    ],
+   "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html": [
+    [
+     {}
+    ]
+   ],
    "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html": [
     [
      {}
@@ -289243,6 +289343,11 @@
      {}
     ]
    ],
+   "html/semantics/document-metadata/the-link-element/resources/css.py": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/document-metadata/the-link-element/resources/empty-href.css": [
     [
      {}
@@ -289263,6 +289368,11 @@
      {}
     ]
    ],
+   "html/semantics/document-metadata/the-link-element/resources/link-style-error.js": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/document-metadata/the-link-element/resources/stylesheet.css": [
     [
      {}
@@ -291448,6 +291558,11 @@
      {}
     ]
    ],
+   "html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/scripting-1/the-script-element/module/resources/fast-module.js": [
     [
      {}
@@ -296493,6 +296608,11 @@
      {}
     ]
    ],
+   "referrer-policy/css-integration/css-test-helper.js": [
+    [
+     {}
+    ]
+   ],
    "referrer-policy/generic/common.js": [
     [
      {}
@@ -296518,6 +296638,11 @@
      {}
     ]
    ],
+   "referrer-policy/generic/subresource/font.py": [
+    [
+     {}
+    ]
+   ],
    "referrer-policy/generic/subresource/image.py": [
     [
      {}
@@ -296538,6 +296663,11 @@
      {}
     ]
    ],
+   "referrer-policy/generic/subresource/svg.py": [
+    [
+     {}
+    ]
+   ],
    "referrer-policy/generic/subresource/worker.py": [
     [
      {}
@@ -296558,6 +296688,16 @@
      {}
     ]
    ],
+   "referrer-policy/generic/template/font.css.template": [
+    [
+     {}
+    ]
+   ],
+   "referrer-policy/generic/template/image.css.template": [
+    [
+     {}
+    ]
+   ],
    "referrer-policy/generic/template/script.js.template": [
     [
      {}
@@ -296568,7 +296708,12 @@
      {}
     ]
    ],
-   "referrer-policy/generic/template/stylesheet.css.template": [
+   "referrer-policy/generic/template/svg.css.template": [
+    [
+     {}
+    ]
+   ],
+   "referrer-policy/generic/template/svg.embedded.template": [
     [
      {}
     ]
@@ -299703,6 +299848,11 @@
      {}
     ]
    ],
+   "resources/test/tests/functional/log-insertion.html": [
+    [
+     {}
+    ]
+   ],
    "resources/test/tests/functional/order.html": [
     [
      {}
@@ -313493,41 +313643,6 @@
      {}
     ]
    ],
-   "webdriver/tests/actions/__init__.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/conftest.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/support/__init__.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/support/keys.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/support/mouse.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/support/refine.py": [
-    [
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/support/test_actions_wdspec.html": [
-    [
-     {}
-    ]
-   ],
    "webdriver/tests/add_cookie/__init__.py": [
     [
      {}
@@ -313773,11 +313888,71 @@
      {}
     ]
    ],
+   "webdriver/tests/perform_actions/__init__.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/conftest.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/support/__init__.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/support/keys.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/support/mouse.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/support/refine.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/support/test_actions_wdspec.html": [
+    [
+     {}
+    ]
+   ],
    "webdriver/tests/refresh/__init__.py": [
     [
      {}
     ]
    ],
+   "webdriver/tests/release_actions/__init__.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/release_actions/conftest.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/release_actions/support/__init__.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/release_actions/support/refine.py": [
+    [
+     {}
+    ]
+   ],
+   "webdriver/tests/release_actions/support/test_actions_wdspec.html": [
+    [
+     {}
+    ]
+   ],
    "webdriver/tests/send_alert_text/__init__.py": [
     [
      {}
@@ -328702,6 +328877,12 @@
      {}
     ]
    ],
+   "content-security-policy/generic/only-valid-whitespaces-are-allowed.html": [
+    [
+     "/content-security-policy/generic/only-valid-whitespaces-are-allowed.html",
+     {}
+    ]
+   ],
    "content-security-policy/generic/policy-does-not-affect-child.sub.html": [
     [
      "/content-security-policy/generic/policy-does-not-affect-child.sub.html",
@@ -331790,6 +331971,12 @@
      {}
     ]
    ],
+   "css/css-animations/historical.html": [
+    [
+     "/css/css-animations/historical.html",
+     {}
+    ]
+   ],
    "css/css-animations/idlharness.html": [
     [
      "/css/css-animations/idlharness.html",
@@ -333756,6 +333943,54 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-alignment-style-changes-001.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-001.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-002.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-002.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-003.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-003.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-004.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-004.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-005.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-005.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-006.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-006.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-007.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-007.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-alignment-style-changes-008.html": [
+    [
+     "/css/css-grid/alignment/grid-alignment-style-changes-008.html",
+     {}
+    ]
+   ],
    "css/css-grid/alignment/grid-column-axis-alignment-positioned-items-001.html": [
     [
      "/css/css-grid/alignment/grid-column-axis-alignment-positioned-items-001.html",
@@ -334518,6 +334753,12 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html": [
+    [
+     "/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html",
+     {}
+    ]
+   ],
    "css/css-grid/grid-definition/grid-change-fit-content-argument-001.html": [
     [
      "/css/css-grid/grid-definition/grid-change-fit-content-argument-001.html",
@@ -336624,6 +336865,12 @@
      {}
     ]
    ],
+   "css/css-tables/caption-writing-mode-001.html": [
+    [
+     "/css/css-tables/caption-writing-mode-001.html",
+     {}
+    ]
+   ],
    "css/css-tables/fixed-layout-1.html": [
     [
      "/css/css-tables/fixed-layout-1.html",
@@ -338550,6 +338797,12 @@
      {}
     ]
    ],
+   "css/css-transitions/transitionevent-interface.html": [
+    [
+     "/css/css-transitions/transitionevent-interface.html",
+     {}
+    ]
+   ],
    "css/css-transitions/transitions-animatable-properties-01.html": [
     [
      "/css/css-transitions/transitions-animatable-properties-01.html",
@@ -343940,6 +344193,12 @@
      {}
     ]
    ],
+   "dom/events/shadow-relatedTarget.html": [
+    [
+     "/dom/events/shadow-relatedTarget.html",
+     {}
+    ]
+   ],
    "dom/historical.html": [
     [
      "/dom/historical.html",
@@ -360890,6 +361149,18 @@
      {}
     ]
    ],
+   "html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html": [
+    [
+     "/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html",
+     {}
+    ]
+   ],
+   "html/semantics/document-metadata/the-link-element/link-style-error-quirks.html": [
+    [
+     "/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html",
+     {}
+    ]
+   ],
    "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html": [
     [
      "/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html",
@@ -363610,6 +363881,12 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html": [
+    [
+     "/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html",
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/the-iframe-element/iframe-synchronously-discard.html": [
     [
      "/html/semantics/embedded-content/the-iframe-element/iframe-synchronously-discard.html",
@@ -366668,6 +366945,12 @@
      {}
     ]
    ],
+   "html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html": [
+    [
+     "/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html",
+     {}
+    ]
+   ],
    "html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html": [
     [
      "/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html",
@@ -368995,7 +369278,9 @@
    "html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html": [
     [
      "/html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html",
-     {}
+     {
+      "timeout": "long"
+     }
     ]
    ],
    "html/syntax/parsing/the-end.html": [
@@ -371438,6 +371723,12 @@
      {}
     ]
    ],
+   "media-capabilities/encodingInfo.html": [
+    [
+     "/media-capabilities/encodingInfo.html",
+     {}
+    ]
+   ],
    "media-capabilities/idlharness.any.js": [
     [
      "/media-capabilities/idlharness.any.html",
@@ -374964,6 +375255,18 @@
      {}
     ]
    ],
+   "navigation-timing/dom_interactive_image_document.html": [
+    [
+     "/navigation-timing/dom_interactive_image_document.html",
+     {}
+    ]
+   ],
+   "navigation-timing/dom_interactive_media_document.html": [
+    [
+     "/navigation-timing/dom_interactive_media_document.html",
+     {}
+    ]
+   ],
    "navigation-timing/idlharness.window.js": [
     [
      "/navigation-timing/idlharness.window.html",
@@ -385114,6 +385417,12 @@
      {}
     ]
    ],
+   "payment-method-id/payment-request-ctor-pmi-handling.https.html": [
+    [
+     "/payment-method-id/payment-request-ctor-pmi-handling.https.html",
+     {}
+    ]
+   ],
    "payment-request/MerchantValidationEvent/complete-method.https.html": [
     [
      "/payment-request/MerchantValidationEvent/complete-method.https.html",
@@ -386004,45 +386313,123 @@
      {}
     ]
    ],
-   "referrer-policy/css-integration/external-import-stylesheet.html": [
+   "referrer-policy/css-integration/child-css/external-import-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/external-import-stylesheet.html",
+     "/referrer-policy/css-integration/child-css/external-import-stylesheet.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/external-stylesheet.html": [
+   "referrer-policy/css-integration/child-css/internal-import-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/external-stylesheet.html",
+     "/referrer-policy/css-integration/child-css/internal-import-stylesheet.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/inline-style.html": [
+   "referrer-policy/css-integration/child-css/processing-instruction.html": [
     [
-     "/referrer-policy/css-integration/inline-style.html",
+     "/referrer-policy/css-integration/child-css/processing-instruction.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/internal-import-stylesheet.html": [
+   "referrer-policy/css-integration/font-face/external-import-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/internal-import-stylesheet.html",
+     "/referrer-policy/css-integration/font-face/external-import-stylesheet.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/internal-stylesheet.html": [
+   "referrer-policy/css-integration/font-face/external-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/internal-stylesheet.html",
+     "/referrer-policy/css-integration/font-face/external-stylesheet.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/presentation-attribute.html": [
+   "referrer-policy/css-integration/font-face/internal-import-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/presentation-attribute.html",
+     "/referrer-policy/css-integration/font-face/internal-import-stylesheet.html",
      {}
     ]
    ],
-   "referrer-policy/css-integration/processing-instruction.html": [
+   "referrer-policy/css-integration/font-face/internal-stylesheet.html": [
     [
-     "/referrer-policy/css-integration/processing-instruction.html",
+     "/referrer-policy/css-integration/font-face/internal-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/font-face/processing-instruction.html": [
+    [
+     "/referrer-policy/css-integration/font-face/processing-instruction.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/external-import-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/image/external-import-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/external-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/image/external-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/inline-style.html": [
+    [
+     "/referrer-policy/css-integration/image/inline-style.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/internal-import-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/image/internal-import-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/internal-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/image/internal-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/presentation-attribute.html": [
+    [
+     "/referrer-policy/css-integration/image/presentation-attribute.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/image/processing-instruction.html": [
+    [
+     "/referrer-policy/css-integration/image/processing-instruction.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/svg/external-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/svg/external-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/svg/inline-style.html": [
+    [
+     "/referrer-policy/css-integration/svg/inline-style.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/svg/internal-stylesheet.html": [
+    [
+     "/referrer-policy/css-integration/svg/internal-stylesheet.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/svg/presentation-attribute.html": [
+    [
+     "/referrer-policy/css-integration/svg/presentation-attribute.html",
+     {}
+    ]
+   ],
+   "referrer-policy/css-integration/svg/processing-instruction.html": [
+    [
+     "/referrer-policy/css-integration/svg/processing-instruction.html",
      {}
     ]
    ],
@@ -400628,19 +401015,19 @@
      {}
     ]
    ],
-   "wasm/jsapi/global/value-set.any.js": [
+   "wasm/jsapi/global/value-get-set.any.js": [
     [
-     "/wasm/jsapi/global/value-set.any.html",
+     "/wasm/jsapi/global/value-get-set.any.html",
      {}
     ],
     [
-     "/wasm/jsapi/global/value-set.any.js",
+     "/wasm/jsapi/global/value-get-set.any.js",
      {
       "jsshell": true
      }
     ],
     [
-     "/wasm/jsapi/global/value-set.any.worker.html",
+     "/wasm/jsapi/global/value-get-set.any.worker.html",
      {}
     ]
    ],
@@ -430848,82 +431235,6 @@
      {}
     ]
    ],
-   "webdriver/tests/actions/control_click.py": [
-    [
-     "/webdriver/tests/actions/control_click.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/key.py": [
-    [
-     "/webdriver/tests/actions/key.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/key_shortcuts.py": [
-    [
-     "/webdriver/tests/actions/key_shortcuts.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/modifier_click.py": [
-    [
-     "/webdriver/tests/actions/modifier_click.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/mouse.py": [
-    [
-     "/webdriver/tests/actions/mouse.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/mouse_dblclick.py": [
-    [
-     "/webdriver/tests/actions/mouse_dblclick.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/mouse_pause_dblclick.py": [
-    [
-     "/webdriver/tests/actions/mouse_pause_dblclick.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/none.py": [
-    [
-     "/webdriver/tests/actions/none.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/pointer_origin.py": [
-    [
-     "/webdriver/tests/actions/pointer_origin.py",
-     {}
-    ]
-   ],
-   "webdriver/tests/actions/sequence.py": [
-    [
-     "/webdriver/tests/actions/sequence.py",
-     {
-      "timeout": "long"
-     }
-    ]
-   ],
-   "webdriver/tests/actions/special_keys.py": [
-    [
-     "/webdriver/tests/actions/special_keys.py",
-     {
-      "timeout": "long"
-     }
-    ]
-   ],
-   "webdriver/tests/actions/validity.py": [
-    [
-     "/webdriver/tests/actions/validity.py",
-     {}
-    ]
-   ],
    "webdriver/tests/add_cookie/add.py": [
     [
      "/webdriver/tests/add_cookie/add.py",
@@ -431492,6 +431803,94 @@
      {}
     ]
    ],
+   "webdriver/tests/perform_actions/key.py": [
+    [
+     "/webdriver/tests/perform_actions/key.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/key_events.py": [
+    [
+     "/webdriver/tests/perform_actions/key_events.py",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
+   "webdriver/tests/perform_actions/key_modifiers.py": [
+    [
+     "/webdriver/tests/perform_actions/key_modifiers.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/key_shortcuts.py": [
+    [
+     "/webdriver/tests/perform_actions/key_shortcuts.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/key_special_keys.py": [
+    [
+     "/webdriver/tests/perform_actions/key_special_keys.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/none.py": [
+    [
+     "/webdriver/tests/perform_actions/none.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer_contextmenu.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer_contextmenu.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer_dblclick.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer_dblclick.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer_modifier_click.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer_modifier_click.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer_origin.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer_origin.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/pointer_pause_dblclick.py": [
+    [
+     "/webdriver/tests/perform_actions/pointer_pause_dblclick.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/perform_actions/sequence.py": [
+    [
+     "/webdriver/tests/perform_actions/sequence.py",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
+   "webdriver/tests/perform_actions/validity.py": [
+    [
+     "/webdriver/tests/perform_actions/validity.py",
+     {}
+    ]
+   ],
    "webdriver/tests/refresh/refresh.py": [
     [
      "/webdriver/tests/refresh/refresh.py",
@@ -431506,6 +431905,20 @@
      }
     ]
    ],
+   "webdriver/tests/release_actions/release.py": [
+    [
+     "/webdriver/tests/release_actions/release.py",
+     {}
+    ]
+   ],
+   "webdriver/tests/release_actions/sequence.py": [
+    [
+     "/webdriver/tests/release_actions/sequence.py",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
    "webdriver/tests/send_alert_text/send.py": [
     [
      "/webdriver/tests/send_alert_text/send.py",
@@ -461001,6 +461414,10 @@
    "a7337acceb93238bb5105f335e5b25323d99619b",
    "support"
   ],
+  "content-security-policy/generic/only-valid-whitespaces-are-allowed.html": [
+   "d7567a93a377b2ec3c360d2ef030618a4046c8aa",
+   "testharness"
+  ],
   "content-security-policy/generic/pass-0_1.js": [
    "3a08dd5621ff4150fc0c974398df81bfc033eaeb",
    "support"
@@ -461021,6 +461438,18 @@
    "63c99919623e396a41870273e35e3e8999a712f0",
    "support"
   ],
+  "content-security-policy/generic/support/load_img_and_post_result_header.html": [
+   "c7a2e75dba37c85ae1710d92a2a8071ea229bf85",
+   "support"
+  ],
+  "content-security-policy/generic/support/load_img_and_post_result_header.html.sub.headers": [
+   "e9bf21bab413b87e0c936ad93d26629b3a6bf59b",
+   "support"
+  ],
+  "content-security-policy/generic/support/load_img_and_post_result_meta.sub.html": [
+   "ac0cf39dd038626d111d842f4e24ac5446154eed",
+   "support"
+  ],
   "content-security-policy/generic/support/log-pass.html": [
    "4334ea4c66b53bc02382189839feaf261fa504d4",
    "support"
@@ -525642,7 +526071,7 @@
    "testharness"
   ],
   "css/css-animations/animationevent-interface.js": [
-   "56d30a4a37770fa2a32698d5401246e882e1f6e0",
+   "e35b7fcb0f98656cdeff41d8d7f4a7620fa52eea",
    "support"
   ],
   "css/css-animations/animationevent-pseudoelement.html": [
@@ -525665,6 +526094,10 @@
    "93d452ace07163b10af18245d6799d9823448e1e",
    "testharness"
   ],
+  "css/css-animations/historical.html": [
+   "5b96a422f55f45cddabdf011acb83e5081ec1ef3",
+   "testharness"
+  ],
   "css/css-animations/idlharness.html": [
    "1d3ed2b9b806792c7efaeeee9ab264101dd222bc",
    "testharness"
@@ -525962,7 +526395,7 @@
    "support"
   ],
   "css/css-backgrounds/background-clip-color-repaint.html": [
-   "6052db526a3a4d0f35bf5c433f718b257049514d",
+   "4a5cee080096d1bec9c07655b988ab163e9e6131",
    "reftest"
   ],
   "css/css-backgrounds/background-clip-color.html": [
@@ -530817,6 +531250,10 @@
    "1e4965e9daf380aec19cf43902c409ad6b457370",
    "reftest"
   ],
+  "css/css-contain/contain-size-fieldset-001.html": [
+   "f92424716ce55fdfbc0ad9954ab2893d63b389b2",
+   "reftest"
+  ],
   "css/css-contain/contain-size-flexbox-001.html": [
    "31e82f5d24c4aa673291a2ce25c660cf10977e28",
    "reftest"
@@ -531061,6 +531498,10 @@
    "1cbaaccd1a0751c5dadf913e1fc31d130ff95259",
    "support"
   ],
+  "css/css-contain/reference/contain-size-fieldset-001-ref.html": [
+   "85f5c73c2ece9a324511356d6f33798b3cfbe811",
+   "support"
+  ],
   "css/css-contain/reference/contain-size-flexbox-001-ref.html": [
    "85628b59c48f7931e7d3e5a498da60cc264dc363",
    "support"
@@ -544701,6 +545142,38 @@
    "634e5c7e1b5151d2c37e4622535f51e85c8cad89",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-alignment-style-changes-001.html": [
+   "25ce0619dbf6184219b0b430d6495c09c5c2c657",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-002.html": [
+   "c97be7ddb81bfc3331bf5a438e75bc365c03079c",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-003.html": [
+   "bca78d76569efb1b12cc3570cde394233db18345",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-004.html": [
+   "3064f42396f6da1e3c111a3979da839f43733711",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-005.html": [
+   "550eed73f50e6d4c7f4e600c15e7ae33f11a03e2",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-006.html": [
+   "1df78c051f7ddd0c0a38bea6913bdf7351ecf80b",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-007.html": [
+   "4d0231bf393249b6756c30973ce08f58bfd115f3",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-alignment-style-changes-008.html": [
+   "026f035ba925433e99ed23ea7d64bfeb76121083",
+   "testharness"
+  ],
   "css/css-grid/alignment/grid-column-axis-alignment-positioned-items-001.html": [
    "32ea4e34820c2d3ccab5d8575f818e63fc0bd57f",
    "testharness"
@@ -545453,6 +545926,10 @@
    "3232913cb1328c0367f09ca8996b8c22e09cc2e0",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html": [
+   "5ffacfdb2b45dbb5fe259a2255456a993313c615",
+   "testharness"
+  ],
   "css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-001.html": [
    "a7d69063189d78e4a2d9bfe080df9e9731569ac8",
    "reftest"
@@ -545506,7 +545983,7 @@
    "support"
   ],
   "css/css-grid/alignment/support/style-change.js": [
-   "5619394da2bc9c5d5902db03e6dcf257e63c303f",
+   "766d140d2b239bcc0c11e92481c5ff302d12db5c",
    "support"
   ],
   "css/css-grid/grid-definition/fr-unit-with-percentage.html": [
@@ -549405,6 +549882,14 @@
    "ab68c7a74317249187a3cfb419539f21f073d306",
    "support"
   ],
+  "css/css-multicol/multicol-under-vertical-rl-scroll-ref.html": [
+   "1a7cfb6e2303ce8778fed9587e208a7df950ff6f",
+   "support"
+  ],
+  "css/css-multicol/multicol-under-vertical-rl-scroll.html": [
+   "f96a26ae77be3b8171335f07efefce4bc0bef937",
+   "reftest"
+  ],
   "css/css-multicol/multicol-width-001-ref.xht": [
    "dddb96880af819d730b83604a487c4938fda4933",
    "support"
@@ -550794,7 +551279,7 @@
    "testharness"
   ],
   "css/css-properties-values-api/registered-properties-inheritance.html": [
-   "8f9eafee19e5c2500811f05723902808a27760df",
+   "614a72a797bc91a76742efc990e07669bee87c11",
    "testharness"
   ],
   "css/css-properties-values-api/registered-property-computation.html": [
@@ -550834,7 +551319,7 @@
    "testharness"
   ],
   "css/css-properties-values-api/unit-cycles.html": [
-   "d65348543c4145bbd693aac67372390bfd91fc11",
+   "c26e1cda1f6842655e7e0158d6a934e470f486ae",
    "testharness"
   ],
   "css/css-properties-values-api/url-resolution.html": [
@@ -550846,7 +551331,7 @@
    "testharness"
   ],
   "css/css-properties-values-api/var-reference-registered-properties.html": [
-   "d8a831571252cdeb3e6c3c6e582a2b74376e905c",
+   "5de6d20f11b1aec41c7b54653ef482db6c7d8c93",
    "testharness"
   ],
   "css/css-pseudo/META.yml": [
@@ -555389,6 +555874,10 @@
    "302e51ae239307a49c239bf0ad5ade17a5c9d940",
    "testharness"
   ],
+  "css/css-tables/caption-writing-mode-001.html": [
+   "835a5116ae36bca9f92698b7766d0b65f1514f9f",
+   "testharness"
+  ],
   "css/css-tables/fixed-layout-1.html": [
    "3e0d013af1c6970a1180cf19db37e8e7b82cc0c0",
    "testharness"
@@ -558633,6 +559122,14 @@
    "59843ae54b64f6ce4f7e616d4be491c911ea84cf",
    "support"
   ],
+  "css/css-text/tab-size/tab-min-rendered-width-1-ref.html": [
+   "7623adb59e65bed4787a9105ce54caa8fed63fa8",
+   "support"
+  ],
+  "css/css-text/tab-size/tab-min-rendered-width-1.html": [
+   "6b014260e3678e579110cf16cfed5413a02c3d01",
+   "reftest"
+  ],
   "css/css-text/tab-size/tab-size-integer-001-ref.html": [
    "db1d6b0ed5b9f16779841931ef5a999dbcd1ea50",
    "support"
@@ -566353,6 +566850,10 @@
    "abc2f38b956096a4e09826c2e812dd8c606c0911",
    "testharness"
   ],
+  "css/css-transitions/transitionevent-interface.html": [
+   "cd47469ec742106ace7d904dc588d746ac514ba5",
+   "testharness"
+  ],
   "css/css-transitions/transitions-animatable-properties-01.html": [
    "534f81839ac875ff6b5c5c7b17784258d7a8932c",
    "testharness"
@@ -591254,7 +591755,7 @@
    "support"
   ],
   "docs/_writing-tests/testharness-api.md": [
-   "952c8365fb7028c00eeca7ee5949310ecce95913",
+   "9f93ea844d7395b5f2461b342805c7371cb90727",
    "support"
   ],
   "docs/_writing-tests/testharness.md": [
@@ -591585,6 +592086,10 @@
    "241dda8b66f8c8fe128e736bcb073479aee634a9",
    "support"
   ],
+  "dom/events/shadow-relatedTarget.html": [
+   "713555b7d8ab6117d12c70d08185335246e44e1a",
+   "testharness"
+  ],
   "dom/historical.html": [
    "921fa07b3f6de0f9a579b75b14d6509039765205",
    "testharness"
@@ -595782,7 +596287,7 @@
    "testharness"
   ],
   "eventsource/eventsource-prototype.htm": [
-   "38f63eb5f0053c737e4e9f89755b4906f9bcf8f6",
+   "24bf9954007d6aeb2087484bd805d0f26f89cbe2",
    "testharness"
   ],
   "eventsource/eventsource-reconnect.htm": [
@@ -597430,7 +597935,7 @@
    "testharness"
   ],
   "fetch/corb/script-html-via-cross-origin-blob-url.sub.html": [
-   "8ce7987ff89d456fb166427f174c38f0fc327bcf",
+   "c8a90c79b3f7f5136dbad30dd3299fc57365b272",
    "testharness"
   ],
   "fetch/corb/script-js-mislabeled-as-html-nosniff.sub.html": [
@@ -598498,7 +599003,7 @@
    "manual"
   ],
   "fullscreen/api/document-exit-fullscreen-timing-manual.html": [
-   "7a536363a213782bde010c93bc26677b62bb2f2a",
+   "6ccc365c711500024898c336d0cbe8679c2cf32c",
    "manual"
   ],
   "fullscreen/api/document-exit-fullscreen-twice-manual.html": [
@@ -598534,7 +599039,7 @@
    "manual"
   ],
   "fullscreen/api/element-ready-check-containing-iframe-manual.html": [
-   "8ba2ab71b158603e1af466d69b91412626ff8722",
+   "0649549265682b7eb8c0f851603d816e89e1cf47",
    "manual"
   ],
   "fullscreen/api/element-ready-check-fullscreen-element-sibling-manual.html": [
@@ -598554,7 +599059,7 @@
    "manual"
   ],
   "fullscreen/api/element-ready-check-not-allowed-manual.html": [
-   "1e18be5e677b3b27c553e961f71ae44d85225a8e",
+   "fa5a923b2b2641b8d3181c587560a554ab621b3e",
    "manual"
   ],
   "fullscreen/api/element-ready-check-not-in-document-manual.html": [
@@ -598566,7 +599071,7 @@
    "testharness"
   ],
   "fullscreen/api/element-request-fullscreen-and-exit-iframe-manual.html": [
-   "dc2a99c1e83369ca72d3ea564e056cd21cba63ab",
+   "6d5bed19f3b12c0b83dfb29cb0df282d52980ef3",
    "manual"
   ],
   "fullscreen/api/element-request-fullscreen-and-move-manual.html": [
@@ -598622,7 +599127,7 @@
    "manual"
   ],
   "fullscreen/api/element-request-fullscreen-timing-manual.html": [
-   "359b688b42722678182b7809baca65c64a59c824",
+   "1ebf7518c3c0712994dafdcd2bf02a467b4aae9e",
    "manual"
   ],
   "fullscreen/api/element-request-fullscreen-top-manual.html": [
@@ -598666,7 +599171,7 @@
    "testharness"
   ],
   "fullscreen/model/move-to-fullscreen-iframe-manual.html": [
-   "69082cacc2b451556ad0675f9fb876dcf3136d92",
+   "59b2c4330f25bd3811cd088fcabd925022038947",
    "manual"
   ],
   "fullscreen/model/move-to-iframe-manual.html": [
@@ -598714,7 +599219,7 @@
    "manual"
   ],
   "fullscreen/rendering/ua-style-iframe-manual.html": [
-   "bf93aa28c3f10e65cf975f5a14833eff7b9ee688",
+   "f2a227437a5455e530e46cb0ff06d1ec18fc9bab",
    "manual"
   ],
   "fullscreen/trusted-click.js": [
@@ -600114,11 +600619,11 @@
    "testharness"
   ],
   "html/browsers/history/the-history-interface/001.html": [
-   "0e5632bbcdffdd6d7ab808a12bb65a8441234162",
+   "7273593547964e92b0e69fbeb018f3b5905dec00",
    "testharness"
   ],
   "html/browsers/history/the-history-interface/002.html": [
-   "eb0c15aab896969b0d8f6561860bbf55c46301f3",
+   "c5bae3407c89989466b5ca1897a0c93f889d9988",
    "testharness"
   ],
   "html/browsers/history/the-history-interface/004.html": [
@@ -607697,6 +608202,14 @@
    "59c5ca70d41cc969aed7ac6a531c1ca9a5f82f0f",
    "reftest"
   ],
+  "html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html": [
+   "2f313f3395ff237c131fdf7646b07541734e5dad",
+   "support"
+  ],
+  "html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html": [
+   "5f131e6658ae1bc7f013974d6975122d5cba2c97",
+   "reftest"
+  ],
   "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml": [
    "f5b533c377160c77541187a301647e174069bd6d",
    "support"
@@ -607905,6 +608418,14 @@
    "edd2600d4a0749d281e7ed1b4da4aefbd7c686ba",
    "testharness"
   ],
+  "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html": [
+   "8023c5255ff2db03f315246ecb7cfdea829f08cc",
+   "support"
+  ],
+  "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html": [
+   "ba58d353a01f2b284e5c296455e6b54b6f705d0b",
+   "reftest"
+  ],
   "html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html": [
    "ee76e93b64e1da9ab5883c328d9fff1eb865acb1",
    "support"
@@ -608418,13 +608939,25 @@
    "testharness"
   ],
   "html/semantics/document-metadata/the-link-element/link-style-error-01.html": [
-   "7a86a86381d85426c20f0cf1c031e316226777c0",
+   "575324d761a15fb2a793d306306804091882e6ca",
+   "testharness"
+  ],
+  "html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html": [
+   "d3c520ba75f56c3e4a33e63716a476a2176ce7a9",
+   "testharness"
+  ],
+  "html/semantics/document-metadata/the-link-element/link-style-error-quirks.html": [
+   "ae2efa415ee51e4b2b54df2f3f90965746b43ed3",
    "testharness"
   ],
   "html/semantics/document-metadata/the-link-element/resources/bad.css": [
    "4e1fe36165c52792e3a3816962c36e6090f04f67",
    "support"
   ],
+  "html/semantics/document-metadata/the-link-element/resources/css.py": [
+   "eb981373a3e2b1694a295d58b4d5baf4c3c5a034",
+   "support"
+  ],
   "html/semantics/document-metadata/the-link-element/resources/empty-href.css": [
    "60f1eab97137f7dc51fc53c8e4f3e49f63342c38",
    "support"
@@ -608441,6 +608974,10 @@
    "fa95e11ba9ef9a5106663a6a0c00f21a1b9ac577",
    "support"
   ],
+  "html/semantics/document-metadata/the-link-element/resources/link-style-error.js": [
+   "d1fa5ac2d6fcb4d94561c18b2d2e22a5a2afd6e3",
+   "support"
+  ],
   "html/semantics/document-metadata/the-link-element/resources/stylesheet.css": [
    "e1b2552ffea7300e3ffba041dd3e5d3ab26c2c33",
    "support"
@@ -609794,7 +610331,7 @@
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html": [
-   "6794126473087f6b3f37cbff4f6481a3bd3a027a",
+   "a9cd73435a3aa3921edc70b76bb8e9a84a21a000",
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-css-cue-pseudo-class.html": [
@@ -611025,6 +611562,10 @@
    "d245bf0b96451b3419e0e69bda86fe4859c9cbfe",
    "testharness"
   ],
+  "html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html": [
+   "57189a0b884d3a55e4bb2ba1a1d3aa83066c0eb3",
+   "testharness"
+  ],
   "html/semantics/embedded-content/the-iframe-element/iframe-synchronously-discard.html": [
    "c339525ebd177ac6249b4cf802b89881bfd99b1a",
    "testharness"
@@ -612218,7 +612759,7 @@
    "testharness"
   ],
   "html/semantics/forms/the-form-element/form-autocomplete.html": [
-   "5c1d05b301e78cea0970535883602844eb0dc801",
+   "618aa0a6c4793701fb1c16fe5924482c94a99e46",
    "testharness"
   ],
   "html/semantics/forms/the-form-element/form-checkvalidity.html": [
@@ -614054,7 +614595,7 @@
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/credentials.sub.html": [
-   "1293d7f6913453118f2adf4e3453be250053278c",
+   "cf23e67ae40c59c7707e90bba642fc4f18ff99ae",
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/crossorigin-common.js": [
@@ -614137,6 +614678,10 @@
    "6a01495c333d196313d2d26f1ec101e15d224699",
    "testharness"
   ],
+  "html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html": [
+   "b939a3ef1639db8027519ac004cd3197e254c0b9",
+   "testharness"
+  ],
   "html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html": [
    "5cc600c5a3db0cdc96de0b957db654aa733a39e0",
    "testharness"
@@ -614658,13 +615203,17 @@
    "support"
   ],
   "html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html": [
-   "f086e702822a42d318396d2aeb348ffac0276a05",
+   "8a0506ccec63b1c7f04b3818e980d0faea45f5eb",
    "support"
   ],
   "html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py": [
    "6ed16212d719203dc9c8b385ee044edff5accf55",
    "support"
   ],
+  "html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html": [
+   "836ece62c5f601b91a9f255f4e6a646160fa7f48",
+   "support"
+  ],
   "html/semantics/scripting-1/the-script-element/module/resources/fast-module.js": [
    "3a76cf71f6c592ce15e2bd2bd158ef4945c9d96b",
    "support"
@@ -616154,7 +616703,7 @@
    "testharness"
   ],
   "html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html": [
-   "e1f9995117f7b9974576e7e4ffb3d01e15b2deaa",
+   "bec3364adffec6c3ea66fb3e3f5bcaa6d244a3da",
    "testharness"
   ],
   "html/syntax/parsing/test.js": [
@@ -618954,7 +619503,7 @@
    "support"
   ],
   "lint.whitelist": [
-   "e39672d0c6eebcba441c089ce358cf5b2dcf79dd",
+   "46c2550e72884c3f060b0fc7355f44562d2803d4",
    "support"
   ],
   "longtask-timing/META.yml": [
@@ -619550,7 +620099,11 @@
    "support"
   ],
   "media-capabilities/decodingInfo.html": [
-   "f3fca4184e4c3f56db700dae390a7416bc3a910a",
+   "982bc1746685871bfa424c88b6eab8d1d00478de",
+   "testharness"
+  ],
+  "media-capabilities/encodingInfo.html": [
+   "5c0e3189082eda87fe44a77262f3b4156783fa39",
    "testharness"
   ],
   "media-capabilities/idlharness.any.js": [
@@ -620326,7 +620879,7 @@
    "testharness"
   ],
   "mediacapture-streams/MediaStream-default-feature-policy.https.html": [
-   "0b45ac6f594a695b28545ee3a99c0c6a7f8bbc12",
+   "21e3f5b9af8567cb015604bbcb021cc04216e4c2",
    "testharness"
   ],
   "mediacapture-streams/MediaStream-finished-add.https.html": [
@@ -623149,6 +623702,14 @@
    "c09a6e03fd19f5a405b391c2c4671df6ff04edf1",
    "support"
   ],
+  "navigation-timing/dom_interactive_image_document.html": [
+   "36742f0eff6d07c7c0694b066dfa017f0d1042be",
+   "testharness"
+  ],
+  "navigation-timing/dom_interactive_media_document.html": [
+   "e4e45725d83605b519ce74ea8ff4561dcd3d7595",
+   "testharness"
+  ],
   "navigation-timing/idlharness.window.js": [
    "8cc3546b3c27a9d93ee5621584d83d56a308513c",
    "testharness"
@@ -630385,6 +630946,10 @@
    "3d1bb8ddda2b999858fba14ec9420f127fb5dd13",
    "support"
   ],
+  "payment-method-id/payment-request-ctor-pmi-handling.https.html": [
+   "5f888f0389f6c756ede8c3e481ece7bcf8b71ccf",
+   "testharness"
+  ],
   "payment-request/META.yml": [
    "f8460d403ffa42d9dfc1bae6e0c3e500f7742fc9",
    "support"
@@ -630818,7 +631383,7 @@
    "testharness"
   ],
   "picture-in-picture/request-picture-in-picture.html": [
-   "a0c3217603b8fdb3529d5aa456226cda4109722d",
+   "403d416c7d454fb0a6a2f8442cc23c53f83212e1",
    "testharness"
   ],
   "picture-in-picture/resources/picture-in-picture-helpers.js": [
@@ -631874,37 +632439,93 @@
    "support"
   ],
   "referrer-policy/css-integration/README.md": [
-   "2edb24fb41edef2ace4b3ea5cf044e78240c1648",
+   "14da25c4d9702f0dcfb87aca255e0ea5df9063a6",
    "support"
   ],
-  "referrer-policy/css-integration/external-import-stylesheet.html": [
-   "7b6ec6431bdbb0fc1bfd4d070b27cb5546abf163",
+  "referrer-policy/css-integration/child-css/external-import-stylesheet.html": [
+   "a2d3e8ced0412b97422847d4d81c1403cf9ae52c",
    "testharness"
   ],
-  "referrer-policy/css-integration/external-stylesheet.html": [
+  "referrer-policy/css-integration/child-css/internal-import-stylesheet.html": [
+   "aebf5031484b799989d6b6a9dd72a5bc28575214",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/child-css/processing-instruction.html": [
+   "b6333e2c7b248c3f3b863bd06f1c99abd472f162",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/css-test-helper.js": [
+   "f5886dbbcbe358438dfbac45c5a0127e9e990ad4",
+   "support"
+  ],
+  "referrer-policy/css-integration/font-face/external-import-stylesheet.html": [
+   "c344c56c5bf322f35e8d8c74427d80391e6637d3",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/font-face/external-stylesheet.html": [
+   "24e4bb99900a556cb0b44144a25c9f8249224eb7",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/font-face/internal-import-stylesheet.html": [
+   "54e2383423cab8679635d05c256c32e27a94c024",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/font-face/internal-stylesheet.html": [
+   "b3869bcebdcdadea3e50d7e8713c853d46ba4816",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/font-face/processing-instruction.html": [
+   "89ee918e24e14b8ea5d35a7dfaf09610eb89ee11",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/image/external-import-stylesheet.html": [
+   "0023af31b17ee883e6e9fe6cdd8f09b8eacf83d1",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/image/external-stylesheet.html": [
    "d14769db4a1221bb6e220aa594c4a3b6bab97aa1",
    "testharness"
   ],
-  "referrer-policy/css-integration/inline-style.html": [
+  "referrer-policy/css-integration/image/inline-style.html": [
    "42128ae062093c0e8feb5d90ab62a6cb281cf8e9",
    "testharness"
   ],
-  "referrer-policy/css-integration/internal-import-stylesheet.html": [
+  "referrer-policy/css-integration/image/internal-import-stylesheet.html": [
    "90003547f4d4e2048cc33f7125d756d42507140d",
    "testharness"
   ],
-  "referrer-policy/css-integration/internal-stylesheet.html": [
+  "referrer-policy/css-integration/image/internal-stylesheet.html": [
    "943108d66e4b273a6d3be30b2ea8a0edb0490c7b",
    "testharness"
   ],
-  "referrer-policy/css-integration/presentation-attribute.html": [
+  "referrer-policy/css-integration/image/presentation-attribute.html": [
    "78401d3ec16866f1e51618bdb5cb028f5eea8490",
    "testharness"
   ],
-  "referrer-policy/css-integration/processing-instruction.html": [
+  "referrer-policy/css-integration/image/processing-instruction.html": [
    "1ca18547dd54c4707250f400999a041f16f77ddf",
    "testharness"
   ],
+  "referrer-policy/css-integration/svg/external-stylesheet.html": [
+   "148584a0b23bbd900d62e28e679d308aa1b204c9",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/svg/inline-style.html": [
+   "1f46acb4a3216e3e5ac81afee50b83ba72ef4852",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/svg/internal-stylesheet.html": [
+   "08be4effa475b232bc2be621dbf24f34ab0e39dd",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/svg/presentation-attribute.html": [
+   "edeceb1a785484111858b650da55a6ec965f5b40",
+   "testharness"
+  ],
+  "referrer-policy/css-integration/svg/processing-instruction.html": [
+   "ba0e6673a3871495c226baf8d3c3daf8ae9e138d",
+   "testharness"
+  ],
   "referrer-policy/generic/common.js": [
    "c98056f680b49b7d765064e9c6d5403ed0cfd21b",
    "support"
@@ -631973,6 +632594,10 @@
    "b2d6c4dfabeafcf1d22a94141d52d04b669f5721",
    "support"
   ],
+  "referrer-policy/generic/subresource/font.py": [
+   "50a5bd2f3996133d4b5904166dc5672e5ae36031",
+   "support"
+  ],
   "referrer-policy/generic/subresource/image.py": [
    "7bc9c657e6b35528d63b6f2d72d73391dedfdf5b",
    "support"
@@ -631982,13 +632607,17 @@
    "support"
   ],
   "referrer-policy/generic/subresource/stylesheet.py": [
-   "328db29b957c4eb355a7907576919cb659d84bf0",
+   "54378216774e49ba564e393b4d1f879ae2d14763",
    "support"
   ],
   "referrer-policy/generic/subresource/subresource.py": [
    "9ba839a133d96d7373a707aa9c71e01b1569297e",
    "support"
   ],
+  "referrer-policy/generic/subresource/svg.py": [
+   "8618875c79f062205c57bac20a322b207914feea",
+   "support"
+  ],
   "referrer-policy/generic/subresource/worker.py": [
    "895bc0d84d12a99c146ba02776138248318b9c1d",
    "support"
@@ -632005,6 +632634,14 @@
    "141711c1483fd13e87e95f151fe6f3191704d7c7",
    "support"
   ],
+  "referrer-policy/generic/template/font.css.template": [
+   "9b19df3cf1f54556f3c2409495d8b6abdd10d2fc",
+   "support"
+  ],
+  "referrer-policy/generic/template/image.css.template": [
+   "0eebd0a45264aa00b5072a8b489a84a85b778a54",
+   "support"
+  ],
   "referrer-policy/generic/template/script.js.template": [
    "e2edf21819dff6afc8a4f5816a0be58f987341ff",
    "support"
@@ -632013,8 +632650,12 @@
    "e4cbd03425968819d773460335404584d9d375fc",
    "support"
   ],
-  "referrer-policy/generic/template/stylesheet.css.template": [
-   "0eebd0a45264aa00b5072a8b489a84a85b778a54",
+  "referrer-policy/generic/template/svg.css.template": [
+   "ffaefed4aa42aa62ca9d3dd9ff5bf989e75cbe01",
+   "support"
+  ],
+  "referrer-policy/generic/template/svg.embedded.template": [
+   "5986c4800a7add03db721f2bf116fe405e5d56cf",
    "support"
   ],
   "referrer-policy/generic/template/test.debug.html.template": [
@@ -640046,7 +640687,7 @@
    "testharness"
   ],
   "resource-timing/resources/TAOResponse.py": [
-   "060f9b0c9a7dcd12473a10561de9c80a63694328",
+   "fefc75b7b7fc68872b36f56bcb0fa59dd41d2918",
    "support"
   ],
   "resource-timing/resources/all_resource_types.htm": [
@@ -640374,7 +641015,7 @@
    "support"
   ],
   "resources/test/conftest.py": [
-   "5fca1d24c419cc5570eed657532c1ae3d3ddaada",
+   "dde9e9dc0a76ab2a34bf45913702ab148b31c2b6",
    "support"
   ],
   "resources/test/harness.html": [
@@ -640430,7 +641071,7 @@
    "support"
   ],
   "resources/test/tests/functional/api-tests-1.html": [
-   "a9d92b12f81fd2ec7e70ded78f4697cfba6fc12e",
+   "c65d026edbaddeee595bc610ce7c955d0bf4529d",
    "support"
   ],
   "resources/test/tests/functional/api-tests-2.html": [
@@ -640497,6 +641138,10 @@
    "cd2c26c278ec36a07f7d0da051d6cb44bf33c5f0",
    "support"
   ],
+  "resources/test/tests/functional/log-insertion.html": [
+   "3f28266d576d31b41861446a03392441ac4f726d",
+   "support"
+  ],
   "resources/test/tests/functional/order.html": [
    "ec9978d898082193a11b646bc23e96f029f5ebe6",
    "support"
@@ -640638,7 +641283,7 @@
    "support"
   ],
   "resources/test/tox.ini": [
-   "d3a30f870a1572d4423ae99f64c67d63afa345da",
+   "7a9e4fa5228931057e9a1b0fc04f7c32ff6f9135",
    "support"
   ],
   "resources/test/variants.js": [
@@ -640646,7 +641291,7 @@
    "support"
   ],
   "resources/test/wptserver.py": [
-   "fa32c33b9d78d6d5a3af1424b845444b7afeeadc",
+   "d47e325fbef64a425ba91f21a49a6d27e03a7e3b",
    "support"
   ],
   "resources/testdriver-vendor.js": [
@@ -640670,7 +641315,7 @@
    "support"
   ],
   "resources/testharness.js": [
-   "352e8b76266b7f5ce3e17278721b55a0fe80a505",
+   "0a92cf10a3d57f8a38921f316f78f2fccc029fb0",
    "support"
   ],
   "resources/testharness.js.headers": [
@@ -643482,7 +644127,7 @@
    "testharness"
   ],
   "service-workers/service-worker/navigation-redirect.https.html": [
-   "0490f2b4058ce808115442b09859fe7a350b2303",
+   "b6281b9e6c30540aae97c31454e4a2a5ac2c62b9",
    "testharness"
   ],
   "service-workers/service-worker/navigation-timing.https.html": [
@@ -644282,15 +644927,15 @@
    "support"
   ],
   "service-workers/service-worker/resources/navigation-redirect-out-scope.py": [
-   "907cefa3b1afa96a55d54935ad8357b232118f9b",
+   "16850723f968fd3fac51a33c6e983c4f013a8823",
    "support"
   ],
   "service-workers/service-worker/resources/navigation-redirect-scope1.py": [
-   "907cefa3b1afa96a55d54935ad8357b232118f9b",
+   "16850723f968fd3fac51a33c6e983c4f013a8823",
    "support"
   ],
   "service-workers/service-worker/resources/navigation-redirect-scope2.py": [
-   "907cefa3b1afa96a55d54935ad8357b232118f9b",
+   "16850723f968fd3fac51a33c6e983c4f013a8823",
    "support"
   ],
   "service-workers/service-worker/resources/navigation-redirect-to-http-iframe.html": [
@@ -647398,7 +648043,7 @@
    "manual"
   ],
   "svg/import/animate-elem-83-t-manual.svg": [
-   "2de478b531530f054594215ea812527a5ee5cdb0",
+   "46b9bedc41b6b4e492b22534a6dfa6342d9031d9",
    "manual"
   ],
   "svg/import/animate-elem-84-t-manual.svg": [
@@ -650342,7 +650987,7 @@
    "support"
   ],
   "tools/ci/check_stability.py": [
-   "2b32eb50c0f62448fed0417d1fe0f7882bf64f14",
+   "a0633110860a729f632e7035743cf57d14260b4c",
    "support"
   ],
   "tools/ci/ci_built_diff.sh": [
@@ -650406,7 +651051,7 @@
    "support"
   ],
   "tools/ci/taskcluster-run.py": [
-   "45416501e0393405b53c00360ef3c3081a9df867",
+   "5a720baa2e9bba12c53a8db898273d7a7a6be4fa",
    "support"
   ],
   "tools/ci/tcdownload.py": [
@@ -650686,7 +651331,7 @@
    "support"
   ],
   "tools/manifest/vcs.py": [
-   "42e9863712f41d5cfdf9279513931b1cbe47f98b",
+   "675eb01714fd82081b2192c74892eb1ccb819285",
    "support"
   ],
   "tools/pytest.ini": [
@@ -655126,7 +655771,7 @@
    "support"
   ],
   "tools/wpt/browser.py": [
-   "7b943c2e73ccbb57f55304a167904efe089b4713",
+   "052ec66a091cf6dde0573006490f19a9cc45afbe",
    "support"
   ],
   "tools/wpt/commands.json": [
@@ -655150,7 +655795,7 @@
    "support"
   ],
   "tools/wpt/run.py": [
-   "7e8827b10698d30fb47f1625ccbb5f7a344daafe",
+   "d08b0f9380712d618ae96593634c84458fc25621",
    "support"
   ],
   "tools/wpt/testfiles.py": [
@@ -655166,7 +655811,7 @@
    "support"
   ],
   "tools/wpt/tests/test_wpt.py": [
-   "d0cb2b85c99e86e9bb039d29c0074a3df17c0afd",
+   "8387dc9613e518e4fefd1181423c8c0ed4c5e0ec",
    "support"
   ],
   "tools/wpt/tox.ini": [
@@ -655242,35 +655887,35 @@
    "support"
   ],
   "tools/wptrunner/requirements_chrome.txt": [
-   "22a07532657dadb79c404fcb61a26e1a127b8cc2",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_chrome_android.txt": [
-   "22a07532657dadb79c404fcb61a26e1a127b8cc2",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_edge.txt": [
-   "22a07532657dadb79c404fcb61a26e1a127b8cc2",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_firefox.txt": [
-   "f1e6a8585caa63b5bd4b9b2594f7170fa49f04ed",
+   "bfe0d4bc347e907a48a256caa48e8e343115d388",
    "support"
   ],
   "tools/wptrunner/requirements_ie.txt": [
-   "22a07532657dadb79c404fcb61a26e1a127b8cc2",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_opera.txt": [
-   "22a07532657dadb79c404fcb61a26e1a127b8cc2",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_safari.txt": [
-   "5a1d26b8b9bccd5cbbe637c7d115808b4fd85f49",
+   "3f86182b7d0897fc9ec97dd831edd399ebce70fd",
    "support"
   ],
   "tools/wptrunner/requirements_sauce.txt": [
-   "77a74222433a693c8458f4a05857c7ed6db85601",
+   "07c525a67fd6de50b8639627a750bbfd1a106b9d",
    "support"
   ],
   "tools/wptrunner/requirements_servo.txt": [
@@ -655414,7 +656059,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/chrome.py": [
-   "8b0ba4585a943598b4c908f2e2da56b0b61505a6",
+   "d41df8dec0ed004b517df5cc245c44e3d8188fd2",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/chrome_android.py": [
@@ -655422,7 +656067,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/chrome_webdriver.py": [
-   "a63460f4544af67ccef3800ddfb64bc654868832",
+   "2ee8ec41ed668a3ac6130908e0c1dce1fbca4a90",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/edge.py": [
@@ -655438,7 +656083,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/firefox.py": [
-   "9f7ebfa2ca544616e2feaeb53c8af73220d7271a",
+   "b370b5d7a5e3308fabe3e21ec5145df57074eca5",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/ie.py": [
@@ -655614,7 +656259,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/stability.py": [
-   "e684bf68076752d50b3271c1d4c74ef45aad4242",
+   "db388bbca0a2beacd11af1083cdf0cba76e5e9d8",
    "support"
   ],
   "tools/wptrunner/wptrunner/testdriver-extra.js": [
@@ -655646,7 +656291,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/testrunner.py": [
-   "7e386b881d4c83a93d2543b7e5b9afd01623a5bc",
+   "353e2ada1eb7cc27e0b70590743a8a3bb5bcc2b8",
    "support"
   ],
   "tools/wptrunner/wptrunner/tests/__init__.py": [
@@ -655678,7 +656323,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/tests/test_stability.py": [
-   "5a051b6c8998682e69d9c74bd4e5458986731b1f",
+   "c3c89f2f192e9fbbd1fc9046837ba1bc854401e5",
    "support"
   ],
   "tools/wptrunner/wptrunner/tests/test_testloader.py": [
@@ -655730,7 +656375,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/wptcommandline.py": [
-   "d25e561ad195ef3de91a42871820ad372269f016",
+   "467903f277347511f23e66cfe0ecb1defa4d351a",
    "support"
   ],
   "tools/wptrunner/wptrunner/wptlogging.py": [
@@ -655790,7 +656435,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/wptrunner.py": [
-   "a6a29724ad71794b8e1492d1c1ba792dfdfcacd4",
+   "6bd1db9927cb738202ace43541c25a44923afe8c",
    "support"
   ],
   "tools/wptrunner/wptrunner/wpttest.py": [
@@ -655878,7 +656523,7 @@
    "support"
   ],
   "tools/wptserve/tests/functional/base.py": [
-   "e49c8287c5985aa5ebbed04ef3070bc785831733",
+   "741ab0bcb745753f72f2e26e37258f877caae513",
    "support"
   ],
   "tools/wptserve/tests/functional/docroot/document.txt": [
@@ -655998,7 +656643,7 @@
    "support"
   ],
   "tools/wptserve/tests/functional/test_handlers.py": [
-   "15c7cb7e803d771bb3814de2b0e85ac606f2759f",
+   "759a096b79957079429ae387186d6e7891651ecf",
    "support"
   ],
   "tools/wptserve/tests/functional/test_input_file.py": [
@@ -656006,11 +656651,11 @@
    "support"
   ],
   "tools/wptserve/tests/functional/test_pipes.py": [
-   "83b2c621641ca17b670eb5a8c08b38f8d37cc2a7",
+   "7739af5e26e17c7b7930a612816151772f3f5cc0",
    "support"
   ],
   "tools/wptserve/tests/functional/test_request.py": [
-   "97d75eb71289adf643ab073ddc740f1f24cffc76",
+   "983539260a5215cab779e76b256f678894f654f3",
    "support"
   ],
   "tools/wptserve/tests/functional/test_response.py": [
@@ -656054,7 +656699,7 @@
    "support"
   ],
   "tools/wptserve/wptserve/pipes.py": [
-   "ad96f591a3a8c8b7e8d13a4ad95a1aae500f66da",
+   "33a43e1f06b9835a2acf9be78b38a765cc9fdb60",
    "support"
   ],
   "tools/wptserve/wptserve/ranges.py": [
@@ -656062,11 +656707,11 @@
    "support"
   ],
   "tools/wptserve/wptserve/request.py": [
-   "cb575ccdba4514a456c0cbf73904bb63c12fd7ff",
+   "233ff151c28e482f1087a853e385ab2f9c819276",
    "support"
   ],
   "tools/wptserve/wptserve/response.py": [
-   "44299cc994ef43ebe72053e1444f5af7cd7f9598",
+   "483265bf084666069c21dd91310a005d2162268b",
    "support"
   ],
   "tools/wptserve/wptserve/router.py": [
@@ -658302,7 +658947,7 @@
    "support"
   ],
   "wasm/jsapi/constructor/compile.any.js": [
-   "0139a18fda3f928dc0eed0bef86098dcbabf5979",
+   "bd23a8666e76f30d212524bc30ffd00c0a546e70",
    "testharness"
   ],
   "wasm/jsapi/constructor/instantiate-bad-imports.any.js": [
@@ -658314,23 +658959,23 @@
    "testharness"
   ],
   "wasm/jsapi/constructor/validate.any.js": [
-   "70bd9f7022ad616c2d5e0be636f6935923e19173",
+   "c8613cbd9b3a467a919d87d3244c4f508dce6317",
    "testharness"
   ],
   "wasm/jsapi/global/constructor.any.js": [
-   "7a45cc4191c55684cde187fc73fb9741d6f5c2c5",
+   "237f99c8b298183a557c10778c70e1d359b9d6b6",
    "testharness"
   ],
   "wasm/jsapi/global/toString.any.js": [
    "ca025576c2b49604f053c83002f3a9cc8ef41a7b",
    "testharness"
   ],
-  "wasm/jsapi/global/value-set.any.js": [
-   "b4e6770f10ed9e3ad55b9ae18ee96deda3ff171e",
+  "wasm/jsapi/global/value-get-set.any.js": [
+   "6de62d5f58362bab593ae7eb453fa14c1424cf2c",
    "testharness"
   ],
   "wasm/jsapi/global/valueOf.any.js": [
-   "176c5a784698399351eedeaac0ec305aa8ab7b81",
+   "d4a84b254f76ea50284619967ab6dc98c99bfea2",
    "testharness"
   ],
   "wasm/jsapi/instance/constructor-bad-imports.any.js": [
@@ -658342,7 +658987,7 @@
    "testharness"
   ],
   "wasm/jsapi/instance/exports.any.js": [
-   "31423918720543da2ba25e392267bf541b756242",
+   "cad468660e099b33f0a03b83a09df0498d67a7e0",
    "testharness"
   ],
   "wasm/jsapi/instance/toString.any.js": [
@@ -658350,7 +658995,7 @@
    "testharness"
   ],
   "wasm/jsapi/instanceTestFactory.js": [
-   "1663ffb34699b7b9ebed6bb6aced99b84da0b4d4",
+   "24f849e6f943d9008343909a00b2f2b0d1ea0c3d",
    "support"
   ],
   "wasm/jsapi/interface.any.js": [
@@ -658358,15 +659003,15 @@
    "testharness"
   ],
   "wasm/jsapi/memory/buffer.any.js": [
-   "b04460b6c5e56cf1fe990e3107aa9efcb4964ed5",
+   "4788ffcf84ff8d88adbafbe416dd7d5b80ec89d1",
    "testharness"
   ],
   "wasm/jsapi/memory/constructor.any.js": [
-   "5caf7cc8bb98eb4f47766011d31e7bde5c126edd",
+   "a584a23ecf0a582b21b913a780accee38e277927",
    "testharness"
   ],
   "wasm/jsapi/memory/grow.any.js": [
-   "95300399f192b7eab70dd8f07c43f4db37eebe01",
+   "1ccfb946756fef71b89672dfc86830c620a9e981",
    "testharness"
   ],
   "wasm/jsapi/memory/toString.any.js": [
@@ -658374,19 +659019,19 @@
    "testharness"
   ],
   "wasm/jsapi/module/constructor.any.js": [
-   "32f183fac8738d30cc8a432768da315949320257",
+   "a467c1a17bb62ac52d323e1976cd067d92a9410d",
    "testharness"
   ],
   "wasm/jsapi/module/customSections.any.js": [
-   "58ac63b61c93a015bfa9d5daab39f8d5b48548da",
+   "04c5abed52435714a18467c419dce17dfcf4073d",
    "testharness"
   ],
   "wasm/jsapi/module/exports.any.js": [
-   "e63a885a4c34add0f6787d3642de83d9766568d1",
+   "9d95b652233b3d7687d4fe14371144519719e97b",
    "testharness"
   ],
   "wasm/jsapi/module/imports.any.js": [
-   "640da591d21d8924d261fdc58b8e7cc762187a11",
+   "b3bb8598b080c376f4de1294780e6072eac2b354",
    "testharness"
   ],
   "wasm/jsapi/module/toString.any.js": [
@@ -658398,19 +659043,19 @@
    "support"
   ],
   "wasm/jsapi/table/constructor.any.js": [
-   "e924bdb2ba42c67bcc6d4a949c2eeb50eac63e31",
+   "99eee19fecd49e432c7f6774c0968218e6d931a3",
    "testharness"
   ],
   "wasm/jsapi/table/get-set.any.js": [
-   "66c41340c2096602c81c1ef3ae8acbfb9f75d98f",
+   "f8a0194364fde1b25eeb998d1837349c3a8bafc2",
    "testharness"
   ],
   "wasm/jsapi/table/grow.any.js": [
-   "d3efb511e4b1db1efa089322c0a3079705dfbdbd",
+   "4978e3ca23d0261aaccf4aad97dd348da22a54d0",
    "testharness"
   ],
   "wasm/jsapi/table/length.any.js": [
-   "a6a9661dbaddc800cb99b7b8e2b804cb0c8e3c62",
+   "b1bfa6cfd1f44fbdbf18769b3f3e8129310c7e0e",
    "testharness"
   ],
   "wasm/jsapi/table/toString.any.js": [
@@ -660185,82 +660830,6 @@
    "a111f103bf142b4041f2a8d1c6017de79b54560e",
    "wdspec"
   ],
-  "webdriver/tests/actions/__init__.py": [
-   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-   "support"
-  ],
-  "webdriver/tests/actions/conftest.py": [
-   "55cecd117828e525ac5712176f6f31787b301226",
-   "support"
-  ],
-  "webdriver/tests/actions/control_click.py": [
-   "2ec819b772fcfa4d0a37395aa64fb89ad7686bda",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/key.py": [
-   "50c4ed9132b10cf63ad515bbfcbd30970b2c1974",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/key_shortcuts.py": [
-   "ec062f752244d3f3fe1c0c83b22f48d972ba5984",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/modifier_click.py": [
-   "fbfd837710b1c04c1dc606edb63b62a574eb0d9b",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/mouse.py": [
-   "ca8bffceb71ff9621ae3359024c8d55ff17f7478",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/mouse_dblclick.py": [
-   "fc53a51ab7691e817139e0a5a8477c9a96dda842",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/mouse_pause_dblclick.py": [
-   "ad179673176b9d8ae90837c7cf09d33c75780a75",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/none.py": [
-   "07944a68ffeedfdbd5adac44244f6435b5c5c6cb",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/pointer_origin.py": [
-   "cad59f0a13b1f584ea45226f061be0038b9de220",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/sequence.py": [
-   "b62d00c3e9b82d6200b3f6a0cd99d8a208281601",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/special_keys.py": [
-   "416cbdcf20fc9e964aefd9683098d90289f3705c",
-   "wdspec"
-  ],
-  "webdriver/tests/actions/support/__init__.py": [
-   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-   "support"
-  ],
-  "webdriver/tests/actions/support/keys.py": [
-   "5995f78c71016d35cdf6cbd3317c5579e24f182d",
-   "support"
-  ],
-  "webdriver/tests/actions/support/mouse.py": [
-   "b3672eb213af68a9e4d9f931ca6499723a1a5019",
-   "support"
-  ],
-  "webdriver/tests/actions/support/refine.py": [
-   "3a6d63e04ce941d26ab3898cb2fc2a730d46c1ce",
-   "support"
-  ],
-  "webdriver/tests/actions/support/test_actions_wdspec.html": [
-   "6f844cd255a075d31caf1c19957af3d6ac833778",
-   "support"
-  ],
-  "webdriver/tests/actions/validity.py": [
-   "ce8a0d60f7df192e21c6abbad1871bb0ac8f5f78",
-   "wdspec"
-  ],
   "webdriver/tests/add_cookie/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
@@ -660805,6 +661374,90 @@
    "0deb1b46488f9b6e79e98931fca54e6b5f693c2a",
    "wdspec"
   ],
+  "webdriver/tests/perform_actions/__init__.py": [
+   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/conftest.py": [
+   "dffae0b98cd67c664883f4e4efd608415c82b179",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/key.py": [
+   "2b3414c5ebfd62955860de540b4614471efbe8ad",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_events.py": [
+   "462688a55e527ffd5d075e4bd981489e5e029f8c",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_modifiers.py": [
+   "55dc9280c6267172a96a4f3c02f2503aa0c22500",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_shortcuts.py": [
+   "31b533ac8504108037ecccb76de2d089c1ad2a58",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_special_keys.py": [
+   "003bba4294105eb2757bfbe9e4f808b4ea13047c",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/none.py": [
+   "07944a68ffeedfdbd5adac44244f6435b5c5c6cb",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer.py": [
+   "9a68f322d70b585ad32e3814bb424fa5d817cc74",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer_contextmenu.py": [
+   "c64c51252a5a4a5be3464fe92e0ced0a81a486a1",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer_dblclick.py": [
+   "8c89cef5f380d769705be704698232c7f9c928ec",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer_modifier_click.py": [
+   "ba81f6d090b248c512cf896bc8e6059f252db8c8",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer_origin.py": [
+   "3ebf14c348c798fb77bbd0f052207f0470a94b60",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/pointer_pause_dblclick.py": [
+   "85679f3614a8fe010cba7dcd698ce5e82bc26660",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/sequence.py": [
+   "3536abeb12bcf667e4b6eab2cb723baa10c9ffa7",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/support/__init__.py": [
+   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/support/keys.py": [
+   "5995f78c71016d35cdf6cbd3317c5579e24f182d",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/support/mouse.py": [
+   "b3672eb213af68a9e4d9f931ca6499723a1a5019",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/support/refine.py": [
+   "3a6d63e04ce941d26ab3898cb2fc2a730d46c1ce",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/support/test_actions_wdspec.html": [
+   "6f844cd255a075d31caf1c19957af3d6ac833778",
+   "support"
+  ],
+  "webdriver/tests/perform_actions/validity.py": [
+   "ce8a0d60f7df192e21c6abbad1871bb0ac8f5f78",
+   "wdspec"
+  ],
   "webdriver/tests/refresh/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
@@ -660817,6 +661470,34 @@
    "b8ef418e115fcdafa861dcb8f61b01116e9e81f6",
    "wdspec"
   ],
+  "webdriver/tests/release_actions/__init__.py": [
+   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+   "support"
+  ],
+  "webdriver/tests/release_actions/conftest.py": [
+   "df86db63067d158922281678c2ed8847a8b64afe",
+   "support"
+  ],
+  "webdriver/tests/release_actions/release.py": [
+   "84719043d1c5095c0831136067e38a2f96f2ca1d",
+   "wdspec"
+  ],
+  "webdriver/tests/release_actions/sequence.py": [
+   "2d816f8094b3975523904c9e197390dfc058dd06",
+   "wdspec"
+  ],
+  "webdriver/tests/release_actions/support/__init__.py": [
+   "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+   "support"
+  ],
+  "webdriver/tests/release_actions/support/refine.py": [
+   "3a6d63e04ce941d26ab3898cb2fc2a730d46c1ce",
+   "support"
+  ],
+  "webdriver/tests/release_actions/support/test_actions_wdspec.html": [
+   "6f844cd255a075d31caf1c19957af3d6ac833778",
+   "support"
+  ],
   "webdriver/tests/send_alert_text/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
@@ -661866,7 +662547,7 @@
    "support"
   ],
   "webrtc/getstats.html": [
-   "9775f2090f2203473d0a75a2edeff8e3b785ddc1",
+   "937f54b74ec8266f890d60a4c67e75c3d6714826",
    "testharness"
   ],
   "webrtc/historical.html": [
@@ -661902,7 +662583,7 @@
    "testharness"
   ],
   "webrtc/tools/.eslintrc.js": [
-   "9368cf4593eaa76075f212af592ece829422dce9",
+   "1778f8505e04cf4ba9eb4154c5396e0fc60186f6",
    "support"
   ],
   "webrtc/tools/README.md": [
@@ -668774,7 +669455,7 @@
    "support"
   ],
   "xhr/resources/responseXML-unavailable-in-worker.js": [
-   "2f3fdf25c3382fd2f34c8235c69f3f0f39f71635",
+   "06da02a71f5471e16d71268ad8ec7fa576bd0546",
    "support"
   ],
   "xhr/resources/send-after-setting-document-domain-window-1.htm": [
diff --git a/tests/wpt/metadata/css/css-animations/animationevent-interface.html.ini b/tests/wpt/metadata/css/css-animations/animationevent-interface.html.ini
index 68e78563596..a4d160df59e 100644
--- a/tests/wpt/metadata/css/css-animations/animationevent-interface.html.ini
+++ b/tests/wpt/metadata/css/css-animations/animationevent-interface.html.ini
@@ -50,3 +50,75 @@
   [animationName has default value of empty string]
     expected: FAIL
 
+  [elapsedTime set to -0.5]
+    expected: FAIL
+
+  [elapsedTime cannot be set to -Infinity]
+    expected: FAIL
+
+  [elapsedTime cannot be set to Infinity]
+    expected: FAIL
+
+  [animationName set to [\]]
+    expected: FAIL
+
+  [elapsedTime set to null]
+    expected: FAIL
+
+  [elapsedTime set to an object with a valueOf function]
+    expected: FAIL
+
+  [animationName set to an object with a valueOf function]
+    expected: FAIL
+
+  [elapsedTime cannot be set to NaN]
+    expected: FAIL
+
+  [elapsedTime set to true]
+    expected: FAIL
+
+  [elapsedTime set to '']
+    expected: FAIL
+
+  [elapsedTime set to [0.5\]]
+    expected: FAIL
+
+  [elapsedTime set to undefined]
+    expected: FAIL
+
+  [animationName set to true]
+    expected: FAIL
+
+  [elapsedTime set to false]
+    expected: FAIL
+
+  [elapsedTime set to [\]]
+    expected: FAIL
+
+  [elapsedTime cannot be set to [0.5, 1.0\]]
+    expected: FAIL
+
+  [animationName set to null]
+    expected: FAIL
+
+  [animationName set to an object]
+    expected: FAIL
+
+  [elapsedTime cannot be set to 'sample']
+    expected: FAIL
+
+  [animationName set to undefined]
+    expected: FAIL
+
+  [animationName set to [1, 2, 3\]]
+    expected: FAIL
+
+  [animationName set to false]
+    expected: FAIL
+
+  [animationName set to a number]
+    expected: FAIL
+
+  [elapsedTime cannot be set to an object]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html.ini b/tests/wpt/metadata/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html.ini
index 973c4163895..d769457c57c 100644
--- a/tests/wpt/metadata/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html.ini
+++ b/tests/wpt/metadata/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html.ini
@@ -1,13 +1,4 @@
 [css-text-line-break-ja-hyphens-strict.html]
-  [2010 HYPHEN may NOT appear at line start if ja and strict]
-    expected: FAIL
-
-  [2013 EN DASH may NOT appear at line start if ja and strict]
-    expected: FAIL
-
-  [30A0 KATAKANA-HIRAGANA DOUBLE HYPHEN may NOT appear at line start if ja and strict]
-    expected: FAIL
-
   [301C WAVE DASH may NOT appear at line start if ja and strict]
     expected:
       if os == "linux": FAIL
diff --git a/tests/wpt/metadata/css/css-text/tab-size/tab-min-rendered-width-1.html.ini b/tests/wpt/metadata/css/css-text/tab-size/tab-min-rendered-width-1.html.ini
new file mode 100644
index 00000000000..bcd481f82f6
--- /dev/null
+++ b/tests/wpt/metadata/css/css-text/tab-size/tab-min-rendered-width-1.html.ini
@@ -0,0 +1,2 @@
+[tab-min-rendered-width-1.html]
+  expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transitions/properties-value-inherit-002.html.ini b/tests/wpt/metadata/css/css-transitions/properties-value-inherit-002.html.ini
index d53af6b3960..a2e15ddcf05 100644
--- a/tests/wpt/metadata/css/css-transitions/properties-value-inherit-002.html.ini
+++ b/tests/wpt/metadata/css/css-transitions/properties-value-inherit-002.html.ini
@@ -1,6 +1,7 @@
 [properties-value-inherit-002.html]
+  expected: TIMEOUT
   [outline-width length(px) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-left-width length(em) / values]
     expected: FAIL
@@ -24,13 +25,13 @@
     expected: FAIL
 
   [opacity number[0,1\](zero-to-one) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [line-height number(integer) / values]
     expected: FAIL
 
   [outline-offset length(px) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [font-size length(pt) / values]
     expected: FAIL
@@ -39,7 +40,7 @@
     expected: FAIL
 
   [vertical-align length(in) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [max-height percentage(%) / values]
     expected: FAIL
@@ -75,7 +76,7 @@
     expected: FAIL
 
   [vertical-align percentage(%) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [background-position length(in) / events]
     expected: FAIL
@@ -99,10 +100,10 @@
     expected: FAIL
 
   [vertical-align length(em) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [clip rectangle(rectangle) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [word-spacing length(em) / values]
     expected: FAIL
@@ -126,7 +127,7 @@
     expected: FAIL
 
   [outline-offset length(ex) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [min-width length(cm) / values]
     expected: FAIL
@@ -141,16 +142,16 @@
     expected: FAIL
 
   [vertical-align length(pc) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [vertical-align length(cm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [max-height length(ex) / values]
     expected: FAIL
 
   [vertical-align length(ex) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [min-height percentage(%) / values]
     expected: FAIL
@@ -159,7 +160,7 @@
     expected: FAIL
 
   [outline-offset length(mm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [font-weight font-weight(keyword) / values]
     expected: FAIL
@@ -168,7 +169,7 @@
     expected: FAIL
 
   [outline-offset length(pt) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [line-height length(mm) / values]
     expected: FAIL
@@ -201,7 +202,7 @@
     expected: FAIL
 
   [vertical-align length(pt) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-left-color color(rgba) / values]
     expected: FAIL
@@ -270,10 +271,10 @@
     expected: FAIL
 
   [outline-offset length(in) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [outline-width length(pt) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-top-width length(pc) / values]
     expected: FAIL
@@ -291,7 +292,7 @@
     expected: FAIL
 
   [outline-width length(in) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [word-spacing length(pt) / values]
     expected: FAIL
@@ -303,7 +304,7 @@
     expected: FAIL
 
   [outline-color color(rgba) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [background-position length(ex) / events]
     expected: FAIL
@@ -327,7 +328,7 @@
     expected: FAIL
 
   [outline-width length(ex) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [font-size length(pc) / values]
     expected: FAIL
@@ -339,7 +340,7 @@
     expected: FAIL
 
   [outline-width length(cm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [max-width percentage(%) / values]
     expected: FAIL
@@ -354,19 +355,19 @@
     expected: FAIL
 
   [outline-width length(mm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-left-width length(pc) / values]
     expected: FAIL
 
   [outline-width length(pc) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [font-weight font-weight(numeric) / values]
     expected: FAIL
 
   [vertical-align length(px) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [letter-spacing length(px) / values]
     expected: FAIL
@@ -393,7 +394,7 @@
     expected: FAIL
 
   [outline-width length(em) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-right-width length(em) / values]
     expected: FAIL
@@ -405,10 +406,10 @@
     expected: FAIL
 
   [outline-offset length(em) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [outline-offset length(cm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [background-position length(mm) / events]
     expected: FAIL
@@ -420,13 +421,13 @@
     expected: FAIL
 
   [z-index integer(integer) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-left-width length(pt) / values]
     expected: FAIL
 
   [vertical-align length(mm) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [border-bottom-width length(pc) / values]
     expected: FAIL
@@ -447,7 +448,7 @@
     expected: FAIL
 
   [outline-offset length(pc) / values]
-    expected: FAIL
+    expected: TIMEOUT
 
   [max-height length(pc) / values]
     expected: FAIL
@@ -473,39 +474,135 @@
   [min-width length(ex) / values]
     expected: FAIL
 
-  [text-indent length(pc) / values]
-    expected: FAIL
-
-  [text-indent length(ex) / values]
-    expected: FAIL
-
-  [text-indent length(px) / values]
-    expected: FAIL
-
-  [text-indent length(mm) / values]
-    expected: FAIL
-
   [word-spacing length(in) / values]
     expected: FAIL
 
-  [text-indent length(cm) / values]
-    expected: FAIL
-
   [text-indent length(pt) / values]
     expected: FAIL
 
-  [text-shadow shadow(shadow) / values]
-    expected: FAIL
-
   [word-spacing percentage(%) / values]
     expected: FAIL
 
-  [text-indent length(in) / values]
+  [outline-width length(pc) / events]
+    expected: TIMEOUT
+
+  [height percentage(%) / values]
     expected: FAIL
 
-  [text-indent length(em) / values]
+  [vertical-align length(px) / events]
+    expected: TIMEOUT
+
+  [padding-right length(em) / values]
     expected: FAIL
 
-  [text-indent percentage(%) / values]
+  [outline-offset length(mm) / events]
+    expected: TIMEOUT
+
+  [vertical-align length(in) / events]
+    expected: TIMEOUT
+
+  [padding-left length(px) / values]
     expected: FAIL
 
+  [vertical-align length(em) / events]
+    expected: TIMEOUT
+
+  [vertical-align length(cm) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(cm) / events]
+    expected: TIMEOUT
+
+  [vertical-align length(mm) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(em) / events]
+    expected: TIMEOUT
+
+  [z-index integer(integer) / events]
+    expected: TIMEOUT
+
+  [vertical-align length(ex) / events]
+    expected: TIMEOUT
+
+  [outline-width length(em) / events]
+    expected: TIMEOUT
+
+  [visibility visibility(keyword) / events]
+    expected: TIMEOUT
+
+  [width length(pc) / values]
+    expected: FAIL
+
+  [opacity number[0,1\](zero-to-one) / events]
+    expected: TIMEOUT
+
+  [margin-bottom length(px) / values]
+    expected: FAIL
+
+  [visibility visibility(keyword) / values]
+    expected: TIMEOUT
+
+  [width length(pt) / values]
+    expected: FAIL
+
+  [outline-width length(cm) / events]
+    expected: TIMEOUT
+
+  [clip rectangle(rectangle) / events]
+    expected: TIMEOUT
+
+  [outline-width length(ex) / events]
+    expected: TIMEOUT
+
+  [outline-width length(mm) / events]
+    expected: TIMEOUT
+
+  [width length(mm) / values]
+    expected: FAIL
+
+  [vertical-align percentage(%) / events]
+    expected: TIMEOUT
+
+  [outline-width length(pt) / events]
+    expected: TIMEOUT
+
+  [outline-color color(rgba) / events]
+    expected: TIMEOUT
+
+  [outline-width length(in) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(ex) / events]
+    expected: TIMEOUT
+
+  [padding-top length(mm) / values]
+    expected: FAIL
+
+  [vertical-align length(pc) / events]
+    expected: TIMEOUT
+
+  [vertical-align length(pt) / events]
+    expected: TIMEOUT
+
+  [width length(ex) / values]
+    expected: FAIL
+
+  [top length(ex) / values]
+    expected: FAIL
+
+  [outline-offset length(pt) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(px) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(in) / events]
+    expected: TIMEOUT
+
+  [outline-width length(px) / events]
+    expected: TIMEOUT
+
+  [outline-offset length(pc) / events]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/css/css-transitions/transitionevent-interface.html.ini b/tests/wpt/metadata/css/css-transitions/transitionevent-interface.html.ini
new file mode 100644
index 00000000000..18ebdebfb7c
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transitions/transitionevent-interface.html.ini
@@ -0,0 +1,7 @@
+[transitionevent-interface.html]
+  [elapsedTime set to undefined]
+    expected: FAIL
+
+  [propertyName set to undefined]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini b/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini
index decfd130b16..d56a003324d 100644
--- a/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini
+++ b/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini
@@ -20,9 +20,6 @@
   [right intermediate]
     expected: FAIL
 
-  [min-width intermediate]
-    expected: FAIL
-
   [background-position end]
     expected: FAIL
 
@@ -35,42 +32,81 @@
   [font-weight intermediate]
     expected: FAIL
 
-  [clip intermediate]
-    expected: FAIL
-
-  [border-right-width intermediate]
-    expected: FAIL
-
-  [border-left-width intermediate]
-    expected: FAIL
-
   [min-height intermediate]
     expected: FAIL
 
-  [border-top-width intermediate]
-    expected: FAIL
-
-  [max-width intermediate]
-    expected: FAIL
-
   [max-height intermediate]
     expected: FAIL
 
   [outline-offset intermediate]
     expected: FAIL
 
-  [border-spacing intermediate]
-    expected: FAIL
-
-  [left intermediate]
-    expected: FAIL
-
   [outline-width intermediate]
     expected: FAIL
 
-  [bottom intermediate]
-    expected: FAIL
-
   [outline-width end]
     expected: FAIL
 
+  [max-height end]
+    expected: FAIL
+
+  [height end]
+    expected: FAIL
+
+  [line-height end]
+    expected: FAIL
+
+  [min-height end]
+    expected: FAIL
+
+  [bottom end]
+    expected: FAIL
+
+  [clip end]
+    expected: FAIL
+
+  [font-weight end]
+    expected: FAIL
+
+  [border-left-color end]
+    expected: FAIL
+
+  [border-top-width end]
+    expected: FAIL
+
+  [margin-right intermediate]
+    expected: FAIL
+
+  [border-left-width end]
+    expected: FAIL
+
+  [border-bottom-width end]
+    expected: FAIL
+
+  [letter-spacing end]
+    expected: FAIL
+
+  [margin-bottom end]
+    expected: FAIL
+
+  [border-right-width end]
+    expected: FAIL
+
+  [border-right-color end]
+    expected: FAIL
+
+  [border-top-color end]
+    expected: FAIL
+
+  [color end]
+    expected: FAIL
+
+  [border-spacing end]
+    expected: FAIL
+
+  [visibility end]
+    expected: FAIL
+
+  [left end]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/events/shadow-relatedTarget.html.ini b/tests/wpt/metadata/dom/events/shadow-relatedTarget.html.ini
new file mode 100644
index 00000000000..464494a62d5
--- /dev/null
+++ b/tests/wpt/metadata/dom/events/shadow-relatedTarget.html.ini
@@ -0,0 +1,4 @@
+[shadow-relatedTarget.html]
+  [shadow-relatedTarget]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/encoding/single-byte-decoder.html.ini b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini
index 32626f90fad..d0509d2ede5 100644
--- a/tests/wpt/metadata/encoding/single-byte-decoder.html.ini
+++ b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini
@@ -2,7 +2,7 @@
   type: testharness
 
 [single-byte-decoder.html?document]
-  expected: CRASH
+  expected: TIMEOUT
   [windows-1254: iso_8859-9 (document.characterSet and document.inputEncoding)]
     expected: FAIL
 
diff --git a/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini b/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini
new file mode 100644
index 00000000000..f917c63e1b7
--- /dev/null
+++ b/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini
@@ -0,0 +1,5 @@
+[format-field-id-2.htm]
+  expected: TIMEOUT
+  [EventSource: Last-Event-ID (2)]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/eventsource/format-field-id.htm.ini b/tests/wpt/metadata/eventsource/format-field-id.htm.ini
new file mode 100644
index 00000000000..38a0c7e2916
--- /dev/null
+++ b/tests/wpt/metadata/eventsource/format-field-id.htm.ini
@@ -0,0 +1,5 @@
+[format-field-id.htm]
+  expected: TIMEOUT
+  [EventSource: Last-Event-ID]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
new file mode 100644
index 00000000000..87b07c3e670
--- /dev/null
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
@@ -0,0 +1,4 @@
+[traverse_the_history_1.html]
+  [Multiple history traversals from the same task]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
similarity index 71%
rename from tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini
rename to tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
index 385376c7321..51f8272a6de 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
@@ -1,4 +1,4 @@
-[traverse_the_history_4.html]
+[traverse_the_history_3.html]
   [Multiple history traversals, last would be aborted]
     expected: FAIL
 
diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini
deleted file mode 100644
index 6be14fec6f5..00000000000
--- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[location-protocol-setter-non-broken-weird.html]
-  type: testharness
-  [Set location.protocol to x]
-    expected: FAIL
-
-  [Set location.protocol to data]
-    expected: FAIL
-
-  [Set location.protocol to ftp]
-    expected: FAIL
-
-  [Set location.protocol to gopher]
-    expected: FAIL
-
-  [Set location.protocol to http+x]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini
index 20865f493ec..9579b42287e 100644
--- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini
@@ -30,3 +30,6 @@
   [Set HTTP URL frame location.protocol to data]
     expected: FAIL
 
+  [Set HTTP URL frame location.protocol to x]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html.ini b/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html.ini
new file mode 100644
index 00000000000..f405dd9fce2
--- /dev/null
+++ b/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html.ini
@@ -0,0 +1,2 @@
+[transformed-tbody-tr-collapsed-border.html]
+  expected: FAIL
diff --git a/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html.ini b/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html.ini
new file mode 100644
index 00000000000..79683d56886
--- /dev/null
+++ b/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html.ini
@@ -0,0 +1,2 @@
+[legend-list-item-numbering.html]
+  expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini
index ed2ecc503bb..0628cc9138c 100644
--- a/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini
+++ b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini
@@ -3,3 +3,39 @@
   [Should get an error event for a text/plain response.]
     expected: FAIL
 
+  [Stylesheet loading using @import with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, same-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, same-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html.ini
new file mode 100644
index 00000000000..b90de8f05bc
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html.ini
@@ -0,0 +1,37 @@
+[link-style-error-limited-quirks.html]
+  [Stylesheet loading using @import with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, same-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, same-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html.ini
new file mode 100644
index 00000000000..bba476d4761
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html.ini
@@ -0,0 +1,31 @@
+[link-style-error-quirks.html]
+  [Stylesheet loading using @import with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with broken Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with no Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using @import with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, cross-origin, and no nosniff]
+    expected: FAIL
+
+  [Stylesheet loading using <link> with wrong Content-Type, same-origin, and nosniff]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html.ini
new file mode 100644
index 00000000000..e07008847d1
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html.ini
@@ -0,0 +1,4 @@
+[iframe-nosrc.html]
+  [load event of iframe should not be fired after processing the element]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html.ini
index 0f1a214d0ee..772148dc71f 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html.ini
@@ -13,21 +13,3 @@
   [picture: source (max-width:500px) valid image, img valid image, resize to narrow]
     expected: FAIL
 
-  [picture: source (max-width:500px) broken image, img valid image, resize to narrow]
-    expected: FAIL
-
-  [img (srcset 1 cand) valid image, resize to wide]
-    expected: FAIL
-
-  [picture: same URL in source (max-width:500px) and img, resize to wide]
-    expected: FAIL
-
-  [img (srcset 1 cand) valid image, resize to narrow]
-    expected: FAIL
-
-  [picture: source (max-width:500px) valid image, img broken image, resize to wide]
-    expected: FAIL
-
-  [picture: same URL in source (max-width:500px) and img, resize to narrow]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/non-active-document.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
new file mode 100644
index 00000000000..8cc42056d34
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
@@ -0,0 +1,10 @@
+[non-active-document.html]
+  [DOMParser]
+    expected: FAIL
+
+  [createHTMLDocument]
+    expected: FAIL
+
+  [<template>]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-autocomplete.html.ini b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-autocomplete.html.ini
index c486ffa9062..40874364077 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-autocomplete.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-autocomplete.html.ini
@@ -183,3 +183,18 @@
   [off is an allowed autocomplete field name]
     expected: FAIL
 
+  [Unknown field]
+    expected: FAIL
+
+  [Test maximum number of tokens]
+    expected: FAIL
+
+  [Serialize combinations of section, mode, contact, and field]
+    expected: FAIL
+
+  [Test 'wearing the autofill anchor mantle' with off/on]
+    expected: FAIL
+
+  [Test whitespace-only attribute value]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini
index c6d49957c4a..ce482a60da8 100644
--- a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini
+++ b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini
@@ -2,3 +2,6 @@
   [document.open() after parser is aborted]
     expected: FAIL
 
+  [async document.open() after parser is aborted]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks/unitless-length/limited-quirks.html.ini b/tests/wpt/metadata/quirks/unitless-length/limited-quirks.html.ini
deleted file mode 100644
index c7e9c7434f5..00000000000
--- a/tests/wpt/metadata/quirks/unitless-length/limited-quirks.html.ini
+++ /dev/null
@@ -1,283 +0,0 @@
-[limited-quirks.html]
-  [top: -\\31 .5]
-    expected: FAIL
-
-  [bottom: -1A]
-    expected: FAIL
-
-  [bottom: -1a]
-    expected: FAIL
-
-  [top: @1]
-    expected: FAIL
-
-  [top: "1a"]
-    expected: FAIL
-
-  [top: @a]
-    expected: FAIL
-
-  [bottom: "1"]
-    expected: FAIL
-
-  [bottom: -/**/1]
-    expected: FAIL
-
-  [top: +/**/1]
-    expected: FAIL
-
-  [bottom: @1a]
-    expected: FAIL
-
-  [top: 1\\31 ]
-    expected: FAIL
-
-  [top: url('1')]
-    expected: FAIL
-
-  [bottom: -\\31 ]
-    expected: FAIL
-
-  [top: calc(1)]
-    expected: FAIL
-
-  [top: \\31 ]
-    expected: FAIL
-
-  [bottom: +1\\31 ]
-    expected: FAIL
-
-  [bottom: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: #0001]
-    expected: FAIL
-
-  [top: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: 1a]
-    expected: FAIL
-
-  [bottom: A]
-    expected: FAIL
-
-  [bottom: #01]
-    expected: FAIL
-
-  [top: +\\31 .5]
-    expected: FAIL
-
-  [bottom: #1]
-    expected: FAIL
-
-  [top: -/**/1]
-    expected: FAIL
-
-  [bottom: +\\31 .5]
-    expected: FAIL
-
-  [bottom: \\31 ]
-    expected: FAIL
-
-  [bottom: calc(1)]
-    expected: FAIL
-
-  [top: #001]
-    expected: FAIL
-
-  [top: +\\31 ]
-    expected: FAIL
-
-  [bottom: +\\31 ]
-    expected: FAIL
-
-  [top: +1.5]
-    expected: FAIL
-
-  [top: +1\\31 ]
-    expected: FAIL
-
-  [bottom: @a]
-    expected: FAIL
-
-  [bottom: @1]
-    expected: FAIL
-
-  [top: #1]
-    expected: FAIL
-
-  [top: 1a]
-    expected: FAIL
-
-  [bottom: +1a]
-    expected: FAIL
-
-  [bottom: +1A]
-    expected: FAIL
-
-  [bottom: "a"]
-    expected: FAIL
-
-  [top: #00001]
-    expected: FAIL
-
-  [bottom: -1\\31 .5]
-    expected: FAIL
-
-  [top: "1"]
-    expected: FAIL
-
-  [bottom: 1.5]
-    expected: FAIL
-
-  [bottom: -\\31 .5]
-    expected: FAIL
-
-  [bottom: url('1')]
-    expected: FAIL
-
-  [bottom: -1.5]
-    expected: FAIL
-
-  [top: \\31 .5]
-    expected: FAIL
-
-  [bottom: "1a"]
-    expected: FAIL
-
-  [bottom: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: +1\\31 .5]
-    expected: FAIL
-
-  [bottom: 1\\31 ]
-    expected: FAIL
-
-  [bottom: +/**/1]
-    expected: FAIL
-
-  [bottom: #00001]
-    expected: FAIL
-
-  [top: url(1)]
-    expected: FAIL
-
-  [bottom: #001]
-    expected: FAIL
-
-  [top: +1\\31 .5]
-    expected: FAIL
-
-  [top: -1a]
-    expected: FAIL
-
-  [top: -1A]
-    expected: FAIL
-
-  [bottom: url(1)]
-    expected: FAIL
-
-  [top: a]
-    expected: FAIL
-
-  [top: A]
-    expected: FAIL
-
-  [top: #000001]
-    expected: FAIL
-
-  [top: 1]
-    expected: FAIL
-
-  [top: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: a]
-    expected: FAIL
-
-  [bottom: 1]
-    expected: FAIL
-
-  [bottom: +1]
-    expected: FAIL
-
-  [bottom: #000001]
-    expected: FAIL
-
-  [bottom: +a]
-    expected: FAIL
-
-  [bottom: +A]
-    expected: FAIL
-
-  [top: 1.5]
-    expected: FAIL
-
-  [top: +A]
-    expected: FAIL
-
-  [top: +a]
-    expected: FAIL
-
-  [top: +1]
-    expected: FAIL
-
-  [top: -1.5]
-    expected: FAIL
-
-  [top: -1\\31 .5]
-    expected: FAIL
-
-  [top: +1a]
-    expected: FAIL
-
-  [top: +1A]
-    expected: FAIL
-
-  [top: @1a]
-    expected: FAIL
-
-  [bottom: \\31 .5]
-    expected: FAIL
-
-  [top: "a"]
-    expected: FAIL
-
-  [top: #01]
-    expected: FAIL
-
-  [bottom: +1.5]
-    expected: FAIL
-
-  [bottom: -A]
-    expected: FAIL
-
-  [bottom: -a]
-    expected: FAIL
-
-  [bottom: -1\\31 ]
-    expected: FAIL
-
-  [top: #0001]
-    expected: FAIL
-
-  [bottom: -1]
-    expected: FAIL
-
-  [top: -\\31 ]
-    expected: FAIL
-
-  [top: -A]
-    expected: FAIL
-
-  [top: -a]
-    expected: FAIL
-
-  [top: -1]
-    expected: FAIL
-
-  [top: -1\\31 ]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/quirks/unitless-length/no-quirks.html.ini b/tests/wpt/metadata/quirks/unitless-length/no-quirks.html.ini
deleted file mode 100644
index 818a429ed39..00000000000
--- a/tests/wpt/metadata/quirks/unitless-length/no-quirks.html.ini
+++ /dev/null
@@ -1,283 +0,0 @@
-[no-quirks.html]
-  [top: -\\31 .5]
-    expected: FAIL
-
-  [bottom: -1A]
-    expected: FAIL
-
-  [bottom: -1a]
-    expected: FAIL
-
-  [top: @1]
-    expected: FAIL
-
-  [top: "1a"]
-    expected: FAIL
-
-  [top: @a]
-    expected: FAIL
-
-  [bottom: "1"]
-    expected: FAIL
-
-  [bottom: -/**/1]
-    expected: FAIL
-
-  [top: +/**/1]
-    expected: FAIL
-
-  [bottom: @1a]
-    expected: FAIL
-
-  [top: 1\\31 ]
-    expected: FAIL
-
-  [top: url('1')]
-    expected: FAIL
-
-  [bottom: -\\31 ]
-    expected: FAIL
-
-  [top: calc(1)]
-    expected: FAIL
-
-  [top: \\31 ]
-    expected: FAIL
-
-  [bottom: +1\\31 ]
-    expected: FAIL
-
-  [bottom: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: #0001]
-    expected: FAIL
-
-  [top: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: 1a]
-    expected: FAIL
-
-  [bottom: A]
-    expected: FAIL
-
-  [bottom: #01]
-    expected: FAIL
-
-  [top: +\\31 .5]
-    expected: FAIL
-
-  [bottom: #1]
-    expected: FAIL
-
-  [top: -/**/1]
-    expected: FAIL
-
-  [bottom: +\\31 .5]
-    expected: FAIL
-
-  [bottom: \\31 ]
-    expected: FAIL
-
-  [bottom: calc(1)]
-    expected: FAIL
-
-  [top: #001]
-    expected: FAIL
-
-  [top: +\\31 ]
-    expected: FAIL
-
-  [bottom: +\\31 ]
-    expected: FAIL
-
-  [top: +1.5]
-    expected: FAIL
-
-  [top: +1\\31 ]
-    expected: FAIL
-
-  [bottom: @a]
-    expected: FAIL
-
-  [bottom: @1]
-    expected: FAIL
-
-  [top: #1]
-    expected: FAIL
-
-  [top: 1a]
-    expected: FAIL
-
-  [bottom: +1a]
-    expected: FAIL
-
-  [bottom: +1A]
-    expected: FAIL
-
-  [bottom: "a"]
-    expected: FAIL
-
-  [top: #00001]
-    expected: FAIL
-
-  [bottom: -1\\31 .5]
-    expected: FAIL
-
-  [top: "1"]
-    expected: FAIL
-
-  [bottom: 1.5]
-    expected: FAIL
-
-  [bottom: -\\31 .5]
-    expected: FAIL
-
-  [bottom: url('1')]
-    expected: FAIL
-
-  [bottom: -1.5]
-    expected: FAIL
-
-  [top: \\31 .5]
-    expected: FAIL
-
-  [bottom: "1a"]
-    expected: FAIL
-
-  [bottom: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: +1\\31 .5]
-    expected: FAIL
-
-  [bottom: 1\\31 ]
-    expected: FAIL
-
-  [bottom: +/**/1]
-    expected: FAIL
-
-  [bottom: #00001]
-    expected: FAIL
-
-  [top: url(1)]
-    expected: FAIL
-
-  [bottom: #001]
-    expected: FAIL
-
-  [top: +1\\31 .5]
-    expected: FAIL
-
-  [top: -1a]
-    expected: FAIL
-
-  [top: -1A]
-    expected: FAIL
-
-  [bottom: url(1)]
-    expected: FAIL
-
-  [top: a]
-    expected: FAIL
-
-  [top: A]
-    expected: FAIL
-
-  [top: #000001]
-    expected: FAIL
-
-  [top: 1]
-    expected: FAIL
-
-  [top: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: a]
-    expected: FAIL
-
-  [bottom: 1]
-    expected: FAIL
-
-  [bottom: +1]
-    expected: FAIL
-
-  [bottom: #000001]
-    expected: FAIL
-
-  [bottom: +a]
-    expected: FAIL
-
-  [bottom: +A]
-    expected: FAIL
-
-  [top: 1.5]
-    expected: FAIL
-
-  [top: +A]
-    expected: FAIL
-
-  [top: +a]
-    expected: FAIL
-
-  [top: +1]
-    expected: FAIL
-
-  [top: -1.5]
-    expected: FAIL
-
-  [top: -1\\31 .5]
-    expected: FAIL
-
-  [top: +1a]
-    expected: FAIL
-
-  [top: +1A]
-    expected: FAIL
-
-  [top: @1a]
-    expected: FAIL
-
-  [bottom: \\31 .5]
-    expected: FAIL
-
-  [top: "a"]
-    expected: FAIL
-
-  [top: #01]
-    expected: FAIL
-
-  [bottom: +1.5]
-    expected: FAIL
-
-  [bottom: -A]
-    expected: FAIL
-
-  [bottom: -a]
-    expected: FAIL
-
-  [bottom: -1\\31 ]
-    expected: FAIL
-
-  [top: #0001]
-    expected: FAIL
-
-  [bottom: -1]
-    expected: FAIL
-
-  [top: -\\31 ]
-    expected: FAIL
-
-  [top: -A]
-    expected: FAIL
-
-  [top: -a]
-    expected: FAIL
-
-  [top: -1]
-    expected: FAIL
-
-  [top: -1\\31 ]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/quirks/unitless-length/quirks.html.ini b/tests/wpt/metadata/quirks/unitless-length/quirks.html.ini
deleted file mode 100644
index 2ed601c6ff4..00000000000
--- a/tests/wpt/metadata/quirks/unitless-length/quirks.html.ini
+++ /dev/null
@@ -1,283 +0,0 @@
-[quirks.html]
-  [top: -\\31 .5]
-    expected: FAIL
-
-  [bottom: -1A]
-    expected: FAIL
-
-  [bottom: -1a]
-    expected: FAIL
-
-  [top: @1]
-    expected: FAIL
-
-  [top: "1a"]
-    expected: FAIL
-
-  [top: @a]
-    expected: FAIL
-
-  [bottom: "1"]
-    expected: FAIL
-
-  [bottom: -/**/1]
-    expected: FAIL
-
-  [top: +/**/1]
-    expected: FAIL
-
-  [bottom: @1a]
-    expected: FAIL
-
-  [top: 1\\31 ]
-    expected: FAIL
-
-  [top: url('1')]
-    expected: FAIL
-
-  [bottom: -\\31 ]
-    expected: FAIL
-
-  [top: calc(1)]
-    expected: FAIL
-
-  [top: \\31 ]
-    expected: FAIL
-
-  [bottom: +1\\31 ]
-    expected: FAIL
-
-  [bottom: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: #0001]
-    expected: FAIL
-
-  [top: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: 1a]
-    expected: FAIL
-
-  [bottom: A]
-    expected: FAIL
-
-  [bottom: #01]
-    expected: FAIL
-
-  [top: +\\31 .5]
-    expected: FAIL
-
-  [bottom: #1]
-    expected: FAIL
-
-  [top: -/**/1]
-    expected: FAIL
-
-  [bottom: +\\31 .5]
-    expected: FAIL
-
-  [bottom: \\31 ]
-    expected: FAIL
-
-  [bottom: calc(1)]
-    expected: FAIL
-
-  [top: #001]
-    expected: FAIL
-
-  [top: +\\31 ]
-    expected: FAIL
-
-  [bottom: +\\31 ]
-    expected: FAIL
-
-  [top: +1.5]
-    expected: FAIL
-
-  [top: +1\\31 ]
-    expected: FAIL
-
-  [bottom: @a]
-    expected: FAIL
-
-  [bottom: @1]
-    expected: FAIL
-
-  [top: #1]
-    expected: FAIL
-
-  [top: 1a]
-    expected: FAIL
-
-  [bottom: +1a]
-    expected: FAIL
-
-  [bottom: +1A]
-    expected: FAIL
-
-  [bottom: "a"]
-    expected: FAIL
-
-  [top: #00001]
-    expected: FAIL
-
-  [bottom: -1\\31 .5]
-    expected: FAIL
-
-  [top: "1"]
-    expected: FAIL
-
-  [bottom: 1.5]
-    expected: FAIL
-
-  [bottom: -\\31 .5]
-    expected: FAIL
-
-  [bottom: url('1')]
-    expected: FAIL
-
-  [bottom: -1.5]
-    expected: FAIL
-
-  [top: \\31 .5]
-    expected: FAIL
-
-  [bottom: "1a"]
-    expected: FAIL
-
-  [bottom: calc(2 * 2px)]
-    expected: FAIL
-
-  [bottom: +1\\31 .5]
-    expected: FAIL
-
-  [bottom: 1\\31 ]
-    expected: FAIL
-
-  [bottom: +/**/1]
-    expected: FAIL
-
-  [bottom: #00001]
-    expected: FAIL
-
-  [top: url(1)]
-    expected: FAIL
-
-  [bottom: #001]
-    expected: FAIL
-
-  [top: +1\\31 .5]
-    expected: FAIL
-
-  [top: -1a]
-    expected: FAIL
-
-  [top: -1A]
-    expected: FAIL
-
-  [bottom: url(1)]
-    expected: FAIL
-
-  [top: a]
-    expected: FAIL
-
-  [top: A]
-    expected: FAIL
-
-  [top: #000001]
-    expected: FAIL
-
-  [top: 1]
-    expected: FAIL
-
-  [top: 1\\31 .5]
-    expected: FAIL
-
-  [bottom: a]
-    expected: FAIL
-
-  [bottom: 1]
-    expected: FAIL
-
-  [bottom: +1]
-    expected: FAIL
-
-  [bottom: #000001]
-    expected: FAIL
-
-  [bottom: +a]
-    expected: FAIL
-
-  [bottom: +A]
-    expected: FAIL
-
-  [top: 1.5]
-    expected: FAIL
-
-  [top: +A]
-    expected: FAIL
-
-  [top: +a]
-    expected: FAIL
-
-  [top: +1]
-    expected: FAIL
-
-  [top: -1.5]
-    expected: FAIL
-
-  [top: -1\\31 .5]
-    expected: FAIL
-
-  [top: +1a]
-    expected: FAIL
-
-  [top: +1A]
-    expected: FAIL
-
-  [top: @1a]
-    expected: FAIL
-
-  [bottom: \\31 .5]
-    expected: FAIL
-
-  [top: "a"]
-    expected: FAIL
-
-  [top: #01]
-    expected: FAIL
-
-  [bottom: +1.5]
-    expected: FAIL
-
-  [bottom: -A]
-    expected: FAIL
-
-  [bottom: -a]
-    expected: FAIL
-
-  [bottom: -1\\31 ]
-    expected: FAIL
-
-  [top: #0001]
-    expected: FAIL
-
-  [bottom: -1]
-    expected: FAIL
-
-  [top: -\\31 ]
-    expected: FAIL
-
-  [top: -A]
-    expected: FAIL
-
-  [top: -a]
-    expected: FAIL
-
-  [top: -1]
-    expected: FAIL
-
-  [top: -1\\31 ]
-    expected: FAIL
-
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/child-css/external-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/child-css/external-import-stylesheet.html.ini
new file mode 100644
index 00000000000..3df025f6781
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/child-css/external-import-stylesheet.html.ini
@@ -0,0 +1,4 @@
+[external-import-stylesheet.html]
+  [Child css from external stylesheet.]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/child-css/internal-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/child-css/internal-import-stylesheet.html.ini
new file mode 100644
index 00000000000..67970486927
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/child-css/internal-import-stylesheet.html.ini
@@ -0,0 +1,4 @@
+[internal-import-stylesheet.html]
+  [Child css from internal stylesheet.]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/child-css/processing-instruction.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/child-css/processing-instruction.html.ini
new file mode 100644
index 00000000000..bd67d76de68
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/child-css/processing-instruction.html.ini
@@ -0,0 +1,5 @@
+[processing-instruction.html]
+  expected: ERROR
+  [Child css via a ProcessingInstruction.]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-import-stylesheet.html.ini
new file mode 100644
index 00000000000..7be8b09026e
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-import-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[external-import-stylesheet.html]
+  expected: ERROR
+  [Font from imported stylesheet (external).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-stylesheet.html.ini
new file mode 100644
index 00000000000..0f921ea1368
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/font-face/external-stylesheet.html.ini
@@ -0,0 +1,4 @@
+[external-stylesheet.html]
+  [Font from external stylesheet.]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-import-stylesheet.html.ini
new file mode 100644
index 00000000000..6efde85d6e1
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-import-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[internal-import-stylesheet.html]
+  expected: ERROR
+  [Font from imported stylesheet (internal).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini
new file mode 100644
index 00000000000..3026778ee88
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini
@@ -0,0 +1,4 @@
+[internal-stylesheet.html]
+  [Font from internal stylesheet.]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/font-face/processing-instruction.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/font-face/processing-instruction.html.ini
new file mode 100644
index 00000000000..1cc22cb19c9
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/font-face/processing-instruction.html.ini
@@ -0,0 +1,5 @@
+[processing-instruction.html]
+  expected: ERROR
+  [Font from external stylesheet (from ProcessingInstruction).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/external-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/external-import-stylesheet.html.ini
new file mode 100644
index 00000000000..7d023990731
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/external-import-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[external-import-stylesheet.html]
+  expected: ERROR
+  [Image from imported stylesheet (external).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/external-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/external-stylesheet.html.ini
new file mode 100644
index 00000000000..b4de37cfc88
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/external-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[external-stylesheet.html]
+  expected: ERROR
+  [Image from external stylesheet.]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/inline-style.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/inline-style.html.ini
new file mode 100644
index 00000000000..d9ca80637be
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/inline-style.html.ini
@@ -0,0 +1,5 @@
+[inline-style.html]
+  expected: ERROR
+  [Image from inline styles.]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/internal-import-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/internal-import-stylesheet.html.ini
new file mode 100644
index 00000000000..49c440b6e36
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/internal-import-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[internal-import-stylesheet.html]
+  expected: ERROR
+  [Image from imported stylesheet (internal).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/internal-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/internal-stylesheet.html.ini
new file mode 100644
index 00000000000..38a9b9d0cee
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/internal-stylesheet.html.ini
@@ -0,0 +1,5 @@
+[internal-stylesheet.html]
+  expected: ERROR
+  [Image from internal stylesheet.]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/presentation-attribute.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/presentation-attribute.html.ini
new file mode 100644
index 00000000000..dd679361c4b
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/presentation-attribute.html.ini
@@ -0,0 +1,4 @@
+[presentation-attribute.html]
+  [Image from presentation attributes.]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/image/processing-instruction.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/image/processing-instruction.html.ini
new file mode 100644
index 00000000000..aee0cff4d78
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/image/processing-instruction.html.ini
@@ -0,0 +1,5 @@
+[processing-instruction.html]
+  expected: ERROR
+  [Image from external stylesheet (from ProcessingInstruction).]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/svg/external-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/svg/external-stylesheet.html.ini
new file mode 100644
index 00000000000..bd05a0aeae6
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/svg/external-stylesheet.html.ini
@@ -0,0 +1,8 @@
+[external-stylesheet.html]
+  expected: ERROR
+  [Test styling SVG from external style fill]
+    expected: TIMEOUT
+
+  [Test styling SVG from external style stroke]
+    expected: NOTRUN
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/svg/inline-style.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/svg/inline-style.html.ini
new file mode 100644
index 00000000000..5e40b913aee
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/svg/inline-style.html.ini
@@ -0,0 +1,8 @@
+[inline-style.html]
+  expected: ERROR
+  [Styling SVG from inline styles stroke]
+    expected: NOTRUN
+
+  [Styling SVG from inline styles fill]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/svg/internal-stylesheet.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/svg/internal-stylesheet.html.ini
new file mode 100644
index 00000000000..b712b6a26db
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/svg/internal-stylesheet.html.ini
@@ -0,0 +1,8 @@
+[internal-stylesheet.html]
+  expected: ERROR
+  [Styling SVG from internal styles stroke]
+    expected: NOTRUN
+
+  [Styling SVG from internal styles fill]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/svg/presentation-attribute.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/svg/presentation-attribute.html.ini
new file mode 100644
index 00000000000..b784877e27b
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/svg/presentation-attribute.html.ini
@@ -0,0 +1,8 @@
+[presentation-attribute.html]
+  expected: ERROR
+  [Styling SVG from presentation attributes fill]
+    expected: TIMEOUT
+
+  [Styling SVG from presentation attributes stroke]
+    expected: NOTRUN
+
diff --git a/tests/wpt/metadata/referrer-policy/css-integration/svg/processing-instruction.html.ini b/tests/wpt/metadata/referrer-policy/css-integration/svg/processing-instruction.html.ini
new file mode 100644
index 00000000000..d2a1cee7ab7
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/css-integration/svg/processing-instruction.html.ini
@@ -0,0 +1,8 @@
+[processing-instruction.html]
+  expected: ERROR
+  [Styling SVG from ProcessingInstruction stroke]
+    expected: NOTRUN
+
+  [Styling SVG from ProcessingInstruction fill]
+    expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/url/urlencoded-parser.any.js.ini b/tests/wpt/metadata/url/urlencoded-parser.any.js.ini
index 207710f757c..110786c5f37 100644
--- a/tests/wpt/metadata/url/urlencoded-parser.any.js.ini
+++ b/tests/wpt/metadata/url/urlencoded-parser.any.js.ini
@@ -2,15 +2,18 @@
   [request.formData() with input: &&&a=b&&&&c=d&]
     expected: FAIL
 
-  [request.formData() with input: _charset_=windows-1252&test=%C2x]
-    expected: FAIL
-
-  [request.formData() with input: a&b&c]
-    expected: FAIL
-
   [request.formData() with input: a=b&c=d]
     expected: FAIL
 
+  [response.formData() with input: a&b&c]
+    expected: FAIL
+
+  [response.formData() with input: _charset_=windows-1252&test=%C2x]
+    expected: FAIL
+
+  [response.formData() with input: a=b&c=d]
+    expected: FAIL
+
 
 [urlencoded-parser.any.worker.html]
   [request.formData() with input: a&b&c]
@@ -22,6 +25,12 @@
   [response.formData() with input: a&b&c]
     expected: FAIL
 
-  [response.formData() with input: &&&a=b&&&&c=d&]
+  [response.formData() with input: a=b&c=d&]
+    expected: FAIL
+
+  [request.formData() with input: a=b&c=d]
+    expected: FAIL
+
+  [response.formData() with input: _charset_=windows-1252&test=%C2x]
     expected: FAIL
 
diff --git a/tests/wpt/metadata/wasm/jsapi/constructor/compile.any.js.ini b/tests/wpt/metadata/wasm/jsapi/constructor/compile.any.js.ini
index 9578de40fc5..7908e9e9966 100644
--- a/tests/wpt/metadata/wasm/jsapi/constructor/compile.any.js.ini
+++ b/tests/wpt/metadata/wasm/jsapi/constructor/compile.any.js.ini
@@ -20,6 +20,9 @@
   [Changing the buffer]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
 
 [compile.any.html]
   [Invalid arguments]
@@ -43,3 +46,6 @@
   [Changing the buffer]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/wasm/jsapi/constructor/instantiate.any.js.ini b/tests/wpt/metadata/wasm/jsapi/constructor/instantiate.any.js.ini
index f4791115004..9905d0809de 100644
--- a/tests/wpt/metadata/wasm/jsapi/constructor/instantiate.any.js.ini
+++ b/tests/wpt/metadata/wasm/jsapi/constructor/instantiate.any.js.ini
@@ -68,6 +68,12 @@
   [getter order for imports object: Module argument]
     expected: FAIL
 
+  [stray argument: BufferSource argument]
+    expected: FAIL
+
+  [stray argument: Module argument]
+    expected: FAIL
+
 
 [instantiate.any.worker.html]
   [Invalid arguments]
@@ -139,3 +145,9 @@
   [getter order for imports object: Module argument]
     expected: FAIL
 
+  [stray argument: BufferSource argument]
+    expected: FAIL
+
+  [stray argument: Module argument]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/wasm/jsapi/global/constructor.any.js.ini b/tests/wpt/metadata/wasm/jsapi/global/constructor.any.js.ini
index 621971f49a4..ebe8673d643 100644
--- a/tests/wpt/metadata/wasm/jsapi/global/constructor.any.js.ini
+++ b/tests/wpt/metadata/wasm/jsapi/global/constructor.any.js.ini
@@ -92,6 +92,9 @@
   [Explicit value "3" for type f32]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
 
 [constructor.any.worker.html]
   [Explicit value object with toString for type f32]
@@ -187,3 +190,6 @@
   [Explicit value "3" for type f32]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/wasm/jsapi/global/value-get-set.any.js.ini b/tests/wpt/metadata/wasm/jsapi/global/value-get-set.any.js.ini
new file mode 100644
index 00000000000..096f6b3aec2
--- /dev/null
+++ b/tests/wpt/metadata/wasm/jsapi/global/value-get-set.any.js.ini
@@ -0,0 +1,207 @@
+[value-get-set.any.worker.html]
+  [Mutable f64 (true on prototype)]
+    expected: FAIL
+
+  [Mutable i32 (true on prototype)]
+    expected: FAIL
+
+  [Immutable f32 (missing)]
+    expected: FAIL
+
+  [Immutable i32 (empty string)]
+    expected: FAIL
+
+  [i64 with default]
+    expected: FAIL
+
+  [Mutable f64 (one)]
+    expected: FAIL
+
+  [Mutable f32 (string)]
+    expected: FAIL
+
+  [Mutable i32 (true)]
+    expected: FAIL
+
+  [Mutable i32 (string)]
+    expected: FAIL
+
+  [Immutable f32 (false)]
+    expected: FAIL
+
+  [Immutable f64 (empty string)]
+    expected: FAIL
+
+  [Immutable i32 (undefined)]
+    expected: FAIL
+
+  [Mutable f32 (one)]
+    expected: FAIL
+
+  [Calling setter without argument]
+    expected: FAIL
+
+  [Immutable i32 (zero)]
+    expected: FAIL
+
+  [Immutable f64 (undefined)]
+    expected: FAIL
+
+  [Mutable i32 (one)]
+    expected: FAIL
+
+  [Immutable f32 (zero)]
+    expected: FAIL
+
+  [Immutable i32 (null)]
+    expected: FAIL
+
+  [Immutable f64 (false)]
+    expected: FAIL
+
+  [Immutable f64 (missing)]
+    expected: FAIL
+
+  [Immutable f64 (null)]
+    expected: FAIL
+
+  [Mutable f32 (true on prototype)]
+    expected: FAIL
+
+  [Immutable i32 (false)]
+    expected: FAIL
+
+  [Immutable i32 (missing)]
+    expected: FAIL
+
+  [Mutable f32 (true)]
+    expected: FAIL
+
+  [Stray argument]
+    expected: FAIL
+
+  [Immutable f32 (null)]
+    expected: FAIL
+
+  [Branding]
+    expected: FAIL
+
+  [Immutable f64 (zero)]
+    expected: FAIL
+
+  [Mutable f64 (true)]
+    expected: FAIL
+
+  [Mutable f64 (string)]
+    expected: FAIL
+
+  [Immutable f32 (empty string)]
+    expected: FAIL
+
+  [Immutable f32 (undefined)]
+    expected: FAIL
+
+
+[value-get-set.any.html]
+  [Mutable f64 (true on prototype)]
+    expected: FAIL
+
+  [Mutable i32 (true on prototype)]
+    expected: FAIL
+
+  [Immutable f32 (missing)]
+    expected: FAIL
+
+  [Immutable i32 (empty string)]
+    expected: FAIL
+
+  [i64 with default]
+    expected: FAIL
+
+  [Mutable f64 (one)]
+    expected: FAIL
+
+  [Mutable f32 (string)]
+    expected: FAIL
+
+  [Mutable i32 (true)]
+    expected: FAIL
+
+  [Mutable i32 (string)]
+    expected: FAIL
+
+  [Immutable f32 (false)]
+    expected: FAIL
+
+  [Immutable f64 (empty string)]
+    expected: FAIL
+
+  [Immutable i32 (undefined)]
+    expected: FAIL
+
+  [Mutable f32 (one)]
+    expected: FAIL
+
+  [Calling setter without argument]
+    expected: FAIL
+
+  [Immutable i32 (zero)]
+    expected: FAIL
+
+  [Immutable f64 (undefined)]
+    expected: FAIL
+
+  [Mutable i32 (one)]
+    expected: FAIL
+
+  [Immutable f32 (zero)]
+    expected: FAIL
+
+  [Immutable i32 (null)]
+    expected: FAIL
+
+  [Immutable f64 (false)]
+    expected: FAIL
+
+  [Immutable f64 (missing)]
+    expected: FAIL
+
+  [Immutable f64 (null)]
+    expected: FAIL
+
+  [Mutable f32 (true on prototype)]
+    expected: FAIL
+
+  [Immutable i32 (false)]
+    expected: FAIL
+
+  [Immutable i32 (missing)]
+    expected: FAIL
+
+  [Mutable f32 (true)]
+    expected: FAIL
+
+  [Stray argument]
+    expected: FAIL
+
+  [Immutable f32 (null)]
+    expected: FAIL
+
+  [Branding]
+    expected: FAIL
+
+  [Immutable f64 (zero)]
+    expected: FAIL
+
+  [Mutable f64 (true)]
+    expected: FAIL
+
+  [Mutable f64 (string)]
+    expected: FAIL
+
+  [Immutable f32 (empty string)]
+    expected: FAIL
+
+  [Immutable f32 (undefined)]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/wasm/jsapi/global/valueOf.any.js.ini b/tests/wpt/metadata/wasm/jsapi/global/valueOf.any.js.ini
index db00839e79f..1a66c3a7c4a 100644
--- a/tests/wpt/metadata/wasm/jsapi/global/valueOf.any.js.ini
+++ b/tests/wpt/metadata/wasm/jsapi/global/valueOf.any.js.ini
@@ -2,8 +2,14 @@
   [Branding]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
 
 [valueOf.any.html]
   [Branding]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
diff --git a/tests/wpt/metadata/wasm/jsapi/table/grow.any.js.ini b/tests/wpt/metadata/wasm/jsapi/table/grow.any.js.ini
index bb6308b8b5b..479918bff2f 100644
--- a/tests/wpt/metadata/wasm/jsapi/table/grow.any.js.ini
+++ b/tests/wpt/metadata/wasm/jsapi/table/grow.any.js.ini
@@ -38,6 +38,9 @@
   [Basic]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
 
 [grow.any.worker.html]
   [Out-of-range argument: 68719476736]
@@ -79,3 +82,6 @@
   [Basic]
     expected: FAIL
 
+  [Stray argument]
+    expected: FAIL
+
diff --git a/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini b/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini
deleted file mode 100644
index dbea4f293ad..00000000000
--- a/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[transition_calc_implicit.html]
-  expected: TIMEOUT
diff --git a/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini b/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini
new file mode 100644
index 00000000000..ac7c34f241f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini
@@ -0,0 +1,2 @@
+[unitless-length.html]
+  expected: TIMEOUT
diff --git a/tests/wpt/web-platform-tests/content-security-policy/generic/only-valid-whitespaces-are-allowed.html b/tests/wpt/web-platform-tests/content-security-policy/generic/only-valid-whitespaces-are-allowed.html
new file mode 100644
index 00000000000..d7567a93a37
--- /dev/null
+++ b/tests/wpt/web-platform-tests/content-security-policy/generic/only-valid-whitespaces-are-allowed.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+  <script>
+    var tests = [
+      // Make sure that csp works properly in normal situations
+      { "csp": "", "expected": true, "name": "Should load image without any CSP" },
+      { "csp": "img-src 'none';", "expected": false, "name": "Should not load image with 'none' CSP" },
+      // Ensure ASCII whitespaces are properly parsed
+      // ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE.
+
+      // between directive name and value
+      { "csp": "img-src\u0009'none';", "expected": false, "name": "U+0009 TAB   should be properly parsed between directive name and value" },
+      { "csp": "img-src\u000C'none';", "expected": false, "name": "U+000C FF    should be properly parsed between directive name and value" },
+      { "csp": "img-src\u000A'none';", "expected": false, "name": "U+000A LF    should be properly parsed between directive name and value" },
+      { "csp": "img-src\u000D'none';", "expected": false, "name": "U+000D CR    should be properly parsed between directive name and value" },
+      { "csp": "img-src\u0020'none';", "expected": false, "name": "U+0020 SPACE should be properly parsed between directive name and value" },
+
+      // inside directive value
+      { "csp": "img-src http://example.com\u0009http://example2.com;", "expected": false, "name": "U+0009 TAB   should be properly parsed inside directive value" },
+      { "csp": "img-src http://example.com\u000Chttp://example2.com;", "expected": false, "name": "U+000C FF    should be properly parsed inside directive value" },
+      { "csp": "img-src http://example.com\u000Ahttp://example2.com;", "expected": false, "name": "U+000A LF    should be properly parsed inside directive value" },
+      { "csp": "img-src http://example.com\u000Dhttp://example2.com;", "expected": false, "name": "U+000D CR    should be properly parsed inside directive value" },
+      { "csp": "img-src http://example.com\u0020http://example2.com;", "expected": false, "name": "U+0020 SPACE should be properly parsed inside directive value" },
+
+      // Ensure nbsp (U+00A0) is not considered a valid whitespace
+      // https://github.com/webcompat/web-bugs/issues/18902 has more details about why this particularly relevant
+      { "csp": "img-src\u00A0'none';", "expected": true, "name": "U+00A0 NBSP  should not be parsed between directive name and value" },
+      { "csp": "img-src http://example.com\u00A0http://example2.com;", "expected": true, "name": "U+00A0 NBSP  should not be parsed inside directive value" },
+    ];
+
+    tests.forEach(test => {
+      async_test(t => {
+        var url = "support/load_img_and_post_result_meta.sub.html?csp=" + encodeURIComponent(test.csp);
+        test_image_loads_as_expected(test, t, url);
+      }, test.name + " - meta tag");
+
+      // We can't test csp delivered in an HTTP header if we're testing CR/LF characters
+      if (test.csp.indexOf("\u000A") == -1 && test.csp.indexOf("\u000D") == -1) {
+        async_test(t => {
+          var url = "support/load_img_and_post_result_meta.sub.html?csp=" + encodeURIComponent(test.csp);
+          test_image_loads_as_expected(test, t, url);
+        }, test.name + " - HTTP header");
+      }
+    });
+
+    function test_image_loads_as_expected(test, t, url) {
+      var i = document.createElement('iframe');
+      i.src = url;
+      window.addEventListener('message', t.step_func(function(e) {
+        if (e.source != i.contentWindow) return;
+        if (test.expected) {
+          assert_equals(e.data, "img loaded");
+        } else {
+          assert_equals(e.data, "img not loaded");
+        }
+        t.done();
+      }));
+      document.body.appendChild(i);
+    }
+  </script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html
new file mode 100644
index 00000000000..c7a2e75dba3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+  <script>
+    var img = document.createElement("img");
+    img.src = "/content-security-policy/support/pass.png";
+    img.onload = function() { parent.postMessage('img loaded', '*'); }
+    img.onerror = function() { parent.postMessage('img not loaded', '*'); }
+    document.body.appendChild(img);
+  </script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html.sub.headers b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html.sub.headers
new file mode 100644
index 00000000000..e9bf21bab41
--- /dev/null
+++ b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_header.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: {{GET[csp]}}
diff --git a/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_meta.sub.html b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_meta.sub.html
new file mode 100644
index 00000000000..ac0cf39dd03
--- /dev/null
+++ b/tests/wpt/web-platform-tests/content-security-policy/generic/support/load_img_and_post_result_meta.sub.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+  <meta http-equiv="Content-Security-Policy" content="{{GET[csp]}}">
+</head>
+<body>
+  <script>
+    var img = document.createElement("img");
+    img.src = "/content-security-policy/support/pass.png";
+    img.onload = function() { parent.postMessage('img loaded', '*'); }
+    img.onerror = function() { parent.postMessage('img not loaded', '*'); }
+    document.body.appendChild(img);
+  </script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/css/css-animations/animationevent-interface.js b/tests/wpt/web-platform-tests/css/css-animations/animationevent-interface.js
index 56d30a4a377..e35b7fcb0f9 100644
--- a/tests/wpt/web-platform-tests/css/css-animations/animationevent-interface.js
+++ b/tests/wpt/web-platform-tests/css/css-animations/animationevent-interface.js
@@ -78,11 +78,139 @@
     assert_equals(event.animationName, "sample");
   }, "animationName set to 'sample'");
 
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: undefined});
+    assert_equals(event.animationName, "");
+  }, "animationName set to undefined");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: null});
+    assert_equals(event.animationName, "null");
+  }, "animationName set to null");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: false});
+    assert_equals(event.animationName, "false");
+  }, "animationName set to false");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: true});
+    assert_equals(event.animationName, "true");
+  }, "animationName set to true");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: 0.5});
+    assert_equals(event.animationName, "0.5");
+  }, "animationName set to a number");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: []});
+    assert_equals(event.animationName, "");
+  }, "animationName set to []");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: [1, 2, 3]});
+    assert_equals(event.animationName, "1,2,3");
+  }, "animationName set to [1, 2, 3]");
+
+  test(function() {
+    var event = new AnimationEvent("test", {animationName: {sample: 0.5}});
+    assert_equals(event.animationName, "[object Object]");
+  }, "animationName set to an object");
+
+  test(function() {
+    var event = new AnimationEvent("test",
+        {animationName: {valueOf: function () { return 'sample'; }}});
+    assert_equals(event.animationName, "[object Object]");
+  }, "animationName set to an object with a valueOf function");
+
   test(function() {
     var event = new AnimationEvent("test", {elapsedTime: 0.5});
     assert_equals(event.elapsedTime, 0.5);
   }, "elapsedTime set to 0.5");
 
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: -0.5});
+    assert_equals(event.elapsedTime, -0.5);
+  }, "elapsedTime set to -0.5");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: undefined});
+    assert_equals(event.elapsedTime, 0);
+  }, "elapsedTime set to undefined");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: null});
+    assert_equals(event.elapsedTime, 0);
+  }, "elapsedTime set to null");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: false});
+    assert_equals(event.elapsedTime, 0);
+  }, "elapsedTime set to false");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: true});
+    assert_equals(event.elapsedTime, 1);
+  }, "elapsedTime set to true");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: ""});
+    assert_equals(event.elapsedTime, 0);
+  }, "elapsedTime set to ''");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: []});
+    assert_equals(event.elapsedTime, 0);
+  }, "elapsedTime set to []");
+
+  test(function() {
+    var event = new AnimationEvent("test", {elapsedTime: [0.5]});
+    assert_equals(event.elapsedTime, 0.5);
+  }, "elapsedTime set to [0.5]");
+
+  test(function() {
+    var event = new AnimationEvent(
+        "test", {elapsedTime: { valueOf: function() { return 0.5; }}});
+    assert_equals(event.elapsedTime, 0.5);
+  }, "elapsedTime set to an object with a valueOf function");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: NaN});
+    }, 'elapsedTime cannot be NaN so was expecting a TypeError');
+  }, "elapsedTime cannot be set to NaN");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: Infinity});
+    }, 'elapsedTime cannot be Infinity so was expecting a TypeError');
+  }, "elapsedTime cannot be set to Infinity");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: -Infinity});
+    }, 'elapsedTime cannot be -Infinity so was expecting a TypeError');
+  }, "elapsedTime cannot be set to -Infinity");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: "sample"});
+    }, 'elapsedTime cannot be a string so was expecting a TypeError');
+  }, "elapsedTime cannot be set to 'sample'");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: [0.5, 1.0]});
+    }, 'elapsedTime cannot be a multi-element array so was expecting a TypeError');
+  }, "elapsedTime cannot be set to [0.5, 1.0]");
+
+  test(function() {
+    assert_throws(new TypeError(), function() {
+      new AnimationEvent("test", {elapsedTime: { sample: 0.5}});
+    }, 'elapsedTime cannot be an object so was expecting a TypeError');
+  }, "elapsedTime cannot be set to an object");
+
   test(function() {
     var eventInit = {animationName: "sample", elapsedTime: 0.5};
     var event = new AnimationEvent("test", eventInit);
diff --git a/tests/wpt/web-platform-tests/css/css-animations/historical.html b/tests/wpt/web-platform-tests/css/css-animations/historical.html
new file mode 100644
index 00000000000..5b96a422f55
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-animations/historical.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+
+<title>Historical CSS Animation features must be removed</title>
+<link rel="help" href="http://www.w3.org/TR/css3-animations">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function isInterfaceNuked(name) {
+  test(function() {
+    assert_equals(window[name], undefined)
+  }, "Historical CSS features must be removed: " + name)
+}
+var nukedInterfaces = [
+  "WebKitAnimationEvent", // Replaced by unprefixed AnimationEvent
+];
+nukedInterfaces.forEach(isInterfaceNuked);
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip-color-repaint.html b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip-color-repaint.html
index 6052db526a3..4a5cee08009 100644
--- a/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip-color-repaint.html
+++ b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip-color-repaint.html
@@ -31,5 +31,4 @@
       document.documentElement.classList.remove("reftest-wait");
     });
   });
-  inner.style.backgroundClip = "border-box";
 </script>
diff --git a/tests/wpt/web-platform-tests/css/css-contain/contain-size-fieldset-001.html b/tests/wpt/web-platform-tests/css/css-contain/contain-size-fieldset-001.html
new file mode 100644
index 00000000000..f92424716ce
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-contain/contain-size-fieldset-001.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on fieldset</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-fieldset-001-ref.html">
+<meta name=assert content="Size containment does apply to fieldsets, thus their size is the same than if they don't have contents.">
+<style>
+fieldset {
+  contain: size;
+  display: inline-block;
+  color: transparent;
+  border: none;
+  padding: 0;
+}
+</style>
+
+<p>This test passes if it has the same output as the reference. You see the word "before", a small space, and then the word "after".</p>
+before<fieldset><legend>legend</legend></fieldset>after
diff --git a/tests/wpt/web-platform-tests/css/css-contain/reference/contain-size-fieldset-001-ref.html b/tests/wpt/web-platform-tests/css/css-contain/reference/contain-size-fieldset-001-ref.html
new file mode 100644
index 00000000000..85f5c73c2ec
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-contain/reference/contain-size-fieldset-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Reference file</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<style>
+fieldset {
+  display: inline-block;
+  color: transparent;
+  border: none;
+  padding: 0;
+}
+</style>
+
+<p>This test passes if it has the same output as the reference. You see the word "before", a small space, and then the word "after".</p>
+before<fieldset></fieldset>after
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-001.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-001.html
new file mode 100644
index 00000000000..25ce0619dbf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-001.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'align-self' property's value of a grid item from 'baseline' will exclude such item from its baseline context, which implies recomputing all the baseline offsets and aligning the items left in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 100px / 50px 50px 50px;
+  background: grey;
+  align-items: baseline;
+}
+#item1 {
+  height: 20px;
+  background: blue;
+}
+#item2 {
+  height: 50px;
+  background: green;
+}
+#item3 {
+  height: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-y": 30 },
+        item2: {"data-offset-y": 0  },
+        item3: {"data-offset-y": 20 }
+    };
+
+    let after = {
+        item1: {"data-offset-y": 10 },
+        item2: {"data-offset-y": 50 },
+        item3: {"data-offset-y": 0  }
+    };
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.alignSelf = "end";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="50" data-expected-height="20" data-offset-x="0"></div>
+        <div id="item2" data-expected-width="50" data-expected-height="50" data-offset-x="50"></div>
+        <div id="item3" data-expected-width="50" data-expected-height="30" data-offset-x="100"></div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-002.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-002.html
new file mode 100644
index 00000000000..c97be7ddb81
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-002.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'align-self' property's value of a grid item to 'baseline' will include such item into a baseline context, which implies recomputing all the baseline offsets and aligning the items in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 100px / 50px 50px 50px;
+  background: grey;
+  align-items: baseline;
+}
+#item1 {
+  height: 20px;
+  background: blue;
+}
+#item2 {
+  height: 50px;
+  background: green;
+  align-self: center;
+}
+#item3 {
+  height: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-y": 10 },
+        item2: {"data-offset-y": 25 },
+        item3: {"data-offset-y": 0  }
+    };
+
+    let after = {
+        item1: {"data-offset-y": 30 },
+        item2: {"data-offset-y": 0  },
+        item3: {"data-offset-y": 20 }
+    };
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.alignSelf = "baseline";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="50" data-expected-height="20" data-offset-x="0"></div>
+        <div id="item2" data-expected-width="50" data-expected-height="50" data-offset-x="50"></div>
+        <div id="item3" data-expected-width="50" data-expected-height="30" data-offset-x="100"></div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-003.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-003.html
new file mode 100644
index 00000000000..bca78d76569
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-003.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing the Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#justify-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align/#typedef-baseline-position">
+<meta name="assert" content="Changing the justify-self' property's value of a grid item from 'baseline' will exclude such item from its baseline context, which implies recomputing all the baseline offsets and aligning the items left in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 50px 50px 50px / 100px;
+  background: grey;
+  justify-items: baseline;
+}
+#container > div { writing-mode: vertical-rl; }
+#item1 {
+  width: 20px;
+  background: blue;
+}
+#item2 {
+  width: 50px;
+  background: green;
+}
+#item3 {
+  width: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-x": 30 },
+        item2: {"data-offset-x": 0  },
+        item3: {"data-offset-x": 20 }
+    };
+
+    let after = {
+        item1: {"data-offset-x": 10 },
+        item2: {"data-offset-x": 50 },
+        item3: {"data-offset-x": 0  }
+    };
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.justifySelf = "end";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="20" data-expected-height="50" data-offset-y="0"></div>
+        <div id="item2" data-expected-width="50" data-expected-height="50" data-offset-y="50"></div>
+        <div id="item3" data-expected-width="30" data-expected-height="50" data-offset-y="100"></div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-004.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-004.html
new file mode 100644
index 00000000000..3064f42396f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-004.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing the Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#justify-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'justify-self' property's value of a grid item to 'baseline' will include such item into a baseline context, which implies recomputing all the baseline offsets and aligning the items in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 50px 50px 50px / 100px;
+  background: grey;
+  justify-items: baseline;
+}
+#container > div { writing-mode: vertical-rl; }
+#item1 {
+  width: 20px;
+  background: blue;
+}
+#item2 {
+  width: 50px;
+  background: green;
+  justify-self: center;
+}
+#item3 {
+  width: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-x": 10 },
+        item2: {"data-offset-x": 25 },
+        item3: {"data-offset-x": 0  }
+    };
+
+    let after = {
+        item1: {"data-offset-x": 30 },
+        item2: {"data-offset-x": 0  },
+        item3: {"data-offset-x": 20 }
+    };
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.justifySelf = "baseline";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="20" data-expected-height="50" data-offset-y="0"></div>
+        <div id="item2" data-expected-width="50" data-expected-height="50" data-offset-y="50"></div>
+        <div id="item3" data-expected-width="30" data-expected-height="50" data-offset-y="100"></div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-005.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-005.html
new file mode 100644
index 00000000000..550eed73f50
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-005.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'align-self' property's value of a grid item from 'baseline' will exclude such item from its baseline context, which implies recomputing all the baseline offsets and aligning the items left in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 100px / 50px 50px 50px;
+  background: grey;
+  align-items: baseline;
+  font-family: Ahem;
+}
+#item1 {
+  font-size: 20px;
+  background: blue;
+}
+#item2 {
+  font-size: 40px;
+  background: green;
+}
+#item3 {
+  font-size: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-y": 16 },
+        item2: {"data-offset-y": 0  },
+        item3: {"data-offset-y": 8  }
+    }
+
+    let after = {
+        item1: {"data-offset-y": 8  },
+        item2: {"data-offset-y": 60 },
+        item3: {"data-offset-y": 0  }
+    }
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.alignSelf = "end";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="50" data-expected-height="20" data-offset-x="0">É</div>
+        <div id="item2" data-expected-width="50" data-expected-height="40" data-offset-x="50">É</div>
+        <div id="item3" data-expected-width="50" data-expected-height="30" data-offset-x="100">É</div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-006.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-006.html
new file mode 100644
index 00000000000..1df78c051f7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-006.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'align-self' property's value of a grid item to 'baseline' will include such item into a baseline context, which implies recomputing all the baseline offsets and aligning the items in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 100px / 50px 50px 50px;
+  background: grey;
+  align-items: baseline;
+  font-family: Ahem;
+}
+#item1 {
+  font-size: 20px;
+  background: blue;
+}
+#item2 {
+  font-size: 40px;
+  background: green;
+  align-self: center;
+}
+#item3 {
+  font-size: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-y": 8  },
+        item2: {"data-offset-y": 30 },
+        item3: {"data-offset-y": 0  }
+    }
+
+    let after = {
+        item1: {"data-offset-y": 16 },
+        item2: {"data-offset-y": 0  },
+        item3: {"data-offset-y": 8  }
+    }
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.alignSelf = "baseline";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="50" data-expected-height="20" data-offset-x="0">É</div>
+        <div id="item2" data-expected-width="50" data-expected-height="40" data-offset-x="50">É</div>
+        <div id="item3" data-expected-width="50" data-expected-height="30" data-offset-x="100">É</div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-007.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-007.html
new file mode 100644
index 00000000000..4d0231bf393
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-007.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing the value of Self-Alignment properties</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#justify-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'align-self' property's value of a grid item from 'baseline' will exclude such item from its baseline context, which implies recomputing all the baseline offsets and aligning the items left in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 50px 50px 50px / 100px;
+  background: grey;
+  justify-items: baseline;
+  font-family: Ahem;
+  text-orientation: sideways;
+}
+#container > div { writing-mode: vertical-lr; }
+#item1 {
+  font-size: 20px;
+  background: blue;
+}
+#item2 {
+  font-size: 40px;
+  background: green;
+}
+#item3 {
+  font-size: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-x": 4 },
+        item2: {"data-offset-x": 0 },
+        item3: {"data-offset-x": 2 }
+    }
+
+    let after = {
+        item1: {"data-offset-x": 2 },
+        item2: {"data-offset-x": 60 },
+        item3: {"data-offset-x": 0  }
+    }
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.justifySelf = "end";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="20" data-expected-height="50" data-offset-y="0">É</div>
+        <div id="item2" data-expected-width="40" data-expected-height="50" data-offset-y="50">É</div>
+        <div id="item3" data-expected-width="30" data-expected-height="50" data-offset-y="100">É</div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-008.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-008.html
new file mode 100644
index 00000000000..026f035ba92
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-alignment-style-changes-008.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Changing the Self-Alignment properties to interfere in Baseline Alignment</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#self-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#justify-self-property">
+<link rel="help" href="https://drafts.csswg.org/css-align/#typedef-baseline-position">
+<meta name="assert" content="Changing the 'justify-self' property's value of a grid item to 'baseline' will include such item into a baseline context, which implies recomputing all the baseline offsets and aligning the items in such context.">
+<style>
+#container {
+  position: relative;
+  display: inline-grid;
+  grid: 50px 50px 50px / 100px;
+  background: grey;
+  justify-items: baseline;
+  font-family: Ahem;
+}
+#container > div { writing-mode: vertical-lr; }
+#item1 {
+  font-size: 20px;
+  background: blue;
+}
+#item2 {
+  font-size: 40px;
+  background: green;
+  justify-self: center;
+}
+#item3 {
+  font-size: 30px;
+  background: red;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script src="support/style-change.js"></script>
+<script>
+function runTest() {
+    let before = {
+        item1: {"data-offset-x": 5  },
+        item2: {"data-offset-x": 30 },
+        item3: {"data-offset-x": 0  }
+    };
+
+    let after = {
+        item1: {"data-offset-x": 10 },
+        item2: {"data-offset-x": 0  },
+        item3: {"data-offset-x": 5  }
+    };
+
+    evaluateStyleChangeMultiple("before", before);
+    item2.style.justifySelf = "baseline";
+    evaluateStyleChangeMultiple("after", after);
+    done();
+}
+</script>
+<body onload="runTest()">
+    <div id="container">
+        <div id="item1" data-expected-width="20" data-expected-height="50" data-offset-y="0">É</div>
+        <div id="item2" data-expected-width="40" data-expected-height="50" data-offset-y="50">É</div>
+        <div id="item3" data-expected-width="30" data-expected-height="50" data-offset-y="100">É</div>
+    </div>
+    <div id="log"></div>
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html
new file mode 100644
index 00000000000..5ffacfdb2b4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment and sizing cyclic dependency</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Items not participating in baseline may later participate if there is an extra pass of the track sizing algorithm.">
+<!-- https://github.com/w3c/csswg-drafts/issues/3046 -->
+<style>
+.grid {
+  position: relative;
+  display: inline-grid;
+  background: grey;
+  text-orientation: sideways;
+  font-family: Ahem;
+}
+.row { grid: minmax(0px, 1fr) / 50px 50px 100px }
+.column { grid: 50px 50px 100px / minmax(0px, 1fr); }
+.item1 {
+   font-size: 30px;
+   background: blue;
+}
+.item2 {
+  font-size: 20px;
+  background: red;
+}
+.item3 {
+  font-size: 80px;
+  background: green;
+}
+.height50 { height: 50px; }
+.relativeHeight { height: 50%; }
+.relativeWidth  { width: 50%; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>flex rows - column-axis baseline - the blue orthogonal item didn't participate in the first iteration</pre>
+<div class="grid row alignItemsBaseline">
+  <div class="item1 verticalLR" data-offset-x="0"   data-offset-y="34" data-expected-width="50"  data-expected-height="30">É</div>
+  <div class="item2"            data-offset-x="50"  data-offset-y="48" data-expected-width="50"  data-expected-height="20">É</div>
+  <div class="item3"            data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="80">É</div>
+</div>
+
+<pre>flex row - column-axis baseline - the blue relative sized item didn't participate in the first iterarion</pre>
+<div class="grid row alignItemsBaseline ">
+  <div class="item1 relativeHeight" data-offset-x="0"   data-offset-y="40" data-expected-width="50"  data-expected-height="40"></div>
+  <div class="item2"                data-offset-x="50"  data-offset-y="64" data-expected-width="50"  data-expected-height="20">É</div>
+  <div class="item3 verticalLR"     data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="80">É</div>
+</div>
+
+<pre>flex row - both the blue relative sized and red orthogonal didn't participate in the first iteration</pre>
+<div class="grid row alignItemsBaseline">
+  <div class="item1 relativeHeight" data-offset-x="0"   data-offset-y="24" data-expected-width="50"  data-expected-height="40"></div>
+  <div class="item2 verticalLR"     data-offset-x="50"  data-offset-y="44" data-expected-width="50"  data-expected-height="20">É</div>
+  <div class="item3"                data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="80">É</div>
+</div>
+
+<pre>flex column - row-axis baseline - the blue orthogonal item didn't participate in the first iteration</pre>
+<div class="grid column justifyItemsBaseline">
+  <div class="item1"            data-offset-x="16" data-offset-y="0"   data-expected-width="30" data-expected-height="50">É</div>
+  <div class="item2 verticalLR" data-offset-x="12" data-offset-y="50"  data-expected-width="20" data-expected-height="50">É</div>
+  <div class="item3 verticalLR" data-offset-x="0"  data-offset-y="100" data-expected-width="80" data-expected-height="100">É</div>
+</div>
+
+<pre>flex column - column-axis baseline - the blue relative sized item didn't participate in the first iterarion</pre>
+<div class="grid column justifyItemsBaseline">
+  <div class="item1 relativeWidth height50" data-offset-x="16" data-offset-y="0"   data-expected-width="40" data-expected-height="50"></div>
+  <div class="item2 verticalLR"             data-offset-x="12" data-offset-y="50"  data-expected-width="20" data-expected-height="50">É</div>
+  <div class="item3 verticalLR"             data-offset-x="0"  data-offset-y="100" data-expected-width="80" data-expected-height="100">É</div>
+</div>
+
+<pre>flex columns - both the blue relative sized and red orthogonal didn't participate in the first iteration</pre>
+<div class="grid column justifyItemsBaseline">
+  <div class="item1 relativeWidth height50" data-offset-x="16" data-offset-y="0"   data-expected-width="40" data-expected-height="50"></div>
+  <div class="item2"                        data-offset-x="16" data-offset-y="50"  data-expected-width="20" data-expected-height="50">É</div>
+  <div class="item3 verticalLR"             data-offset-x="0"  data-offset-y="100" data-expected-width="80" data-expected-height="100">É</div>
+</div>
+
+</body>
diff --git a/tests/wpt/web-platform-tests/css/css-grid/alignment/support/style-change.js b/tests/wpt/web-platform-tests/css/css-grid/alignment/support/style-change.js
index 5619394da2b..766d140d2b2 100644
--- a/tests/wpt/web-platform-tests/css/css-grid/alignment/support/style-change.js
+++ b/tests/wpt/web-platform-tests/css/css-grid/alignment/support/style-change.js
@@ -3,3 +3,12 @@ function evaluateStyleChange(element, phase, expectedProperty, expectedResult) {
     element.setAttribute(expectedProperty, expectedResult);
     checkLayout("." + phase, false);
 }
+function evaluateStyleChangeMultiple(phase, expectedResult) {
+    for (var item in expectedResult) {
+        var element = document.getElementById(item);
+        element.className += " " + phase;
+        for (var key in expectedResult[item])
+            element.setAttribute(key, expectedResult[item][key]);
+    }
+    checkLayout("." + phase, false);
+}
diff --git a/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll-ref.html b/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll-ref.html
new file mode 100644
index 00000000000..1a7cfb6e230
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Multicol under vertical-rl scrolling container</title>
+<p>Passes if there are two green squares</p>
+<div id="scroller" style="width: 200px; height: 200px; overflow: scroll; border: 1px solid black">
+  <div style="width: 580px; height: 500px; position: relative">
+    <div style="position: absolute; right: 0">
+      <div style="width: 80px; height: 80px; background: green"></div>
+      <div style="height: 20px"></div>
+      <div style="width: 80px; height: 80px; background: green"></div>
+    </div>
+  </div>
+</div>
+<script>
+// Scroll all the way to the right.
+scroller.scrollLeft = 800;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll.html b/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll.html
new file mode 100644
index 00000000000..f96a26ae77b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-multicol/multicol-under-vertical-rl-scroll.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Multicol under vertical-rl scrolling container</title>
+<link rel="match" href="multicol-under-vertical-rl-scroll-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-multicol">
+<p>Passes if there are two green squares</p>
+<div style="width: 200px; height: 200px; overflow: scroll; writing-mode: vertical-rl; border: 1px solid black">
+  <div style="columns: 2; column-gap: 20px; width: 80px; height: 180px">
+    <div style="width: 160px; background: green"></div>
+  </div>
+  <div style="width: 500px; height: 500px"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html
index 8f9eafee19e..614a72a797b 100644
--- a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html
+++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html
@@ -72,4 +72,18 @@ test(function(){
     assert_equals(getComputedStyle(inner).getPropertyValue('--inherited-length-5'), '42px');
 }, "Reference to syntax-incompatible variable results in inherited value");
 
+test(function(){
+    CSS.registerProperty({name: '--inherited-em', syntax: '<length>', initialValue: '0px', inherits: true});
+    outer.style = 'font-size: 11px; --inherited-em: 10em;';
+    inner.style = 'font-size: 22px; --unregistered:var(--inherited-em);';
+    assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '110px');
+}, "Font-relative units are absolutized before before inheritance");
+
+test(function(){
+    CSS.registerProperty({name: '--calc-length', syntax: '<length>', initialValue: '0px', inherits: true});
+    outer.style = '--calc-length: calc(10px + 10px);';
+    inner.style = '--unregistered:var(--calc-length);';
+    assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '20px');
+}, "Calc expressions are resolved before inheritance");
+
 </script>
diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/unit-cycles.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/unit-cycles.html
index d65348543c4..c26e1cda1f6 100644
--- a/tests/wpt/web-platform-tests/css/css-properties-values-api/unit-cycles.html
+++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/unit-cycles.html
@@ -4,12 +4,12 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
-    function register_length(name) {
+    function register_length(name, inherits=true) {
         CSS.registerProperty({
             name: name,
             syntax: '<length>',
             initialValue: '0px',
-            inherits: false
+            inherits: inherits
         });
     }
 
@@ -22,6 +22,9 @@
     register_length('--font-size-rem-via-var');
     register_length('--font-size-ex-via-var');
     register_length('--font-size-ch-via-var');
+    register_length('--font-size-em-inherited', true);
+    register_length('--font-size-ex-inherited', true);
+    register_length('--font-size-ch-inherited', true);
 </script>
 <style>
     :root {
@@ -43,12 +46,20 @@
         --font-size-ch-via-var: var(--unregistered-ch);
     }
 
+    #parent {
+        --font-size-em-inherited: 4em;
+        --font-size-ex-inherited: 4ex;
+        --font-size-ch-inherited: 4ch;
+    }
+
     #target {
         font-size: 11px;
     }
 </style>
 
-<div id=target></div>
+<div id=parent>
+    <div id=target></div>
+</div>
 <div id=ref></div>
 
 <script>
@@ -170,4 +181,25 @@
         assert_property_equals('--font-size-rem-via-var', expected10rem, root);
     }, 'Lengths with rem units are detected via var references');
 
+    test(function() {
+        let expected4em = compute_dimension('4em', 'unset');
+        target.style = 'font-size: var(--font-size-em-inherited);';
+        assert_property_equals('font-size', expected4em);
+        assert_property_equals('--font-size-em-inherited', expected4em);
+    }, 'Inherited lengths with em units may be used');
+
+    test(function() {
+        let expected4ex = compute_dimension('4ex', 'unset');
+        target.style = 'font-size: var(--font-size-ex-inherited);';
+        assert_property_equals('font-size', expected4ex);
+        assert_property_equals('--font-size-ex-inherited', expected4ex);
+    }, 'Inherited lengths with ex units may be used');
+
+    test(function() {
+        let expected4ch = compute_dimension('4ch', 'unset');
+        target.style = 'font-size: var(--font-size-ch-inherited);';
+        assert_property_equals('font-size', expected4ch);
+        assert_property_equals('--font-size-ch-inherited', expected4ch);
+    }, 'Inherited lengths with ch units may be used');
+
 </script>
diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html
index d8a83157125..5de6d20f11b 100644
--- a/tests/wpt/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html
+++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html
@@ -54,7 +54,7 @@ test(function() {
     assert_equals(computedStyle.getPropertyValue('--registered-length-6'), '80px');
     assert_equals(computedStyle.getPropertyValue('--registered-length-7'), '123px');
     assert_equals(computedStyle.getPropertyValue('--length-1'), ' 20px');
-    assert_equals(computedStyle.getPropertyValue('--length-2'), '  10px');
+    assert_equals(computedStyle.getPropertyValue('--length-2'), ' 10px');
     assert_equals(computedStyle.getPropertyValue('--length-3'), ' calc(123px + 123px)');
     assert_equals(computedStyle.getPropertyValue('--registered-length-invalid'), '15px');
 
@@ -96,5 +96,43 @@ test(function(){
     assert_equals(computedStyle.getPropertyValue('--registered-length-list-3'), '1px, 10px, 2px, 1px, 20px, 10px, 2px');
 }, 'Registered lists may be concatenated');
 
+test(function(){
+    CSS.registerProperty({
+        name: '--length-em',
+        syntax: '<length>',
+        initialValue: '0px',
+        inherits: false
+    });
+    element.style = 'font-size: 11px; --length-em: 10em; --unregistered:var(--length-em);';
+    let computedStyle = getComputedStyle(element);
+    assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px');
+    element.style = '';
+}, 'Font-relative units are absolutized when substituting');
+
+test(function(){
+    CSS.registerProperty({
+        name: '--length-calc',
+        syntax: '<length>',
+        initialValue: '0px',
+        inherits: false
+    });
+    element.style = 'font-size: 11px; --length-calc: calc(10em + 10px); --unregistered:var(--length-calc);';
+    let computedStyle = getComputedStyle(element);
+    assert_equals(computedStyle.getPropertyValue('--unregistered'), '120px');
+    element.style = '';
+}, 'Calc expressions are resolved when substituting');
+
+test(function(){
+    CSS.registerProperty({
+        name: '--length-calc-list',
+        syntax: '<length>#',
+        initialValue: '0px',
+        inherits: false
+    });
+    element.style = 'font-size: 11px; --length-calc-list: 10em, calc(10em + 10px); --unregistered:var(--length-calc-list);';
+    let computedStyle = getComputedStyle(element);
+    assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px, 120px');
+    element.style = '';
+}, 'Lists with relative units are absolutized when substituting');
 
 </script>
diff --git a/tests/wpt/web-platform-tests/css/css-tables/caption-writing-mode-001.html b/tests/wpt/web-platform-tests/css/css-tables/caption-writing-mode-001.html
new file mode 100644
index 00000000000..835a5116ae3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-tables/caption-writing-mode-001.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<link rel="author" title="David Grogan" href="dgrogan@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-flows">
+<meta name="flags" content="" />
+<meta name="assert" content="caption margins are resolved against table's height when table has vertical flow" />
+<style>
+x-table {
+  display: table;
+  width: 300px;
+  height: 200px;
+  writing-mode: vertical-lr;
+  outline: 2px dashed blue;
+}
+x-caption {
+  display: table-caption;
+  height: 50px;
+  width: 120px;
+  writing-mode: horizontal-tb;
+  outline: 1px solid black;
+}
+</style>
+
+<x-table>
+  <x-caption id=captionMarginLeft style="margin-left:20%">caption</x-caption>
+</x-table>
+<x-table>
+  <x-caption id=captionMarginTop style="margin:auto 0">caption</x-caption>
+</x-table>
+<p>This is a script test because of how ridiculously differently the current
+engines render these cases.</p>
+
+
+<script>
+let caption_margin_left = getComputedStyle(id=captionMarginLeft).marginLeft;
+test(() => assert_equals(caption_margin_left, "40px"), "Caption percent margins are resolved against table's height for vertical-lr tables");
+let caption_margin_top = getComputedStyle(captionMarginTop).marginTop;
+test(() => assert_equals(caption_margin_top, "75px"), "Caption with auto top/bottom margins is centered vertically for vertical-lr tables");
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1-ref.html b/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1-ref.html
new file mode 100644
index 00000000000..7623adb59e6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Text Test: minimum rendered width of tab character</title>
+  <link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+  <style>
+    span { background-color: yellow; display: inline-block; letter-spacing: -.1em; }
+    pre { position: absolute; top: 0; }
+  </style>
+</head>
+<body>
+<pre>
+</pre>
+<pre>
+</pre>
+<script>
+  let pre = document.getElementsByTagName("pre")[0];
+  let test = "";
+  for (i = 7.0; i <= 8.125; i += 0.125) {
+    test += `<span style="width:${i}ch">${i}ch</span>\n`;
+  }
+  pre.innerHTML = test;
+  pre = document.getElementsByTagName("pre")[1];
+  test = "";
+  for (i = 0; i < 5; i++) {
+    test += `\tfoo\n`;
+  }
+  for (i = 0; i < 5; i++) {
+    test += `\t\tfoo\n`;
+  }
+  pre.innerHTML = test;
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1.html b/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1.html
new file mode 100644
index 00000000000..6b014260e36
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Text Test: minimum rendered width of tab character</title>
+  <link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+  <link rel="reviewer" title="Xidorn Quan" href="https://www.upsuper.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
+  <link rel="match" href="tab-min-rendered-width-1-ref.html">
+  <meta name="assert" content="If [rendered width of tab would be] less than 0.5ch, then the subsequent tab stop is used instead.">
+  <style>
+    span { background-color: yellow; display: inline-block; letter-spacing: -.1em; }
+    pre { position: absolute; top: 0; }
+  </style>
+</head>
+<body>
+<pre>
+</pre>
+<script>
+  let pre = document.getElementsByTagName("pre")[0];
+  let test = "";
+  for (i = 7.0; i <= 8.125; i += 0.125) {
+    test += `<span style="width:${i}ch">${i}ch</span>&#9;foo\n`;
+  }
+  pre.innerHTML = test;
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/css/css-transitions/transitionevent-interface.html b/tests/wpt/web-platform-tests/css/css-transitions/transitionevent-interface.html
new file mode 100644
index 00000000000..cd47469ec74
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transitions/transitionevent-interface.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Transitions Test: TransitionEvent interface</title>
+<link rel="help" href="https://drafts.csswg.org/css-transitions-1/#interface-transitionevent">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="transitionevent-interface.js"></script>
+
+<script>
+test(function() {
+  var event = new TransitionEvent("");
+  assert_true(event instanceof window.TransitionEvent);
+}, "the event is an instance of TransitionEvent");
+
+test(function() {
+  var event = new TransitionEvent("");
+  assert_true(event instanceof window.Event);
+}, "the event inherts from Event");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent();
+  }, 'First argument is required, so was expecting a TypeError.');
+}, 'Missing type argument');
+
+test(function() {
+  var event = new TransitionEvent("test");
+  assert_equals(event.type, "test");
+}, "type argument is string");
+
+test(function() {
+  var event = new TransitionEvent(null);
+  assert_equals(event.type, "null");
+}, "type argument is null");
+
+test(function() {
+  var event = new TransitionEvent(undefined);
+  assert_equals(event.type, "undefined");
+}, "event type set to undefined");
+
+test(function() {
+  var event = new TransitionEvent("test");
+  assert_equals(event.propertyName, "");
+}, "propertyName has default value of empty string");
+
+test(function() {
+  var event = new TransitionEvent("test");
+  assert_equals(event.elapsedTime, 0.0);
+}, "elapsedTime has default value of 0.0");
+
+test(function() {
+  var event = new TransitionEvent("test");
+  assert_readonly(event, "propertyName", "readonly attribute value");
+}, "propertyName is readonly");
+
+test(function() {
+  var event = new TransitionEvent("test");
+  assert_readonly(event, "elapsedTime", "readonly attribute value");
+}, "elapsedTime is readonly");
+
+test(function() {
+  var event = new TransitionEvent("test", null);
+  assert_equals(event.propertyName, "");
+  assert_equals(event.elapsedTime, 0.0);
+}, "animationEventInit argument is null");
+
+test(function() {
+  var event = new TransitionEvent("test", undefined);
+  assert_equals(event.propertyName, "");
+  assert_equals(event.elapsedTime, 0.0);
+}, "animationEventInit argument is undefined");
+
+test(function() {
+  var event = new TransitionEvent("test", {});
+  assert_equals(event.propertyName, "");
+  assert_equals(event.elapsedTime, 0.0);
+}, "animationEventInit argument is empty dictionary");
+
+test(function() {
+  var event = new TransitionEvent("test", {pseudoElement: "::testPseudo"});
+  assert_equals(event.pseudoElement, "::testPseudo");
+}, "TransitionEvent.pseudoElement initialized from the dictionary");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: "sample"});
+  assert_equals(event.propertyName, "sample");
+}, "propertyName set to 'sample'");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: undefined});
+  assert_equals(event.propertyName, "");
+}, "propertyName set to undefined");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: null});
+  assert_equals(event.propertyName, "null");
+}, "propertyName set to null");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: false});
+  assert_equals(event.propertyName, "false");
+}, "propertyName set to false");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: true});
+  assert_equals(event.propertyName, "true");
+}, "propertyName set to true");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: 0.5});
+  assert_equals(event.propertyName, "0.5");
+}, "propertyName set to a number");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: []});
+  assert_equals(event.propertyName, "");
+}, "propertyName set to []");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: [1, 2, 3]});
+  assert_equals(event.propertyName, "1,2,3");
+}, "propertyName set to [1, 2, 3]");
+
+test(function() {
+  var event = new TransitionEvent("test", {propertyName: {sample: 0.5}});
+  assert_equals(event.propertyName, "[object Object]");
+}, "propertyName set to an object");
+
+test(function() {
+  var event = new TransitionEvent("test",
+      {propertyName: {valueOf: function () { return 'sample'; }}});
+  assert_equals(event.propertyName, "[object Object]");
+}, "propertyName set to an object with a valueOf function");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: 0.5});
+  assert_equals(event.elapsedTime, 0.5);
+}, "elapsedTime set to 0.5");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: -0.5});
+  assert_equals(event.elapsedTime, -0.5);
+}, "elapsedTime set to -0.5");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: undefined});
+  assert_equals(event.elapsedTime, 0);
+}, "elapsedTime set to undefined");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: null});
+  assert_equals(event.elapsedTime, 0);
+}, "elapsedTime set to null");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: false});
+  assert_equals(event.elapsedTime, 0);
+}, "elapsedTime set to false");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: true});
+  assert_equals(event.elapsedTime, 1);
+}, "elapsedTime set to true");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: ""});
+  assert_equals(event.elapsedTime, 0);
+}, "elapsedTime set to ''");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: []});
+  assert_equals(event.elapsedTime, 0);
+}, "elapsedTime set to []");
+
+test(function() {
+  var event = new TransitionEvent("test", {elapsedTime: [0.5]});
+  assert_equals(event.elapsedTime, 0.5);
+}, "elapsedTime set to [0.5]");
+
+test(function() {
+  var event = new TransitionEvent(
+      "test", {elapsedTime: { valueOf: function() { return 0.5; }}});
+  assert_equals(event.elapsedTime, 0.5);
+}, "elapsedTime set to an object with a valueOf function");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: NaN});
+  }, 'elapsedTime cannot be NaN so was expecting a TypeError');
+}, "elapsedTime cannot be set to NaN");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: Infinity});
+  }, 'elapsedTime cannot be Infinity so was expecting a TypeError');
+}, "elapsedTime cannot be set to Infinity");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: -Infinity});
+  }, 'elapsedTime cannot be -Infinity so was expecting a TypeError');
+}, "elapsedTime cannot be set to -Infinity");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: "sample"});
+  }, 'elapsedTime cannot be a string so was expecting a TypeError');
+}, "elapsedTime cannot be set to 'sample'");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: [0.5, 1.0]});
+  }, 'elapsedTime cannot be a multi-element array so was expecting a TypeError');
+}, "elapsedTime cannot be set to [0.5, 1.0]");
+
+test(function() {
+  assert_throws(new TypeError(), function() {
+    new TransitionEvent("test", {elapsedTime: { sample: 0.5}});
+  }, 'elapsedTime cannot be an object so was expecting a TypeError');
+}, "elapsedTime cannot be set to an object");
+
+test(function() {
+  var eventInit = {propertyName: "sample", elapsedTime: 0.5};
+  var event = new TransitionEvent("test", eventInit);
+  assert_equals(event.propertyName, "sample");
+  assert_equals(event.elapsedTime, 0.5);
+}, "TransitionEventInit properties set value");
+</script>
diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md
index 952c8365fb7..9f93ea844d7 100644
--- a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md
+++ b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md
@@ -793,14 +793,6 @@ asserts that one `assert_func(actual, expected_array_N, extra_arg1, ..., extra_a
   allows multiple behaviours. Test authors should not use this method simply to hide
   UA bugs.
 
-### `assert_exists(object, property_name, description)`
-**deprecated**
-asserts that object has an own property `property_name`
-
-### `assert_not_exists(object, property_name, description)`
-**deprecated**
-assert that object does not have own property `property_name`
-
 ## Metadata ##
 
 It is possible to add optional metadata to tests; this can be done in
diff --git a/tests/wpt/web-platform-tests/dom/events/shadow-relatedTarget.html b/tests/wpt/web-platform-tests/dom/events/shadow-relatedTarget.html
new file mode 100644
index 00000000000..713555b7d8a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/events/shadow-relatedTarget.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!--
+  This test is adopted from Olli Pettay's test case at
+  http://mozilla.pettay.fi/shadow_focus.html
+-->
+<div id="host"></div>
+<input id="lightInput">
+<script>
+const root = host.attachShadow({ mode: "closed" });
+root.innerHTML = "<input id='shadowInput'>";
+
+async_test((test) => {
+  root.getElementById("shadowInput").focus();
+  window.addEventListener("focus", test.step_func_done((e) => {
+    assert_equals(e.relatedTarget, host);
+  }, "relatedTarget should be pointing to shadow host."), true);
+  lightInput.focus();
+}, "relatedTarget should not leak at capturing phase, at window object.");
+
+async_test((test) => {
+  root.getElementById("shadowInput").focus();
+  lightInput.addEventListener("focus", test.step_func_done((e) => {
+    assert_equals(e.relatedTarget, host);
+  }, "relatedTarget should be pointing to shadow host."), true);
+  lightInput.focus();
+}, "relatedTarget should not leak at target.");
+
+</script>
diff --git a/tests/wpt/web-platform-tests/eventsource/eventsource-prototype.htm b/tests/wpt/web-platform-tests/eventsource/eventsource-prototype.htm
index 38f63eb5f00..24bf9954007 100644
--- a/tests/wpt/web-platform-tests/eventsource/eventsource-prototype.htm
+++ b/tests/wpt/web-platform-tests/eventsource/eventsource-prototype.htm
@@ -12,7 +12,7 @@
         EventSource.prototype.ReturnTrue = function() { return true }
         var source = new EventSource("resources/message.py")
         assert_true(source.ReturnTrue())
-        assert_exists(window, "EventSource")
+        assert_own_property(window, "EventSource")
         source.close()
       })
     </scrIpt>
diff --git a/tests/wpt/web-platform-tests/fetch/corb/script-html-via-cross-origin-blob-url.sub.html b/tests/wpt/web-platform-tests/fetch/corb/script-html-via-cross-origin-blob-url.sub.html
index 8ce7987ff89..c8a90c79b3f 100644
--- a/tests/wpt/web-platform-tests/fetch/corb/script-html-via-cross-origin-blob-url.sub.html
+++ b/tests/wpt/web-platform-tests/fetch/corb/script-html-via-cross-origin-blob-url.sub.html
@@ -19,7 +19,7 @@ async_test(function(t) {
   }
 
   function step2_processSubframeMsg(msg) {
-    assert_not_exists(msg, 'error');
+    assert_false(msg.hasOwnProperty('error'), 'unexpected property found: "error"');
     assert_equals(msg.blob_type, 'text/html');
     assert_equals(msg.blob_size, 147);
 
diff --git a/tests/wpt/web-platform-tests/fullscreen/api/document-exit-fullscreen-timing-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/document-exit-fullscreen-timing-manual.html
index 7a536363a21..6ccc365c711 100644
--- a/tests/wpt/web-platform-tests/fullscreen/api/document-exit-fullscreen-timing-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/api/document-exit-fullscreen-timing-manual.html
@@ -20,7 +20,7 @@ async_test(t => {
     const events = [];
     const callback = t.step_func(event => {
       // fullscreenElement should have changed before either event is fired.
-      assert_equals(document.fullscreenElement, null, `fullscreenElement in {event.type} event`);
+      assert_equals(document.fullscreenElement, null, `fullscreenElement in ${event.type} event`);
       events.push(event.type);
       if (event.type == 'fullscreenchange') {
         step_timeout(t.unreached_func('timer callback'));
diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html
index 8ba2ab71b15..06495492656 100644
--- a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html
@@ -7,18 +7,19 @@
 <iframe allowfullscreen></iframe>
 <iframe allowfullscreen></iframe>
 <script>
-async_test(function(t)
-{
-    var iframes = document.getElementsByTagName("iframe");
-    trusted_request(t, iframes[0].contentDocument.body, document.body);
-    iframes[0].contentDocument.onfullscreenchange = t.step_func(function()
-    {
-        assert_equals(document.fullscreenElement, iframes[0]);
-        trusted_request(t, iframes[1].contentDocument.body, iframes[0].contentDocument.body);
-        iframes[1].contentDocument.onfullscreenchange = t.step_func_done(function() {
-            assert_equals(document.fullscreenElement, iframes[1]);
-        });
-        iframes[1].contentDocument.onfullscreenerror = t.unreached_func("fullscreenchange error");
-    });
-});
+// wait for load event to avoid https://bugzil.la/1493878
+window.onload = function() {
+  async_test(function(t) {
+      var iframes = document.getElementsByTagName("iframe");
+      trusted_request(t, iframes[0].contentDocument.body, document.body);
+      iframes[0].contentDocument.onfullscreenchange = t.step_func(function() {
+          assert_equals(document.fullscreenElement, iframes[0]);
+          trusted_request(t, iframes[1].contentDocument.body, iframes[0].contentDocument.body);
+          iframes[1].contentDocument.onfullscreenchange = t.step_func_done(function() {
+              assert_equals(document.fullscreenElement, iframes[1]);
+          });
+          iframes[1].contentDocument.onfullscreenerror = t.unreached_func("fullscreenchange error");
+      });
+  });
+};
 </script>
diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-not-allowed-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-not-allowed-manual.html
index 1e18be5e677..fa5a923b2b2 100644
--- a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-not-allowed-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-not-allowed-manual.html
@@ -6,14 +6,16 @@
 <div id="log"></div>
 <iframe></iframe>
 <script>
-async_test(function(t)
-{
-    var iframe = document.querySelector("iframe");
-    document.onfullscreenchange = t.unreached_func("document fullscreenchange event");
-    document.onfullscreenerror = t.unreached_func("document fullscreenerror event");
-    iframe.contentDocument.onfullscreenchange = t.unreached_func("iframe fullscreenchange event");
-    iframe.contentDocument.onfullscreenerror = t.step_func_done();
-    assert_false(iframe.contentDocument.fullscreenEnabled, "fullscreen enabled flag");
-    trusted_request(t, iframe.contentDocument.body, document.body);
-});
+// wait for load event to avoid https://bugzil.la/1493878
+window.onload = function() {
+  async_test(function(t) {
+      var iframe = document.querySelector("iframe");
+      document.onfullscreenchange = t.unreached_func("document fullscreenchange event");
+      document.onfullscreenerror = t.unreached_func("document fullscreenerror event");
+      iframe.contentDocument.onfullscreenchange = t.unreached_func("iframe fullscreenchange event");
+      iframe.contentDocument.onfullscreenerror = t.step_func_done();
+      assert_false(iframe.contentDocument.fullscreenEnabled, "fullscreen enabled flag");
+      trusted_request(t, iframe.contentDocument.body, document.body);
+  });
+};
 </script>
diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-and-exit-iframe-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-and-exit-iframe-manual.html
index dc2a99c1e83..6d5bed19f3b 100644
--- a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-and-exit-iframe-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-and-exit-iframe-manual.html
@@ -6,37 +6,40 @@
 <div id="log"></div>
 <iframe allowfullscreen></iframe>
 <script>
-async_test(t => {
-  const iframe = document.querySelector('iframe');
-  const iframeDoc = iframe.contentDocument;
-  const iframeBody = iframeDoc.body;
+// wait for load event to avoid https://bugzil.la/1493878
+window.onload = function() {
+  async_test(t => {
+    const iframe = document.querySelector('iframe');
+    const iframeDoc = iframe.contentDocument;
+    const iframeBody = iframeDoc.body;
 
-  let count = 0;
-  document.onfullscreenchange = iframeDoc.onfullscreenchange = t.step_func(event => {
-    count++;
-    assert_between_inclusive(count, 1, 4, 'number of fullscreenchange events');
-    // Both when entering and exiting, the fullscreenchange event is fired first
-    // on the outer document and then on the iframe's document. This is because
-    // the events are fired in animation frame tasks, which run in "frame tree"
-    // order.
-    const expected = {
-      target: count == 1 || count == 3 ? iframe : iframeBody,
-      outerFullscreenElement: count <= 2 ? iframe : null,
-      innerFullscreenElement: count <= 2 ? iframeBody : null,
-    };
-    assert_equals(event.target, expected.target, 'event target');
-    assert_equals(document.fullscreenElement, expected.outerFullscreenElement, 'outer fullscreenElement');
-    assert_equals(iframeDoc.fullscreenElement, expected.innerFullscreenElement, 'inner fullscreenElement');
-    if (count == 2) {
-      iframeDoc.exitFullscreen();
-    } else if (count == 4) {
-      // Done, but set timeout to fail on extra events.
-      step_timeout(t.step_func_done());
-    }
+    let count = 0;
+    document.onfullscreenchange = iframeDoc.onfullscreenchange = t.step_func(event => {
+      count++;
+      assert_between_inclusive(count, 1, 4, 'number of fullscreenchange events');
+      // Both when entering and exiting, the fullscreenchange event is fired first
+      // on the outer document and then on the iframe's document. This is because
+      // the events are fired in animation frame tasks, which run in "frame tree"
+      // order.
+      const expected = {
+        target: count == 1 || count == 3 ? iframe : iframeBody,
+        outerFullscreenElement: count <= 2 ? iframe : null,
+        innerFullscreenElement: count <= 2 ? iframeBody : null,
+      };
+      assert_equals(event.target, expected.target, 'event target');
+      assert_equals(document.fullscreenElement, expected.outerFullscreenElement, 'outer fullscreenElement');
+      assert_equals(iframeDoc.fullscreenElement, expected.innerFullscreenElement, 'inner fullscreenElement');
+      if (count == 2) {
+        iframeDoc.exitFullscreen();
+      } else if (count == 4) {
+        // Done, but set timeout to fail on extra events.
+        step_timeout(t.step_func_done());
+      }
+    });
+    document.onfullscreenerror = t.unreached_func('fullscreenerror event');
+    iframeDoc.onfullscreenerror = t.unreached_func('iframe fullscreenerror event');
+
+    trusted_request(t, iframeBody, iframeBody);
   });
-  document.onfullscreenerror = t.unreached_func('fullscreenerror event');
-  iframeDoc.onfullscreenerror = t.unreached_func('iframe fullscreenerror event');
-
-  trusted_request(t, iframeBody, iframeBody);
-});
+};
 </script>
diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-timing-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-timing-manual.html
index 359b688b427..1ebf7518c3c 100644
--- a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-timing-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-timing-manual.html
@@ -28,21 +28,25 @@ async_test(t => {
 }, 'Timing of fullscreenchange and resize events');
 
 async_test(t => {
-  var promise = document.createElement('a').requestFullscreen();
-  var promise_executed = false;
-  if (promise) {
-    promise.catch(()=>{promise_executed = true; });
-  } else {
-    // if promises aren't supported treat it as executed.
-    promise_executed = true;
-  }
+  // Gecko throttles requestAnimationFrame before the first paint, so
+  // wrap the test to work around that.
+  requestAnimationFrame(t.step_func(() => {
+    var promise = document.createElement('a').requestFullscreen();
+    var promise_executed = false;
+    if (promise) {
+      promise.catch(()=>{promise_executed = true; });
+    } else {
+      // if promises aren't supported treat it as executed.
+      promise_executed = true;
+    }
 
-  // If fullscreenerror is an animation frame event, then animation frame
-  // callbacks should be run after it is fired, before the timer callback.
-  document.onfullscreenerror = t.step_func(() => {
-    assert_true(promise_executed, "promise executed");
-    step_timeout(t.unreached_func('timer callback'));
-    requestAnimationFrame(t.step_func_done());
-  });
+    // If fullscreenerror is an animation frame event, then animation frame
+    // callbacks should be run after it is fired, before the timer callback.
+    document.onfullscreenerror = t.step_func(() => {
+      assert_true(promise_executed, "promise executed");
+      step_timeout(t.unreached_func('timer callback'));
+      requestAnimationFrame(t.step_func_done());
+    });
+  }));
 }, 'Timing of fullscreenerror event');
 </script>
diff --git a/tests/wpt/web-platform-tests/fullscreen/model/move-to-fullscreen-iframe-manual.html b/tests/wpt/web-platform-tests/fullscreen/model/move-to-fullscreen-iframe-manual.html
index 69082cacc2b..59b2c4330f2 100644
--- a/tests/wpt/web-platform-tests/fullscreen/model/move-to-fullscreen-iframe-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/model/move-to-fullscreen-iframe-manual.html
@@ -5,33 +5,36 @@
 <script src="../trusted-click.js"></script>
 <iframe allowfullscreen></iframe>
 <script>
-async_test(t => {
-  const iframe = document.querySelector('iframe');
-  const iframeDoc = iframe.contentDocument;
+// wait for load event to avoid https://bugzil.la/1493878
+window.onload = function() {
+  async_test(t => {
+    const iframe = document.querySelector('iframe');
+    const iframeDoc = iframe.contentDocument;
 
-  // Enter fullscreen for the iframe's body element.
-  trusted_request(t, iframeDoc.body, iframeDoc.body);
-  document.onfullscreenchange = t.step_func(() => {
-    assert_equals(document.fullscreenElement, iframe, "document's initial fullscreen element");
-    assert_equals(iframeDoc.fullscreenElement, iframeDoc.body, "iframe's initial fullscreen element");
+    // Enter fullscreen for the iframe's body element.
+    trusted_request(t, iframeDoc.body, iframeDoc.body);
+    document.onfullscreenchange = t.step_func(() => {
+      assert_equals(document.fullscreenElement, iframe, "document's initial fullscreen element");
+      assert_equals(iframeDoc.fullscreenElement, iframeDoc.body, "iframe's initial fullscreen element");
 
-    // Then, move the outer document's body into the iframe. This is an unusual
-    // thing to do, but means that the iframe is removed from its document and
-    // should trigger fullscreen exit.
-    iframeDoc.documentElement.appendChild(document.body);
+      // Then, move the outer document's body into the iframe. This is an unusual
+      // thing to do, but means that the iframe is removed from its document and
+      // should trigger fullscreen exit.
+      iframeDoc.documentElement.appendChild(document.body);
 
-    // If we exit in an orderly fashion, that's all one can ask for.
-    document.onfullscreenchange = t.step_func_done(() => {
-      assert_equals(document.fullscreenElement, null, "document's final fullscreen element");
+      // If we exit in an orderly fashion, that's all one can ask for.
+      document.onfullscreenchange = t.step_func_done(() => {
+        assert_equals(document.fullscreenElement, null, "document's final fullscreen element");
 
-      // Because the iframe was removed, its browsing context was discarded and
-      // its contentDocument has become null. Because that browsing context was
-      // neither a descendant browsing context nor had an active document,
-      // nothing at all was done with it in the exit fullscreen algorithm, so
-      // its fullscreenElement is unchanged.
-      assert_equals(iframe.contentDocument, null, "iframe's content document");
-      assert_equals(iframeDoc.fullscreenElement, iframeDoc.body, "iframe's final fullscreen element");
+        // Because the iframe was removed, its browsing context was discarded and
+        // its contentDocument has become null. Because that browsing context was
+        // neither a descendant browsing context nor had an active document,
+        // nothing at all was done with it in the exit fullscreen algorithm, so
+        // its fullscreenElement is unchanged.
+        assert_equals(iframe.contentDocument, null, "iframe's content document");
+        assert_equals(iframeDoc.fullscreenElement, iframeDoc.body, "iframe's final fullscreen element");
+      });
     });
   });
-});
+};
 </script>
diff --git a/tests/wpt/web-platform-tests/fullscreen/rendering/ua-style-iframe-manual.html b/tests/wpt/web-platform-tests/fullscreen/rendering/ua-style-iframe-manual.html
index bf93aa28c3f..f2a227437a5 100644
--- a/tests/wpt/web-platform-tests/fullscreen/rendering/ua-style-iframe-manual.html
+++ b/tests/wpt/web-platform-tests/fullscreen/rendering/ua-style-iframe-manual.html
@@ -14,21 +14,32 @@ iframe {
 <div id="log"></div>
 <div id="ancestor"><iframe></iframe></div>
 <script>
+function assert_dir_properties(style, propBase, value, state) {
+  for (let dir of ["Top", "Right", "Bottom", "Left"]) {
+    let prop = propBase.replace('{}', dir);
+    assert_equals(style[prop], value, `${state} ${prop} style`);
+  }
+}
+
 async_test(t => {
   const ancestor = document.getElementById('ancestor');
   const iframe = ancestor.firstChild;
 
   const initialStyle = getComputedStyle(iframe);
-  assert_equals(initialStyle.border, '1px solid rgb(0, 0, 255)', 'initial border style');
-  assert_equals(initialStyle.padding, '1px', 'initial padding style');
+  assert_dir_properties(initialStyle, 'border{}Width', '1px', 'initial');
+  assert_dir_properties(initialStyle, 'border{}Style', 'solid', 'initial');
+  assert_dir_properties(initialStyle, 'border{}Color', 'rgb(0, 0, 255)', 'initial');
+  assert_dir_properties(initialStyle, 'padding{}', '1px', 'initial');
   assert_equals(initialStyle.transform, 'matrix(0.5, 0, 0, 0.5, 0, 0)', 'initial transform style');
 
   trusted_request(t, iframe);
 
   document.addEventListener('fullscreenchange', t.step_func_done(() => {
     const fullscreenStyle = getComputedStyle(iframe);
-    assert_equals(fullscreenStyle.border, '0px none rgb(0, 0, 0)', 'fullscreen border style');
-    assert_equals(fullscreenStyle.padding, '0px', 'fullscreen padding style');
+    assert_dir_properties(fullscreenStyle, 'border{}Width', '0px', 'fullscreen');
+    assert_dir_properties(fullscreenStyle, 'border{}Style', 'none', 'fullscreen');
+    assert_dir_properties(fullscreenStyle, 'border{}Color', 'rgb(0, 0, 0)', 'fullscreen');
+    assert_dir_properties(fullscreenStyle, 'padding{}', '0px', 'fullscreen');
     assert_equals(fullscreenStyle.transform, 'none', 'fullscreen transform style');
   }));
 });
diff --git a/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/001.html b/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/001.html
index 0e5632bbcdf..72735935479 100644
--- a/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/001.html
+++ b/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/001.html
@@ -44,7 +44,7 @@ function reportload() {
         test(function () {
             assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' );
         }, 'history.length should update when setting location.hash');
-        test(function () { assert_true( !!history.pushState, 'critical test; ignore any failures after this' ); }, 'history.pushState must exist'); //assert_exists does not allow prototype inheritance
+        test(function () { assert_true( !!history.pushState, 'critical test; ignore any failures after this' ); }, 'history.pushState must exist'); //assert_own_property does not allow prototype inheritance
         test(function () { assert_true( !!iframe.contentWindow.history.pushState, 'critical test; ignore any failures after this' ); }, 'history.pushState must exist within iframes');
         test(function () {
             assert_equals( iframe.contentWindow.history.state, null );
@@ -250,7 +250,7 @@ function reportload() {
             assert_equals( ev.state.numdata, 1, 'state numeric data was not correct' );
             assert_equals( ev.state.strdata, 'string data', 'state string data was not correct' );
             assert_true( !!ev.state.datedata.getTime, 'state date data was not correct' );
-            assert_exists( ev.state, 'regdata', 'state regex data was not correct' );
+            assert_own_property( ev.state, 'regdata', 'state regex data was not correct' );
             assert_equals( ev.state.regdata.source, 'a', 'state regex pattern data was not correct' );
             assert_true( ev.state.regdata.global, 'state regex flag data was not correct' );
             assert_equals( ev.state.regdata.lastIndex, 0, 'state regex lastIndex data was not correct' );
diff --git a/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/002.html b/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/002.html
index eb0c15aab89..c5bae3407c8 100644
--- a/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/002.html
+++ b/tests/wpt/web-platform-tests/html/browsers/history/the-history-interface/002.html
@@ -43,7 +43,7 @@ function reportload() {
         test(function () {
             assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' );
         }, 'history.length should update when setting location.hash');
-        test(function () { assert_true( !!history.replaceState, 'critical test; ignore any failures after this' ); }, 'history.replaceState must exist'); //assert_exists does not allow prototype inheritance
+        test(function () { assert_true( !!history.replaceState, 'critical test; ignore any failures after this' ); }, 'history.replaceState must exist'); //assert_own_property does not allow prototype inheritance
         test(function () { assert_true( !!iframe.contentWindow.history.replaceState, 'critical test; ignore any failures after this' ); }, 'history.replaceState must exist within iframes');
         test(function () {
             assert_equals( iframe.contentWindow.history.state, null );
@@ -225,7 +225,7 @@ function reportload() {
             assert_equals( ev.state.numdata, 1, 'state numeric data was not correct' );
             assert_equals( ev.state.strdata, 'string data', 'state string data was not correct' );
             assert_true( !!ev.state.datedata.getTime, 'state date data was not correct' );
-            assert_exists( ev.state, 'regdata', 'state regex data was not correct' );
+            assert_own_property( ev.state, 'regdata', 'state regex data was not correct' );
             assert_equals( ev.state.regdata.source, 'a', 'state regex pattern data was not correct' );
             assert_true( ev.state.regdata.global, 'state regex flag data was not correct' );
             assert_equals( ev.state.regdata.lastIndex, 0, 'state regex lastIndex data was not correct' );
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html
new file mode 100644
index 00000000000..2f313f3395f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+table {
+  border-collapse: collapse;
+}
+td {
+  border: 5px solid black;
+  width: 100px;
+  height: 100px;
+}
+</style>
+Passes if there is a grid containing 2x2 squares.
+<table>
+  <tbody>
+    <tr><td></td><td></td></tr>
+    <tr><td></td><td></td></tr>
+  </tbody>
+</table>
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html
new file mode 100644
index 00000000000..5f131e6658a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Test for transformed tbody and tr with collapsed borders</title>
+<link rel="match" href="transformed-tbody-tr-collapsed-border-ref.html">
+<style>
+table {
+  border-collapse: collapse;
+}
+tbody, tr {
+  transform: translateY(0);
+}
+td {
+  border: 5px solid black;
+  width: 100px;
+  height: 100px;
+}
+</style>
+Passes if there is a grid containing 2x2 squares.
+<table>
+  <tbody>
+    <tr><td></td><td></td></tr>
+    <tr><td></td><td></td></tr>
+  </tbody>
+</table>
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html
new file mode 100644
index 00000000000..8023c5255ff
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference for legend and display: list-item numbering</title>
+<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+
+<style>
+ol { margin: 0; padding: 0; border: none; }
+ol > * { margin: 0 40px; padding: 0; }
+</style>
+
+<ol>
+  <li value="2">B</li>
+  <li value="1">A</li>
+  <li value="3">C</li>
+</ol>
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html
new file mode 100644
index 00000000000..ba58d353a01
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Legend and display: list-item numbering</title>
+<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+<link rel=match href="legend-list-item-numbering-ref.html">
+
+<style>
+fieldset { margin: 0; padding: 0; border: none; list-style-type: decimal; }
+fieldset > * { margin: 0 40px; padding: 0; display: list-item; }
+</style>
+
+<fieldset>
+  <div>A</div>
+  <legend>B</legend>
+  <div>C</div>
+</fieldset>
diff --git a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html
index 7a86a86381d..575324d761a 100644
--- a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html
+++ b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html
@@ -4,6 +4,7 @@
 <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src=/common/get-host-info.sub.js></script>
 <div id="log"></div>
 <div id="test">
 <script>
@@ -31,18 +32,6 @@ tUnsupported.step(function() {
   elt.rel = "stylesheet";
   elt.href = "nonexistent:stylesheet.css";
   document.getElementsByTagName("head")[0].appendChild(elt);
-})
-
-var tText = async_test("Should get an error event for a text/plain response.")
-tText.step(function() {
-  var elt = document.createElement("link");
-  elt.onerror = tText.step_func(function() {
-    assert_true(true, "Got error event for 404 error.")
-    tText.done()
-  })
-  elt.onload = tText.unreached_func("load event should not be fired");
-  elt.rel = "stylesheet";
-  elt.href = "../../../../../common/css-red.txt";
-  document.getElementsByTagName("head")[0].appendChild(elt);
-})
+});
 </script>
+<script src=resources/link-style-error.js></script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html
new file mode 100644
index 00000000000..d3c520ba75f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-limited-quirks.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//" "">
+<title>link: error events in limited quirks mode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=/common/get-host-info.sub.js></script>
+<div id="log"></div>
+<script src=resources/link-style-error.js></script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html
new file mode 100644
index 00000000000..ae2efa415ee
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/link-style-error-quirks.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML PUBLIC "-//Sun Microsystems Corp.//DTD HotJava Strict HTML//" "">
+<title>link: error events in quirks mode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=/common/get-host-info.sub.js></script>
+<div id="log"></div>
+<script src=resources/link-style-error.js></script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/css.py b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/css.py
new file mode 100644
index 00000000000..eb981373a3e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/css.py
@@ -0,0 +1,7 @@
+def main(request, response):
+  response.add_required_headers = False
+  if "content_type" in request.GET:
+    response.writer.write_header("Content-Type", request.GET.first("content_type"))
+  if "nosniff" in request.GET:
+  	response.writer.write_header("x-content-type-options", "nosniff")
+  response.writer.write_content("body { background:red }")
diff --git a/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/link-style-error.js b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/link-style-error.js
new file mode 100644
index 00000000000..d1fa5ac2d6f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/document-metadata/the-link-element/resources/link-style-error.js
@@ -0,0 +1,47 @@
+["<link>", "@import"].forEach(linkType => {
+  [
+   ["same-origin", "resources/css.py"],
+   ["cross-origin", get_host_info().HTTP_REMOTE_ORIGIN + "/html/semantics/document-metadata/the-link-element/resources/css.py"]
+  ].forEach(originType => {
+    ["no Content-Type", "wrong Content-Type", "broken Content-Type"].forEach(contentType => {
+      ["no nosniff", "nosniff"].forEach(nosniff => {
+        async_test(t => {
+          const l = document.createElement("link");
+          t.add_cleanup(() => l.remove());
+          if (nosniff === "nosniff" || contentType === "wrong Content-Type" && (document.compatMode === "CSS1Compat" || originType[0] === "cross-origin")) {
+            l.onerror = t.step_func_done();
+            l.onload = t.unreached_func("error event should have fired");
+          } else {
+            l.onload = t.step_func_done();
+            l.onerror = t.unreached_func("load event should have fired");
+          }
+          l.rel = "stylesheet";
+          let query = [];
+          if (contentType === "broken Content-Type") {
+            query.push("content_type=oops");
+          } else if (contentType === "wrong Content-Type") {
+            query.push("content_type=text/plain")
+          }
+          if (nosniff === "nosniff") {
+            query.push("nosniff");
+          }
+          let stringQuery = "";
+          query.forEach(val => {
+            if (stringQuery === "") {
+              stringQuery += "?" + val;
+            } else {
+              stringQuery += "&" + val;
+            }
+          });
+          const link = new URL(originType[1] + stringQuery, location).href;
+          if (linkType === "<link>") {
+            l.href = link;
+          } else {
+            l.href = "data:text/css,@import url(" + link + ");";
+          }
+          document.head.appendChild(l);
+        }, "Stylesheet loading using " + linkType + " with " + contentType + ", " + originType[0] + ", and " + nosniff);
+      });
+    });
+  });
+});
diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
index 67941264730..a9cd73435a3 100644
--- a/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
+++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/track/track-element/track-change-event.html
@@ -15,7 +15,7 @@ async_test(function(t) {
     video.textTracks.onchange = t.step_func_done(function() {
         assert_equals(event.target, video.textTracks);
         assert_true(event instanceof Event, 'instanceof');
-        assert_not_exists(event, 'track');
+        assert_false(event.hasOwnProperty('track'), 'unexpected property found: "track"');
     });
 });
 </script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html
new file mode 100644
index 00000000000..57189a0b884
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>Check processing of iframe without src and srcdoc attribute</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+<iframe></iframe>
+<script>
+  let iframe = document.querySelector("iframe");
+
+  async_test(t => {
+    let originDoc = iframe.contentDocument;
+    window.addEventListener("load", t.step_func_done(() => {
+      assert_equals(iframe.contentDocument, originDoc, "contentDocument shouldn't be changed");
+    }));
+  }, "iframe.contentDocument should not be changed");
+
+  async_test(t => {
+    iframe.addEventListener("load", t.unreached_func());
+    window.addEventListener("load", () => t.done());
+  }, "load event of iframe should not be fired after processing the element");
+</script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/the-form-element/form-autocomplete.html b/tests/wpt/web-platform-tests/html/semantics/forms/the-form-element/form-autocomplete.html
index 5c1d05b301e..618aa0a6c47 100644
--- a/tests/wpt/web-platform-tests/html/semantics/forms/the-form-element/form-autocomplete.html
+++ b/tests/wpt/web-platform-tests/html/semantics/forms/the-form-element/form-autocomplete.html
@@ -42,10 +42,10 @@
     }, desc);
   }
 
-  autocompletetest(document.forms.missing_attribute, ["on", "on", "on", "off", ""], "form autocomplete attribute missing");
-  autocompletetest(document.forms.autocomplete_on, ["on", "on", "on", "off", ""], "form autocomplete attribute on");
-  autocompletetest(document.forms.autocomplete_off, ["off", "off", "on", "off", ""], "form autocomplete attribute off");
-  autocompletetest(document.forms.autocomplete_invalid, ["on", "on", "on", "off", ""], "form autocomplete attribute invalid");
+  autocompletetest(document.forms.missing_attribute, ["on", "", "on", "off", ""], "form autocomplete attribute missing");
+  autocompletetest(document.forms.autocomplete_on, ["on", "", "on", "off", ""], "form autocomplete attribute on");
+  autocompletetest(document.forms.autocomplete_off, ["off", "", "on", "off", ""], "form autocomplete attribute off");
+  autocompletetest(document.forms.autocomplete_invalid, ["on", "", "on", "off", ""], "form autocomplete attribute invalid");
 
   var keywords = [ "on", "off", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp" ];
 
@@ -58,4 +58,59 @@
       assert_equals(input.autocomplete, keyword);
     }, keyword + " is an allowed autocomplete field name");
   });
+
+
+test(() => {
+  const select = document.createElement("select");
+  select.setAttribute("autocomplete", "  \n");
+  assert_equals(select.autocomplete, "");
+}, "Test whitespace-only attribute value");
+
+test(() => {
+  const select = document.createElement("select");
+
+  select.setAttribute("autocomplete", "foo off");
+  assert_equals(select.autocomplete, "");
+
+  // Normal category; max=3
+  select.setAttribute("autocomplete", "foo section-foo billing name");
+  assert_equals(select.autocomplete, "");
+
+  // Contact category; max=4
+  select.setAttribute("autocomplete", "foo section-bar billing work name");
+  assert_equals(select.autocomplete, "");
+}, "Test maximum number of tokens");
+
+test(() => {
+  const textarea = document.createElement("textarea");
+
+  textarea.setAttribute("autocomplete", "call-sign");
+  assert_equals(textarea.autocomplete, "");
+}, "Unknown field");
+
+test(() => {
+  const hidden = document.createElement("input");
+  hidden.type = "hidden";
+  hidden.setAttribute("autocomplete", "on");
+  assert_equals(hidden.autocomplete, "");
+  hidden.setAttribute("autocomplete", "off");
+  assert_equals(hidden.autocomplete, "");
+}, "Test 'wearing the autofill anchor mantle' with off/on");
+
+test(() => {
+  const textarea = document.createElement("textarea");
+
+  textarea.setAttribute("autocomplete", " HOME\ntel");
+  assert_equals(textarea.autocomplete, "home tel");
+
+  textarea.setAttribute("autocomplete", "shipping   country");
+  assert_equals(textarea.autocomplete, "shipping country");
+
+  textarea.setAttribute("autocomplete", "billing  work  email");
+  assert_equals(textarea.autocomplete, "billing work email");
+
+  textarea.setAttribute("autocomplete", "  section-FOO  bday");
+  assert_equals(textarea.autocomplete, "section-foo bday");
+}, "Serialize combinations of section, mode, contact, and field");
+
 </script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
index 1293d7f6913..cf23e67ae40 100644
--- a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
+++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
@@ -39,31 +39,31 @@ promise_test(t => {
   }).then(() => {
     const w = iframe.contentWindow;
 
-    assert_equals(w.sameOriginNone, 'not found',
-                  'Modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+    assert_equals(w.sameOriginNone, 'found',
+                  'Modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
     assert_equals(w.sameOriginAnonymous, 'found',
                   'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
     assert_equals(w.sameOriginUseCredentials, 'found',
                   'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
     assert_equals(w.crossOriginNone, 'not found',
-                  'Modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+                  'Modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
     assert_equals(w.crossOriginAnonymous, 'not found',
-                  'Modules should be loaded without the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+                  'Modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
     assert_equals(w.crossOriginUseCredentials, 'found',
                   'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
 
-    assert_equals(w.sameOriginNoneDecendent, 'not found',
-                  'Decendent modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is same-origin');
-    assert_equals(w.sameOriginAnonymousDecendent, 'found',
-                  'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
-    assert_equals(w.sameOriginUseCredentialsDecendent, 'found',
-                  'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
-    assert_equals(w.crossOriginNoneDecendent, 'not found',
-                  'Decendent modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
-    assert_equals(w.crossOriginAnonymousDecendent, 'not found',
-                  'Decendent modules should be loaded without the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
-    assert_equals(w.crossOriginUseCredentialsDecendent, 'found',
-                  'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+    assert_equals(w.sameOriginNoneDescendant, 'found',
+                  'Descendant modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+    assert_equals(w.sameOriginAnonymousDescendant, 'found',
+                  'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+    assert_equals(w.sameOriginUseCredentialsDescendant, 'found',
+                  'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+    assert_equals(w.crossOriginNoneDescendant, 'not found',
+                  'Descendant modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+    assert_equals(w.crossOriginAnonymousDescendant, 'not found',
+                  'Descendant modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+    assert_equals(w.crossOriginUseCredentialsDescendant, 'found',
+                  'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
 });
 }, 'Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
 </script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html
new file mode 100644
index 00000000000..b939a3ef163
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<script type="text/javascript">
+host_info = get_host_info();
+
+document.cookie = 'same=1';
+
+const setCookiePromise = fetch(
+    'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=cross&path=/html/semantics/scripting-1/the-script-element/module/',
+    {
+      mode: 'no-cors',
+      credentials: 'include',
+    });
+
+const windowLoadPromise = new Promise(resolve => {
+  window.addEventListener('load', () => {
+    resolve();
+  });
+});
+
+promise_test(t => {
+  const iframe = document.createElement('iframe');
+
+  return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+    const messagePromise = new Promise(resolve => {
+      window.addEventListener('message', event => {
+        resolve();
+      });
+    });
+
+    iframe.src = '../resources/dynamic-import-credentials-iframe.sub.html';
+    document.body.appendChild(iframe);
+
+    return messagePromise;
+  }).then(() => {
+    const w = iframe.contentWindow;
+
+    assert_equals(w.sameOriginNoneDynamicDescendant, 'found',
+                  'Dynamic descendant modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+    assert_equals(w.sameOriginAnonymousDynamicDescendant, 'found',
+                  'Dynamic descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+    assert_equals(w.sameOriginUseCredentialsDynamicDescendant, 'found',
+                  'Dynamic descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+    assert_equals(w.crossOriginNoneDynamicDescendant, 'not found',
+                  'Dynamic descendant modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+    assert_equals(w.crossOriginAnonymousDynamicDescendant, 'not found',
+                  'Dynamic descendant modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+    assert_equals(w.crossOriginUseCredentialsDynamicDescendant, 'found',
+                  'Dynamic descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'Dynamic imports should be loaded with or without the credentials based on the same-origin-ness and the parent script\'s crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
index f086e702822..8a0506ccec6 100644
--- a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
+++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
@@ -25,22 +25,22 @@
 </script>
 
 <script type="module">
-import "./check-cookie.py?id=sameOriginNoneDecendent&cookieName=same";
+import "./check-cookie.py?id=sameOriginNoneDescendant&cookieName=same";
 </script>
 <script type="module" crossOrigin="anonymous">
-import "./check-cookie.py?id=sameOriginAnonymousDecendent&cookieName=same";
+import "./check-cookie.py?id=sameOriginAnonymousDescendant&cookieName=same";
 </script>
 <script type="module" crossOrigin="use-credentials">
-import "./check-cookie.py?id=sameOriginUseCredentialsDecendent&cookieName=same";
+import "./check-cookie.py?id=sameOriginUseCredentialsDescendant&cookieName=same";
 </script>
 <script type="module">
-import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNoneDecendent&cookieName=cross";
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNoneDescendant&cookieName=cross";
 </script>
 <script type="module" crossOrigin="anonymous">
-import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymousDecendent&cookieName=cross";
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymousDescendant&cookieName=cross";
 </script>
 <script type="module" crossOrigin="use-credentials">
-import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentialsDecendent&cookieName=cross";
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentialsDescendant&cookieName=cross";
 </script>
 
 <script type="text/javascript">
diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html
new file mode 100644
index 00000000000..836ece62c5f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<script type="module">
+import("./check-cookie.py?id=sameOriginNoneDynamicDescendant&cookieName=same");
+</script>
+<script type="module" crossOrigin="anonymous">
+import("./check-cookie.py?id=sameOriginAnonymousDynamicDescendant&cookieName=same");
+</script>
+<script type="module" crossOrigin="use-credentials">
+import("./check-cookie.py?id=sameOriginUseCredentialsDynamicDescendant&cookieName=same");
+</script>
+<script type="module">
+import("http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNoneDynamicDescendant&cookieName=cross");
+</script>
+<script type="module" crossOrigin="anonymous">
+import("http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymousDynamicDescendant&cookieName=cross");
+</script>
+<script type="module" crossOrigin="use-credentials">
+import("http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentialsDynamicDescendant&cookieName=cross");
+</script>
+
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+  window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html b/tests/wpt/web-platform-tests/html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html
index e1f9995117f..bec3364adff 100644
--- a/tests/wpt/web-platform-tests/html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html
+++ b/tests/wpt/web-platform-tests/html/syntax/parsing/template/creating-an-element-for-the-token/template-owner-document.html
@@ -2,6 +2,7 @@
 <html>
 <head>
 <title>HTML Templates: ownerDocument property of the element in template</title>
+<meta name="timeout" content="long">
 <meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
 <meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
 <meta name="assert" content="ownerDocument property of the element appended to template must be set to the template contents owner of the ownerDocument of the template element">
diff --git a/tests/wpt/web-platform-tests/lint.whitelist b/tests/wpt/web-platform-tests/lint.whitelist
index e39672d0c6e..46c2550e728 100644
--- a/tests/wpt/web-platform-tests/lint.whitelist
+++ b/tests/wpt/web-platform-tests/lint.whitelist
@@ -655,6 +655,8 @@ CSS-COLLIDING-REF-NAME: css/vendor-imports/mozilla/mozilla-central-reftests/cont
 CSS-COLLIDING-REF-NAME: css/css-contain/reference/contain-size-grid-001-ref.html
 CSS-COLLIDING-REF-NAME: css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-grid-001-ref.html
 CSS-COLLIDING-SUPPORT-NAME: css/css-backgrounds/support/red.png
+CSS-COLLIDING-REF-NAME: css/css-contain/reference/contain-size-fieldset-001-ref.html
+CSS-COLLIDING-REF-NAME: css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-fieldset-001-ref.html
 CSS-COLLIDING-SUPPORT-NAME: css/compositing/mix-blend-mode/support/red.png
 CSS-COLLIDING-SUPPORT-NAME: css/compositing/background-blending/support/red.png
 CSS-COLLIDING-SUPPORT-NAME: css/CSS2/normal-flow/support/replaced-min-max-3.png
diff --git a/tests/wpt/web-platform-tests/media-capabilities/decodingInfo.html b/tests/wpt/web-platform-tests/media-capabilities/decodingInfo.html
index f3fca4184e4..982bc174668 100644
--- a/tests/wpt/web-platform-tests/media-capabilities/decodingInfo.html
+++ b/tests/wpt/web-platform-tests/media-capabilities/decodingInfo.html
@@ -291,7 +291,8 @@ promise_test(t => {
 
 async_test(t => {
   var validTypes = [ 'file', 'media-source' ];
-  var invalidTypes = [ undefined, null, '', 'foobar', 'mse', 'MediaSource' ];
+  var invalidTypes = [ undefined, null, '', 'foobar', 'mse', 'MediaSource',
+                       'record', 'transmission' ];
 
   var validPromises = [];
   var invalidCaught = 0;
diff --git a/tests/wpt/web-platform-tests/media-capabilities/encodingInfo.html b/tests/wpt/web-platform-tests/media-capabilities/encodingInfo.html
new file mode 100644
index 00000000000..5c0e3189082
--- /dev/null
+++ b/tests/wpt/web-platform-tests/media-capabilities/encodingInfo.html
@@ -0,0 +1,328 @@
+<!DOCTYPE html>
+<title>MediaCapabilities.decodingInfo()</title>
+<script src=/resources/testharness.js></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+// Minimal VideoConfiguration that will be allowed per spec. All optional
+// properties are missing.
+var minimalVideoConfiguration = {
+  contentType: 'video/webm; codecs="vp09.00.10.08"',
+  width: 800,
+  height: 600,
+  bitrate: 3000,
+  framerate: 24,
+};
+
+// Minimal AudioConfiguration that will be allowed per spec. All optional
+// properties are missing.
+var minimalAudioConfiguration = {
+  contentType: 'audio/webm; codecs="opus"',
+};
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo());
+}, "Test that encodingInfo rejects if it doesn't get a configuration");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({}));
+}, "Test that encodingInfo rejects if the MediaConfiguration isn't valid");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    video: minimalVideoConfiguration,
+    audio: minimalAudioConfiguration,
+  }));
+}, "Test that encodingInfo rejects if the MediaConfiguration does not have a type");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+  }));
+}, "Test that encodingInfo rejects if the configuration doesn't have an audio or video field");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: -1,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration has a negative framerate");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: 0,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration has a framerate set to 0");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: Infinity,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration has a framerate set to Infinity");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'fgeoa',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: 24,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration contentType doesn't parse");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'audio/fgeoa',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: 24,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration contentType isn't of type video");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"; foo="bar"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: 24,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration contentType has more than one parameter");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; foo="bar"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: 24,
+    },
+  }));
+}, "Test that encodingInfo rejects if the video configuration contentType has one parameter that isn't codecs");
+
+promise_test(t => {
+  return navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24000/1001',
+    }
+  });
+}, "Test that encodingInfo() accepts framerate in the form of x/y");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24000/0',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate in the form of x/0");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '0/10001',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate in the form of 0/y");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '-24000/10001',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate in the form of -x/y");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24000/-10001',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate in the form of x/-y");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24000/',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate in the form of x/");
+
+promise_test(t => {
+  return navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24000/1e4',
+    }
+  });
+}, "Test that encodingInfo() accepts framerate with 'e'");
+
+promise_test(t => {
+  return navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '24/1.0001',
+    }
+  });
+}, "Test that encodingInfo() accepts framerate as fraction with decimals");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: {
+      contentType: 'video/webm; codecs="vp09.00.10.08"',
+      width: 800,
+      height: 600,
+      bitrate: 3000,
+      framerate: '1/3x',
+    }
+  }));
+}, "Test that encodingInfo() rejects framerate with trailing unallowed characters");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    audio: { contentType: 'fgeoa' },
+  }));
+}, "Test that encodingInfo rejects if the audio configuration contenType doesn't parse");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    audio: { contentType: 'video/fgeoa' },
+  }));
+}, "Test that encodingInfo rejects if the audio configuration contentType isn't of type audio");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    audio: { contentType: 'audio/webm; codecs="opus"; foo="bar"' },
+  }));
+}, "Test that encodingInfo rejects if the audio configuration contentType has more than one parameters");
+
+promise_test(t => {
+  return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    audio: { contentType: 'audio/webm; foo="bar"' },
+  }));
+}, "Test that encodingInfo rejects if the audio configuration contentType has one parameter that isn't codecs");
+
+promise_test(t => {
+  return navigator.mediaCapabilities.encodingInfo({
+    type: 'record',
+    video: minimalVideoConfiguration,
+    audio: minimalAudioConfiguration,
+  }).then(ability => {
+    assert_idl_attribute(ability, 'supported');
+    assert_idl_attribute(ability, 'smooth');
+    assert_idl_attribute(ability, 'powerEfficient');
+  });
+}, "Test that encodingInfo returns a valid MediaCapabilitiesInfo objects");
+
+async_test(t => {
+  var validTypes = [ 'record', 'transmission' ];
+  var invalidTypes = [ undefined, null, '', 'foobar', 'mse', 'MediaSource',
+                       'file', 'media-source', ];
+
+  var validPromises = [];
+  var invalidCaught = 0;
+
+  validTypes.forEach(type => {
+    validPromises.push(navigator.mediaCapabilities.encodingInfo({
+      type: type,
+      video: minimalVideoConfiguration,
+      audio: minimalAudioConfiguration,
+    }));
+  });
+
+  // validTypes are tested via Promise.all(validPromises) because if one of the
+  // promises fail, Promise.all() will reject. This mechanism can't be used for
+  // invalid types which will be tested individually and increment invalidCaught
+  // when rejected until the amount of rejection matches the expectation.
+  Promise.all(validPromises).then(t.step_func(() => {
+    for (var i = 0; i < invalidTypes.length; ++i) {
+      navigator.mediaCapabilities.encodingInfo({
+        type: invalidTypes[i],
+        video: minimalVideoConfiguration,
+        audio: minimalAudioConfiguration,
+      }).then(t.unreached_func(), t.step_func(e => {
+        assert_equals(e.name, 'TypeError');
+        ++invalidCaught;
+        if (invalidCaught == invalidTypes.length)
+          t.done();
+      }));
+    }
+  }), t.unreached_func('Promise.all should not reject for valid types'));
+}, "Test that encodingInfo rejects if the MediaConfiguration does not have a valid type");
+
+</script>
diff --git a/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html b/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html
index 0b45ac6f594..21e3f5b9af8 100644
--- a/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html
+++ b/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html
@@ -13,7 +13,7 @@
   // mic/camera has been explicitly allowed by feature policy.
   function promise_factory(allowed_features) {
     return new Promise((resolve, reject) => {
-      navigator.getUserMedia({video: true, audio: true}).then(
+      navigator.mediaDevices.getUserMedia({video: true, audio: true}).then(
           function(stream) {
             // If microphone is allowed, there should be at least one microphone
             // in the result. If camera is allowed, there should be at least one
diff --git a/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_image_document.html b/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_image_document.html
new file mode 100644
index 00000000000..36742f0eff6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_image_document.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <title>Test domInteractive on image document.</title>
+        <link rel="author" title="Google" href="http://www.google.com/" />
+        <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/>
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+    </head>
+    <script>
+        const t = async_test("Test domInteractive on image document");
+        function frameLoaded() {
+            const timing = document.querySelector("iframe").contentWindow.performance.timing;
+            assert_greater_than(timing.domInteractive, 0,
+                "Expect domInteractive to be positive value.");
+            t.done();
+        }
+    </script>
+    <body>
+        <h1>Description</h1>
+        <p>This tests that a image document has positive-value domInteractive.</p>
+        <iframe src="../images/smiley.png" onload="frameLoaded()"></iframe>
+    </body>
+</html>
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_media_document.html b/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_media_document.html
new file mode 100644
index 00000000000..e4e45725d83
--- /dev/null
+++ b/tests/wpt/web-platform-tests/navigation-timing/dom_interactive_media_document.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <title>Test domInteractive on media document.</title>
+        <link rel="author" title="Google" href="http://www.google.com/" />
+        <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/>
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+    </head>
+    <script>
+        const t = async_test("Test domInteractive on media document");
+        function frameLoaded() {
+            const timing = document.querySelector("iframe").contentWindow.performance.timing;
+            assert_greater_than(timing.domInteractive, 0,
+                "Expect domInteractive to be positive value.");
+            t.done();
+        }
+    </script>
+    <body>
+        <h1>Description</h1>
+        <p>This tests that a media document has positive-value domInteractive.</p>
+        <iframe src="../media/A4.mp4" onload="frameLoaded()"></iframe>
+    </body>
+</html>
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/payment-method-id/payment-request-ctor-pmi-handling.https.html b/tests/wpt/web-platform-tests/payment-method-id/payment-request-ctor-pmi-handling.https.html
new file mode 100644
index 00000000000..5f888f0389f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/payment-method-id/payment-request-ctor-pmi-handling.https.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<!-- Copyright © 2017 Mozilla and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<meta charset="utf-8">
+<title>Test for validity of payment method identifiers during construction</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+"use strict";
+const validAmount = Object.freeze({
+  currency: "USD",
+  value: "1.0",
+});
+const validTotal = Object.freeze({
+  label: "Default Total",
+  amount: validAmount,
+});
+const defaultDetails = Object.freeze({
+  total: validTotal,
+});
+
+test(() => {
+  const validMethods = [
+    "https://wpt",
+    "https://wpt.fyi/",
+    "https://wpt.fyi/payment",
+    "https://wpt.fyi/payment-request",
+    "https://wpt.fyi/payment-request?",
+    "https://wpt.fyi/payment-request?this=is",
+    "https://wpt.fyi/payment-request?this=is&totally",
+    "https://wpt.fyi:443/payment-request?this=is&totally",
+    "https://wpt.fyi:443/payment-request?this=is&totally#fine",
+    "https://:@wpt.fyi:443/payment-request?this=is&totally#👍",
+    " \thttps://wpt\n ",
+    "https://xn--c1yn36f",
+    "https://點看",
+  ];
+  for (const validMethod of validMethods) {
+    try {
+      const methods = [{ supportedMethods: validMethod }];
+      new PaymentRequest(methods, defaultDetails);
+    } catch (err) {
+      assert_unreached(
+        `Unexpected exception with valid standardized PMI: ${validMethod}. ${err}`
+      );
+    }
+  }
+}, "Must support valid standard URL PMIs");
+
+test(() => {
+  const validMethods = [
+    "e",
+    "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa",
+    "a-b-q-n-s-pw0",
+    "m-u",
+    "s-l5",
+    "k9-f",
+    "m-l",
+    "u4-n-t",
+    "i488jh6-g18-fck-yb-v7-i",
+    "x-x-t-t-c34-o",
+    "basic-card",
+    // gets coerced to "basic-card", for compat with old version of spec
+    ["basic-card"],
+  ];
+  for (const validMethod of validMethods) {
+    try {
+      const methods = [{ supportedMethods: validMethod }];
+      new PaymentRequest(methods, defaultDetails);
+    } catch (err) {
+      assert_unreached(
+        `Unexpected exception with valid standardized PMI: ${validMethod}. ${err}`
+      );
+    }
+  }
+}, "Must not throw on syntactically valid standardized payment method identifiers, even if they are not supported");
+
+test(() => {
+  const invalidMethods = [
+    "basic-💳",
+    "¡basic-*-card!",
+    "Basic-Card",
+    "0",
+    "-",
+    "--",
+    "a--b",
+    "-a--b",
+    "a-b-",
+    "0-",
+    "0-a",
+    "a0--",
+    "A-",
+    "A-B",
+    "A-b",
+    "a-0",
+    "a-0b",
+    " a-b",
+    "\t\na-b",
+    "a-b ",
+    "a-b\n\t",
+    "basic-card?not-really",
+    "basic-card://not-ok",
+    "basic card",
+    "/basic card/",
+    "BaSicCarD",
+    "BASIC-CARD",
+    " basic-card ",
+    "this is not supported",
+    " ",
+    "foo,var",
+    ["visa","mastercard"], // stringifies to "visa,mastercard"
+  ];
+  for (const invalidMethod of invalidMethods) {
+    assert_throws(
+      new RangeError(),
+      () => {
+        const methods = [{ supportedMethods: invalidMethod }];
+        new PaymentRequest(methods, defaultDetails);
+      },
+      `expected RangeError processing invalid standardized PMI "${invalidMethod}"`
+    );
+  }
+}, "Must throw on syntactically invalid standardized payment method identifiers");
+
+test(() => {
+  const invalidMethods = [
+    "https://username@example.com/pay",
+    "https://:password@example.com/pay",
+    "https://username:password@example.com/pay",
+    "http://username:password@example.com/pay",
+    "http://foo.com:100000000/pay",
+    "not-https://wpt.fyi/payment-request",
+    "../realitive/url",
+    "/absolute/../path?",
+    "https://",
+  ];
+  for (const invalidMethod of invalidMethods) {
+    assert_throws(
+      new RangeError(),
+      () => {
+        const methods = [{ supportedMethods: invalidMethod }];
+        new PaymentRequest(methods, defaultDetails);
+      },
+      `expected RangeError processing invalid URL PMI "${invalidMethod}"`
+    );
+  }
+}, "Constructor MUST throw if given an invalid URL-based payment method identifier");
+
+</script>
diff --git a/tests/wpt/web-platform-tests/picture-in-picture/request-picture-in-picture.html b/tests/wpt/web-platform-tests/picture-in-picture/request-picture-in-picture.html
index a0c3217603b..403d416c7d4 100644
--- a/tests/wpt/web-platform-tests/picture-in-picture/request-picture-in-picture.html
+++ b/tests/wpt/web-platform-tests/picture-in-picture/request-picture-in-picture.html
@@ -9,8 +9,8 @@
 <script>
 promise_test(async t => {
   const video = await loadVideo();
-  return requestPictureInPictureWithTrustedClick(video);
-}, 'request Picture-in-Picture resolves on user click');
+  return promise_rejects(t, 'NotAllowedError', video.requestPictureInPicture());
+}, 'request Picture-in-Picture requires a user gesture');
 
 promise_test(t => {
   const video = document.createElement('video');
@@ -31,6 +31,6 @@ promise_test(async t => {
 
 promise_test(async t => {
   const video = await loadVideo();
-  return promise_rejects(t, 'NotAllowedError', video.requestPictureInPicture());
-}, 'request Picture-in-Picture requires a user gesture');
+  return requestPictureInPictureWithTrustedClick(video);
+}, 'request Picture-in-Picture resolves on user click');
 </script>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/README.md b/tests/wpt/web-platform-tests/referrer-policy/css-integration/README.md
index 2edb24fb41e..14da25c4d97 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/css-integration/README.md
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/README.md
@@ -1,12 +1,14 @@
-These tests exercise differnt ways to load an image, generated via
-```/referrer-policy/generic/subresource/image.py?id=<UUID>``` and later
-verify the headers used to request that image.
+These tests exercise different ways to fetch a resource (image, font-face, svg
+references), generated via the sub-resource python script in
+```./generic/subresource/``` (for example, loading an image:
+```/referrer-policy/generic/subresource/image.py?id=<UUID>```) and later verify
+the headers used to fetch the resource.
 
 Since there is no way to wait for a resource referenced from CSS to be loaded,
 all tests use ```step_timeout()``` to delay the verification step until
-after the image (hopefully) was loaded.
+after the resource (hopefully) was loaded.
 
 Since there is also no way to retrieve headers (or other information) from
-images loaded via CSS, we store the headers with the given ```UUID``` as key
-on the server, and retrieve them later via an XHR to
+resources loaded via CSS, we store the headers with the given ```UUID``` as key
+on the server, and retrieve them later via an XHR, for example:
 ```/referrer-policy/generic/subresource/image.py?id=<UUID>&report-headers```.
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/external-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/external-import-stylesheet.html
new file mode 100644
index 00000000000..a2d3e8ced04
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/external-import-stylesheet.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Child css from external stylesheet</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that child css are loaded with the referrer and referrer policy
+    from the external stylesheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Child css from external stylesheet.");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" + location.port;
+      let css_url = url_prefix +
+        "/referrer-policy/generic/subresource/stylesheet.py?id=" + id +
+        "&import-rule" + "&referrer-policy=no-referrer";
+      let check_url = url_prefix + "/referrer-policy/generic/subresource/stylesheet.py" +
+                      "?id=" + id + "&report-headers";
+
+      let link = document.createElement("link");
+      link.href = css_url;
+      link.rel = "stylesheet";
+      link.onload = function() {
+        css_test.step_timeout(
+            queryXhr.bind(this, check_url,
+                          function(message) {
+                            css_test.step(function() {
+                              assert_own_property(message, "headers");
+                              assert_equals(message.referrer, undefined);
+                            });
+                            css_test.done();
+                          }),
+            1000);
+      };
+      document.head.appendChild(link);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/internal-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/internal-import-stylesheet.html
new file mode 100644
index 00000000000..aebf5031484
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/internal-import-stylesheet.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Child css from internal stylesheet</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="never">
+  </head>
+  <body>
+    <p>Check that child css are loaded with the referrer and referrer policy
+    from the internal stylesheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Child css from internal stylesheet.");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" + location.port;
+      let css_url = url_prefix + "/referrer-policy/generic/subresource/stylesheet.py?id=" + id + "&import-rule";
+      let check_url = url_prefix + "/referrer-policy/generic/subresource/stylesheet.py" +
+                      "?id=" + id + "&report-headers";
+
+      let style = document.createElement("style");
+      style.type = 'text/css';
+      style.appendChild(document.createTextNode("@import url('" + css_url + "');"));
+      document.head.appendChild(style);
+      css_test.step_timeout(
+        queryXhr.bind(this, check_url,
+                      function(message) {
+                        css_test.step(function() {
+                          assert_own_property(message, "headers");
+                          assert_own_property(message, "referrer");
+                          assert_equals(message.referrer, css_url);
+                        });
+                        css_test.done();
+                      }),
+        1000);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/processing-instruction.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/processing-instruction.html
new file mode 100644
index 00000000000..b6333e2c7b2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/child-css/processing-instruction.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - child css via a ProcessingInstruction</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that child css are loaded with the referrer and referrer policy the
+    external stylesheet(referenced from a ProcessingInstruction).</p>
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Child css via a ProcessingInstruction.");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" +
+                       location.port +
+                       "/referrer-policy/generic/subresource/stylesheet.py?id=" +
+                       id;
+      let css_url = url_prefix + "&amp;import-rule";
+      let expected = url_prefix + "&import-rule";
+      let check_url = url_prefix + "&report-headers";
+
+      let processingInstruction =
+        document.createProcessingInstruction(
+          "xml-stylesheet", "href=\"" +css_url + "\" type=\"text/css\"");
+      css_test.step_timeout(
+          queryXhr.bind(this, check_url,
+                        function(message) {
+                          css_test.step(function() {
+                            assert_own_property(message, "headers");
+                            assert_own_property(message, "referrer");
+                            assert_equals(message.referrer, expected);
+                          });
+                          css_test.done();
+                        }),
+          1000);
+      document.insertBefore(processingInstruction, document.firstChild);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/css-test-helper.js b/tests/wpt/web-platform-tests/referrer-policy/css-integration/css-test-helper.js
new file mode 100644
index 00000000000..f5886dbbcbe
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/css-test-helper.js
@@ -0,0 +1,66 @@
+var svg_ns = "http://www.w3.org/2000/svg";
+var url_prefix = location.protocol + "//" + location.hostname + ":" +
+                 location.port + "/referrer-policy/generic/subresource/";
+
+var svg_test_properties = [
+  'fill',
+  'stroke',
+  'filter',
+  'clip-path',
+  'marker-start',
+  'marker-mid',
+  'marker-end',
+  'mask',
+  'mask-image',
+];
+
+// Schedules async_test's for each of the test properties
+// Parameters:
+//     testProperties: An array of test properties.
+//     testDescription: A test description
+//     testFunction: A function call which sets up the expect result and runs
+//                   the actual test
+function runSvgTests(testProperties, testDescription, testFunction) {
+  let runNextTest = function () {
+    let property = testProperties.shift();
+    if (property === undefined) {
+      return;
+    }
+
+    let current = {
+      test: async_test(testDescription + " " + property),
+      id: token(),
+      property: property,
+    };
+
+    testFunction(current);
+
+    let check_url = url_prefix + "svg.py" + "?id=" + current.id +
+                    "&report-headers";
+    current.test.step_timeout(
+      queryXhr.bind(this, check_url,
+                    function(message) {
+                      current.test.step(function() {
+                        assert_own_property(message, "headers");
+                        assert_own_property(message, "referrer");
+                        assert_equals(message.referrer, current.expected);
+                      });
+                      current.test.done();
+                    }),
+      800);
+
+  };
+
+  add_result_callback(runNextTest);
+  runNextTest();
+}
+
+function createSvg() {
+  let svg = document.createElementNS(svg_ns, 'svg');
+  svg.setAttribute('width', '400');
+  svg.setAttribute('height', '400');
+  let path = document.createElementNS(svg_ns, 'path');
+  path.setAttribute('d', 'M 50,5 95,100 5,100 z');
+  svg.appendChild(path);
+  return svg;
+}
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-import-stylesheet.html
new file mode 100644
index 00000000000..c344c56c5bf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-import-stylesheet.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Font from imported stylesheet (external)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="never">
+  </head>
+  <body>
+    <p>Check that resources from imported stylesheets (loaded from external
+    stylesheets) are loaded with the referrer and referrer policy from the
+    external stylesheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Font from imported stylesheet (external).");
+      let id = token();
+      let css_url = location.protocol + "//www1." + location.hostname + ":" +
+        location.port +
+        "/referrer-policy/generic/subresource/stylesheet.py?id=" + id +
+        "&import-rule" + "&type=font";
+      let url_prefix = location.protocol + "//" + location.hostname + ":" + location.port;
+      let css_referrer = url_prefix +
+        "/referrer-policy/generic/subresource/stylesheet.py?id=" + id + "&type=font";
+      let font_url = url_prefix + "/referrer-policy/generic/subresource/font.py" +
+                     "?id=" + id + "&report-headers" + "&type=font";
+
+      let link = document.createElement("link");
+      link.href = css_url;
+      link.rel = "stylesheet";
+      link.onload = function() {
+        css_test.step_timeout(
+            queryXhr.bind(this, font_url,
+                          function(message) {
+                            css_test.step(function() {
+                              assert_own_property(message, "headers");
+                              assert_own_property(message, "referrer");
+                              assert_equals(message.referrer, css_referrer);
+                            });
+                            css_test.done();
+                          }),
+            1000);
+      };
+      document.head.appendChild(link);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-stylesheet.html
new file mode 100644
index 00000000000..24e4bb99900
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/external-stylesheet.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Font from external stylesheet</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="never">
+  </head>
+  <body>
+    <p>Check that resources from external stylesheets are loaded with
+    the referrer and referrer policy from the external stylesheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Font from external stylesheet.");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" + location.port;
+      let css_url = url_prefix + "/referrer-policy/generic/subresource/stylesheet.py?id=" + id + "&type=font";
+      let font_url = url_prefix + "/referrer-policy/generic/subresource/font.py" +
+                    "?id=" + id + "&report-headers";
+
+      let link = document.createElement("link");
+      link.href = css_url;
+      link.rel = "stylesheet";
+      link.onload = function() {
+        css_test.step_timeout(
+            queryXhr.bind(this, font_url,
+                          function(message) {
+                            css_test.step(function() {
+                              assert_own_property(message, "headers");
+                              assert_own_property(message, "referrer");
+                              assert_equals(message.referrer, css_url);
+                            });
+                            css_test.done();
+                          }),
+            1000);
+      };
+      document.head.appendChild(link);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-import-stylesheet.html
new file mode 100644
index 00000000000..54e2383423c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-import-stylesheet.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Font from imported stylesheet (internal)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from stylesheets (imported from internal
+    stylesheets) are loaded with the referrer and referrer policy from from the
+    imported style sheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Font from imported stylesheet (internal).");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" +
+                       location.port + "/referrer-policy/generic/subresource/";
+      let css_url = url_prefix + "stylesheet.py?id=" + id + "&type=font";
+      let font_url = url_prefix + "font.py?report-headers&id=" + id;
+
+      let style = document.createElement("style");
+      style.textContent = "@import url('" + css_url + "');";
+      document.head.appendChild(style);
+      css_test.step_timeout(
+          queryXhr.bind(this, font_url,
+                        function(message) {
+                          css_test.step(function() {
+                            assert_own_property(message, "headers");
+                            assert_own_property(message, "referrer");
+                            assert_equals(message.referrer, css_url);
+                          });
+                          css_test.done();
+                        }),
+          1000);
+      </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-stylesheet.html
new file mode 100644
index 00000000000..b3869bcebdc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/internal-stylesheet.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Font from internal stylesheet</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from internal stylesheets are loaded with
+    the referrer and referrer policy from the document.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Font from internal stylesheet.");
+      let id = token();
+      let css_url = location.protocol + "//www1." + location.hostname + ":" +
+                    location.port +
+                    "/referrer-policy/generic/subresource/font.py" + "?id=" +
+                    id + "&type=font";
+      let font_url = css_url + "&report-headers";
+
+      let style = document.createElement("style");
+      style.textContent = "@font-face { font-family: 'wpt'; font-style: normal; font-weight: normal; src: url(" + css_url + "); format('truetype'); } body { font-family: 'wpt';}";
+      document.head.appendChild(style);
+      css_test.step_timeout(
+          queryXhr.bind(this, font_url,
+                        function(message) {
+                          css_test.step(function() {
+                            assert_own_property(message, "headers");
+                            assert_own_property(message, "referrer");
+                            assert_equals(message.referrer, location.origin + "/");
+                          });
+                          css_test.done();
+                        }),
+          1000);
+      </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/processing-instruction.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/processing-instruction.html
new file mode 100644
index 00000000000..89ee918e24e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/font-face/processing-instruction.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - Font from external stylesheet inserted via a ProcessingInstruction</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <meta name="referrer" content="never">
+  </head>
+  <body>
+    <p>Check that resources from external stylesheets (referenced from a
+    ProcessingInstruction) are loaded with the referrer and referrer policy
+    from the external stylesheet.</p>
+
+    <div class="styled"></div>
+
+    <script>
+      let css_test = async_test("Font from external stylesheet (from ProcessingInstruction).");
+      let id = token();
+      let url_prefix = location.protocol + "//www1." + location.hostname + ":" + location.port;
+      let css_url = url_prefix +
+                    "/referrer-policy/generic/subresource/stylesheet.py?id=" +
+                    id + "&amp;type=font";
+      let expected = url_prefix +
+                    "/referrer-policy/generic/subresource/stylesheet.py?id=" +
+                    id + "&type=font";
+      let font_url = url_prefix + "/referrer-policy/generic/subresource/font.py" +
+                     "?id=" + id + "&report-headers";
+
+      let processingInstruction =
+        document.createProcessingInstruction(
+          "xml-stylesheet", "href=\"" + css_url + "\" type=\"text/css\"");
+      css_test.step_timeout(
+          queryXhr.bind(this, font_url,
+                        function(message) {
+                          css_test.step(function() {
+                            assert_own_property(message, "headers");
+                            assert_own_property(message, "referrer");
+                            assert_equals(message.referrer, expected);
+                          });
+                          css_test.done();
+                        }),
+          1000);
+      document.insertBefore(processingInstruction, document.firstChild);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/external-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/external-import-stylesheet.html
similarity index 84%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/external-import-stylesheet.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/external-import-stylesheet.html
index 7b6ec6431bd..0023af31b17 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/css-integration/external-import-stylesheet.html
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/external-import-stylesheet.html
@@ -19,10 +19,13 @@
     <script>
       var css_test = async_test("Image from imported stylesheet (external).");
       var id = token();
-      var cross_origin_url_prefix = location.protocol + "//www1." + location.hostname + ":" + location.port;
-      var css_url = cross_origin_url_prefix + "/referrer-policy/generic/subresource/stylesheet.py?id=" + id + "&import-rule";
+      var css_url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+        "/referrer-policy/generic/subresource/stylesheet.py?id=" + id +
+        "&import-rule" + "&type=image";
       var url_prefix = location.protocol + "//" + location.hostname + ":" + location.port;
-      var css_referrer = url_prefix + "/referrer-policy/generic/subresource/stylesheet.py?id=" + id;
+      var css_referrer = url_prefix +
+        "/referrer-policy/generic/subresource/stylesheet.py?id=" + id +
+        "&type=image";
       var img_url = url_prefix + "/referrer-policy/generic/subresource/image.py" +
                     "?id=" + id + "&report-headers";
 
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/external-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/external-stylesheet.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/external-stylesheet.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/external-stylesheet.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/inline-style.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/inline-style.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/inline-style.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/inline-style.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/internal-import-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/internal-import-stylesheet.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/internal-import-stylesheet.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/internal-import-stylesheet.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/internal-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/internal-stylesheet.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/internal-stylesheet.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/internal-stylesheet.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/presentation-attribute.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/presentation-attribute.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/presentation-attribute.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/presentation-attribute.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/processing-instruction.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/image/processing-instruction.html
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/css-integration/processing-instruction.html
rename to tests/wpt/web-platform-tests/referrer-policy/css-integration/image/processing-instruction.html
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/external-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/external-stylesheet.html
new file mode 100644
index 00000000000..148584a0b23
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/external-stylesheet.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - styling SVG from external stylesheet</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <!-- Helper functions for referrer-policy css tests. -->
+    <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+    <meta name="referrer" content="never">
+  </head>
+  <body>
+    <p>Check that resources from external stylesheets are loaded with
+    the referrer and referrer policy from the external stylesheet.</p>
+
+    <script>
+      function addLinkStyleSheet(test) {
+        let css_url = url_prefix + "stylesheet.py?id=" + test.id +
+                      "&type=svg" + "&property=" + test.property;
+        test.expected = css_url;
+
+        let stylesheet =
+          document.createElementNS("http://www.w3.org/1999/xhtml", "link");
+        stylesheet.setAttribute("type", "text/css");
+        stylesheet.setAttribute("rel", "stylesheet");
+        stylesheet.setAttribute("href", css_url);
+        let svg = createSvg();
+        document.body.appendChild(svg);
+        svg.appendChild(stylesheet);
+      }
+
+      runSvgTests(svg_test_properties,
+                  "Test styling SVG from external style",
+                  addLinkStyleSheet);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/inline-style.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/inline-style.html
new file mode 100644
index 00000000000..1f46acb4a32
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/inline-style.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - styling SVG from inline style</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <!-- Helper functions for referrer-policy css tests. -->
+    <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from inline styles are loaded with
+    the referrer and referrer policy from the document.</p>
+    <script>
+      function setInlineStyle(test)
+      {
+        test.expected = location.origin + "/";
+        let svg = createSvg();
+        document.body.appendChild(svg);
+        let element = svg.getElementsByTagName('path')[0];
+        element.style = test.property + ": url(" + url_prefix + "svg.py?id=" +
+                        test.id + "#invalidFragment);";
+      }
+
+      runSvgTests(svg_test_properties,
+                  "Styling SVG from inline styles",
+                  setInlineStyle);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/internal-stylesheet.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/internal-stylesheet.html
new file mode 100644
index 00000000000..08be4effa47
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/internal-stylesheet.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - styling SVG from internal style</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <!-- Helper functions for referrer-policy css tests. -->
+    <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from internal styles are loaded with
+    the referrer and referrer policy from the document.</p>
+    <script>
+      function setInternalStyle(test) {
+        test.expected = location.origin + "/";
+        let style = document.createElementNS(svg_ns, "style");
+        style.textContent = "path { " + test.property + ": url(" + url_prefix +
+                            "svg.py?id=" + test.id + "#invalidFragment);";
+        let svg = createSvg();
+        svg.appendChild(style);
+        document.body.appendChild(svg);
+      }
+
+      runSvgTests(svg_test_properties,
+                  "Styling SVG from internal styles",
+                  setInternalStyle);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/presentation-attribute.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/presentation-attribute.html
new file mode 100644
index 00000000000..edeceb1a785
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/presentation-attribute.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - styling SVG from external stylesheet from
+           presentation attribute</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <!-- Helper functions for referrer-policy css tests. -->
+    <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from presentation attributes are loaded with
+    the referrer and referrer policy from the document.</p>
+   <script>
+      function setPresentationAttribute(test)
+      {
+        test.expected = location.origin + "/";
+        let svg = createSvg();
+        document.body.appendChild(svg);
+        let element = svg.getElementsByTagName("path")[0];
+        // The test property should have map 1:1 with presentation attribute.
+        let attr = test.property;
+        element.setAttribute(attr, "url(" + url_prefix + "svg.py?id=" +
+                             test.id + "#invalidFragment)");
+      }
+
+      // mask-image is not the presentation attribute.
+      runSvgTests(svg_test_properties.filter(p => p != 'mask-image'),
+                  "Styling SVG from presentation attributes",
+                  setPresentationAttribute);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
+
diff --git a/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/processing-instruction.html b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/processing-instruction.html
new file mode 100644
index 00000000000..ba0e6673a38
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/css-integration/svg/processing-instruction.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSS integration - styling SVG from external stylesheet via
+           ProcessingInstruction</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/common/utils.js"></script>
+    <!-- Common global functions for referrer-policy tests. -->
+    <script src="/referrer-policy/generic/common.js"></script>
+    <!-- Helper functions for referrer-policy css tests. -->
+    <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+    <meta name="referrer" content="origin">
+  </head>
+  <body>
+    <p>Check that resources from external stylesheets (referenced from a
+    ProcessingInstruction) are loaded with the referrer and referrer policy
+    from the external stylesheet.</p>
+    <script>
+      function addProcessingInstruction(test) {
+        let svg_url = url_prefix + "svg.py?id=" + test.id + "&type=svg" +
+                      "&property=" + test.property + "&embedded-svg";
+        let iframe = document.createElement("iframe");
+        test.expected = url_prefix + "stylesheet.py?id=" + test.id +
+                        "&type=svg" + "&property=" + test.property;
+        iframe.src = svg_url;
+        document.body.appendChild(iframe);
+      }
+
+      runSvgTests(svg_test_properties,
+                  "Styling SVG from ProcessingInstruction",
+                  addProcessingInstruction);
+    </script>
+
+    <div id="log"></div>
+  </body>
+</html>
+
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/font.py b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/font.py
new file mode 100644
index 00000000000..50a5bd2f399
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/font.py
@@ -0,0 +1,72 @@
+import os, sys, json, base64
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+import subresource
+
+def generate_payload(request, server_data):
+    data = ('{"headers": %(headers)s}') % server_data
+    if "id" in request.GET:
+        request.server.stash.put(request.GET["id"], data)
+    # Simple base64 encoded .tff font
+    return base64.decodestring("AAEAAAANAIAAAwBQRkZUTU6u6MkAAAXcAAAAHE9TLzJWYW"
+                               "QKAAABWAAAAFZjbWFwAA8D7wAAAcAAAAFCY3Z0IAAhAnkA"
+                               "AAMEAAAABGdhc3D//wADAAAF1AAAAAhnbHlmCC6aTwAAAx"
+                               "QAAACMaGVhZO8ooBcAAADcAAAANmhoZWEIkAV9AAABFAAA"
+                               "ACRobXR4EZQAhQAAAbAAAAAQbG9jYQBwAFQAAAMIAAAACm"
+                               "1heHAASQA9AAABOAAAACBuYW1lehAVOgAAA6AAAAIHcG9z"
+                               "dP+uADUAAAWoAAAAKgABAAAAAQAAMhPyuV8PPPUACwPoAA"
+                               "AAAMU4Lm0AAAAAxTgubQAh/5wFeAK8AAAACAACAAAAAAAA"
+                               "AAEAAAK8/5wAWgXcAAAAAAV4AAEAAAAAAAAAAAAAAAAAAA"
+                               "AEAAEAAAAEAAwAAwAAAAAAAgAAAAEAAQAAAEAALgAAAAAA"
+                               "AQXcAfQABQAAAooCvAAAAIwCigK8AAAB4AAxAQIAAAIABg"
+                               "kAAAAAAAAAAAABAAAAAAAAAAAAAAAAUGZFZABAAEEAQQMg"
+                               "/zgAWgK8AGQAAAABAAAAAAAABdwAIQAAAAAF3AAABdwAZA"
+                               "AAAAMAAAADAAAAHAABAAAAAAA8AAMAAQAAABwABAAgAAAA"
+                               "BAAEAAEAAABB//8AAABB////wgABAAAAAAAAAQYAAAEAAA"
+                               "AAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+                               "AAAAAAAAAAAAAAAAAAAhAnkAAAAqACoAKgBGAAAAAgAhAA"
+                               "ABKgKaAAMABwAusQEALzyyBwQA7TKxBgXcPLIDAgDtMgCx"
+                               "AwAvPLIFBADtMrIHBgH8PLIBAgDtMjMRIREnMxEjIQEJ6M"
+                               "fHApr9ZiECWAAAAwBk/5wFeAK8AAMABwALAAABNSEVATUh"
+                               "FQE1IRUB9AH0/UQDhPu0BRQB9MjI/tTIyP7UyMgAAAAAAA"
+                               "4ArgABAAAAAAAAACYATgABAAAAAAABAAUAgQABAAAAAAAC"
+                               "AAYAlQABAAAAAAADACEA4AABAAAAAAAEAAUBDgABAAAAAA"
+                               "AFABABNgABAAAAAAAGAAUBUwADAAEECQAAAEwAAAADAAEE"
+                               "CQABAAoAdQADAAEECQACAAwAhwADAAEECQADAEIAnAADAA"
+                               "EECQAEAAoBAgADAAEECQAFACABFAADAAEECQAGAAoBRwBD"
+                               "AG8AcAB5AHIAaQBnAGgAdAAgACgAYwApACAAMgAwADAAOA"
+                               "AgAE0AbwB6AGkAbABsAGEAIABDAG8AcgBwAG8AcgBhAHQA"
+                               "aQBvAG4AAENvcHlyaWdodCAoYykgMjAwOCBNb3ppbGxhIE"
+                               "NvcnBvcmF0aW9uAABNAGEAcgBrAEEAAE1hcmtBAABNAGUA"
+                               "ZABpAHUAbQAATWVkaXVtAABGAG8AbgB0AEYAbwByAGcAZQ"
+                               "AgADIALgAwACAAOgAgAE0AYQByAGsAQQAgADoAIAA1AC0A"
+                               "MQAxAC0AMgAwADAAOAAARm9udEZvcmdlIDIuMCA6IE1hcm"
+                               "tBIDogNS0xMS0yMDA4AABNAGEAcgBrAEEAAE1hcmtBAABW"
+                               "AGUAcgBzAGkAbwBuACAAMAAwADEALgAwADAAMAAgAABWZX"
+                               "JzaW9uIDAwMS4wMDAgAABNAGEAcgBrAEEAAE1hcmtBAAAA"
+                               "AgAAAAAAAP+DADIAAAABAAAAAAAAAAAAAAAAAAAAAAAEAA"
+                               "AAAQACACQAAAAAAAH//wACAAAAAQAAAADEPovuAAAAAMU4"
+                               "Lm0AAAAAxTgubQ==");
+
+def generate_report_headers_payload(request, server_data):
+    stashed_data = request.server.stash.take(request.GET["id"])
+    return stashed_data
+
+def main(request, response):
+    handler = lambda data: generate_payload(request, data)
+    content_type = 'application/x-font-truetype'
+
+    if "report-headers" in request.GET:
+        handler = lambda data: generate_report_headers_payload(request, data)
+        content_type = 'application/json'
+
+    subresource.respond(request,
+                        response,
+                        payload_generator = handler,
+                        content_type = content_type,
+                        access_control_allow_origin = "*")
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/stylesheet.py b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/stylesheet.py
index 328db29b957..54378216774 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/stylesheet.py
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/stylesheet.py
@@ -3,24 +3,66 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
 import subresource
 
 def generate_payload(request, server_data):
-    return subresource.get_template("stylesheet.css.template") % {"id": request.GET["id"]}
+    data = ('{"headers": %(headers)s}') % server_data
+    type = 'image'
+    if "type" in request.GET:
+        type = request.GET["type"]
+
+    if "id" in request.GET:
+        request.server.stash.put(request.GET["id"], data)
+
+    if type == 'image':
+        return subresource.get_template("image.css.template") % {"id": request.GET["id"]}
+
+    elif type == 'font':
+        return subresource.get_template("font.css.template") % {"id": request.GET["id"]}
+
+    elif type == 'svg':
+        return subresource.get_template("svg.css.template") % {
+            "id": request.GET["id"],
+            "property": request.GET["property"]}
 
 def generate_import_rule(request, server_data):
-    data = "@import url('%(url)s?id=%(id)s');" % {
+    type = 'image'
+    property = None;
+    if "type" in request.GET:
+        type = request.GET["type"]
+    if type == "svg" and "property" in request.GET:
+        property = request.GET["property"]
+    if property is None:
+        return "@import url('%(url)s?id=%(id)s&type=%(type)s');" % {
+            "id": request.GET["id"],
+            "url": subresource.create_redirect_url(request, cross_origin = True),
+            "type": type
+        }
+    return "@import url('%(url)s?id=%(id)s&type=%(type)s&property=%(property)s');" % {
         "id": request.GET["id"],
-        "url": subresource.create_redirect_url(request, cross_origin = True)
+        "url": subresource.create_redirect_url(request, cross_origin = True),
+        "type": type,
+        "property": property
     }
-    return data
+
+def generate_report_headers_payload(request, server_data):
+    stashed_data = request.server.stash.take(request.GET["id"])
+    return stashed_data
 
 def main(request, response):
     payload_generator = lambda data: generate_payload(request, data)
+    content_type = "text/css"
+    referrer_policy = "unsafe-url"
     if "import-rule" in request.GET:
         payload_generator = lambda data: generate_import_rule(request, data)
 
+    if "report-headers" in request.GET:
+        payload_generator = lambda data: generate_report_headers_payload(request, data)
+        content_type = 'application/json'
+
+    if "referrer-policy" in request.GET:
+        referrer_policy = request.GET["referrer-policy"]
+
     subresource.respond(
         request,
         response,
         payload_generator = payload_generator,
-        content_type = "text/css",
-        maybe_additional_headers = { "Referrer-Policy": "unsafe-url" })
-
+        content_type = content_type,
+        maybe_additional_headers = { "Referrer-Policy": referrer_policy })
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/svg.py b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/svg.py
new file mode 100644
index 00000000000..8618875c79f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/subresource/svg.py
@@ -0,0 +1,36 @@
+import os, sys, json
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+import subresource
+
+def generate_payload(request, server_data):
+    data = ('{"headers": %(headers)s}') % server_data
+    if "id" in request.GET:
+        with request.server.stash.lock:
+            request.server.stash.take(request.GET["id"])
+            request.server.stash.put(request.GET["id"], data)
+    return "<svg xmlns='http://www.w3.org/2000/svg'></svg>";
+
+def generate_payload_embedded(request, server_data):
+    return subresource.get_template("svg.embedded.template") % {
+        "id": request.GET["id"],
+        "property": request.GET["property"]};
+
+def generate_report_headers_payload(request, server_data):
+    stashed_data = request.server.stash.take(request.GET["id"])
+    return stashed_data
+
+def main(request, response):
+    handler = lambda data: generate_payload(request, data)
+    content_type = 'image/svg+xml'
+
+    if "embedded-svg" in request.GET:
+        handler = lambda data: generate_payload_embedded(request, data)
+
+    if "report-headers" in request.GET:
+        handler = lambda data: generate_report_headers_payload(request, data)
+        content_type = 'application/json'
+
+    subresource.respond(request,
+                        response,
+                        payload_generator = handler,
+                        content_type = content_type)
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/template/font.css.template b/tests/wpt/web-platform-tests/referrer-policy/generic/template/font.css.template
new file mode 100644
index 00000000000..9b19df3cf1f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/template/font.css.template
@@ -0,0 +1,9 @@
+@font-face {
+  font-family: 'wpt';
+  font-style: normal;
+  font-weight: normal;
+  src: url(/referrer-policy/generic/subresource/font.py?id=%(id)s) format('truetype');
+}
+body {
+  font-family: 'wpt';
+}
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/template/stylesheet.css.template b/tests/wpt/web-platform-tests/referrer-policy/generic/template/image.css.template
similarity index 100%
rename from tests/wpt/web-platform-tests/referrer-policy/generic/template/stylesheet.css.template
rename to tests/wpt/web-platform-tests/referrer-policy/generic/template/image.css.template
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.css.template b/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.css.template
new file mode 100644
index 00000000000..ffaefed4aa4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.css.template
@@ -0,0 +1,3 @@
+path {
+  %(property)s: url(/referrer-policy/generic/subresource/svg.py?id=%(id)s#invalidFragment);
+}
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.embedded.template b/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.embedded.template
new file mode 100644
index 00000000000..5986c4800a7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/template/svg.embedded.template
@@ -0,0 +1,5 @@
+<?xml version='1.0' standalone='no'?>
+<?xml-stylesheet href='stylesheet.py?id=%(id)s&amp;type=svg&amp;property=%(property)s' type='text/css'?>
+<svg xmlns='http://www.w3.org/2000/svg'>
+  <path d='M 50,5 95,100 5,100 z' />
+</svg>
diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py b/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py
index 060f9b0c9a7..fefc75b7b7f 100644
--- a/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py
+++ b/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py
@@ -17,22 +17,22 @@ def main(request, response):
     # case-sensitive match for origin, pass
         response.headers.set('Timing-Allow-Origin', origin)
     elif tao == 'space':
-    # space seperated list of origin and wildcard, fail
+    # space separated list of origin and wildcard, fail
         response.headers.set('Timing-Allow-Origin', (origin + ' *'))
     elif tao == 'multi':
-    # more than one TAO values, seperated by comma, pass
+    # more than one TAO values, separated by comma, pass
         response.headers.set('Timing-Allow-Origin', origin)
         response.headers.append('Timing-Allow-Origin', '*')
     elif tao == 'multi_wildcard':
-    # multiple wildcards, seperated by comma, pass
+    # multiple wildcards, separated by comma, pass
         response.headers.set('Timing-Allow-Origin', '*')
         response.headers.append('Timing-Allow-Origin', '*')
     elif tao == 'match_origin':
-    # contains a match of origin, seperated by comma, pass
+    # contains a match of origin, separated by comma, pass
         response.headers.set('Timing-Allow-Origin', origin)
         response.headers.append('Timing-Allow-Origin', "fake")
     elif tao == 'match_wildcard':
-    # contains a wildcard, seperated by comma, pass
+    # contains a wildcard, separated by comma, pass
         response.headers.set('Timing-Allow-Origin', "fake")
         response.headers.append('Timing-Allow-Origin', '*')
     elif tao == 'uppercase':
diff --git a/tests/wpt/web-platform-tests/resources/test/conftest.py b/tests/wpt/web-platform-tests/resources/test/conftest.py
index 5fca1d24c41..dde9e9dc0a7 100644
--- a/tests/wpt/web-platform-tests/resources/test/conftest.py
+++ b/tests/wpt/web-platform-tests/resources/test/conftest.py
@@ -2,11 +2,12 @@ import io
 import json
 import os
 import ssl
-import urllib2
 
 import html5lib
 import pytest
 from selenium import webdriver
+from six import text_type
+from six.moves import urllib
 
 from wptserver import WPTServer
 
@@ -63,8 +64,8 @@ class HTMLItem(pytest.Item, pytest.Collector):
         # Some tests are reliant on the WPT servers substitution functionality,
         # so tests must be retrieved from the server rather than read from the
         # file system directly.
-        handle = urllib2.urlopen(self.url,
-                                 context=parent.session.config.ssl_context)
+        handle = urllib.request.urlopen(self.url,
+                                        context=parent.session.config.ssl_context)
         try:
             markup = handle.read()
         finally:
@@ -87,7 +88,7 @@ class HTMLItem(pytest.Item, pytest.Collector):
                 continue
             if element.tag == 'script':
                 if element.attrib.get('id') == 'expected':
-                    self.expected = json.loads(unicode(element.text))
+                    self.expected = json.loads(text_type(element.text))
 
                 src = element.attrib.get('src', '')
 
@@ -186,7 +187,7 @@ class HTMLItem(pytest.Item, pytest.Collector):
     @staticmethod
     def _assert_sequence(nums):
         if nums and len(nums) > 0:
-            assert nums == range(1, nums[-1] + 1)
+            assert nums == list(range(1, nums[-1] + 1))
 
     @staticmethod
     def _scrub_stack(test_obj):
diff --git a/tests/wpt/web-platform-tests/resources/test/tests/functional/api-tests-1.html b/tests/wpt/web-platform-tests/resources/test/tests/functional/api-tests-1.html
index a9d92b12f81..c65d026edba 100644
--- a/tests/wpt/web-platform-tests/resources/test/tests/functional/api-tests-1.html
+++ b/tests/wpt/web-platform-tests/resources/test/tests/functional/api-tests-1.html
@@ -147,8 +147,8 @@
         var A = function(){this.a = "a"}
         A.prototype = {b:"b"}
         var a = new A();
-        assert_exists(a, "a");
-        assert_not_exists(a, "b");
+        assert_own_property(a, "a");
+        assert_false(a.hasOwnProperty("b"), "unexpected property found: \"b\"");
         assert_inherits(a, "b");
     }
     test(testAssertInherits, "test for assert[_not]_exists and insert_inherits")
diff --git a/tests/wpt/web-platform-tests/resources/test/tests/functional/log-insertion.html b/tests/wpt/web-platform-tests/resources/test/tests/functional/log-insertion.html
new file mode 100644
index 00000000000..3f28266d576
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/test/tests/functional/log-insertion.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<title>Log insertion</title>
+<meta name="variant" content="">
+<meta name="variant" content="?keep-promise">
+<script src="../../variants.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+  window.onload = t.step_func_done(function() {
+    var body = document.body;
+    assert_not_equals(body, null);
+
+    var log = document.getElementById("log");
+    assert_equals(log.parentNode, body);
+  });
+});
+</script>
+<script type="text/json" id="expected">
+{
+  "summarized_status": {
+    "status_string": "OK",
+    "message": null
+  },
+  "summarized_tests": [{
+    "status_string": "PASS",
+    "name": "Log insertion",
+    "message": null,
+    "properties": {}
+  }],
+  "type": "complete"
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/resources/test/tox.ini b/tests/wpt/web-platform-tests/resources/test/tox.ini
index d3a30f870a1..7a9e4fa5228 100644
--- a/tests/wpt/web-platform-tests/resources/test/tox.ini
+++ b/tests/wpt/web-platform-tests/resources/test/tox.ini
@@ -1,6 +1,6 @@
 [tox]
-# wptserve etc. are Python2-only.
-envlist = py27
+# Note that only py27 is run in CI.
+envlist = py27,py36
 skipsdist=True
 
 [testenv]
@@ -11,6 +11,7 @@ deps =
   pytest>=2.9
   pyvirtualdisplay
   selenium
+  six
   requests
 
 commands = pytest {posargs} -vv tests
diff --git a/tests/wpt/web-platform-tests/resources/test/wptserver.py b/tests/wpt/web-platform-tests/resources/test/wptserver.py
index fa32c33b9d7..d47e325fbef 100644
--- a/tests/wpt/web-platform-tests/resources/test/wptserver.py
+++ b/tests/wpt/web-platform-tests/resources/test/wptserver.py
@@ -3,7 +3,7 @@ import os
 import subprocess
 import time
 import sys
-import urllib2
+from six.moves import urllib
 
 
 class WPTServer(object):
@@ -38,9 +38,9 @@ class WPTServer(object):
                 logging.warn('Command "%s" exited with %s', ' '.join(wptserve_cmd), exit_code)
                 break
             try:
-                urllib2.urlopen(self.base_url, timeout=1)
+                urllib.request.urlopen(self.base_url, timeout=1)
                 return
-            except urllib2.URLError:
+            except urllib.error.URLError:
                 pass
 
         raise Exception('Could not start wptserve on %s' % self.base_url)
diff --git a/tests/wpt/web-platform-tests/resources/testharness.js b/tests/wpt/web-platform-tests/resources/testharness.js
index 352e8b76266..0a92cf10a3d 100644
--- a/tests/wpt/web-platform-tests/resources/testharness.js
+++ b/tests/wpt/web-platform-tests/resources/testharness.js
@@ -1255,24 +1255,12 @@ policies and contribution forms [3].
     expose(assert_class_string, "assert_class_string");
 
 
-    function _assert_own_property(name) {
-        return function(object, property_name, description)
-        {
-            assert(object.hasOwnProperty(property_name),
-                   name, description,
-                   "expected property ${p} missing", {p:property_name});
-        };
+    function assert_own_property(object, property_name, description) {
+        assert(object.hasOwnProperty(property_name),
+               "assert_own_property", description,
+               "expected property ${p} missing", {p:property_name});
     }
-    expose(_assert_own_property("assert_exists"), "assert_exists");
-    expose(_assert_own_property("assert_own_property"), "assert_own_property");
-
-    function assert_not_exists(object, property_name, description)
-    {
-        assert(!object.hasOwnProperty(property_name),
-               "assert_not_exists", description,
-               "unexpected property ${p} found", {p:property_name});
-    }
-    expose(assert_not_exists, "assert_not_exists");
+    expose(assert_own_property, "assert_own_property");
 
     function _assert_inherits(name) {
         return function (object, property_name, description)
@@ -2559,27 +2547,24 @@ policies and contribution forms [3].
             if (output_document.body) {
                 output_document.body.appendChild(node);
             } else {
-                var is_html = false;
-                var is_svg = false;
-                var output_window = output_document.defaultView;
-                if (output_window && "SVGSVGElement" in output_window) {
-                    is_svg = output_document.documentElement instanceof output_window.SVGSVGElement;
-                } else if (output_window) {
-                    is_html = (output_document.namespaceURI == "http://www.w3.org/1999/xhtml" &&
-                               output_document.localName == "html");
-                }
+                var root = output_document.documentElement;
+                var is_html = (root &&
+                               root.namespaceURI == "http://www.w3.org/1999/xhtml" &&
+                               root.localName == "html");
+                var is_svg = (output_document.defaultView &&
+                              "SVGSVGElement" in output_document.defaultView &&
+                              root instanceof output_document.defaultView.SVGSVGElement);
                 if (is_svg) {
                     var foreignObject = output_document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
                     foreignObject.setAttribute("width", "100%");
                     foreignObject.setAttribute("height", "100%");
-                    output_document.documentElement.appendChild(foreignObject);
+                    root.appendChild(foreignObject);
                     foreignObject.appendChild(node);
                 } else if (is_html) {
-                    var body = output_document.createElementNS("http://www.w3.org/1999/xhtml", "body");
-                    output_document.documentElement.appendChild(body);
-                    body.appendChild(node);
+                    root.appendChild(output_document.createElementNS("http://www.w3.org/1999/xhtml", "body"))
+                        .appendChild(node);
                 } else {
-                    output_document.documentElement.appendChild(node);
+                    root.appendChild(node);
                 }
             }
         }
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html
index 0490f2b4058..b6281b9e6c3 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html
@@ -92,10 +92,6 @@ function redirect_test(url,
                        expected_request_infos,
                        test_name) {
   promise_test(async t => {
-    const message_promise = new Promise(resolve => {
-        // A message with ID 'last_url' will be sent from the iframe.
-        message_resolvers['last_url'] = resolve;
-    });
     const frame = await with_iframe(url);
     t.add_cleanup(() => { frame.remove(); });
 
@@ -105,7 +101,7 @@ function redirect_test(url,
       });
     });
     await check_all_intercepted_urls(expected_intercepted_urls);
-    const last_url = await message_promise;
+    const last_url = await send_to_iframe(frame, 'getLocation');
     assert_equals(last_url, expected_last_url, 'Last URL should match.');
   }, test_name);
 }
@@ -129,7 +125,7 @@ function send_to_iframe(frame, message) {
     message_resolvers[message_id] = resolve;
     frame.contentWindow.postMessage(
         {id: message_id, message},
-        host_info['HTTPS_REMOTE_ORIGIN']);
+        '*');
   });
 }
 
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
index 907cefa3b1a..16850723f96 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
@@ -11,10 +11,12 @@ def main(request, response):
     return status, [("content-type", "text/html")], '''
 <!DOCTYPE html>
 <script>
+onmessage = event => {
   window.parent.postMessage(
       {
-        id: 'last_url',
+        id: event.data.id,
         result: location.href
       }, '*');
+};
 </script>
 '''
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
index 907cefa3b1a..16850723f96 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
@@ -11,10 +11,12 @@ def main(request, response):
     return status, [("content-type", "text/html")], '''
 <!DOCTYPE html>
 <script>
+onmessage = event => {
   window.parent.postMessage(
       {
-        id: 'last_url',
+        id: event.data.id,
         result: location.href
       }, '*');
+};
 </script>
 '''
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
index 907cefa3b1a..16850723f96 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
@@ -11,10 +11,12 @@ def main(request, response):
     return status, [("content-type", "text/html")], '''
 <!DOCTYPE html>
 <script>
+onmessage = event => {
   window.parent.postMessage(
       {
-        id: 'last_url',
+        id: event.data.id,
         result: location.href
       }, '*');
+};
 </script>
 '''
diff --git a/tests/wpt/web-platform-tests/svg/import/animate-elem-83-t-manual.svg b/tests/wpt/web-platform-tests/svg/import/animate-elem-83-t-manual.svg
index 2de478b5315..46b9bedc41b 100644
--- a/tests/wpt/web-platform-tests/svg/import/animate-elem-83-t-manual.svg
+++ b/tests/wpt/web-platform-tests/svg/import/animate-elem-83-t-manual.svg
@@ -43,7 +43,7 @@
       <p>
         The third test validates a simple values-animation on a path's d attribute
         made of M, C and Z commands where the values attribute is specified and
-        specifies three seperate values.
+        specifies three separate values.
         The attribute is compatible with the path element's d attribute.
       </p>
       <p>
diff --git a/tests/wpt/web-platform-tests/tools/ci/check_stability.py b/tests/wpt/web-platform-tests/tools/ci/check_stability.py
index 2b32eb50c0f..a0633110860 100644
--- a/tests/wpt/web-platform-tests/tools/ci/check_stability.py
+++ b/tests/wpt/web-platform-tests/tools/ci/check_stability.py
@@ -272,6 +272,7 @@ def run(venv, wpt_args, **kwargs):
         wpt_kwargs["verify_log_full"] = False
         if wpt_kwargs["repeat"] == 1:
             wpt_kwargs["repeat"] = 10
+        wpt_kwargs["headless"] = False
 
         wpt_kwargs = setup_wptrunner(venv, **wpt_kwargs)
 
diff --git a/tests/wpt/web-platform-tests/tools/ci/taskcluster-run.py b/tests/wpt/web-platform-tests/tools/ci/taskcluster-run.py
index 45416501e03..5a720baa2e9 100755
--- a/tests/wpt/web-platform-tests/tools/ci/taskcluster-run.py
+++ b/tests/wpt/web-platform-tests/tools/ci/taskcluster-run.py
@@ -73,7 +73,8 @@ def main(product, commit_range, wpt_args):
         "-y",
         "--no-pause",
         "--no-restart-on-unexpected",
-        "--install-fonts"
+        "--install-fonts",
+        "--no-headless"
     ]
     wpt_args += browser_specific_args.get(product, [])
 
diff --git a/tests/wpt/web-platform-tests/tools/manifest/vcs.py b/tests/wpt/web-platform-tests/tools/manifest/vcs.py
index 42e9863712f..675eb01714f 100644
--- a/tests/wpt/web-platform-tests/tools/manifest/vcs.py
+++ b/tests/wpt/web-platform-tests/tools/manifest/vcs.py
@@ -1,5 +1,6 @@
 import os
 import subprocess
+import platform
 
 from .sourcefile import SourceFile
 
@@ -16,9 +17,12 @@ class Git(object):
             full_cmd = ["git", cmd] + list(args)
             try:
                 return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
-            except WindowsError:
-                full_cmd[0] = "git.bat"
-                return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
+            except Exception as e:
+                if platform.uname()[0] == "Windows" and isinstance(e, WindowsError):
+                        full_cmd[0] = "git.bat"
+                        return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
+                else:
+                    raise
         return git
 
     @classmethod
diff --git a/tests/wpt/web-platform-tests/tools/wpt/browser.py b/tests/wpt/web-platform-tests/tools/wpt/browser.py
index 7b943c2e73c..052ec66a091 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/browser.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/browser.py
@@ -102,6 +102,11 @@ class Firefox(Browser):
             "beta": "latest-beta",
             "nightly": "latest"
         }
+        application_name = {
+            "stable": "Firefox.app",
+            "beta": "Firefox.app",
+            "nightly": "Firefox Nightly.app"
+        }
         if channel not in branch:
             raise ValueError("Unrecognised release channel: %s" % channel)
 
@@ -131,10 +136,10 @@ class Firefox(Browser):
         try:
             mozinstall.install(filename, dest)
         except mozinstall.mozinstall.InstallError:
-            if platform == "mac" and os.path.exists(os.path.join(dest, "Firefox Nightly.app")):
+            if platform == "mac" and os.path.exists(os.path.join(dest, application_name[channel])):
                 # mozinstall will fail if nightly is already installed in the venv because
                 # mac installation uses shutil.copy_tree
-                mozinstall.uninstall(os.path.join(dest, "Firefox Nightly.app"))
+                mozinstall.uninstall(os.path.join(dest, application_name[channel]))
                 mozinstall.install(filename, dest)
             else:
                 raise
@@ -142,7 +147,7 @@ class Firefox(Browser):
         os.remove(filename)
         return self.find_binary_path(dest)
 
-    def find_binary_path(self, path=None):
+    def find_binary_path(self,path=None, channel="nightly"):
         """Looks for the firefox binary in the virtual environment"""
 
         platform = {
@@ -151,9 +156,15 @@ class Firefox(Browser):
             "Darwin": "mac"
         }.get(uname[0])
 
+        application_name = {
+            "stable": "Firefox.app",
+            "beta": "Firefox.app",
+            "nightly": "Firefox Nightly.app"
+        }.get(channel)
+
         if path is None:
             #os.getcwd() doesn't include the venv path
-            path = os.path.join(os.getcwd(), "_venv", "browsers")
+            path = os.path.join(os.getcwd(), "_venv", "browsers", channel)
 
         binary = None
 
@@ -163,7 +174,8 @@ class Firefox(Browser):
             import mozinstall
             binary = mozinstall.get_binary(path, "firefox")
         elif platform == "mac":
-            binary = find_executable("firefox", os.path.join(path, "Firefox Nightly.app", "Contents", "MacOS"))
+            binary = find_executable("firefox", os.path.join(path, application_name,
+                                                             "Contents", "MacOS"))
 
         return binary
 
@@ -171,14 +183,15 @@ class Firefox(Browser):
         if venv_path is None:
             venv_path = os.path.join(os.getcwd(), "_venv")
 
-        path = os.path.join(venv_path, "browsers")
-        if channel is not None:
-            path = os.path.join(path, channel)
-        binary = self.find_binary_path(path)
+        if channel is None:
+            channel = "nightly"
+
+        path = os.path.join(venv_path, "browsers", channel)
+        binary = self.find_binary_path(path, channel)
 
         if not binary and uname[0] == "Darwin":
-            macpaths = ["/Applications/FirefoxNightly.app/Contents/MacOS",
-                        os.path.expanduser("~/Applications/FirefoxNightly.app/Contents/MacOS"),
+            macpaths = ["/Applications/Firefox Nightly.app/Contents/MacOS",
+                        os.path.expanduser("~/Applications/Firefox Nightly.app/Contents/MacOS"),
                         "/Applications/Firefox Developer Edition.app/Contents/MacOS",
                         os.path.expanduser("~/Applications/Firefox Developer Edition.app/Contents/MacOS"),
                         "/Applications/Firefox.app/Contents/MacOS",
diff --git a/tests/wpt/web-platform-tests/tools/wpt/run.py b/tests/wpt/web-platform-tests/tools/wpt/run.py
index 7e8827b1069..d08b0f93807 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/run.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/run.py
@@ -177,6 +177,9 @@ class Firefox(BrowserSetup):
 
     def setup_kwargs(self, kwargs):
         if kwargs["binary"] is None:
+            if kwargs["browser_channel"] is None:
+                logger.info("No browser channel specified. Running nightly instead.")
+
             binary = self.browser.find_binary(self.venv.path,
                                               kwargs["browser_channel"])
             if binary is None:
@@ -221,6 +224,10 @@ Consider installing certutil via your OS package manager or directly.""")
                                                     channel=kwargs["browser_channel"])
             kwargs["prefs_root"] = prefs_root
 
+        if kwargs["headless"] is None:
+            kwargs["headless"] = True
+            logger.info("Running in headless mode, pass --no-headless to disable")
+
         # Allow WebRTC tests to call getUserMedia.
         kwargs["extra_prefs"].append("media.navigator.streams.fake=true")
 
diff --git a/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py b/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py
index d0cb2b85c99..8387dc9613e 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py
@@ -169,23 +169,25 @@ def test_run_firefox(manifest_dir):
     if is_port_8000_in_use():
         pytest.skip("port 8000 already in use")
 
-    os.environ["MOZ_HEADLESS"] = "1"
-    try:
-        if sys.platform == "darwin":
-            fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app")
-        else:
-            fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox")
-        if os.path.exists(fx_path):
-            shutil.rmtree(fx_path)
-        with pytest.raises(SystemExit) as excinfo:
-            wpt.main(argv=["run", "--no-pause", "--install-browser", "--yes",
-                           "--metadata", manifest_dir,
-                           "firefox", "/dom/nodes/Element-tagName.html"])
-        assert os.path.exists(fx_path)
+    if sys.platform == "darwin":
+        fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app")
+    else:
+        fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox")
+    if os.path.exists(fx_path):
         shutil.rmtree(fx_path)
-        assert excinfo.value.code == 0
-    finally:
-        del os.environ["MOZ_HEADLESS"]
+    with pytest.raises(SystemExit) as excinfo:
+        wpt.main(argv=["run", "--no-pause", "--install-browser", "--yes",
+                       # The use of `--binary-args` is intentional: it
+                       # demonstrates that internally-managed command-line
+                       # arguments are properly merged with those specified by
+                       # the user. See
+                       # https://github.com/web-platform-tests/wpt/pull/13154
+                       "--binary-arg=-headless",
+                       "--metadata", manifest_dir,
+                       "firefox", "/dom/nodes/Element-tagName.html"])
+    assert os.path.exists(fx_path)
+    shutil.rmtree(fx_path)
+    assert excinfo.value.code == 0
 
 
 @pytest.mark.slow
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome.txt
index 22a07532657..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome_android.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome_android.txt
index 22a07532657..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome_android.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_chrome_android.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_edge.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_edge.txt
index 22a07532657..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_edge.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_edge.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_firefox.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_firefox.txt
index f1e6a8585ca..bfe0d4bc347 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_firefox.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_firefox.txt
@@ -1,8 +1,8 @@
-marionette_driver==2.6.0
-mozprofile==1.1.0
+marionette_driver==2.7.0
+mozprofile==2.0.0
 mozprocess == 0.26
 mozcrash == 1.0
-mozrunner == 7.0.0
+mozrunner==7.0.2
 mozleak == 0.1
 mozinstall==1.16.0
 mozdownload==1.24
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_ie.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_ie.txt
index 22a07532657..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_ie.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_ie.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_opera.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_opera.txt
index 22a07532657..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_opera.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_opera.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_safari.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_safari.txt
index 5a1d26b8b9b..3f86182b7d0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_safari.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_safari.txt
@@ -1,2 +1,2 @@
 mozprocess == 0.26
-selenium==3.13.0
+selenium==3.14.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_sauce.txt b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_sauce.txt
index 77a74222433..07c525a67fd 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/requirements_sauce.txt
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/requirements_sauce.txt
@@ -1,3 +1,3 @@
 mozprocess == 0.26
-selenium==3.14.0
+selenium==3.14.1
 requests==2.19.1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome.py
index 8b0ba4585a9..d41df8dec0e 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome.py
@@ -47,6 +47,11 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
     for (kwarg, capability) in [("binary", "binary"), ("binary_args", "args")]:
         if kwargs[kwarg] is not None:
             capabilities["goog:chromeOptions"][capability] = kwargs[kwarg]
+    if kwargs["headless"]:
+        if "args" not in capabilities["goog:chromeOptions"]:
+            capabilities["goog:chromeOptions"]["args"] = []
+        if "--headless" not in capabilities["goog:chromeOptions"]["args"]:
+            capabilities["goog:chromeOptions"]["args"].append("--headless")
     if test_type == "testharness":
         capabilities["goog:chromeOptions"]["useAutomationExtension"] = False
         capabilities["goog:chromeOptions"]["excludeSwitches"] = ["enable-automation"]
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py
index a63460f4544..2ee8ec41ed6 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py
@@ -41,6 +41,12 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
         if kwargs[kwarg] is not None:
             capabilities["goog:chromeOptions"][capability] = kwargs[kwarg]
 
+    if kwargs["headless"]:
+        if "args" not in capabilities["goog:chromeOptions"]:
+            capabilities["goog:chromeOptions"]["args"] = []
+        if "--headless" not in capabilities["goog:chromeOptions"]["args"]:
+            capabilities["goog:chromeOptions"]["args"].append("--headless")
+
     if test_type == "testharness":
         capabilities["goog:chromeOptions"]["useAutomationExtension"] = False
         capabilities["goog:chromeOptions"]["excludeSwitches"] = ["enable-automation"]
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/firefox.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/firefox.py
index 9f7ebfa2ca5..b370b5d7a5e 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -83,7 +83,8 @@ def browser_kwargs(test_type, run_info_data, config, **kwargs):
             "asan": run_info_data.get("asan"),
             "stylo_threads": kwargs["stylo_threads"],
             "chaos_mode_flags": kwargs["chaos_mode_flags"],
-            "config": config}
+            "config": config,
+            "headless": kwargs["headless"]}
 
 
 def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
@@ -106,6 +107,11 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
             options["binary"] = kwargs["binary"]
         if kwargs["binary_args"]:
             options["args"] = kwargs["binary_args"]
+        if kwargs["headless"]:
+            if "args" not in options:
+                options["args"] = []
+            if "--headless" not in options["args"]:
+                options["args"].append("--headless")
         options["prefs"] = {
             "network.dns.localDomains": ",".join(server_config.domains_set)
         }
@@ -155,7 +161,7 @@ class FirefoxBrowser(Browser):
                  symbols_path=None, stackwalk_binary=None, certutil_binary=None,
                  ca_certificate_path=None, e10s=False, stackfix_dir=None,
                  binary_args=None, timeout_multiplier=None, leak_check=False, asan=False,
-                 stylo_threads=1, chaos_mode_flags=None, config=None):
+                 stylo_threads=1, chaos_mode_flags=None, config=None, headless=None):
         Browser.__init__(self, logger)
         self.binary = binary
         self.prefs_root = prefs_root
@@ -188,6 +194,7 @@ class FirefoxBrowser(Browser):
         self.lsan_handler = None
         self.stylo_threads = stylo_threads
         self.chaos_mode_flags = chaos_mode_flags
+        self.headless = headless
 
     def settings(self, test):
         self.lsan_allowed = test.lsan_allowed
@@ -216,6 +223,8 @@ class FirefoxBrowser(Browser):
         env["STYLO_THREADS"] = str(self.stylo_threads)
         if self.chaos_mode_flags is not None:
             env["MOZ_CHAOSMODE"] = str(self.chaos_mode_flags)
+        if self.headless:
+            env["MOZ_HEADLESS"] = "1"
 
         preferences = self.load_prefs()
 
@@ -251,9 +260,11 @@ class FirefoxBrowser(Browser):
         if self.ca_certificate_path is not None:
             self.setup_ssl()
 
+        args = self.binary_args[:] if self.binary_args else []
+        args += [cmd_arg("marionette"), "about:blank"]
+
         debug_args, cmd = browser_command(self.binary,
-                                          self.binary_args if self.binary_args else [] +
-                                          [cmd_arg("marionette"), "about:blank"],
+                                          args,
                                           self.debug_info)
 
         self.runner = FirefoxRunner(profile=self.profile,
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py
index e684bf68076..db388bbca0a 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py
@@ -115,8 +115,9 @@ def find_slow_status(test):
     """Check if a single test almost times out.
 
     We are interested in tests that almost time out (i.e. likely to be flaky).
-    Therefore, timeout statuses are ignored, including (EXTERNAL-)TIMEOUT &
-    CRASH (tests that time out may be marked as CRASH if crashes are detected).
+    Therefore, timeout statuses are ignored, including (EXTERNAL-)TIMEOUT.
+    CRASH & ERROR are also ignored because the they override TIMEOUT; a test
+    that both crashes and times out is marked as CRASH, so it won't be flaky.
 
     Returns:
         A result status produced by a run that almost times out; None, if no
@@ -125,7 +126,7 @@ def find_slow_status(test):
     if "timeout" not in test:
         return None
     threshold = test["timeout"] * FLAKY_THRESHOLD
-    for status in ['PASS', 'FAIL', 'OK', 'ERROR']:
+    for status in ['PASS', 'FAIL', 'OK']:
         if (status in test["longest_duration"] and
             test["longest_duration"][status] > threshold):
             return status
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py
index 7e386b881d4..353e2ada1eb 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py
@@ -210,7 +210,7 @@ class BrowserManager(object):
         self.command_queue.put((command, args))
 
     def init_timeout(self):
-        # This is called from a seperate thread, so we send a message to the
+        # This is called from a separate thread, so we send a message to the
         # main loop so we get back onto the manager thread
         self.logger.debug("init_failed called from timer")
         self.send_message("init_failed")
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py
index 5a051b6c899..c3c89f2f192 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py
@@ -20,6 +20,9 @@ def test_find_slow_status():
     assert stability.find_slow_status({
         "longest_duration": {"CRASH": 10},
         "timeout": 10}) is None
+    assert stability.find_slow_status({
+        "longest_duration": {"ERROR": 10},
+        "timeout": 10}) is None
     assert stability.find_slow_status({
         "longest_duration": {"PASS": 1},
         "timeout": 10}) is None
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
index d25e561ad19..467903f2773 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
@@ -205,6 +205,10 @@ scheme host and port.""")
                               help="Allow the wptrunner to install fonts on your system")
     config_group.add_argument("--font-dir", action="store", type=abs_path, dest="font_dir",
                               help="Path to local font installation directory", default=None)
+    config_group.add_argument("--headless", action="store_true",
+                              help="Run browser in headless mode", default=None)
+    config_group.add_argument("--no-headless", action="store_false", dest="headless",
+                              help="Don't run browser in headless mode")
 
     build_type = parser.add_mutually_exclusive_group()
     build_type.add_argument("--debug-build", dest="debug", action="store_true",
@@ -365,6 +369,7 @@ def set_from_config(kwargs):
 
     check_paths(kwargs)
 
+
 def get_test_paths(config):
     # Set up test_paths
     test_paths = OrderedDict()
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py
index a6a29724ad7..6bd1db9927c 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py
@@ -124,6 +124,8 @@ def get_pause_after_test(test_loader, **kwargs):
     if kwargs["pause_after_test"] is None:
         if kwargs["repeat_until_unexpected"]:
             return False
+        if kwargs["headless"]:
+            return False
         if kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and total_tests == 1:
             return True
         return False
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/base.py b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/base.py
index e49c8287c59..741ab0bcb74 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/base.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/base.py
@@ -75,7 +75,7 @@ class TestUsingServer(unittest.TestCase):
             req.add_data(body)
 
         if auth is not None:
-            req.add_header("Authorization", "Basic %s" % base64.b64encode('%s:%s' % auth))
+            req.add_header("Authorization", b"Basic %s" % base64.b64encode(("%s:%s" % auth).encode("utf-8")))
 
         return urlopen(req)
 
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_handlers.py b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_handlers.py
index 15c7cb7e803..759a096b799 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_handlers.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_handlers.py
@@ -88,19 +88,16 @@ class TestFileHandler(TestUsingServer):
             self.request("/document.txt", headers={"Range":"bytes=%i-%i" % (len(expected), len(expected) + 10)})
         self.assertEqual(cm.exception.code, 416)
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_config(self):
         resp = self.request("/sub.sub.txt")
         expected = b"localhost localhost %i" % self.server.port
         assert resp.read().rstrip() == expected
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_headers(self):
         resp = self.request("/sub_headers.sub.txt", headers={"X-Test": "PASS"})
         expected = b"PASS"
         assert resp.read().rstrip() == expected
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_params(self):
         resp = self.request("/sub_params.sub.txt", query="test=PASS")
         expected = b"PASS"
@@ -108,7 +105,6 @@ class TestFileHandler(TestUsingServer):
 
 
 class TestFunctionHandler(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_string_rv(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -119,7 +115,7 @@ class TestFunctionHandler(TestUsingServer):
         resp = self.request(route[1])
         self.assertEqual(200, resp.getcode())
         self.assertEqual("9", resp.info()["Content-Length"])
-        self.assertEqual("test data", resp.read())
+        self.assertEqual(b"test data", resp.read())
 
     def test_tuple_1_rv(self):
         @wptserve.handlers.handler
@@ -134,7 +130,6 @@ class TestFunctionHandler(TestUsingServer):
 
         assert cm.value.code == 500
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_tuple_2_rv(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -146,9 +141,8 @@ class TestFunctionHandler(TestUsingServer):
         self.assertEqual(200, resp.getcode())
         self.assertEqual("4", resp.info()["Content-Length"])
         self.assertEqual("test-value", resp.info()["test-header"])
-        self.assertEqual("test", resp.read())
+        self.assertEqual(b"test", resp.read())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_tuple_3_rv(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -159,9 +153,8 @@ class TestFunctionHandler(TestUsingServer):
         resp = self.request(route[1])
         self.assertEqual(202, resp.getcode())
         self.assertEqual("test-value", resp.info()["test-header"])
-        self.assertEqual("test data", resp.read())
+        self.assertEqual(b"test data", resp.read())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_tuple_3_rv_1(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -173,7 +166,7 @@ class TestFunctionHandler(TestUsingServer):
         self.assertEqual(202, resp.getcode())
         self.assertEqual("Some Status", resp.msg)
         self.assertEqual("test-value", resp.info()["test-header"])
-        self.assertEqual("test data", resp.read())
+        self.assertEqual(b"test data", resp.read())
 
     def test_tuple_4_rv(self):
         @wptserve.handlers.handler
@@ -263,7 +256,6 @@ class TestPythonHandler(TestUsingServer):
         self.assertEqual("PASS", resp.info()["X-Test"])
         self.assertEqual(b"PASS", resp.read())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_import(self):
         dir_name = os.path.join(doc_root, "subdir")
         assert dir_name not in sys.path
@@ -273,7 +265,7 @@ class TestPythonHandler(TestUsingServer):
         assert "test_module" not in sys.modules
         self.assertEqual(200, resp.getcode())
         self.assertEqual("text/plain", resp.info()["Content-Type"])
-        self.assertEqual("PASS", resp.read())
+        self.assertEqual(b"PASS", resp.read())
 
     def test_no_main(self):
         with pytest.raises(HTTPError) as cm:
@@ -314,13 +306,12 @@ class TestDirectoryHandler(TestUsingServer):
 
 
 class TestAsIsHandler(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_as_is(self):
         resp = self.request("/test.asis")
         self.assertEqual(202, resp.getcode())
         self.assertEqual("Giraffe", resp.msg)
         self.assertEqual("PASS", resp.info()["X-Test"])
-        self.assertEqual("Content", resp.read())
+        self.assertEqual(b"Content", resp.read())
         #Add a check that the response is actually sane
 
 
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_pipes.py b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_pipes.py
index 83b2c621641..7739af5e26e 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_pipes.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_pipes.py
@@ -57,40 +57,35 @@ class TestSlice(TestUsingServer):
         self.assertEqual(resp.read(), expected[:10])
 
 class TestSub(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_config(self):
         resp = self.request("/sub.txt", query="pipe=sub")
-        expected = "localhost localhost %i" % self.server.port
+        expected = b"localhost localhost %i" % self.server.port
         self.assertEqual(resp.read().rstrip(), expected)
 
     @pytest.mark.xfail(sys.platform == "win32",
                        reason="https://github.com/web-platform-tests/wpt/issues/12949")
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_file_hash(self):
         resp = self.request("/sub_file_hash.sub.txt")
-        expected = """
+        expected = b"""
 md5: JmI1W8fMHfSfCarYOSxJcw==
 sha1: nqpWqEw4IW8NjD6R375gtrQvtTo=
 sha224: RqQ6fMmta6n9TuA/vgTZK2EqmidqnrwBAmQLRQ==
 sha256: G6Ljg1uPejQxqFmvFOcV/loqnjPTW5GSOePOfM/u0jw=
 sha384: lkXHChh1BXHN5nT5BYhi1x67E1CyYbPKRKoF2LTm5GivuEFpVVYtvEBHtPr74N9E
-sha512: r8eLGRTc7ZznZkFjeVLyo6/FyQdra9qmlYCwKKxm3kfQAswRS9+3HsYk3thLUhcFmmWhK4dXaICz
-JwGFonfXwg=="""
+sha512: r8eLGRTc7ZznZkFjeVLyo6/FyQdra9qmlYCwKKxm3kfQAswRS9+3HsYk3thLUhcFmmWhK4dXaICzJwGFonfXwg=="""
         self.assertEqual(resp.read().rstrip(), expected.strip())
 
     def test_sub_file_hash_unrecognized(self):
         with self.assertRaises(urllib.error.HTTPError):
             self.request("/sub_file_hash_unrecognized.sub.txt")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_headers(self):
         resp = self.request("/sub_headers.txt", query="pipe=sub", headers={"X-Test": "PASS"})
-        expected = "PASS"
+        expected = b"PASS"
         self.assertEqual(resp.read().rstrip(), expected)
 
     @pytest.mark.xfail(sys.platform == "win32",
                        reason="https://github.com/web-platform-tests/wpt/issues/12949")
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_location(self):
         resp = self.request("/sub_location.sub.txt?query_string")
         expected = """
@@ -101,30 +96,27 @@ pathname: /sub_location.sub.txt
 port: {0}
 query: ?query_string
 scheme: http
-server: http://localhost:{0}""".format(self.server.port)
+server: http://localhost:{0}""".format(self.server.port).encode("ascii")
         self.assertEqual(resp.read().rstrip(), expected.strip())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_params(self):
         resp = self.request("/sub_params.txt", query="test=PASS&pipe=sub")
-        expected = "PASS"
+        expected = b"PASS"
         self.assertEqual(resp.read().rstrip(), expected)
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_url_base(self):
         resp = self.request("/sub_url_base.sub.txt")
-        self.assertEqual(resp.read().rstrip(), "Before / After")
+        self.assertEqual(resp.read().rstrip(), b"Before / After")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_uuid(self):
         resp = self.request("/sub_uuid.sub.txt")
-        self.assertRegexpMatches(resp.read().rstrip(), r"Before [a-f0-9-]+ After")
+        self.assertRegexpMatches(resp.read().rstrip(), b"Before [a-f0-9-]+ After")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_sub_var(self):
         resp = self.request("/sub_var.sub.txt")
         port = self.server.port
-        expected = "localhost %s A %s B localhost C" % (port, port)
+        print(port, type(port))
+        expected = b"localhost %d A %d B localhost C" % (port, port)
         self.assertEqual(resp.read().rstrip(), expected)
 
 class TestTrickle(TestUsingServer):
@@ -144,12 +136,10 @@ class TestTrickle(TestUsingServer):
         self.assertEqual(resp.info()["Expires"], "0")
 
 class TestPipesWithVariousHandlers(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_with_python_file_handler(self):
         resp = self.request("/test_string.py", query="pipe=slice(null,2)")
-        self.assertEqual(resp.read(), "PA")
+        self.assertEqual(resp.read(), b"PA")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_with_python_func_handler(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -157,9 +147,8 @@ class TestPipesWithVariousHandlers(TestUsingServer):
         route = ("GET", "/test/test_pipes_1/", handler)
         self.server.router.register(*route)
         resp = self.request(route[1], query="pipe=slice(null,2)")
-        self.assertEqual(resp.read(), "PA")
+        self.assertEqual(resp.read(), b"PA")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_with_python_func_handler_using_response_writer(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -168,9 +157,8 @@ class TestPipesWithVariousHandlers(TestUsingServer):
         self.server.router.register(*route)
         resp = self.request(route[1], query="pipe=slice(null,2)")
         # slice has not been applied to the response, because response.writer was used.
-        self.assertEqual(resp.read(), "PASS")
+        self.assertEqual(resp.read(), b"PASS")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_header_pipe_with_python_func_using_response_writer(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -180,9 +168,8 @@ class TestPipesWithVariousHandlers(TestUsingServer):
         resp = self.request(route[1], query="pipe=header(X-TEST,FAIL)")
         # header pipe was ignored, because response.writer was used.
         self.assertFalse(resp.info().get("X-TEST"))
-        self.assertEqual(resp.read(), "CONTENT")
+        self.assertEqual(resp.read(), b"CONTENT")
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_with_json_handler(self):
         @wptserve.handlers.json_handler
         def handler(request, response):
@@ -190,32 +177,29 @@ class TestPipesWithVariousHandlers(TestUsingServer):
         route = ("GET", "/test/test_pipes_2/", handler)
         self.server.router.register(*route)
         resp = self.request(route[1], query="pipe=slice(null,2)")
-        self.assertEqual(resp.read(), '"{')
+        self.assertEqual(resp.read(), b'"{')
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_slice_with_as_is_handler(self):
         resp = self.request("/test.asis", query="pipe=slice(null,2)")
         self.assertEqual(202, resp.getcode())
         self.assertEqual("Giraffe", resp.msg)
         self.assertEqual("PASS", resp.info()["X-Test"])
         # slice has not been applied to the response, because response.writer was used.
-        self.assertEqual("Content", resp.read())
+        self.assertEqual(b"Content", resp.read())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_headers_with_as_is_handler(self):
         resp = self.request("/test.asis", query="pipe=header(X-TEST,FAIL)")
         self.assertEqual(202, resp.getcode())
         self.assertEqual("Giraffe", resp.msg)
         # header pipe was ignored.
         self.assertEqual("PASS", resp.info()["X-TEST"])
-        self.assertEqual("Content", resp.read())
+        self.assertEqual(b"Content", resp.read())
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_trickle_with_as_is_handler(self):
         t0 = time.time()
         resp = self.request("/test.asis", query="pipe=trickle(1:d2:5:d1:r2)")
         t1 = time.time()
-        self.assertTrue('Content' in resp.read())
+        self.assertTrue(b'Content' in resp.read())
         self.assertGreater(6, t1-t0)
 
 if __name__ == '__main__':
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_request.py b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_request.py
index 97d75eb7128..983539260a5 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_request.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/tests/functional/test_request.py
@@ -1,5 +1,3 @@
-import sys
-
 import pytest
 
 wptserve = pytest.importorskip("wptserve")
@@ -8,7 +6,6 @@ from wptserve.request import InputFile
 
 
 class TestInputFile(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_seek(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -16,28 +13,27 @@ class TestInputFile(TestUsingServer):
             f = request.raw_input
             f.seek(5)
             rv.append(f.read(2))
-            rv.append(f.tell())
+            rv.append(b"%d" % f.tell())
             f.seek(0)
             rv.append(f.readline())
-            rv.append(f.tell())
+            rv.append(b"%d" % f.tell())
             rv.append(f.read(-1))
-            rv.append(f.tell())
+            rv.append(b"%d" % f.tell())
             f.seek(0)
             rv.append(f.read())
             f.seek(0)
             rv.extend(f.readlines())
 
-            return " ".join(str(item) for item in rv)
+            return b" ".join(rv)
 
         route = ("POST", "/test/test_seek", handler)
         self.server.router.register(*route)
-        resp = self.request(route[1], method="POST", body="12345ab\ncdef")
+        resp = self.request(route[1], method="POST", body=b"12345ab\ncdef")
         self.assertEqual(200, resp.getcode())
-        self.assertEqual(["ab", "7", "12345ab\n", "8", "cdef", "12",
-                          "12345ab\ncdef", "12345ab\n", "cdef"],
-                         resp.read().split(" "))
+        self.assertEqual([b"ab", b"7", b"12345ab\n", b"8", b"cdef", b"12",
+                          b"12345ab\ncdef", b"12345ab\n", b"cdef"],
+                         resp.read().split(b" "))
 
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_seek_input_longer_than_buffer(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -45,11 +41,11 @@ class TestInputFile(TestUsingServer):
             f = request.raw_input
             f.seek(5)
             rv.append(f.read(2))
-            rv.append(f.tell())
+            rv.append(b"%d" % f.tell())
             f.seek(0)
-            rv.append(f.tell())
-            rv.append(f.tell())
-            return " ".join(str(item) for item in rv)
+            rv.append(b"%d" % f.tell())
+            rv.append(b"%d" % f.tell())
+            return b" ".join(rv)
 
         route = ("POST", "/test/test_seek", handler)
         self.server.router.register(*route)
@@ -57,10 +53,10 @@ class TestInputFile(TestUsingServer):
         old_max_buf = InputFile.max_buffer_size
         InputFile.max_buffer_size = 10
         try:
-            resp = self.request(route[1], method="POST", body="1"*20)
+            resp = self.request(route[1], method="POST", body=b"1"*20)
             self.assertEqual(200, resp.getcode())
-            self.assertEqual(["11", "7", "0", "0"],
-                            resp.read().split(" "))
+            self.assertEqual([b"11", b"7", b"0", b"0"],
+                             resp.read().split(b" "))
         finally:
             InputFile.max_buffer_size = old_max_buf
 
@@ -119,7 +115,6 @@ class TestRequest(TestUsingServer):
 
 
 class TestAuth(TestUsingServer):
-    @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
     def test_auth(self):
         @wptserve.handlers.handler
         def handler(request, response):
@@ -129,4 +124,4 @@ class TestAuth(TestUsingServer):
         self.server.router.register(*route)
         resp = self.request(route[1], auth=("test", "PASS"))
         self.assertEqual(200, resp.getcode())
-        self.assertEqual(["test", "PASS"], resp.read().split(" "))
+        self.assertEqual([b"test", b"PASS"], resp.read().split(b" "))
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/pipes.py b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/pipes.py
index ad96f591a3a..33a43e1f06b 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/pipes.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/pipes.py
@@ -1,5 +1,6 @@
 from cgi import escape
 from collections import deque
+import base64
 import gzip as gzip_module
 import hashlib
 import os
@@ -273,8 +274,9 @@ def slice(request, response, start, end=None):
                 (spelled "null" in a query string) to indicate the end of
                 the file.
     """
-    content = resolve_content(response)
-    response.content = content[start:end]
+    content = resolve_content(response)[start:end]
+    response.content = content
+    response.headers.set("Content-Length", len(content))
     return response
 
 
@@ -392,7 +394,7 @@ class SubFunctions(object):
 
     @staticmethod
     def file_hash(request, algorithm, path):
-        algorithm = algorithm.decode("ascii")
+        assert isinstance(algorithm, text_type)
         if algorithm not in SubFunctions.supported_algorithms:
             raise ValueError("Unsupported encryption algorithm: '%s'" % algorithm)
 
@@ -400,7 +402,7 @@ class SubFunctions(object):
         absolute_path = os.path.join(request.doc_root, path)
 
         try:
-            with open(absolute_path) as f:
+            with open(absolute_path, "rb") as f:
                 hash_obj.update(f.read())
         except IOError:
             # In this context, an unhandled IOError will be interpreted by the
@@ -410,7 +412,7 @@ class SubFunctions(object):
             # the path to the file to be hashed is invalid.
             raise Exception('Cannot open file for hash computation: "%s"' % absolute_path)
 
-        return hash_obj.digest().encode('base64').strip()
+        return base64.b64encode(hash_obj.digest()).strip()
 
 def template(request, content, escape_type="html"):
     #TODO: There basically isn't any error handling here
@@ -425,7 +427,6 @@ def template(request, content, escape_type="html"):
         tokens = deque(tokens)
 
         token_type, field = tokens.popleft()
-        field = field.decode("ascii")
 
         if token_type == "var":
             variable = field
@@ -470,14 +471,14 @@ def template(request, content, escape_type="html"):
             raise Exception("Undefined template variable %s" % field)
 
         while tokens:
-            ttype, field = tokens.popleft()
+            ttype, tfield = tokens.popleft()
             if ttype == "index":
-                value = value[field]
+                value = value[tfield]
             elif ttype == "arguments":
-                value = value(request, *field)
+                value = value(request, *tfield)
             else:
                 raise Exception(
-                    "unexpected token type %s (token '%r'), expected ident or arguments" % (ttype, field)
+                    "unexpected token type %s (token '%r'), expected ident or arguments" % (ttype, tfield)
                 )
 
         assert isinstance(value, (int, (binary_type, text_type))), tokens
@@ -485,12 +486,19 @@ def template(request, content, escape_type="html"):
         if variable is not None:
             variables[variable] = value
 
+        if field == "GET" and not isinstance(value, str):
+            value = value.decode("utf-8")
+
         escape_func = {"html": lambda x:escape(x, quote=True),
                        "none": lambda x:x}[escape_type]
 
         #Should possibly support escaping for other contexts e.g. script
         #TODO: read the encoding of the response
-        return escape_func(text_type(value)).encode("utf-8")
+        if isinstance(value, binary_type):
+            value = value.decode("utf-8")
+        elif isinstance(value, int):
+            value = text_type(value)
+        return escape_func(value).encode("utf-8")
 
     template_regexp = re.compile(br"{{([^}]*)}}")
     new_content = template_regexp.sub(config_replacement, content)
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/request.py b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/request.py
index cb575ccdba4..233ff151c28 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/request.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/request.py
@@ -1,7 +1,7 @@
 import base64
 import cgi
 from six.moves.http_cookies import BaseCookie
-from six import BytesIO
+from six import BytesIO, binary_type, text_type
 import tempfile
 
 from six.moves.urllib.parse import parse_qsl, urlsplit
@@ -318,8 +318,8 @@ class Request(object):
     def cookies(self):
         if self._cookies is None:
             parser = BaseCookie()
-            cookie_headers = self.headers.get("cookie", "")
-            parser.load(cookie_headers)
+            cookie_headers = self.headers.get("cookie", u"")
+            parser.load(cookie_headers.encode("utf-8"))
             cookies = Cookies()
             for key, value in parser.iteritems():
                 cookies[key] = CookieValue(value)
@@ -355,6 +355,16 @@ class H2Request(Request):
         super(H2Request, self).__init__(request_handler)
 
 
+def maybedecode(s):
+    if isinstance(s, text_type):
+        return s
+
+    if isinstance(s, binary_type):
+        return s.decode("ascii")
+
+    raise TypeError("Unexpected value in RequestHeaders: %r" % s)
+
+
 class RequestHeaders(dict):
     """Dictionary-like API for accessing request headers."""
     def __init__(self, items):
@@ -369,15 +379,17 @@ class RequestHeaders(dict):
                 for value in values:
                     # getallmatchingheaders returns raw header lines, so
                     # split to get name, value
-                    multiples.append(value.split(':', 1)[1].strip())
-                dict.__setitem__(self, key, multiples)
+                    multiples.append(maybedecode(value).split(':', 1)[1].strip())
+                headers = multiples
             else:
-                dict.__setitem__(self, key, [items[header]])
+                headers = [maybedecode(items[header])]
+            dict.__setitem__(self, maybedecode(key), headers)
 
 
     def __getitem__(self, key):
         """Get all headers of a certain (case-insensitive) name. If there is
         more than one, the values are returned comma separated"""
+        key = maybedecode(key)
         values = dict.__getitem__(self, key.lower())
         if len(values) == 1:
             return values[0]
@@ -403,6 +415,7 @@ class RequestHeaders(dict):
     def get_list(self, key, default=missing):
         """Get all the header values for a particular field name as
         a list"""
+        key = maybedecode(key)
         try:
             return dict.__getitem__(self, key.lower())
         except KeyError:
@@ -412,6 +425,7 @@ class RequestHeaders(dict):
                 raise
 
     def __contains__(self, key):
+        key = maybedecode(key)
         return dict.__contains__(self, key.lower())
 
     def iteritems(self):
@@ -599,6 +613,7 @@ class Authentication(object):
 
         if "authorization" in headers:
             header = headers.get("authorization")
+            assert isinstance(header, text_type)
             auth_type, data = header.split(" ", 1)
             if auth_type in auth_schemes:
                 self.username, self.password = auth_schemes[auth_type](data)
@@ -606,5 +621,6 @@ class Authentication(object):
                 raise HTTPException(400, "Unsupported authentication scheme %s" % auth_type)
 
     def decode_basic(self, data):
-        decoded_data = base64.decodestring(data)
-        return decoded_data.split(":", 1)
+        assert isinstance(data, text_type)
+        decoded_data = base64.decodestring(data.encode("utf-8"))
+        return decoded_data.decode("utf-8").split(":", 1)
diff --git a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/response.py b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/response.py
index 44299cc994e..483265bf084 100644
--- a/tests/wpt/web-platform-tests/tools/wptserve/wptserve/response.py
+++ b/tests/wpt/web-platform-tests/tools/wptserve/wptserve/response.py
@@ -183,8 +183,10 @@ class Response(object):
         True, the entire content of the file will be returned as a string facilitating
         non-streaming operations like template substitution.
         """
-        if isinstance(self.content, (binary_type, text_type)):
+        if isinstance(self.content, binary_type):
             yield self.content
+        elif isinstance(self.content, text_type):
+            yield self.content.encode("utf-8")
         elif hasattr(self.content, "read"):
             if read_file:
                 yield self.content.read()
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js
index 0139a18fda3..bd23a8666e7 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js
@@ -68,6 +68,10 @@ promise_test(() => {
   return WebAssembly.compile(emptyModuleBinary).then(assert_Module);
 }, "Result type");
 
+promise_test(() => {
+  return WebAssembly.compile(emptyModuleBinary, {}).then(assert_Module);
+}, "Stray argument");
+
 promise_test(() => {
   const buffer = new WasmModuleBuilder().toBuffer();
   assert_equals(buffer[0], 0);
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js
index 70bd9f7022a..c8613cbd9b3 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js
@@ -94,3 +94,7 @@ for (const [module, expected] of modules) {
     }
   }
 }
+
+test(() => {
+  assert_true(WebAssembly.validate(emptyModuleBinary, {}));
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js
index 7a45cc4191c..237f99c8b29 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js
@@ -119,3 +119,9 @@ for (const type of ["i32", "f32", "f64"]) {
     }, `Explicit value ${name} for type ${type}`);
   }
 }
+
+test(() => {
+  const argument = { "value": "i32" };
+  const global = new WebAssembly.Global(argument, 0, {});
+  assert_Global(global, 0);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/value-get-set.any.js
similarity index 84%
rename from tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js
rename to tests/wpt/web-platform-tests/wasm/jsapi/global/value-get-set.any.js
index b4e6770f10e..6de62d5f583 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/value-get-set.any.js
@@ -92,3 +92,20 @@ test(() => {
 
   assert_throws(new TypeError(), () => setter.call(global));
 }, "Calling setter without argument");
+
+test(() => {
+  const argument = { "value": "i32", "mutable": true };
+  const global = new WebAssembly.Global(argument);
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  const setter = desc.set;
+  assert_equals(typeof setter, "function");
+
+  assert_equals(getter.call(global, {}), 0);
+  assert_equals(setter.call(global, 1, {}), undefined);
+  assert_equals(global.value, 1);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js
index 176c5a78469..d4a84b254f7 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js
@@ -20,3 +20,9 @@ test(() => {
     assert_throws(new TypeError(), () => fn.call(thisValue), `this=${format_value(thisValue)}`);
   }
 }, "Branding");
+
+test(() => {
+  const argument = { "value": "i32" };
+  const global = new WebAssembly.Global(argument, 0);
+  assert_equals(global.valueOf({}), 0);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js
index 31423918720..cad468660e0 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js
@@ -33,6 +33,20 @@ test(() => {
   }
 }, "Branding");
 
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const instance = new WebAssembly.Instance(module);
+  const exports = instance.exports;
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(getter.call(instance, {}), exports);
+}, "Stray argument");
+
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const instance = new WebAssembly.Instance(module);
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/instanceTestFactory.js b/tests/wpt/web-platform-tests/wasm/jsapi/instanceTestFactory.js
index 1663ffb3469..24f849e6f94 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/instanceTestFactory.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/instanceTestFactory.js
@@ -214,4 +214,16 @@ const instanceTestFactory = [
       };
     }
   ],
+
+  [
+    "stray argument",
+    function() {
+      return {
+        buffer: emptyModuleBinary,
+        args: [{}, {}],
+        exports: {},
+        verify: () => {}
+      };
+    }
+  ],
 ];
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js
index b04460b6c5e..4788ffcf84f 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js
@@ -26,6 +26,20 @@ test(() => {
   }
 }, "Branding");
 
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  const buffer = memory.buffer;
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, "buffer");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(getter.call(memory, {}), buffer);
+}, "Stray argument");
+
 test(() => {
   const argument = { "initial": 0 };
   const memory = new WebAssembly.Memory(argument);
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js
index 5caf7cc8bb9..a584a23ecf0 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js
@@ -139,3 +139,9 @@ test(() => {
   const memory = new WebAssembly.Memory(argument);
   assert_Memory(memory, { "size": 4 });
 }, "Non-zero initial");
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument, {});
+  assert_Memory(memory, { "size": 0 });
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js
index 95300399f19..1ccfb946756 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js
@@ -168,3 +168,18 @@ for (const value of outOfRangeValues) {
     assert_throws(new TypeError(), () => memory.grow(value));
   }, `Out-of-range argument: ${format_value(value)}`);
 }
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
+
+  const result = memory.grow(2, {});
+  assert_equals(result, 0);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
+  assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js
index 32f183fac87..a467c1a17bb 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js
@@ -58,3 +58,8 @@ test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_true(Object.isExtensible(module));
 }, "Extensibility");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary, {});
+  assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js
index 58ac63b61c9..04c5abed524 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js
@@ -160,3 +160,8 @@ test(() => {
     bytes,
   ]);
 }, "Custom sections with U+FFFD");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  assert_sections(WebAssembly.Module.customSections(module, "", {}), []);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js
index e63a885a4c3..9d95b652233 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js
@@ -128,3 +128,9 @@ test(() => {
   ];
   assert_exports(exports, expected);
 }, "exports");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const exports = WebAssembly.Module.exports(module, {});
+  assert_exports(exports, []);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js
index 640da591d21..b3bb8598b08 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js
@@ -118,3 +118,9 @@ test(() => {
   ];
   assert_imports(imports, expected);
 }, "imports");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const imports = WebAssembly.Module.imports(module, {});
+  assert_imports(imports, []);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js
index e924bdb2ba4..99eee19fecd 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js
@@ -96,6 +96,12 @@ test(() => {
   assert_Table(table, { "length": 5 });
 }, "Basic (non-zero)");
 
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 0 };
+  const table = new WebAssembly.Table(argument, {});
+  assert_Table(table, { "length": 0 });
+}, "Stray argument");
+
 test(() => {
   const proxy = new Proxy({}, {
     has(o, x) {
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js
index 66c41340c20..f8a0194364f 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js
@@ -220,3 +220,11 @@ test(() => {
   assert_equals(called, 1);
 }, "Order of argument conversion");
 
+test(() => {
+  const {fn} = functions;
+  const argument = { "element": "anyfunc", "initial": 1 };
+  const table = new WebAssembly.Table(argument);
+
+  assert_equals(table.get(0, {}), null);
+  assert_equals(table.set(0, fn, {}), undefined);
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js
index d3efb511e4b..4978e3ca23d 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js
@@ -84,3 +84,13 @@ for (const value of outOfRangeValues) {
     assert_throws(new TypeError(), () => table.grow(value));
   }, `Out-of-range argument: ${format_value(value)}`);
 }
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, nulls(5), "before");
+
+  const result = table.grow(3, {});
+  assert_equals(result, 5);
+  assert_equal_to_array(table, nulls(8), "after");
+}, "Stray argument");
diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js
index a6a9661dbad..b1bfa6cfd1f 100644
--- a/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js
+++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js
@@ -26,6 +26,20 @@ test(() => {
   }
 }, "Branding");
 
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 2 };
+  const table = new WebAssembly.Table(argument);
+  assert_equals(table.length, 2, "Initial length");
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Table.prototype, "length");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(getter.call(table, {}), 2);
+}, "Stray argument");
+
 test(() => {
   const argument = { "element": "anyfunc", "initial": 2 };
   const table = new WebAssembly.Table(argument);
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py b/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py
deleted file mode 100644
index 416cbdcf20f..00000000000
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# META: timeout=long
-
-import pytest
-import time
-from tests.actions.support.keys import ALL_EVENTS, Keys
-from tests.actions.support.refine import filter_dict, get_keys, get_events
-from webdriver import error
-
-@pytest.mark.parametrize("name,expected", ALL_EVENTS.items())
-def test_webdriver_special_key_sends_keydown(session,
-                                             key_reporter,
-                                             key_chain,
-                                             name,
-                                             expected):
-    if name.startswith("F"):
-        # Prevent default behavior for F1, etc., but only after keydown
-        # bubbles up to body. (Otherwise activated browser menus/functions
-        # may interfere with subsequent tests.)
-        session.execute_script("""
-            document.body.addEventListener("keydown",
-                    function(e) { e.preventDefault() });
-        """)
-    if (session.capabilities["browserName"] == 'internet explorer'):
-        key_reporter.click()
-        session.execute_script("resetEvents();")
-    key_chain.key_down(getattr(Keys, name)).perform()
-
-    # only interested in keydown
-    first_event = get_events(session)[0]
-    # make a copy so we can throw out irrelevant keys and compare to events
-    expected = dict(expected)
-
-    del expected["value"]
-
-    # check and remove keys that aren't in expected
-    assert first_event["type"] == "keydown"
-    assert first_event["repeat"] == False
-    first_event = filter_dict(first_event, expected)
-    if first_event["code"] == None:
-        del first_event["code"]
-        del expected["code"]
-    assert first_event == expected
-    # only printable characters should be recorded in input field
-    entered_keys = get_keys(key_reporter)
-    if len(expected["key"]) == 1:
-        assert entered_keys == expected["key"]
-    else:
-        assert len(entered_keys) == 0
-
-
-@pytest.mark.parametrize("value", [
-    (u"f"),
-    (u"\u0BA8\u0BBF"),
-    (u"\u1100\u1161\u11A8"),
-])
-def test_multiple_codepoint_keys_behave_correctly(session,
-                                                  key_reporter,
-                                                  key_chain,
-                                                  value):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-
-    assert get_keys(key_reporter) == value
-
-
-@pytest.mark.parametrize("value", [
-    (u"fa"),
-    (u"\u0BA8\u0BBFb"),
-    (u"\u0BA8\u0BBF\u0BA8"),
-    (u"\u1100\u1161\u11A8c")
-])
-def test_invalid_multiple_codepoint_keys_fail(session,
-                                              key_reporter,
-                                              key_chain,
-                                              value):
-    with pytest.raises(error.InvalidArgumentException):
-        key_chain \
-            .key_down(value) \
-            .key_up(value) \
-            .perform()
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/__init__.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/__init__.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/__init__.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/conftest.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/conftest.py
similarity index 91%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/conftest.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/conftest.py
index 55cecd11782..dffae0b98cd 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/conftest.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/conftest.py
@@ -37,4 +37,4 @@ def key_reporter(session, test_actions_page, request):
 
 @pytest.fixture
 def test_actions_page(session, url):
-    session.url = url("/webdriver/tests/actions/support/test_actions_wdspec.html")
+    session.url = url("/webdriver/tests/perform_actions/support/test_actions_wdspec.html")
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key.py
new file mode 100644
index 00000000000..2b3414c5ebf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key.py
@@ -0,0 +1,25 @@
+import pytest
+
+from webdriver.error import NoSuchWindowException
+
+from tests.perform_actions.support.keys import Keys
+from tests.perform_actions.support.refine import get_keys
+
+
+def test_null_response_value(session, key_chain):
+    value = key_chain.key_up("a").perform()
+    assert value is None
+
+
+def test_no_browsing_context(session, closed_window, key_chain):
+    with pytest.raises(NoSuchWindowException):
+        key_chain.key_up("a").perform()
+
+
+def test_backspace_erases_keys(session, key_reporter, key_chain):
+    key_chain \
+        .send_keys("efcd") \
+        .send_keys([Keys.BACKSPACE, Keys.BACKSPACE]) \
+        .perform()
+
+    assert get_keys(key_reporter) == "ef"
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/key.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_events.py
similarity index 51%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/key.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_events.py
index 50c4ed9132b..462688a55e5 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/key.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_events.py
@@ -1,33 +1,91 @@
+# META: timeout=long
+
 import pytest
 
-from webdriver.error import NoSuchWindowException
-
-from tests.actions.support.keys import Keys
-from tests.actions.support.refine import filter_dict, get_keys, get_events
+from tests.perform_actions.support.keys import ALL_EVENTS, Keys
+from tests.perform_actions.support.refine import filter_dict, get_events, get_keys
 
 
-def test_null_response_value(session, key_chain):
-    value = key_chain.key_up("a").perform()
-    assert value is None
-
-    value = session.actions.release()
-    assert value is None
-
-
-def test_no_browsing_context(session, closed_window, key_chain):
-    with pytest.raises(NoSuchWindowException):
-        key_chain.key_up("a").perform()
-
-
-def test_lone_keyup_sends_no_events(session, key_reporter, key_chain):
+def test_keyup_only_sends_no_events(session, key_reporter, key_chain):
     key_chain.key_up("a").perform()
+
     assert len(get_keys(key_reporter)) == 0
     assert len(get_events(session)) == 0
+
     session.actions.release()
     assert len(get_keys(key_reporter)) == 0
     assert len(get_events(session)) == 0
 
 
+@pytest.mark.parametrize("key, event", [
+    (Keys.ALT, "ALT"),
+    (Keys.CONTROL, "CONTROL"),
+    (Keys.META, "META"),
+    (Keys.SHIFT, "SHIFT"),
+    (Keys.R_ALT, "R_ALT"),
+    (Keys.R_CONTROL, "R_CONTROL"),
+    (Keys.R_META, "R_META"),
+    (Keys.R_SHIFT, "R_SHIFT"),
+])
+def test_modifier_key_sends_correct_events(session, key_reporter, key_chain, key, event):
+    code = ALL_EVENTS[event]["code"]
+    value = ALL_EVENTS[event]["key"]
+
+    key_chain \
+        .key_down(key) \
+        .key_up(key) \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": code, "key": value, "type": "keydown"},
+        {"code": code, "key": value, "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    assert events == expected
+
+    assert len(get_keys(key_reporter)) == 0
+
+
+@pytest.mark.parametrize("key,event", [
+    (Keys.ESCAPE, "ESCAPE"),
+    (Keys.RIGHT, "RIGHT"),
+])
+def test_non_printable_key_sends_events(session, key_reporter, key_chain, key, event):
+    code = ALL_EVENTS[event]["code"]
+    value = ALL_EVENTS[event]["key"]
+
+    key_chain \
+        .key_down(key) \
+        .key_up(key) \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": code, "key": value, "type": "keydown"},
+        {"code": code, "key": value, "type": "keypress"},
+        {"code": code, "key": value, "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    if len(events) == 2:
+        # most browsers don't send a keypress for non-printable keys
+        assert events == [expected[0], expected[2]]
+    else:
+        assert events == expected
+
+    assert len(get_keys(key_reporter)) == 0
+
+
 @pytest.mark.parametrize("value,code", [
     (u"a", "KeyA",),
     ("a", "KeyA",),
@@ -39,133 +97,57 @@ def test_lone_keyup_sends_no_events(session, key_reporter, key_chain):
     (u"\u2603", ""),
     (u"\uF6C2", ""),  # PUA
 ])
-def test_single_printable_key_sends_correct_events(session,
-                                                   key_reporter,
-                                                   key_chain,
-                                                   value,
-                                                   code):
+def test_printable_key_sends_correct_events(session, key_reporter, key_chain, value, code):
     key_chain \
         .key_down(value) \
         .key_up(value) \
         .perform()
+    all_events = get_events(session)
+
     expected = [
         {"code": code, "key": value, "type": "keydown"},
         {"code": code, "key": value, "type": "keypress"},
         {"code": code, "key": value, "type": "keyup"},
     ]
-    all_events = get_events(session)
+
     events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
+    if len(events) > 0 and events[0]["code"] is None:
         # Remove 'code' entry if browser doesn't support it
         expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
         events = [filter_dict(e, expected[0]) for e in events]
     assert events == expected
+
     assert get_keys(key_reporter) == value
 
 
-@pytest.mark.parametrize("value", [
-    (u"\U0001F604"),
-    (u"\U0001F60D"),
-])
-def test_single_emoji_records_correct_key(session, key_reporter, key_chain, value):
-    # Not using key_chain.send_keys() because we always want to treat value as
-    # one character here. `len(value)` varies by platform for non-BMP characters,
-    # so we don't want to iterate over value.
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    # events sent by major browsers are inconsistent so only check key value
-    assert get_keys(key_reporter) == value
-
-
-@pytest.mark.parametrize("value,code,key", [
-    (u"\uE050", "ShiftRight", "Shift"),
-    (u"\uE053", "OSRight", "Meta"),
-    (Keys.CONTROL, "ControlLeft", "Control"),
-])
-def test_single_modifier_key_sends_correct_events(session,
-                                                  key_reporter,
-                                                  key_chain,
-                                                  value,
-                                                  code,
-                                                  key):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    all_events = get_events(session)
-    expected = [
-        {"code": code, "key": key, "type": "keydown"},
-        {"code": code, "key": key, "type": "keyup"},
-    ]
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    assert events == expected
-    assert len(get_keys(key_reporter)) == 0
-
-
-@pytest.mark.parametrize("value,code,key", [
-    (Keys.ESCAPE, "Escape", "Escape"),
-    (Keys.RIGHT, "ArrowRight", "ArrowRight"),
-])
-def test_single_nonprintable_key_sends_events(session,
-                                              key_reporter,
-                                              key_chain,
-                                              value,
-                                              code,
-                                              key):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    expected = [
-        {"code": code, "key": key, "type": "keydown"},
-        {"code": code, "key": key, "type": "keypress"},
-        {"code": code, "key": key, "type": "keyup"},
-    ]
-    all_events = get_events(session)
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    if len(events) == 2:
-        # most browsers don't send a keypress for non-printable keys
-        assert events == [expected[0], expected[2]]
-    else:
-        assert events == expected
-    assert len(get_keys(key_reporter)) == 0
-
-
-def test_sequence_of_keydown_printable_keys_sends_events(session,
-                                                         key_reporter,
-                                                         key_chain):
+def test_sequence_of_keydown_printable_keys_sends_events(session, key_reporter, key_chain):
     key_chain \
         .key_down("a") \
         .key_down("b") \
         .perform()
+    all_events = get_events(session)
+
     expected = [
         {"code": "KeyA", "key": "a", "type": "keydown"},
         {"code": "KeyA", "key": "a", "type": "keypress"},
         {"code": "KeyB", "key": "b", "type": "keydown"},
         {"code": "KeyB", "key": "b", "type": "keypress"},
     ]
-    all_events = get_events(session)
+
     events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
+    if len(events) > 0 and events[0]["code"] is None:
         # Remove 'code' entry if browser doesn't support it
         expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
         events = [filter_dict(e, expected[0]) for e in events]
     assert events == expected
+
     assert get_keys(key_reporter) == "ab"
 
 
-def test_sequence_of_keydown_character_keys(session, key_reporter, key_chain):
+def test_sequence_of_keydown_printable_characters_sends_events(session, key_reporter, key_chain):
     key_chain.send_keys("ef").perform()
+    all_events = get_events(session)
+
     expected = [
         {"code": "KeyE", "key": "e", "type": "keydown"},
         {"code": "KeyE", "key": "e", "type": "keypress"},
@@ -174,20 +156,50 @@ def test_sequence_of_keydown_character_keys(session, key_reporter, key_chain):
         {"code": "KeyF", "key": "f", "type": "keypress"},
         {"code": "KeyF", "key": "f", "type": "keyup"},
     ]
-    all_events = get_events(session)
+
     events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
+    if len(events) > 0 and events[0]["code"] is None:
         # Remove 'code' entry if browser doesn't support it
         expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
         events = [filter_dict(e, expected[0]) for e in events]
     assert events == expected
+
     assert get_keys(key_reporter) == "ef"
 
 
-def test_backspace_erases_keys(session, key_reporter, key_chain):
-    key_chain \
-        .send_keys("efcd") \
-        .send_keys([Keys.BACKSPACE, Keys.BACKSPACE]) \
-        .perform()
-    assert get_keys(key_reporter) == "ef"
+@pytest.mark.parametrize("name,expected", ALL_EVENTS.items())
+def test_special_key_sends_keydown(session, key_reporter, key_chain, name, expected):
+    if name.startswith("F"):
+        # Prevent default behavior for F1, etc., but only after keydown
+        # bubbles up to body. (Otherwise activated browser menus/functions
+        # may interfere with subsequent tests.)
+        session.execute_script("""
+            document.body.addEventListener("keydown",
+                    function(e) { e.preventDefault() });
+        """)
+    if (session.capabilities["browserName"] == 'internet explorer'):
+        key_reporter.click()
+        session.execute_script("resetEvents();")
+    key_chain.key_down(getattr(Keys, name)).perform()
 
+    # only interested in keydown
+    first_event = get_events(session)[0]
+    # make a copy so we can throw out irrelevant keys and compare to events
+    expected = dict(expected)
+
+    del expected["value"]
+
+    # check and remove keys that aren't in expected
+    assert first_event["type"] == "keydown"
+    assert first_event["repeat"] is False
+    first_event = filter_dict(first_event, expected)
+    if first_event["code"] is None:
+        del first_event["code"]
+        del expected["code"]
+    assert first_event == expected
+    # only printable characters should be recorded in input field
+    entered_keys = get_keys(key_reporter)
+    if len(expected["key"]) == 1:
+        assert entered_keys == expected["key"]
+    else:
+        assert len(entered_keys) == 0
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_modifiers.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_modifiers.py
new file mode 100644
index 00000000000..55dc9280c62
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_modifiers.py
@@ -0,0 +1,24 @@
+import pytest
+
+from tests.perform_actions.support.keys import Keys
+
+
+@pytest.mark.parametrize("modifier", [Keys.SHIFT, Keys.R_SHIFT])
+def test_shift_modifier_generates_capital_letters(session, key_reporter, key_chain, modifier):
+    key_chain \
+        .send_keys("b") \
+        .key_down(modifier) \
+        .key_down("c") \
+        .key_up(modifier) \
+        .key_up("c") \
+        .key_down("d") \
+        .key_up("d") \
+        .key_down(modifier) \
+        .key_down("e") \
+        .key_up("e") \
+        .key_down("f") \
+        .key_up(modifier) \
+        .key_up("f") \
+        .perform()
+
+    assert key_reporter.property("value") == "bCdEF"
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/key_shortcuts.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_shortcuts.py
similarity index 92%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/key_shortcuts.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_shortcuts.py
index ec062f75224..31b533ac850 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/key_shortcuts.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_shortcuts.py
@@ -1,5 +1,5 @@
-from tests.actions.support.keys import Keys, MODIFIER_KEY
-from tests.actions.support.refine import get_keys
+from tests.perform_actions.support.keys import Keys, MODIFIER_KEY
+from tests.perform_actions.support.refine import get_keys
 
 
 def test_mod_a_and_backspace_deletes_all_text(session, key_reporter, key_chain):
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_special_keys.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_special_keys.py
new file mode 100644
index 00000000000..003bba42941
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/key_special_keys.py
@@ -0,0 +1,38 @@
+import pytest
+
+from webdriver import error
+
+from tests.perform_actions.support.refine import get_keys
+
+
+@pytest.mark.parametrize("value", [
+    (u"\U0001F604"),
+    (u"\U0001F60D"),
+    (u"\u0BA8\u0BBF"),
+    (u"\u1100\u1161\u11A8"),
+])
+def test_codepoint_keys_behave_correctly(session, key_reporter, key_chain, value):
+    # Not using key_chain.send_keys() because we always want to treat value as
+    # one character here. `len(value)` varies by platform for non-BMP characters,
+    # so we don't want to iterate over value.
+    key_chain \
+        .key_down(value) \
+        .key_up(value) \
+        .perform()
+
+    # events sent by major browsers are inconsistent so only check key value
+    assert get_keys(key_reporter) == value
+
+
+@pytest.mark.parametrize("value", [
+    (u"fa"),
+    (u"\u0BA8\u0BBFb"),
+    (u"\u0BA8\u0BBF\u0BA8"),
+    (u"\u1100\u1161\u11A8c")
+])
+def test_invalid_multiple_codepoint_keys_fail(session, key_reporter, key_chain, value):
+    with pytest.raises(error.InvalidArgumentException):
+        key_chain \
+            .key_down(value) \
+            .key_up(value) \
+            .perform()
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/none.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/none.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/none.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/none.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer.py
similarity index 94%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/mouse.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer.py
index ca8bffceb71..9a68f322d70 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer.py
@@ -2,8 +2,8 @@ import pytest
 
 from webdriver.error import NoSuchWindowException
 
-from tests.actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.actions.support.refine import get_events, filter_dict
+from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
+from tests.perform_actions.support.refine import filter_dict, get_events
 from tests.support.asserts import assert_move_to_coordinates
 from tests.support.inline import inline
 from tests.support.wait import wait
@@ -18,9 +18,6 @@ def test_null_response_value(session, mouse_chain):
     value = mouse_chain.click().perform()
     assert value is None
 
-    value = session.actions.release()
-    assert value is None
-
 
 def test_no_browsing_context(session, closed_window, mouse_chain):
     with pytest.raises(NoSuchWindowException):
@@ -91,7 +88,7 @@ def test_click_element_center(session, test_actions_page, mouse_chain):
             assert e["target"] == "outer"
 
 
-def test_click_navigation(session, url, release_actions):
+def test_click_navigation(session, url):
     destination = url("/webdriver/tests/actions/support/test_actions_wdspec.html")
     start = link_doc(destination)
 
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/control_click.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_contextmenu.py
similarity index 94%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/control_click.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_contextmenu.py
index 2ec819b772f..c64c51252a5 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/control_click.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_contextmenu.py
@@ -1,7 +1,7 @@
 import pytest
 
-from tests.actions.support.refine import filter_dict, get_events
-from tests.actions.support.keys import Keys
+from tests.perform_actions.support.keys import Keys
+from tests.perform_actions.support.refine import filter_dict, get_events
 
 
 @pytest.mark.parametrize("modifier, prop", [
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_dblclick.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_dblclick.py
similarity index 93%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_dblclick.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_dblclick.py
index fc53a51ab76..8c89cef5f38 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_dblclick.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_dblclick.py
@@ -1,6 +1,6 @@
 import pytest
 
-from tests.actions.support.refine import get_events, filter_dict
+from tests.perform_actions.support.refine import filter_dict, get_events
 from tests.support.asserts import assert_move_to_coordinates
 
 
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/modifier_click.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_modifier_click.py
similarity index 94%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/modifier_click.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_modifier_click.py
index fbfd837710b..ba81f6d090b 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/modifier_click.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_modifier_click.py
@@ -1,7 +1,7 @@
 import pytest
 
-from tests.actions.support.refine import filter_dict, get_events
-from tests.actions.support.keys import Keys
+from tests.perform_actions.support.keys import Keys
+from tests.perform_actions.support.refine import filter_dict, get_events
 
 
 @pytest.mark.parametrize("modifier, prop", [
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/pointer_origin.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_origin.py
similarity index 98%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/pointer_origin.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_origin.py
index cad59f0a13b..3ebf14c348c 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/pointer_origin.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_origin.py
@@ -2,7 +2,7 @@ import pytest
 
 from webdriver import MoveTargetOutOfBoundsException
 
-from tests.actions.support.mouse import get_inview_center, get_viewport_rect
+from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
 from tests.support.inline import inline
 
 
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_pause_dblclick.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_pause_dblclick.py
similarity index 92%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_pause_dblclick.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_pause_dblclick.py
index ad179673176..85679f3614a 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/mouse_pause_dblclick.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/pointer_pause_dblclick.py
@@ -1,5 +1,5 @@
-from tests.actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.actions.support.refine import get_events, filter_dict
+from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
+from tests.perform_actions.support.refine import filter_dict, get_events
 
 _DBLCLICK_INTERVAL = 640
 
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/sequence.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/sequence.py
new file mode 100644
index 00000000000..3536abeb12b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/sequence.py
@@ -0,0 +1,9 @@
+# META: timeout=long
+
+from tests.perform_actions.support.refine import get_events, get_keys
+
+
+def test_perform_no_actions_send_no_events(session, key_reporter, key_chain):
+    key_chain.perform()
+    assert len(get_keys(key_reporter)) == 0
+    assert len(get_events(session)) == 0
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/support/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/__init__.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/support/__init__.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/__init__.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/support/keys.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/keys.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/support/keys.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/keys.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/support/mouse.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/mouse.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/support/mouse.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/mouse.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/support/refine.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/refine.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/support/refine.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/refine.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/support/test_actions_wdspec.html b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/test_actions_wdspec.html
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/support/test_actions_wdspec.html
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/support/test_actions_wdspec.html
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/validity.py b/tests/wpt/web-platform-tests/webdriver/tests/perform_actions/validity.py
similarity index 100%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/validity.py
rename to tests/wpt/web-platform-tests/webdriver/tests/perform_actions/validity.py
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/conftest.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/conftest.py
new file mode 100644
index 00000000000..df86db63067
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/conftest.py
@@ -0,0 +1,40 @@
+import pytest
+
+
+@pytest.fixture
+def key_chain(session):
+    return session.actions.sequence("key", "keyboard_id")
+
+
+@pytest.fixture
+def mouse_chain(session):
+    return session.actions.sequence(
+        "pointer",
+        "pointer_id",
+        {"pointerType": "mouse"})
+
+
+@pytest.fixture
+def none_chain(session):
+    return session.actions.sequence("none", "none_id")
+
+
+@pytest.fixture(autouse=True)
+def release_actions(session, request):
+    # release all actions after each test
+    # equivalent to a teardown_function, but with access to session fixture
+    request.addfinalizer(session.actions.release)
+
+
+@pytest.fixture
+def key_reporter(session, test_actions_page, request):
+    """Represents focused input element from `test_keys_page` fixture."""
+    input_el = session.find.css("#keys", all=False)
+    input_el.click()
+    session.execute_script("resetEvents();")
+    return input_el
+
+
+@pytest.fixture
+def test_actions_page(session, url):
+    session.url = url("/webdriver/tests/release_actions/support/test_actions_wdspec.html")
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/release.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/release.py
new file mode 100644
index 00000000000..84719043d1c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/release.py
@@ -0,0 +1,18 @@
+from tests.support.asserts import assert_error, assert_success
+
+
+def release_actions(session):
+    return session.transport.send(
+        "DELETE",
+        "/session/{session_id}/actions".format(**vars(session)),
+    )
+
+
+def test_null_response_value(session):
+    response = release_actions(session)
+    assert_success(response, None)
+
+
+def test_no_browsing_context(session, closed_window):
+    response = release_actions(session)
+    assert_error(response, "no such window")
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/sequence.py
similarity index 91%
rename from tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py
rename to tests/wpt/web-platform-tests/webdriver/tests/release_actions/sequence.py
index b62d00c3e9b..2d816f8094b 100644
--- a/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py
+++ b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/sequence.py
@@ -1,12 +1,6 @@
 # META: timeout=long
 
-from tests.actions.support.refine import get_keys, filter_dict, get_events
-
-
-def test_perform_no_actions_send_no_events(session, key_reporter, key_chain):
-    key_chain.perform()
-    assert len(get_keys(key_reporter)) == 0
-    assert len(get_events(session)) == 0
+from tests.release_actions.support.refine import filter_dict, get_events, get_keys
 
 
 def test_release_no_actions_sends_no_events(session, key_reporter):
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/refine.py b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/refine.py
new file mode 100644
index 00000000000..3a6d63e04ce
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/refine.py
@@ -0,0 +1,33 @@
+def get_events(session):
+    """Return list of key events recorded in the test_keys_page fixture."""
+    events = session.execute_script("return allEvents.events;") or []
+    # `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in
+    # test_keys_wdspec.html), so this converts them back into unicode literals.
+    for e in events:
+        # example: turn "U+d83d" (6 chars) into u"\ud83d" (1 char)
+        if "key" in e and e["key"].startswith(u"U+"):
+            key = e["key"]
+            hex_suffix = key[key.index("+") + 1:]
+            e["key"] = unichr(int(hex_suffix, 16))
+    return events
+
+
+def get_keys(input_el):
+    """Get printable characters entered into `input_el`.
+
+    :param input_el: HTML input element.
+    """
+    rv = input_el.property("value")
+    if rv is None:
+        return ""
+    else:
+        return rv
+
+
+def filter_dict(source, d):
+    """Filter `source` dict to only contain same keys as `d` dict.
+
+    :param source: dictionary to filter.
+    :param d: dictionary whose keys determine the filtering.
+    """
+    return {k: source[k] for k in d.keys()}
diff --git a/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/test_actions_wdspec.html b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/test_actions_wdspec.html
new file mode 100644
index 00000000000..6f844cd255a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webdriver/tests/release_actions/support/test_actions_wdspec.html
@@ -0,0 +1,197 @@
+<!doctype html>
+<meta charset=utf-8>
+<html>
+<head>
+    <title>Test Actions</title>
+    <style>
+      div { padding:0px; margin: 0px; }
+      #trackPointer { position: fixed; }
+      #resultContainer { width: 600px; height: 60px; }
+      .area { width: 100px; height: 50px; background-color: #ccc; }
+      .block { width: 5px; height: 5px; border: solid 1px red; }
+      #dragArea { position: relative; }
+      #dragTarget { position: absolute; top:22px; left:47px;}
+    </style>
+    <script>
+        "use strict";
+        var els = {};
+        var allEvents = { events: [] };
+        function displayMessage(message) {
+            document.getElementById("events").innerHTML = "<p>" + message + "</p>";
+        }
+
+        function appendMessage(message) {
+            document.getElementById("events").innerHTML += "<p>" + message + "</p>";
+        }
+
+        /**
+         * Escape |key| if it's in a surrogate-half character range.
+         *
+         * Example: given "\ud83d" return "U+d83d".
+         *
+         * Otherwise JSON.stringify will convert it to U+FFFD (REPLACEMENT CHARACTER)
+         * when returning a value from executeScript, for example.
+         */
+        function escapeSurrogateHalf(key) {
+          if (typeof key !== "undefined" && key.length === 1) {
+            var charCode = key.charCodeAt(0);
+            var highSurrogate = charCode >= 0xD800 && charCode <= 0xDBFF;
+            var surrogate = highSurrogate || (charCode >= 0xDC00 && charCode <= 0xDFFF);
+            if (surrogate) {
+              key = "U+" + charCode.toString(16);
+            }
+          }
+          return key;
+        }
+
+        function recordKeyboardEvent(event) {
+          var key = escapeSurrogateHalf(event.key);
+          allEvents.events.push({
+            "code": event.code,
+            "key": key,
+            "which": event.which,
+            "location": event.location,
+            "ctrl": event.ctrlKey,
+            "meta": event.metaKey,
+            "shift": event.shiftKey,
+            "repeat": event.repeat,
+            "type": event.type
+          });
+          appendMessage(event.type + " " +
+              "code: " + event.code + ", " +
+              "key: " + key + ", " +
+              "which: " + event.which + ", " +
+              "keyCode: " + event.keyCode);
+        }
+
+        function recordPointerEvent(event) {
+          if (event.type === "contextmenu") {
+            event.preventDefault();
+          }
+          allEvents.events.push({
+            "type": event.type,
+            "button": event.button,
+            "buttons": event.buttons,
+            "pageX": event.pageX,
+            "pageY": event.pageY,
+            "ctrlKey": event.ctrlKey,
+            "metaKey": event.metaKey,
+            "altKey": event.altKey,
+            "shiftKey": event.shiftKey,
+            "target": event.target.id
+          });
+          appendMessage(event.type + " " +
+              "button: " + event.button + ", " +
+              "pageX: " + event.pageX + ", " +
+              "pageY: " + event.pageY + ", " +
+              "button: " + event.button + ", " +
+              "buttons: " + event.buttons + ", " +
+              "ctrlKey: " + event.ctrlKey + ", " +
+              "altKey: " + event.altKey + ", " +
+              "metaKey: " + event.metaKey + ", " +
+              "shiftKey: " + event.shiftKey + ", " +
+              "target id: " + event.target.id);
+        }
+
+        function recordFirstPointerMove(event) {
+          recordPointerEvent(event);
+          window.removeEventListener("mousemove", recordFirstPointerMove);
+        }
+
+        function grabOnce(event) {
+          grab(event);
+          els.dragTarget.removeEventListener("mousedown", grabOnce);
+        }
+
+        function dropOnce(moveHandler) {
+          return function (event) {
+            moveHandler(event);
+            els.dragArea.removeEventListener("mouseup", dropOnce);
+          }
+        }
+
+        function resetEvents() {
+          allEvents.events.length = 0;
+          displayMessage("");
+        }
+
+        function drop(moveHandler) {
+          return function (event) {
+            els.dragArea.removeEventListener("mousemove", moveHandler);
+            els.dragTarget.style.backgroundColor = "yellow";
+            els.dragTarget.addEventListener("mousedown", grab);
+            recordPointerEvent(event);
+          };
+        }
+
+        function move(el, offsetX, offsetY, timeout) {
+          return function(event) {
+            setTimeout(function() {
+              el.style.top = event.clientY + offsetY + "px";
+              el.style.left = event.clientX + offsetX + "px";
+            }, timeout);
+          };
+        }
+
+        function grab(event) {
+          event.target.style.backgroundColor = "red";
+          let boxRect = event.target.getBoundingClientRect();
+          let areaRect = event.target.parentElement.getBoundingClientRect();
+          let moveHandler = move(
+              event.target,
+              // coordinates of dragTarget must be relative to dragArea such that
+              // dragTarget remains under the pointer
+              -(areaRect.left + (event.clientX - boxRect.left)),
+              -(areaRect.top + (event.clientY - boxRect.top)),
+              20);
+          els.dragArea.addEventListener("mousemove", moveHandler);
+          els.dragArea.addEventListener("mouseup", dropOnce(drop(moveHandler)));
+        }
+
+        document.addEventListener("DOMContentLoaded", function() {
+          var keyReporter = document.getElementById("keys");
+          keyReporter.addEventListener("keyup", recordKeyboardEvent);
+          keyReporter.addEventListener("keypress", recordKeyboardEvent);
+          keyReporter.addEventListener("keydown", recordKeyboardEvent);
+
+          var outer = document.getElementById("outer");
+          outer.addEventListener("click", recordPointerEvent);
+          outer.addEventListener("dblclick", recordPointerEvent);
+          outer.addEventListener("mousedown", recordPointerEvent);
+          outer.addEventListener("mouseup", recordPointerEvent);
+          outer.addEventListener("contextmenu", recordPointerEvent);
+
+          window.addEventListener("mousemove", recordFirstPointerMove);
+          //visual cue for mousemove
+          var pointer = document.getElementById("trackPointer");
+          window.addEventListener("mousemove", move(pointer, 15, 15, 30));
+          // drag and drop
+          els.dragArea = document.getElementById("dragArea");
+          els.dragTarget = document.getElementById("dragTarget");
+          els.dragTarget.addEventListener("mousedown", grabOnce);
+        });
+    </script>
+</head>
+<body>
+  <div id="trackPointer" class="block"></div>
+  <div>
+    <h2>KeyReporter</h2>
+    <input type="text" id="keys" size="80">
+  </div>
+  <div>
+    <h2>ClickReporter</h2>
+    <div id="outer" class="area">
+    </div>
+  </div>
+  <div>
+    <h2>DragReporter</h2>
+    <div id="dragArea" class="area">
+      <div id="dragTarget" class="block"></div>
+    </div>
+  </div>
+  <div id="resultContainer">
+    <h2>Events</h2>
+    <div id="events"></div>
+  </div>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/webrtc/getstats.html b/tests/wpt/web-platform-tests/webrtc/getstats.html
index 9775f2090f2..937f54b74ec 100644
--- a/tests/wpt/web-platform-tests/webrtc/getstats.html
+++ b/tests/wpt/web-platform-tests/webrtc/getstats.html
@@ -71,7 +71,7 @@ This test uses data only, and thus does not require fake media devices.
       assert_not_equals(report, null, 'No report');
       let sessionStat = getStatsRecordByType(report, 'peer-connection');
       assert_not_equals(sessionStat, null, 'Did not find peer-connection stats');
-      assert_exists(sessionStat, 'dataChannelsOpened', 'no dataChannelsOpened stat');
+      assert_own_property(sessionStat, 'dataChannelsOpened', 'no dataChannelsOpened stat');
       // Once every 4000 or so tests, the datachannel won't be opened when the getStats
       // function is done, so allow both 0 and 1 datachannels.
       assert_true(sessionStat.dataChannelsOpened == 1 || sessionStat.dataChannelsOpened == 0,
diff --git a/tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js b/tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js
index 9368cf4593e..1778f8505e0 100644
--- a/tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js
+++ b/tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js
@@ -26,7 +26,7 @@ module.exports = {
     assert_unreached: true,
     assert_throws: true,
     assert_idl_attribute: true,
-    assert_exists: true,
+    assert_own_property: true,
     assert_greater_than: true,
     assert_less_than: true,
     assert_greater_than_equal: true,
diff --git a/tests/wpt/web-platform-tests/xhr/resources/responseXML-unavailable-in-worker.js b/tests/wpt/web-platform-tests/xhr/resources/responseXML-unavailable-in-worker.js
index 2f3fdf25c33..06da02a71f5 100644
--- a/tests/wpt/web-platform-tests/xhr/resources/responseXML-unavailable-in-worker.js
+++ b/tests/wpt/web-platform-tests/xhr/resources/responseXML-unavailable-in-worker.js
@@ -2,8 +2,8 @@ self.importScripts('/resources/testharness.js');
 
 test(function() {
     let xhr = new XMLHttpRequest();
-    assert_not_exists(xhr, "responseXML", "responseXML should not be available on instances.");
-    assert_not_exists(XMLHttpRequest.prototype, "responseXML", "responseXML should not be on the prototype.");
+    assert_false(xhr.hasOwnProperty("responseXML"), "responseXML should not be available on instances.");
+    assert_false(XMLHttpRequest.prototype.hasOwnProperty("responseXML"), "responseXML should not be on the prototype.");
 }, "XMLHttpRequest's responseXML property should not be exposed in workers.");
 
 done();
diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
index c67d2455356..b2ef943c060 100644
--- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
+++ b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
@@ -11,3 +11,6 @@
   [WebGL test #60: could not create image (SVG)]
     expected: FAIL
 
+  [WebGL test #44: could not create image (SVG)]
+    expected: FAIL
+