Merge mozilla-inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Tue, 02 Apr 2019 00:55:55 +0300
changeset 467421 e8b3c73b4e328be88aa90f31e1fa9772b537507d
parent 467420 5a85cf971fef1404d6ed2893263f609c5a0de2d9 (current diff)
parent 467351 4c3e64360b7b1e4d635c6a4ddce72c704a1f9a5d (diff)
child 467458 faf1c93917405851987e483b665f485c99b41962
child 467513 ce51e7ec806cbb157d5e336472ef9c05747bc3bd
push id112625
push usercsabou@mozilla.com
push dateMon, 01 Apr 2019 22:06:22 +0000
treeherdermozilla-inbound@e8b3c73b4e32 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.0a1
first release with
nightly linux32
e8b3c73b4e32 / 68.0a1 / 20190401215651 / files
nightly linux64
e8b3c73b4e32 / 68.0a1 / 20190401215651 / files
nightly mac
e8b3c73b4e32 / 68.0a1 / 20190401215651 / files
nightly win32
e8b3c73b4e32 / 68.0a1 / 20190401215651 / files
nightly win64
e8b3c73b4e32 / 68.0a1 / 20190401215651 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
devtools/client/debugger/new/test/mochitest/helpers.js
testing/web-platform/meta/2dcontext/shadows/2d.shadow.enable.blur.html.ini
testing/web-platform/meta/acid/acid2/reftest.html.ini
testing/web-platform/meta/audio-output/setSinkId.html.ini
testing/web-platform/meta/css/CSS2/backgrounds/background-root-018.xht.ini
testing/web-platform/meta/css/CSS2/css1/c5510-padn-000.xht.ini
testing/web-platform/meta/css/CSS2/text/white-space-pre-element-001.xht.ini
testing/web-platform/meta/css/css-flexbox/percentage-heights-quirks-node.html.ini
testing/web-platform/meta/dom/nodes/Document-createEvent.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-classic.sub.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-module.sub.html.ini
testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js.ini
testing/web-platform/meta/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html.ini
testing/web-platform/meta/mediacapture-streams/MediaDevices-getSupportedConstraints.html.ini
testing/web-platform/meta/mediacapture-streams/historical.html.ini
testing/web-platform/meta/orientation-event/idlharness.window.js.ini
testing/web-platform/meta/screen-capture/idlharness.window.js.ini
testing/web-platform/meta/shadow-dom/untriaged/shadow-trees/text-decoration-001.html.ini
testing/web-platform/meta/wake-lock/idlharness.https.window.js.ini
testing/web-platform/meta/wake-lock/wakelock-api.https.html.ini
testing/web-platform/meta/wake-lock/wakelock-cancel-twice.https.html.ini
testing/web-platform/meta/wake-lock/wakelock-promise.https.html.ini
testing/web-platform/meta/wake-lock/wakelockrequest-is-independent.https.html.ini
testing/web-platform/meta/web-nfc/nfc_push.https.html.ini
testing/web-platform/meta/web-nfc/nfc_watch.https.html.ini
testing/web-platform/tests/IndexedDB/bindings-inject-key.html
testing/web-platform/tests/acid/acid2/reference.html
testing/web-platform/tests/acid/acid2/reference.png
testing/web-platform/tests/acid/acid2/test.html
testing/web-platform/tests/acid/acid3/empty.css
testing/web-platform/tests/acid/acid3/empty.html
testing/web-platform/tests/acid/acid3/empty.png
testing/web-platform/tests/acid/acid3/empty.txt
testing/web-platform/tests/acid/acid3/empty.xml
testing/web-platform/tests/acid/acid3/favicon.ico
testing/web-platform/tests/acid/acid3/reference.png
testing/web-platform/tests/acid/acid3/reference.sub.html
testing/web-platform/tests/acid/acid3/support-a.png
testing/web-platform/tests/acid/acid3/support-b.png
testing/web-platform/tests/acid/acid3/svg.xml
testing/web-platform/tests/acid/acid3/xhtml.1
testing/web-platform/tests/acid/acid3/xhtml.2
testing/web-platform/tests/acid/acid3/xhtml.3
testing/web-platform/tests/audio-output/setSinkId.html
testing/web-platform/tests/conformance-checkers/html-aria/live-events/test-case-live-event-1.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/597.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/598.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/599.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/557.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/565.html
testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/566.html
testing/web-platform/tests/conformance-checkers/html-aria/properties-global-norole/properties-global-norole-aria-label-Test-string-value.html
testing/web-platform/tests/css/css-display/run-in/META.yml
testing/web-platform/tests/css/css-flexbox/percentage-heights-quirks-node.html
testing/web-platform/tests/dom/nodes/Document-createEvent.html
testing/web-platform/tests/encoding/legacy-mb-japanese/euc-jp/eucjp_chars-cseucpkdfmtjapanese.html
testing/web-platform/tests/encoding/legacy-mb-japanese/euc-jp/eucjp_chars-x-euc-jp.html
testing/web-platform/tests/encoding/legacy-mb-japanese/euc-jp/eucjp_chars.html
testing/web-platform/tests/encoding/legacy-mb-japanese/euc-jp/eucjp_errors.html
testing/web-platform/tests/encoding/legacy-mb-japanese/iso-2022-jp/iso2022jp_chars-csiso2022jp.html
testing/web-platform/tests/encoding/legacy-mb-japanese/iso-2022-jp/iso2022jp_chars.html
testing/web-platform/tests/encoding/legacy-mb-japanese/iso-2022-jp/iso2022jp_errors.html
testing/web-platform/tests/fonts/noto/NotoSansMongolian-regular.woff2
testing/web-platform/tests/fonts/noto/NotoSansNko-regular-webfont.woff2
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-locationbar-manual.html
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-menubar-manual.html
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-personalbar-manual.html
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-scrollbars-manual.html
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-statusbar-manual.html
testing/web-platform/tests/html/browsers/the-window-object/the-windowproxy-object/test-window-proxy-toolbar-manual.html
testing/web-platform/tests/html/browsers/the-window-object/window-named-properties.html
testing/web-platform/tests/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html
testing/web-platform/tests/mediacapture-streams/MediaDevices-getSupportedConstraints.html
testing/web-platform/tests/mediacapture-streams/historical.html
testing/web-platform/tests/orientation-event/idlharness.window.js
testing/web-platform/tests/pointerlock/mouse_buttons_back_forward-manual.html
testing/web-platform/tests/pointerlock/movementX_Y_basic-manual.html
testing/web-platform/tests/pointerlock/pointerlock_remove_target-manual.html
testing/web-platform/tests/pointerlock/pointerlock_remove_target_on_mouseup-manual.html
testing/web-platform/tests/pointerlock/pointerlock_shadow-manual.html
testing/web-platform/tests/resource-timing/resource_memory_cached.sub.html
testing/web-platform/tests/screen-capture/idlharness.window.js
testing/web-platform/tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html
testing/web-platform/tests/shadow-dom/untriaged/shadow-trees/text-decoration-001.html
testing/web-platform/tests/svg/text/reftests/text-complex-001.svg
testing/web-platform/tests/svg/text/reftests/text-shape-inside-001-ref.svg
testing/web-platform/tests/svg/text/reftests/text-shape-inside-001.svg
testing/web-platform/tests/svg/text/reftests/text-shape-inside-002-ref.svg
testing/web-platform/tests/svg/text/reftests/text-shape-inside-002.svg
testing/web-platform/tests/tools/wptrunner/wptrunner/formatters.py
testing/web-platform/tests/uievents/click/click_event_target-manual.html
testing/web-platform/tests/wake-lock/idlharness.https.window.js
testing/web-platform/tests/wake-lock/wakelock-api.https.html
testing/web-platform/tests/wake-lock/wakelock-cancel-twice.https.html
testing/web-platform/tests/wake-lock/wakelock-promise.https.html
testing/web-platform/tests/wake-lock/wakelockrequest-is-independent.https.html
testing/web-platform/tests/web-nfc/nfc_push.https.html
testing/web-platform/tests/web-nfc/nfc_watch.https.html
testing/web-platform/tests/workers/WorkerGlobalScope_close.htm
testing/web-platform/tests/workers/constructors/Worker/no-arguments-ctor.html
testing/web-platform/tests/workers/constructors/Worker/resolve-empty-string.html
testing/web-platform/tests/workers/constructors/Worker/unresolvable-url.html
testing/web-platform/tests/xhr/resources/header-content-length-twice.asis
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-windowless-workers.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-windowless-workers.js
@@ -38,16 +38,18 @@ add_task(async function() {
   dbg.client.waitForWorkers(true);
 
   const workers = await getWorkers(dbg);
   ok(workers.length == 2, "Got two workers");
   const worker1Thread = workers[0].actor;
   const worker2Thread = workers[1].actor;
 
   const mainThreadSource = findSource(dbg, "doc-windowless-workers.html");
+
+  await waitForSource(dbg, "simple-worker.js");
   const workerSource = findSource(dbg, "simple-worker.js");
 
   info("Test pausing in the main thread");
   assertNotPaused(dbg);
   await dbg.actions.breakOnNext();
   await waitForPaused(dbg, "doc-windowless-workers.html");
   assertPausedAtSourceAndLine(dbg, mainThreadSource.id, 10);
 
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -187,20 +187,17 @@ async function waitForSources(dbg, ...so
  * @param {Object} dbg
  * @param {String} source
  * @return {Promise}
  * @static
  */
 function waitForSource(dbg, url) {
   return waitForState(
     dbg,
-    state => {
-      const sources = dbg.selectors.getSources(state);
-      return Object.values(sources).find(s => (s.url || "").includes(url));
-    },
+    state => findSource(dbg, url, { silent: true }),
     "source exists"
   );
 }
 
 async function waitForElement(dbg, name, ...args) {
   await waitUntil(() => findElement(dbg, name, ...args));
   return findElement(dbg, name, ...args);
 }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2496,16 +2496,28 @@ nsDOMWindowUtils::ZoomToFocusedInput() {
           document->GetDocumentElement(), &presShellId, &viewId)) {
     uint32_t flags = layers::DISABLE_ZOOM_OUT;
     if (!Preferences::GetBool("formhelper.autozoom")) {
       flags |= layers::PAN_INTO_VIEW_ONLY;
     } else {
       flags |= layers::ONLY_ZOOM_TO_DEFAULT_SCALE;
     }
 
+    // The content may be inside a scrollable subframe inside a non-scrollable
+    // root content document. In this scenario, we want to ensure that the
+    // main-thread side knows to scroll the content into view before we get
+    // the bounding content rect and ask APZ to adjust the visual viewport.
+    shell->ScrollContentIntoView(
+        content,
+        nsIPresShell::ScrollAxis(nsIPresShell::SCROLL_MINIMUM,
+                                 nsIPresShell::SCROLL_IF_NOT_VISIBLE),
+        nsIPresShell::ScrollAxis(nsIPresShell::SCROLL_MINIMUM,
+                                 nsIPresShell::SCROLL_IF_NOT_VISIBLE),
+        nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
+
     CSSRect bounds =
         nsLayoutUtils::GetBoundingContentRect(content, rootScrollFrame);
     if (bounds.IsEmpty()) {
       // Do not zoom on empty bounds. Bail out.
       return NS_OK;
     }
     bounds.Inflate(15.0f, 0.0f);
     widget->ZoomToRect(presShellId, viewId, bounds, flags);
--- a/dom/html/test/test_bug430351.html
+++ b/dom/html/test/test_bug430351.html
@@ -456,17 +456,17 @@ function testElements(parent, tags, shou
 
         parent.innerHTML = tag;
 
         // Focus the deepest descendant.
         var descendant = parent;
         while ((descendant = descendant.firstChild))
             element = descendant;
 
-        if (element.nodeName == "IFRAME" && element.hasAttribute("src"))
+        if (element.nodeName == "IFRAME")
             var foo = element.contentDocument;
 
         element.focus();
 
         var errorPrefix = serializer.serializeToString(element) + " in " +
                           serializer.serializeToString(parent);
 
         try {
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_zoomToFocusedInput_scroll.html
@@ -0,0 +1,28 @@
+<!DOCTYPE>
+<html>
+  <head>
+  <title>Checking zoomToFocusedInput scrolls that focused input element is visible position</title>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  </head>
+<body>
+<div style="height: 8000px;">ABC</div>
+<input id="input1">
+<script type="application/javascript">
+function test() {
+  let SimpleTest = window.opener.SimpleTest;
+
+  SimpleTest.is(0, window.scrollY, "scroll position starts at zero");
+  input1.focus();
+  SimpleTest.isnot(0, window.scrollY, "scroll position isn't top");
+  window.scrollTo(0, 0);
+  SimpleTest.is(0, window.scrollY, "scroll position is top");
+
+  SpecialPowers.getDOMWindowUtils(window).zoomToFocusedInput();
+  SimpleTest.isnot(0, window.scrollY, "scroll position isn't top");
+}
+
+waitUntilApzStable().then(test).then(subtestDone);
+</script>
+</body>
+</html>
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -53,8 +53,9 @@
 [test_wheel_scroll.html]
   skip-if = (os == 'android') # wheel events not supported on mobile
 [test_wheel_transactions.html]
   skip-if = (toolkit == 'android') # wheel events not supported on mobile
 [test_group_overrides.html]
   skip-if = (toolkit == 'android') # wheel events not supported on mobile
 [test_group_hittest.html]
   skip-if = (toolkit == 'android') # mouse events not supported on mobile
+[test_group_zoomToFocusedInput.html]
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/test_group_zoomToFocusedInput.html
@@ -0,0 +1,27 @@
+<!DOCTYPE>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Various zoomToFocusedInput tests</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+var subtests = [
+  {"file": "helper_zoomToFocusedInput_scroll.html"},
+];
+
+if (isApzEnabled()) {
+  SimpleTest.waitForExplicitFinish();
+  window.onload = function() {
+    runSubtestsSeriallyInFreshWindows(subtests)
+    .then(SimpleTest.finish, SimpleTest.finish);
+  };
+}
+
+  </script>
+</head>
+<body>
+</body>
+</html>
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -258,25 +258,33 @@ extern JS_FRIEND_API void AssertGCThingM
 extern JS_FRIEND_API void AssertGCThingIsNotNurseryAllocable(
     js::gc::Cell* cell);
 #else
 inline void AssertGCThingMustBeTenured(JSObject* obj) {}
 inline void AssertGCThingIsNotNurseryAllocable(js::gc::Cell* cell) {}
 #endif
 
 /**
- * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of
- * heap classes that refer to GC things should use Heap<T> (or possibly
- * TenuredHeap<T>, described below).
+ * The Heap<T> class is a heap-stored reference to a JS GC thing for use outside
+ * the JS engine. All members of heap classes that refer to GC things should use
+ * Heap<T> (or possibly TenuredHeap<T>, described below).
  *
  * Heap<T> is an abstraction that hides some of the complexity required to
  * maintain GC invariants for the contained reference. It uses operator
- * overloading to provide a normal pointer interface, but notifies the GC every
- * time the value it contains is updated. This is necessary for generational GC,
- * which keeps track of all pointers into the nursery.
+ * overloading to provide a normal pointer interface, but adds barriers to
+ * notify the GC of changes.
+ *
+ * Heap<T> implements the following barriers:
+ *
+ *  - Pre-write barrier (necessary for incremental GC).
+ *  - Post-write barrier (necessary for generational GC).
+ *  - Read barrier (necessary for cycle collector integration).
+ *
+ * Heap<T> may be moved or destroyed outside of GC finalization and hence may be
+ * used in dynamic storage such as a Vector.
  *
  * Heap<T> instances must be traced when their containing object is traced to
  * keep the pointed-to GC thing alive.
  *
  * Heap<T> objects should only be used on the heap. GC references stored on the
  * C/C++ stack must use Rooted/Handle/MutableHandle instead.
  *
  * Type T must be a public GC pointer type.
--- a/js/src/builtin/MapObject.h
+++ b/js/src/builtin/MapObject.h
@@ -20,16 +20,18 @@ namespace js {
  * Comparing two ropes for equality can fail. The js::HashTable template
  * requires infallible hash() and match() operations. Therefore we require
  * all values to be converted to hashable form before being used as a key
  * in a Map or Set object.
  *
  * All values except ropes are hashable as-is.
  */
 class HashableValue {
+  // This is used for map and set keys. We use OrderedHashTableRef to update all
+  // nursery keys on minor GC, so a post barrier is not required here.
   PreBarrieredValue value;
 
  public:
   struct Hasher {
     typedef HashableValue Lookup;
     static HashNumber hash(const Lookup& v,
                            const mozilla::HashCodeScrambler& hcs) {
       return v.hash(hcs);
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -14,38 +14,121 @@
 #include "js/HeapAPI.h"
 #include "js/Id.h"
 #include "js/RootingAPI.h"
 #include "js/Value.h"
 
 /*
  * [SMDOC] GC Barriers
  *
- * A write barrier is a mechanism used by incremental or generation GCs to
+ * Several kinds of barrier are necessary to allow the GC to function correctly.
+ * These are triggered by reading or writing to GC pointers in the heap and
+ * serve to tell the collector about changes to the graph of reachable GC
+ * things.
+ *
+ * Since it would be awkward to change every write to memory into a function
+ * call, this file contains a bunch of C++ classes and templates that use
+ * operator overloading to take care of barriers automatically. In most cases,
+ * all that's necessary is to replace:
+ *
+ *     Type* field;
+ *
+ * with:
+ *
+ *     HeapPtr<Type> field;
+ *
+ * All heap-based GC pointers and tagged pointers must use one of these classes,
+ * except in a couple of exceptional cases.
+ *
+ * These classes are designed to be used by the internals of the JS engine.
+ * Barriers designed to be used externally are provided in js/RootingAPI.h.
+ *
+ * Overview
+ * ========
+ *
+ * This file implements the following concrete classes:
+ *
+ * HeapPtr       General wrapper for heap-based pointers that provides pre- and
+ *               post-write barriers. Most clients should use this.
+ *
+ * GCPtr         An optimisation of HeapPtr for objects which are only destroyed
+ *               by GC finalization (this rules out use in Vector, for example).
+ *
+ * PreBarriered  Provides a pre-barrier but not a post-barrier. Necessary when
+ *               generational GC updates are handled manually, e.g. for hash
+ *               table keys that don't use MovableCellHasher.
+ *
+ * HeapSlot      Provides pre and post-barriers, optimised for use in JSObject
+ *               slots and elements.
+ *
+ * ReadBarriered Provides read and post-write barriers, for use with weak
+ *               pointers.
+ *
+ * The following classes are implemented in js/RootingAPI.h (in the JS
+ * namespace):
+ *
+ * Heap          General wrapper for external clients. Like HeapPtr but also
+ *               handles cycle collector concerns. Most external clients should
+ *               use this.
+ *
+ * TenuredHeap   Like Heap but doesn't allow nursery pointers. Allows storing
+ *               flags in unused lower bits of the pointer.
+ *
+ * Which class to use?
+ * -------------------
+ *
+ * Answer the following questions to decide which barrier class is right for
+ * your use case:
+ *
+ * Is your code part of the JS engine?
+ *   Yes, it's internal =>
+ *     Is your pointer weak or strong?
+ *       Strong =>
+ *         Do you want automatic handling of nursery pointers?
+ *           Yes, of course =>
+ *             Can your object be destroyed outside of a GC?
+ *               Yes => Use HeapPtr<T>
+ *               No => Use GCPtr<T> (optimization)
+ *           No, I'll do this myself => Use PreBarriered<T>
+ *       Weak => Use ReadBarriered<T>
+ *   No, it's external =>
+ *     Can your pointer refer to nursery objects?
+ *       Yes => Use JS::Heap<T>
+ *       Never => Use JS::TenuredHeap<T> (optimization)
+ *
+ * Write barriers
+ * ==============
+ *
+ * A write barrier is a mechanism used by incremental or generational GCs to
  * ensure that every value that needs to be marked is marked. In general, the
  * write barrier should be invoked whenever a write can cause the set of things
  * traced through by the GC to change. This includes:
+ *
  *   - writes to object properties
  *   - writes to array slots
  *   - writes to fields like JSObject::shape_ that we trace through
  *   - writes to fields in private data
  *   - writes to non-markable fields like JSObject::private that point to
  *     markable data
+ *
  * The last category is the trickiest. Even though the private pointer does not
  * point to a GC thing, changing the private pointer may change the set of
  * objects that are traced by the GC. Therefore it needs a write barrier.
  *
  * Every barriered write should have the following form:
+ *
  *   <pre-barrier>
  *   obj->field = value; // do the actual write
  *   <post-barrier>
+ *
  * The pre-barrier is used for incremental GC and the post-barrier is for
  * generational GC.
  *
- *                               PRE-BARRIER
+ * Pre-write barrier
+ * -----------------
  *
  * To understand the pre-barrier, let's consider how incremental GC works. The
  * GC itself is divided into "slices". Between each slice, JS code is allowed to
  * run. Each slice should be short so that the user doesn't notice the
  * interruptions. In our GC, the structure of the slices is as follows:
  *
  * 1. ... JS work, which leads to a request to do GC ...
  * 2. [first GC slice, which performs all root marking and (maybe) more marking]
@@ -92,28 +175,18 @@
  * value0. Note that it only does this if we're in the middle of an incremental
  * GC. Since this is rare, the cost of the write barrier is usually just an
  * extra branch.
  *
  * In practice, we implement the pre-barrier differently based on the type of
  * value0. E.g., see JSObject::writeBarrierPre, which is used if obj->field is
  * a JSObject*. It takes value0 as a parameter.
  *
- *                                READ-BARRIER
- *
- * Incremental GC requires that weak pointers have read barriers. The problem
- * happens when, during an incremental GC, some code reads a weak pointer and
- * writes it somewhere on the heap that has been marked black in a previous
- * slice. Since the weak pointer will not otherwise be marked and will be swept
- * and finalized in the last slice, this will leave the pointer just written
- * dangling after the GC. To solve this, we immediately mark black all weak
- * pointers that get read between slices so that it is safe to store them in an
- * already marked part of the heap, e.g. in Rooted.
- *
- *                                POST-BARRIER
+ * Post-write barrier
+ * ------------------
  *
  * For generational GC, we want to be able to quickly collect the nursery in a
  * minor collection.  Part of the way this is achieved is to only mark the
  * nursery itself; tenured things, which may form the majority of the heap, are
  * not traced through or marked.  This leads to the problem of what to do about
  * tenured objects that have pointers into the nursery: if such things are not
  * marked, they may be discarded while there are still live objects which
  * reference them. The solution is to maintain information about these pointers,
@@ -125,33 +198,51 @@
  *
  * Whenever a slot which could contain such a pointer is written, we check
  * whether the pointed-to thing is in the nursery (if storeBuffer() returns a
  * buffer).  If so we add the cell into the store buffer, which is the
  * collector's representation of the remembered set.  This means that when we
  * come to do a minor collection we can examine the contents of the store buffer
  * and mark any edge targets that are in the nursery.
  *
- *                            IMPLEMENTATION DETAILS
+ * Read barriers
+ * =============
+ *
+ * Weak pointer read barrier
+ * -------------------------
+ *
+ * Weak pointers must have a read barrier to prevent the referent from being
+ * collected if it is read after the start of an incremental GC.
  *
- * Since it would be awkward to change every write to memory into a function
- * call, this file contains a bunch of C++ classes and templates that use
- * operator overloading to take care of barriers automatically. In many cases,
- * all that's necessary to make some field be barriered is to replace
- *     Type* field;
- * with
- *     GCPtr<Type> field;
+ * The problem happens when, during an incremental GC, some code reads a weak
+ * pointer and writes it somewhere on the heap that has been marked black in a
+ * previous slice. Since the weak pointer will not otherwise be marked and will
+ * be swept and finalized in the last slice, this will leave the pointer just
+ * written dangling after the GC. To solve this, we immediately mark black all
+ * weak pointers that get read between slices so that it is safe to store them
+ * in an already marked part of the heap, e.g. in Rooted.
+ *
+ * Cycle collector read barrier
+ * ----------------------------
+ *
+ * Heap pointers external to the engine may be marked gray. The JS API has an
+ * invariant that no gray pointers may be passed, and this maintained by a read
+ * barrier that calls ExposeGCThingToActiveJS on such pointers. This is
+ * implemented by JS::Heap<T> in js/RootingAPI.h.
+ *
+ * Implementation Details
+ * ======================
  *
  * One additional note: not all object writes need to be pre-barriered. Writes
  * to newly allocated objects do not need a pre-barrier. In these cases, we use
  * the "obj->field.init(value)" method instead of "obj->field = value". We use
  * the init naming idiom in many places to signify that a field is being
  * assigned for the first time.
  *
- * This file implements four classes, illustrated here:
+ * This file implements the following hierarchy of classes:
  *
  * BarrieredBase             base class of all barriers
  *  |  |
  *  | WriteBarrieredBase     base class which provides common write operations
  *  |  |  |  |  |
  *  |  |  |  | PreBarriered  provides pre-barriers only
  *  |  |  |  |
  *  |  |  | GCPtr            provides pre- and post-barriers
@@ -178,59 +269,31 @@
  *          -> T::writeBarrierPre
  *
  * GCPtr<T>::post and HeapPtr<T>::post
  *  -> InternalBarrierMethods<T*>::postBarrier
  *      -> T::writeBarrierPost
  *  -> InternalBarrierMethods<Value>::postBarrier
  *      -> StoreBuffer::put
  *
- * These classes are designed to be used by the internals of the JS engine.
- * Barriers designed to be used externally are provided in js/RootingAPI.h.
- * These external barriers call into the same post-barrier implementations at
- * InternalBarrierMethods<T>::post via an indirect call to Heap(.+)Barrier.
+ * Barriers for use outside of the JS engine call into the same barrier
+ * implementations at InternalBarrierMethods<T>::post via an indirect call to
+ * Heap(.+)WriteBarriers.
  *
  * These clases are designed to be used to wrap GC thing pointers or values that
  * act like them (i.e. JS::Value and jsid).  It is possible to use them for
  * other types by supplying the necessary barrier implementations but this
  * is not usually necessary and should be done with caution.
  */
 
 class JSFlatString;
-class JSLinearString;
 
 namespace js {
 
-class AccessorShape;
-class ArrayObject;
-class ArgumentsObject;
-class ArrayBufferObjectMaybeShared;
-class ArrayBufferObject;
-class ArrayBufferViewObject;
-class SharedArrayBufferObject;
-class BaseShape;
-class DebugEnvironmentProxy;
-class GlobalObject;
-class LazyScript;
-class ModuleObject;
-class ModuleEnvironmentObject;
-class ModuleNamespaceObject;
 class NativeObject;
-class PlainObject;
-class PropertyName;
-class SavedFrame;
-class EnvironmentObject;
-class ScriptSourceObject;
-class Shape;
-class UnownedBaseShape;
-class ObjectGroup;
-
-namespace jit {
-class JitCode;
-}  // namespace jit
 
 #ifdef DEBUG
 
 // Barriers can't be triggered during backend Ion compilation, which may run on
 // a helper thread.
 bool CurrentThreadIsIonCompiling();
 
 bool CurrentThreadIsIonCompilingSafeForMinorGC();
@@ -394,17 +457,20 @@ class WriteBarrieredBase
     InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
   }
 };
 
 /*
  * PreBarriered only automatically handles pre-barriers. Post-barriers must be
  * manually implemented when using this class. GCPtr and HeapPtr should be used
  * in all cases that do not require explicit low-level control of moving
- * behavior, e.g. for HashMap keys.
+ * behavior.
+ *
+ * This class is useful for example for HashMap keys where automatically
+ * updating a moved nursery pointer would break the hash table.
  */
 template <class T>
 class PreBarriered : public WriteBarrieredBase<T> {
  public:
   PreBarriered() : WriteBarrieredBase<T>(JS::SafelyInitialized<T>()) {}
   /*
    * Allow implicit construction for use in generic contexts, such as
    * DebuggerWeakMap::markKeys.
@@ -906,83 +972,72 @@ struct DefaultHasher<js::PreBarriered<T>
 /* Specialized hashing policy for ReadBarriereds. */
 template <class T>
 struct DefaultHasher<js::ReadBarriered<T>> : js::ReadBarrieredHasher<T> {};
 
 }  // namespace mozilla
 
 namespace js {
 
+
 class ArrayObject;
-class ArrayBufferObject;
+class DebugEnvironmentProxy;
 class GlobalObject;
+class ObjectGroup;
+class PropertyName;
 class Scope;
 class ScriptSourceObject;
 class Shape;
 class BaseShape;
 class UnownedBaseShape;
 class WasmInstanceObject;
 class WasmTableObject;
+
 namespace jit {
 class JitCode;
 }  // namespace jit
 
-typedef PreBarriered<JSObject*> PreBarrieredObject;
-typedef PreBarriered<JSScript*> PreBarrieredScript;
-typedef PreBarriered<jit::JitCode*> PreBarrieredJitCode;
-typedef PreBarriered<JSString*> PreBarrieredString;
-typedef PreBarriered<JSAtom*> PreBarrieredAtom;
+using PreBarrieredObject = PreBarriered<JSObject*>;
+using PreBarrieredValue = PreBarriered<Value>;
+
+using GCPtrNativeObject = GCPtr<NativeObject*>;
+using GCPtrArrayObject = GCPtr<ArrayObject*>;
+using GCPtrBaseShape = GCPtr<BaseShape*>;
+using GCPtrAtom = GCPtr<JSAtom*>;
+using GCPtrFlatString = GCPtr<JSFlatString*>;
+using GCPtrFunction = GCPtr<JSFunction*>;
+using GCPtrObject = GCPtr<JSObject*>;
+using GCPtrScript = GCPtr<JSScript*>;
+using GCPtrString = GCPtr<JSString*>;
+using GCPtrShape = GCPtr<Shape*>;
+using GCPtrUnownedBaseShape = GCPtr<UnownedBaseShape*>;
+using GCPtrObjectGroup = GCPtr<ObjectGroup*>;
+using GCPtrScope = GCPtr<Scope*>;
+using GCPtrValue = GCPtr<Value>;
+using GCPtrId = GCPtr<jsid>;
 
-typedef GCPtr<NativeObject*> GCPtrNativeObject;
-typedef GCPtr<ArrayObject*> GCPtrArrayObject;
-typedef GCPtr<ArrayBufferObjectMaybeShared*> GCPtrArrayBufferObjectMaybeShared;
-typedef GCPtr<ArrayBufferObject*> GCPtrArrayBufferObject;
-typedef GCPtr<BaseShape*> GCPtrBaseShape;
-typedef GCPtr<JSAtom*> GCPtrAtom;
-typedef GCPtr<JSFlatString*> GCPtrFlatString;
-typedef GCPtr<JSFunction*> GCPtrFunction;
-typedef GCPtr<JSLinearString*> GCPtrLinearString;
-typedef GCPtr<JSObject*> GCPtrObject;
-typedef GCPtr<JSScript*> GCPtrScript;
-typedef GCPtr<JSString*> GCPtrString;
-typedef GCPtr<ModuleObject*> GCPtrModuleObject;
-typedef GCPtr<ModuleEnvironmentObject*> GCPtrModuleEnvironmentObject;
-typedef GCPtr<ModuleNamespaceObject*> GCPtrModuleNamespaceObject;
-typedef GCPtr<PlainObject*> GCPtrPlainObject;
-typedef GCPtr<PropertyName*> GCPtrPropertyName;
-typedef GCPtr<Shape*> GCPtrShape;
-typedef GCPtr<UnownedBaseShape*> GCPtrUnownedBaseShape;
-typedef GCPtr<jit::JitCode*> GCPtrJitCode;
-typedef GCPtr<ObjectGroup*> GCPtrObjectGroup;
-typedef GCPtr<Scope*> GCPtrScope;
+using ImmutablePropertyNamePtr = ImmutableTenuredPtr<PropertyName*>;
+using ImmutableSymbolPtr = ImmutableTenuredPtr<JS::Symbol*>;
 
-typedef PreBarriered<Value> PreBarrieredValue;
-typedef GCPtr<Value> GCPtrValue;
-
-typedef PreBarriered<jsid> PreBarrieredId;
-typedef GCPtr<jsid> GCPtrId;
-
-typedef ImmutableTenuredPtr<PropertyName*> ImmutablePropertyNamePtr;
-typedef ImmutableTenuredPtr<JS::Symbol*> ImmutableSymbolPtr;
+using ReadBarrieredDebugEnvironmentProxy =
+    ReadBarriered<DebugEnvironmentProxy*>;
+using ReadBarrieredGlobalObject = ReadBarriered<GlobalObject*>;
+using ReadBarrieredObject = ReadBarriered<JSObject*>;
+using ReadBarrieredScript = ReadBarriered<JSScript*>;
+using ReadBarrieredScriptSourceObject = ReadBarriered<ScriptSourceObject*>;
+using ReadBarrieredShape = ReadBarriered<Shape*>;
+using ReadBarrieredJitCode = ReadBarriered<jit::JitCode*>;
+using ReadBarrieredObjectGroup = ReadBarriered<ObjectGroup*>;
+using ReadBarrieredSymbol = ReadBarriered<JS::Symbol*>;
+using ReadBarrieredWasmInstanceObject = ReadBarriered<WasmInstanceObject*>;
+using ReadBarrieredWasmTableObject = ReadBarriered<WasmTableObject*>;
 
-typedef ReadBarriered<DebugEnvironmentProxy*>
-    ReadBarrieredDebugEnvironmentProxy;
-typedef ReadBarriered<GlobalObject*> ReadBarrieredGlobalObject;
-typedef ReadBarriered<JSObject*> ReadBarrieredObject;
-typedef ReadBarriered<JSFunction*> ReadBarrieredFunction;
-typedef ReadBarriered<JSScript*> ReadBarrieredScript;
-typedef ReadBarriered<ScriptSourceObject*> ReadBarrieredScriptSourceObject;
-typedef ReadBarriered<Shape*> ReadBarrieredShape;
-typedef ReadBarriered<jit::JitCode*> ReadBarrieredJitCode;
-typedef ReadBarriered<ObjectGroup*> ReadBarrieredObjectGroup;
-typedef ReadBarriered<JS::Symbol*> ReadBarrieredSymbol;
-typedef ReadBarriered<WasmInstanceObject*> ReadBarrieredWasmInstanceObject;
-typedef ReadBarriered<WasmTableObject*> ReadBarrieredWasmTableObject;
-
-typedef ReadBarriered<Value> ReadBarrieredValue;
+using HeapPtrJitCode = HeapPtr<jit::JitCode*>;
+using HeapPtrRegExpShared = HeapPtr<RegExpShared*>;
+using HeapPtrValue = HeapPtr<Value>;
 
 namespace detail {
 
 template <typename T>
 struct DefineComparisonOps<PreBarriered<T>> : mozilla::TrueType {
   static const T& get(const PreBarriered<T>& v) { return v.get(); }
 };
 
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -145,17 +145,17 @@ class SafepointWriter;
 class SafepointIndex;
 class OsiIndex;
 class IonIC;
 
 // An IonScript attaches Ion-generated information to a JSScript.
 struct IonScript {
  private:
   // Code pointer containing the actual method.
-  PreBarrieredJitCode method_;
+  HeapPtrJitCode method_;
 
   // Entrypoint for OSR, or nullptr.
   jsbytecode* osrPc_;
 
   // Offset to OSR entrypoint from method_->raw(), or 0.
   uint32_t osrEntryOffset_;
 
   // Offset to entrypoint skipping type arg check from method_->raw().
@@ -252,16 +252,18 @@ struct IonScript {
     return reinterpret_cast<const uint8_t*>(this);
   }
 
  public:
   SnapshotOffset* bailoutTable() {
     return (SnapshotOffset*)&bottomBuffer()[bailoutTable_];
   }
   PreBarrieredValue* constants() {
+    // Nursery constants are manually barriered in CodeGenerator::link() so a
+    // post barrier is not required..
     return (PreBarrieredValue*)&bottomBuffer()[constantTable_];
   }
   const SafepointIndex* safepointIndices() const {
     return const_cast<IonScript*>(this)->safepointIndices();
   }
   SafepointIndex* safepointIndices() {
     return (SafepointIndex*)&bottomBuffer()[safepointIndexOffset_];
   }
--- a/js/src/jit/JSJitFrameIter.h
+++ b/js/src/jit/JSJitFrameIter.h
@@ -11,16 +11,19 @@
 
 #include "jit/IonCode.h"
 #include "jit/Snapshots.h"
 #include "js/ProfilingFrameIterator.h"
 #include "vm/JSFunction.h"
 #include "vm/JSScript.h"
 
 namespace js {
+
+class ArgumentsObject;
+
 namespace jit {
 
 typedef void* CalleeToken;
 
 enum class FrameType {
   // A JS frame is analogous to a js::InterpreterFrame, representing one
   // scripted function activation. IonJS frames are used by the optimizing
   // compiler.
--- a/js/src/tests/lib/wptreport.py
+++ b/js/src/tests/lib/wptreport.py
@@ -4,17 +4,17 @@
 
 # Integration between the jstests harness and `WptreportFormatter`.
 #
 # `WptreportFormatter` uses the data format specified in
 # <https://firefox-source-docs.mozilla.org/mozbase/mozlog.html>.
 
 from time import time
 
-from wptrunner.formatters import WptreportFormatter
+from wptrunner.formatters.wptreport import WptreportFormatter
 
 
 class WptreportHandler(object):
     def __init__(self, out):
         """
         Initialize the WptreportHandler handler.
 
         :param str out: path to a file to write output to.
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -10,16 +10,17 @@
 #include "mozilla/MemoryReporting.h"
 
 #include "gc/Barrier.h"
 #include "vm/NativeObject.h"
 
 namespace js {
 
 class AbstractFramePtr;
+class ArgumentsObject;
 class ScriptFrameIter;
 
 namespace jit {
 class JitFrameLayout;
 }  // namespace jit
 
 // RareArgumentsData stores the deleted-elements bits for an arguments object.
 // Because |delete arguments[i]| is uncommon, we allocate this data the first
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1946,17 +1946,20 @@ class Breakpoint {
   friend class Debugger;
   friend class BreakpointSite;
 
  public:
   Debugger* const debugger;
   BreakpointSite* const site;
 
  private:
-  /* |handler| is marked unconditionally during minor GC. */
+  /*
+   * |handler| is marked unconditionally during minor GC so a post barrier is
+   * not required.
+   */
   js::PreBarrieredObject handler;
 
   /**
    * Link elements for each list this breakpoint can be in.
    */
   mozilla::DoublyLinkedListElement<Breakpoint> debuggerLink;
   mozilla::DoublyLinkedListElement<Breakpoint> siteLink;
 
@@ -1964,17 +1967,17 @@ class Breakpoint {
   Breakpoint(Debugger* debugger, BreakpointSite* site, JSObject* handler);
 
   enum MayDestroySite { False, True };
   void destroy(FreeOp* fop,
                MayDestroySite mayDestroySite = MayDestroySite::True);
 
   Breakpoint* nextInDebugger();
   Breakpoint* nextInSite();
-  const PreBarrieredObject& getHandler() const { return handler; }
+  JSObject* getHandler() const { return handler; }
   PreBarrieredObject& getHandlerRef() { return handler; }
 
   inline WasmBreakpoint* asWasm();
 };
 
 class JSBreakpointSite : public BreakpointSite {
  public:
   JSScript* script;
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -148,19 +148,19 @@ class RegExpObject : public NativeObject
 
   bool hasShared() { return !!sharedRef(); }
 
   void setShared(RegExpShared& shared) {
     MOZ_ASSERT(!hasShared());
     sharedRef().init(&shared);
   }
 
-  PreBarriered<RegExpShared*>& sharedRef() {
+  HeapPtrRegExpShared& sharedRef() {
     auto& ref = NativeObject::privateRef(PRIVATE_SLOT);
-    return reinterpret_cast<PreBarriered<RegExpShared*>&>(ref);
+    return reinterpret_cast<HeapPtrRegExpShared&>(ref);
   }
 
   static void trace(JSTracer* trc, JSObject* obj);
   void trace(JSTracer* trc);
 
   void initIgnoringLastIndex(JSAtom* source, RegExpFlag flags);
 
   // NOTE: This method is *only* safe to call on RegExps that haven't been
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -907,17 +907,17 @@ class Shape : public gc::TenuredCell {
   friend class TenuringTracer;
   friend struct StackBaseShape;
   friend struct StackShape;
   friend class JS::ubi::Concrete<Shape>;
   friend class js::gc::RelocationOverlay;
 
  protected:
   GCPtrBaseShape base_;
-  PreBarrieredId propid_;
+  GCPtrId propid_;
 
   // Flags that are not modified after the Shape is created. Off-thread Ion
   // compilation can access the immutableFlags word, so we don't want any
   // mutable state here to avoid (TSan) races.
   enum ImmutableFlags : uint32_t {
     // Mask to get the index in object slots for isDataProperty() shapes.
     // For other shapes in the property tree with a parent, stores the
     // parent's slot index (which may be invalid), and invalid for all
@@ -1282,22 +1282,22 @@ class Shape : public gc::TenuredCell {
   }
 
   void incrementNumLinearSearches() {
     uint32_t count = numLinearSearches();
     MOZ_ASSERT(count < LINEAR_SEARCHES_MAX);
     mutableFlags = (mutableFlags & ~LINEAR_SEARCHES_MASK) | (count + 1);
   }
 
-  const PreBarrieredId& propid() const {
+  const GCPtrId& propid() const {
     MOZ_ASSERT(!isEmptyShape());
     MOZ_ASSERT(!JSID_IS_VOID(propid_));
     return propid_;
   }
-  PreBarrieredId& propidRef() {
+  GCPtrId& propidRef() {
     MOZ_ASSERT(!JSID_IS_VOID(propid_));
     return propid_;
   }
   jsid propidRaw() const {
     // Return the actual jsid, not an internal reference.
     return propid();
   }
 
--- a/js/src/wasm/WasmJS.h
+++ b/js/src/wasm/WasmJS.h
@@ -20,16 +20,17 @@
 #define wasm_js_h
 
 #include "gc/Policy.h"
 #include "vm/NativeObject.h"
 #include "wasm/WasmTypes.h"
 
 namespace js {
 
+class ArrayBufferObjectMaybeShared;
 class GlobalObject;
 class StructTypeDescr;
 class TypedArrayObject;
 class WasmFunctionScope;
 class WasmInstanceScope;
 class SharedArrayRawBuffer;
 
 namespace wasm {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/2dcontext/imagebitmap/__dir__.ini
@@ -0,0 +1,2 @@
+leak-threshold: [default:102400]
+lsan-allowed: [Alloc, Create, MakeUnique, PLDHashTable::Add, Realloc, SetPropertyAsInterface, WeakPtr, already_AddRefed, mozilla::SupportsWeakPtr, mozilla::WeakPtr, mozilla::dom::BrowsingContext::Create, mozilla::dom::ContentParent::CreateBrowser, mozilla::dom::TabParent::GetLoadContext, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::CacheFile::OnFileOpened, mozilla::net::CacheFileHandles::NewHandle, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsLocalFile::Clone, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSegmentedBuffer::AppendNewSegment]
deleted file mode 100644
--- a/testing/web-platform/meta/2dcontext/shadows/2d.shadow.enable.blur.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.shadow.enable.blur.html]
-  [Shadows are drawn if shadowBlur is set]
-    expected:
-      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
-
--- a/testing/web-platform/meta/IndexedDB/idlharness.any.js.ini
+++ b/testing/web-platform/meta/IndexedDB/idlharness.any.js.ini
@@ -3,50 +3,62 @@
     expected: FAIL
 
   [IDBFactory interface: operation databases()]
     expected: FAIL
 
   [IDBTransaction interface: operation commit()]
     expected: FAIL
 
+  [IDBCursor interface: attribute request]
+    expected: FAIL
+
 
 [idlharness.any.html]
   [idlharness]
     expected: FAIL
 
   [IDBFactory interface: [object IDBFactory\] must inherit property "databases()" with the proper type]
     expected: FAIL
 
   [IDBFactory interface: operation databases()]
     expected: FAIL
 
   [IDBTransaction interface: operation commit()]
     expected: FAIL
 
+  [IDBCursor interface: attribute request]
+    expected: FAIL
+
 
 [idlharness.any.worker.html]
   [idlharness]
     expected: FAIL
 
   [IDBFactory interface: [object IDBFactory\] must inherit property "databases()" with the proper type]
     expected: FAIL
 
   [IDBFactory interface: operation databases()]
     expected: FAIL
 
   [IDBTransaction interface: operation commit()]
     expected: FAIL
 
+  [IDBCursor interface: attribute request]
+    expected: FAIL
+
 
 [idlharness.https.any.serviceworker.html]
   expected: TIMEOUT
 
 [idlharness.any.serviceworker.html]
   [IDBFactory interface: [object IDBFactory\] must inherit property "databases()" with the proper type]
     expected: FAIL
 
   [IDBFactory interface: operation databases()]
     expected: FAIL
 
   [IDBTransaction interface: operation commit()]
     expected: FAIL
 
+  [IDBCursor interface: attribute request]
+    expected: FAIL
+
--- a/testing/web-platform/meta/acid/acid2/reftest.html.ini
+++ b/testing/web-platform/meta/acid/acid2/reftest.html.ini
@@ -1,2 +1,7 @@
 [reftest.html]
-  expected: FAIL
+  expected:
+    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+    if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+    if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/animation-worklet/playback-rate.https.html.ini
+++ b/testing/web-platform/meta/animation-worklet/playback-rate.https.html.ini
@@ -1,9 +1,10 @@
 [playback-rate.https.html]
+  expected: ERROR
   [Zero current time is not affected by playbackRate set while the animation is in play-pending state.]
     expected: FAIL
 
   [Non zero current time is not affected by playbackRate set while the animation is in play state.]
     expected: FAIL
 
   [When playback rate is updated, the underlying effect is properly updated with the current time of its WorkletAnimation and produces correct visual result.]
     expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-cancel.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-cancel.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-creation.https.html.ini
@@ -0,0 +1,25 @@
+[worklet-animation-creation.https.html]
+  [WorkletAnimation creation with timeline and options should work]
+    expected: FAIL
+
+  [If an effect has no target, object construction should fail]
+    expected: FAIL
+
+  [WorkletAnimation creation with timeline should work]
+    expected: FAIL
+
+  [If the effects are from different documents, object construction should fail]
+    expected: FAIL
+
+  [WorkletAnimation creation without timeline should use default documentation timeline]
+    expected: FAIL
+
+  [Constructing worklet animation for unregisested animator should throw]
+    expected: FAIL
+
+  [If there are no effects specified, object construction should fail]
+    expected: FAIL
+
+  [ScrollTimeline is a valid timeline for a WorkletAnimation]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-duration.https.html.ini
@@ -0,0 +1,4 @@
+[worklet-animation-duration.https.html]
+  [WorkletAnimation should continue to be in effect forever, even if its duration is passed]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-start-delay.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-start-delay.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-with-non-ascii-name.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-with-non-ascii-name.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-with-scroll-timeline-and-display-none.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-with-scroll-timeline-root-scroller.https.html]
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/animation-worklet/worklet-animation-with-scroll-timeline.https.html.ini
@@ -0,0 +1,2 @@
+[worklet-animation-with-scroll-timeline.https.html]
+  expected: TIMEOUT
deleted file mode 100644
--- a/testing/web-platform/meta/audio-output/setSinkId.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[setSinkId.html]
-  prefs: [media.setsinkid.enabled:true]
--- a/testing/web-platform/meta/clipboard-apis/async-interfaces.https.html.ini
+++ b/testing/web-platform/meta/clipboard-apis/async-interfaces.https.html.ini
@@ -1,4 +1,40 @@
 [async-interfaces.https.html]
   [ClipboardEvent interface: new ClipboardEvent("x") must inherit property "clipboardData" with the proper type]
     expected: FAIL
 
+  [ClipboardItem interface: operation createDelayed([object Object\],[object Object\], ClipboardItemOptions)]
+    expected: FAIL
+
+  [ClipboardItem interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [ClipboardItem interface: operation getType(DOMString)]
+    expected: FAIL
+
+  [ClipboardItem interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [ClipboardItem interface: attribute lastModified]
+    expected: FAIL
+
+  [ClipboardItem interface: existence and properties of interface object]
+    expected: FAIL
+
+  [ClipboardItem interface: attribute delayed]
+    expected: FAIL
+
+  [ClipboardItem interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [ClipboardItem interface object length]
+    expected: FAIL
+
+  [ClipboardItem interface: attribute types]
+    expected: FAIL
+
+  [ClipboardItem interface: attribute presentationStyle]
+    expected: FAIL
+
+  [ClipboardItem interface object name]
+    expected: FAIL
+
--- a/testing/web-platform/meta/clipboard-apis/async-navigator-clipboard-basics.https.html.ini
+++ b/testing/web-platform/meta/clipboard-apis/async-navigator-clipboard-basics.https.html.ini
@@ -15,8 +15,14 @@
     expected: FAIL
 
   [navigator.clipboard.read() succeeds]
     expected: FAIL
 
   [navigator.clipboard.write(image/png Blob) succeeds]
     expected: FAIL
 
+  [navigator.clipboard.write([text/plain Blob\]) succeeds]
+    expected: FAIL
+
+  [navigator.clipboard.write([image/png Blob\]) succeeds]
+    expected: FAIL
+
--- a/testing/web-platform/meta/content-security-policy/reporting-api/reporting-api-sends-reports-on-violation.https.sub.html.ini
+++ b/testing/web-platform/meta/content-security-policy/reporting-api/reporting-api-sends-reports-on-violation.https.sub.html.ini
@@ -1,4 +1,8 @@
 [reporting-api-sends-reports-on-violation.https.sub.html]
+  expected: TIMEOUT
   [Violation report status OK.]
     expected: FAIL
 
+  [Report is observable to ReportingObserver]
+    expected: TIMEOUT
+
--- a/testing/web-platform/meta/css/CSS2/backgrounds/background-root-018.xht.ini
+++ b/testing/web-platform/meta/css/CSS2/backgrounds/background-root-018.xht.ini
@@ -1,2 +1,3 @@
 [background-root-018.xht]
-  expected: FAIL
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/css/CSS2/css1/c5510-padn-000.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[c5510-padn-000.xht]
-  expected: FAIL
--- a/testing/web-platform/meta/css/CSS2/text/white-space-003.xht.ini
+++ b/testing/web-platform/meta/css/CSS2/text/white-space-003.xht.ini
@@ -1,2 +1,18 @@
 [white-space-003.xht]
-  expected: FAIL
+  expected:
+    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): PASS
+    if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
+    FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/css/CSS2/text/white-space-pre-element-001.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[white-space-pre-element-001.xht]
-  expected: FAIL
--- a/testing/web-platform/meta/css/CSS2/text/white-space-processing-040.xht.ini
+++ b/testing/web-platform/meta/css/CSS2/text/white-space-processing-040.xht.ini
@@ -1,2 +1,18 @@
 [white-space-processing-040.xht]
-  expected: FAIL
+  expected:
+    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): PASS
+    if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
+    if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): PASS
+    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
+    FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html.ini
@@ -0,0 +1,7 @@
+[intrinsic-width-overflow-auto.tentative.html]
+  [.flexbox 1]
+    expected: FAIL
+
+  [.flexbox 2]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/css/css-flexbox/percentage-heights-quirks-node.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[percentage-heights-quirks-node.html]
-  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim-vertical-lr.html.ini
@@ -0,0 +1,27 @@
+[grid-minimum-contribution-baseline-shim-vertical-lr.html]
+  [.grid 3]
+    expected: FAIL
+
+  [.grid 2]
+    expected: FAIL
+
+  [.grid 1]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [.grid 5]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [.grid 4]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [.grid 6]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim-vertical-rl.html.ini
@@ -0,0 +1,25 @@
+[grid-minimum-contribution-baseline-shim-vertical-rl.html]
+  [.grid 1]
+    expected: FAIL
+
+  [.grid 3]
+    expected: FAIL
+
+  [.grid 2]
+    expected: FAIL
+
+  [.grid 5]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [.grid 4]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [.grid 6]
+    expected:
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim.html.ini
@@ -0,0 +1,7 @@
+[grid-minimum-contribution-baseline-shim.html]
+  [.grid 3]
+    expected: FAIL
+
+  [.grid 2]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-overflow/webkit-line-clamp/webkit-line-clamp-with-line-height.tentative.html.ini
@@ -0,0 +1,2 @@
+[webkit-line-clamp-with-line-height.tentative.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-position/z-index-blend-will-change-overlapping-layers.html.ini
@@ -0,0 +1,3 @@
+[z-index-blend-will-change-overlapping-layers.html]
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
--- a/testing/web-platform/meta/css/css-properties-values-api/register-property-syntax-parsing.html.ini
+++ b/testing/web-platform/meta/css/css-properties-values-api/register-property-syntax-parsing.html.ini
@@ -393,8 +393,59 @@
     expected: FAIL
 
   [syntax:'<length>#', initialValue:'' is invalid]
     expected: FAIL
 
   [syntax:'<length>+', initialValue:'' is invalid]
     expected: FAIL
 
+  [syntax:'<transform-list>+', initialValue:'scale(2)' is invalid]
+    expected: FAIL
+
+  [syntax:'\\1F914 hmm', initialValue:'🤔hmm' is valid]
+    expected: FAIL
+
+  [syntax:'<length>#+', initialValue:'10px' is invalid]
+    expected: FAIL
+
+  [syntax:' <length>+ | <color>#', initialValue:'red, blue' is valid]
+    expected: FAIL
+
+  [syntax:'|banana', initialValue:'banana' is invalid]
+    expected: FAIL
+
+  [syntax:'hmm\\1F914', initialValue:'hmm🤔' is valid]
+    expected: FAIL
+
+  [syntax:'\\1F914\\1F914', initialValue:'🤔🤔' is valid]
+    expected: FAIL
+
+  [syntax:'||', initialValue:'banana' is invalid]
+    expected: FAIL
+
+  [syntax:'\t<color>\n|   foo', initialValue:'foo' is valid]
+    expected: FAIL
+
+  [syntax:'\\1F914', initialValue:'🤔' is valid]
+    expected: FAIL
+
+  [syntax:'<length>+#', initialValue:'10px' is invalid]
+    expected: FAIL
+
+  [syntax:'\\1F914hmm', initialValue:'🤔hmm' is valid]
+    expected: FAIL
+
+  [syntax:'<transform-list>#', initialValue:'scale(2)' is invalid]
+    expected: FAIL
+
+  [syntax:'banan\\61', initialValue:'banana' is valid]
+    expected: FAIL
+
+  [syntax:'|', initialValue:'banana' is invalid]
+    expected: FAIL
+
+  [syntax:'<length>##', initialValue:'10px' is invalid]
+    expected: FAIL
+
+  [syntax:' |', initialValue:'banana' is invalid]
+    expected: FAIL
+
--- a/testing/web-platform/meta/css/css-properties-values-api/registered-property-computation.html.ini
+++ b/testing/web-platform/meta/css/css-properties-values-api/registered-property-computation.html.ini
@@ -222,8 +222,23 @@
     expected: FAIL
 
   [<integer> values are computed correctly [calc(2.6 + 3.1)\]]
     expected: FAIL
 
   [<length> values are computed correctly when font-size is inherited [calc(14em + 10px)\]]
     expected: FAIL
 
+  [<length> values are computed correctly [25.4mm\]]
+    expected: FAIL
+
+  [<length> values are computed correctly [6pc\]]
+    expected: FAIL
+
+  [<length> values are computed correctly [1in\]]
+    expected: FAIL
+
+  [<length> values are computed correctly [72pt\]]
+    expected: FAIL
+
+  [<length> values are computed correctly [2.54cm\]]
+    expected: FAIL
+
--- a/testing/web-platform/meta/css/css-properties-values-api/registered-property-initial.html.ini
+++ b/testing/web-platform/meta/css/css-properties-values-api/registered-property-initial.html.ini
@@ -27,8 +27,62 @@
     expected: FAIL
 
   [Initial value for <color> correctly computed [pink, inherits\]]
     expected: FAIL
 
   [Initial value for <length> correctly computed [calc(10px + 15px)\]]
     expected: FAIL
 
+  [Initial non-inherited value can be substituted [calc(13% + 37%), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [\t1turn, --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [calc(20 + 20 + 10), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [\tcalc(13% + 37px), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [scale(calc(2 + 2)) translateX(calc(3px + 1px)), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [2000ms, --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [ pink , --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [calc(13 + 37), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [calc(10px + 15px), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [scale(calc(2 + 2)), --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [\tfoo\t, --x\]]
+    expected: FAIL
+
+  [Initial non-inherited value can be substituted [\ttest, --x\]]
+    expected: FAIL
+
+  [Initial value for <length> correctly computed [2.54cm\]]
+    expected: FAIL
+
+  [Initial value for <length> correctly computed [72pt\]]
+    expected: FAIL
+
+  [Initial value for <percentage> correctly computed [calc(10% + 20%)\]]
+    expected: FAIL
+
+  [Initial value for <length> correctly computed [25.4mm\]]
+    expected: FAIL
+
+  [Initial value for <length> correctly computed [6pc\]]
+    expected: FAIL
+
+  [Initial value for <length> correctly computed [1in\]]
+    expected: FAIL
+
--- a/testing/web-platform/meta/css/css-pseudo/idlharness.html.ini
+++ b/testing/web-platform/meta/css/css-pseudo/idlharness.html.ini
@@ -73,8 +73,17 @@ prefs: [dom.animations-api.getAnimations
     expected: FAIL
 
   [CSSPseudoElementList interface: calling item(unsigned long) on beforeElements with too few arguments must throw TypeError]
     expected: FAIL
 
   [CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type]
     expected: FAIL
 
+  [CSSPseudoElement interface: existence and properties of interface object]
+    expected: FAIL
+
+  [CSSPseudoElement interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [Element interface: operation pseudo(CSSOMString)]
+    expected: FAIL
+
--- a/testing/web-platform/meta/css/css-tables/html5-table-formatting-1.html.ini
+++ b/testing/web-platform/meta/css/css-tables/html5-table-formatting-1.html.ini
@@ -1,16 +1,4 @@
 [html5-table-formatting-1.html]
   [Empty tables do not take table-columns into account]
     expected: FAIL
 
-  [Table-columns are taken into account after missing cells are generated (non-empty line)]
-    expected:
-      if (os == "android"): FAIL
-
-  [Table-columns are taken into account after missing cells are generated (partially empty line)]
-    expected:
-      if (os == "android"): FAIL
-
-  [Table-columns are taken into account after missing cells are generated (empty line)]
-    expected:
-      if (os == "android"): FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/overflow-wrap/overflow-wrap-break-word-007.html.ini
@@ -0,0 +1,2 @@
+[overflow-wrap-break-word-007.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-002.html.ini
@@ -0,0 +1,2 @@
+[shaping-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-003.html.ini
@@ -0,0 +1,2 @@
+[shaping-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-008.html.ini
@@ -0,0 +1,2 @@
+[shaping-008.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-017.html.ini
@@ -0,0 +1,2 @@
+[shaping-017.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-018.html.ini
@@ -0,0 +1,2 @@
+[shaping-018.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping-021.html.ini
@@ -0,0 +1,2 @@
+[shaping-021.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-000.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-000.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-001.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-001.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-002.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-003.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-004.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-004.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-005.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-005.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-006.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-006.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-007.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-007.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_cchar-008.html.ini
@@ -0,0 +1,2 @@
+[shaping_cchar-008.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/shaping/shaping_lig-000.html.ini
@@ -0,0 +1,3 @@
+[shaping_lig-000.html]
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/white-space/pre-wrap-008.html.ini
@@ -0,0 +1,2 @@
+[pre-wrap-008.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-text/word-break/word-break-break-all-015.html.ini
@@ -0,0 +1,2 @@
+[word-break-break-all-015.html]
+  expected: FAIL
--- a/testing/web-platform/meta/css/css-writing-modes/text-orientation-script-001k.html.ini
+++ b/testing/web-platform/meta/css/css-writing-modes/text-orientation-script-001k.html.ini
@@ -1,12 +1,13 @@
 [text-orientation-script-001k.html]
+  max-asserts: 2
   [Default orientation for vo=U]
     expected: FAIL
 
   [Orientation=Upright]
     expected: FAIL
 
   [Orientation=Rotated]
     expected:
-      if (os == "win"): PASS
+      if os == "win": PASS
       FAIL
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-feblend-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-feblend-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fecomponenttransfer-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fecomponenttransfer-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fecomposite-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fecomposite-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-feconvolvematrix-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-feconvolvematrix-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fediffuselighting-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fediffuselighting-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fediffuselighting-003.html.ini
@@ -0,0 +1,2 @@
+[tainting-fediffuselighting-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fediffuselighting-dynamic.html.ini
@@ -0,0 +1,2 @@
+[tainting-fediffuselighting-dynamic.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fedisplacementmap-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fedisplacementmap-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fedropshadow-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fedropshadow-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fedropshadow-003.html.ini
@@ -0,0 +1,2 @@
+[tainting-fedropshadow-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-feflood-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-feflood-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-feflood-dynamic.html.ini
@@ -0,0 +1,2 @@
+[tainting-feflood-dynamic.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fegaussianblur-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fegaussianblur-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-femorphology-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-femorphology-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-feoffset-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-feoffset-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fespecularlighting-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fespecularlighting-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fespecularlighting-003.html.ini
@@ -0,0 +1,2 @@
+[tainting-fespecularlighting-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/filter-effects/tainting-fetile-002.html.ini
@@ -0,0 +1,2 @@
+[tainting-fetile-002.html]
+  expected: FAIL
--- a/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html.ini
+++ b/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html.ini
@@ -1,4 +1,3 @@
 [float-retry-push-image.html]
   expected:
     if webrender and (os == "win"): PASS
-    FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/custom-elements/reactions/HTMLLIElement.html.ini
@@ -0,0 +1,4 @@
+[HTMLLIElement.html]
+  [Custom Elements: CEReactions on HTMLLIElement interface]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/custom-elements/reactions/HTMLLabelElement.html.ini
@@ -0,0 +1,4 @@
+[HTMLLabelElement.html]
+  [Custom Elements: CEReactions on HTMLLabelElement interface]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/custom-elements/reactions/HTMLMetaElement.html.ini
@@ -0,0 +1,4 @@
+[HTMLMetaElement.html]
+  [Custom Elements: CEReactions on HTMLMetaElement interface]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/custom-elements/reactions/HTMLOptGroupElement.html.ini
@@ -0,0 +1,4 @@
+[HTMLOptGroupElement.html]
+  [Custom Elements: CEReactions on HTMLOptGroupElement interface]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/custom-elements/reactions/HTMLParamElement.html.ini
@@ -0,0 +1,4 @@
+[HTMLParamElement.html]
+  [Custom Elements: CEReactions on HTMLParamElement interface]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/dom/events/Event-dispatch-listener-order.window.js.ini
@@ -0,0 +1,4 @@
+[Event-dispatch-listener-order.window.html]
+  [Event-dispatch-listener-order]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/dom/events/document-level-touchmove-event-listener-passive-by-default.html.ini
@@ -0,0 +1,2 @@
+[document-level-touchmove-event-listener-passive-by-default.html]
+  expected: ERROR
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/dom/events/legacy-pre-activation-behavior.window.js.ini
@@ -0,0 +1,4 @@
+[legacy-pre-activation-behavior.window.html]
+  [Use NONE phase during legacy-pre-activation behavior]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/dom/nodes/Document-createEvent.html.ini
+++ /dev/null
@@ -1,26 +0,0 @@
-[Document-createEvent.html]
-  prefs: [dom.w3c_touch_events.legacy_apis.enabled:true]
-  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "KeyEvents"]
-    expected: FAIL
-    bug: 1251198
-
-  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MouseScrollEvents"]
-    expected: FAIL
-    bug: 1251198
-
-  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "MutationEvent"]
-    expected: FAIL
-    bug: 1251198
-
-  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MutationEvents"]
-    expected: FAIL
-    bug: 1251198
-
-  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ScrollAreaEvent"]
-    expected: FAIL
-    bug: 1251198
-
-  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "TimeEvent"]
-    expected: FAIL
-    bug: 1251198
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/dom/nodes/Document-createEvent.https.html.ini
@@ -0,0 +1,148 @@
+[Document-createEvent.html]
+  prefs: [dom.w3c_touch_events.legacy_apis.enabled:true]
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "KeyEvents"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ScrollAreaEvent"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "KeyEvents"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MouseScrollEvents"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "MutationEvent"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MutationEvents"]
+    expected: FAIL
+
+
+[Document-createEvent.https.html]
+  [createEvent('TouchEvent') should be initialized correctly.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [createEvent('TOUCHEVENT') should be initialized correctly.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [createEvent('touchevent') should be initialized correctly.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "TimeEvent"]
+    expected: FAIL
+
+  [TouchEvent should be an alias for TouchEvent.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "ScrollAreaEvent"]
+    expected: FAIL
+
+  [TOUCHEVENT should be an alias for TouchEvent.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "KeyEvents"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MouseScrollEvents"]
+    expected: FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for non-legacy event interface "MutationEvent"]
+    expected: FAIL
+
+  [touchevent should be an alias for TouchEvent.]
+    expected:
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+
+  [Should throw NOT_SUPPORTED_ERR for pluralized non-legacy event interface "MutationEvents"]
+    expected: FAIL
+
--- a/testing/web-platform/meta/domparsing/XMLSerializer-serializeToString.html.ini
+++ b/testing/web-platform/meta/domparsing/XMLSerializer-serializeToString.html.ini
@@ -30,8 +30,11 @@
     expected: FAIL
 
   [Check if start tag serialization takes into account of its xmlns:* attributes]
     expected: FAIL
 
   [Check if an attribute with namespace and no prefix is serialized with the nearest-declared prefix even if the prefix is assigned to another namespace.]
     expected: FAIL
 
+  [Check if redundant xmlns="..." is dropped.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/element-timing/cross-origin-element.sub.html.ini
@@ -0,0 +1,5 @@
+[cross-origin-element.sub.html]
+  expected: TIMEOUT
+  [Cross-origin image element is NOT observable.]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/element-timing/images-repeated-resource.html.ini
@@ -0,0 +1,5 @@
+[images-repeated-resource.html]
+  expected: TIMEOUT
+  [Element with elementtiming attribute is observable.]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/element-timing/observe-video-poster.html.ini
@@ -0,0 +1,5 @@
+[observe-video-poster.html]
+  expected: TIMEOUT
+  [Able to observe a video's poster image.]
+    expected: TIMEOUT
+
--- a/testing/web-platform/meta/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.ini
+++ b/testing/web-platform/meta/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.ini
@@ -1,7 +1,10 @@
 [lazyload-enabled-tentative.sub.html]
   [Sanity-check: Contents do not load immediately (no eager-loading) when the lazyload attribute is 'on' and frame is in viewport.]
     expected: FAIL
 
   [lazyload-enabled-tentative]
     expected: FAIL
 
+  [Sanity-check: Contents do not load immediately (no eager-loading) when the load attribute is 'lazy' and frame is in viewport.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/feature-policy/feature-policy-for-sandbox/feature-propagation-to-auxiliary-context.html.ini
@@ -0,0 +1,4 @@
+[feature-propagation-to-auxiliary-context.html]
+  [feature-propagation-to-auxiliary-context]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/feature-policy/reporting/unoptimized-images-reporting-onload.html.ini
@@ -0,0 +1,5 @@
+[unoptimized-images-reporting-onload.html]
+  expected: TIMEOUT
+  [unoptimized-images Report Format]
+    expected: TIMEOUT
+
--- a/testing/web-platform/meta/fetch/http-cache/304-update.html.ini
+++ b/testing/web-platform/meta/fetch/http-cache/304-update.html.ini
@@ -1,5 +1,5 @@
 [304-update.html]
   disabled:
-    if (os == "linux"): https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
-    if (os == "mac"): https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
-    if (os == "win"): https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
+    if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
+    if os == "mac": https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
+    if os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1477342
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/fetch/stale-while-revalidate/fetch-sw.https.tentative.html.ini
@@ -0,0 +1,4 @@
+[fetch-sw.https.tentative.html]
+  [Second fetch returns same response]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/fetch/stale-while-revalidate/fetch.tentative.html.ini
@@ -0,0 +1,4 @@
+[fetch.tentative.html]
+  [Second fetch returns same response]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/the-window-object/BarProp.window.js.ini
@@ -0,0 +1,7 @@
+[BarProp.window.html]
+  [BarProp objects of an auxiliary Window]
+    expected: FAIL
+
+  [BarBrop objects of a nested Window]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/the-window-object/close-method.window.js.ini
@@ -0,0 +1,9 @@
+[close-method.window.html]
+  [window.close() affects name targeting immediately]
+    expected: FAIL
+
+  [window.close() queues a task to discard, but window.closed knows immediately]
+    expected:
+      if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/the-window-object/closed-attribute.window.js.ini
@@ -0,0 +1,13 @@
+[closed-attribute.window.html]
+  [closed/close() and cross-origin auxiliary browsing context]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [closed/close() and same-origin auxiliary browsing context]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [closed/close() and cross-site auxiliary browsing context]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/the-window-object/self-et-al.window.js.ini
@@ -0,0 +1,17 @@
+[self-et-al.window.html]
+  [popupWindow.window before, after closing, and after discarding]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [popupWindow.globalThis before, after closing, and after discarding]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [popupWindow.frames before, after closing, and after discarding]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [popupWindow.self before, after closing, and after discarding]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-classic.sub.html.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[string-compilation-integrity-classic.sub.html]
-  expected: ERROR
-  [setTimeout should fail to import]
-    expected: TIMEOUT
-
-  [the Function constructor should fail to import]
-    expected: NOTRUN
-
-  [eval should fail to import]
-    expected: FAIL
-
-  [reflected inline event handlers should fail to import]
-    expected: NOTRUN
-
-  [inline event handlers triggered via UA code should fail to import]
-    expected: NOTRUN
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-module.sub.html.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[string-compilation-integrity-module.sub.html]
-  expected: ERROR
-  [setTimeout should fail to import]
-    expected: TIMEOUT
-
-  [the Function constructor should fail to import]
-    expected: NOTRUN
-
-  [eval should fail to import]
-    expected: FAIL
-
-  [reflected inline event handlers should fail to import]
-    expected: NOTRUN
-
-  [inline event handlers triggered via UA code should fail to import]
-    expected: NOTRUN
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html.ini
@@ -0,0 +1,7 @@
+[activation-transfer-cross-origin-with-click.sub.tentative.html]
+  [Message propagates values on post]
+    expected: FAIL
+
+  [Cross-origin user activation transfer through postMessages]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/user-activation/activation-transfer-with-click.tentative.html.ini
@@ -0,0 +1,7 @@
+[activation-transfer-with-click.tentative.html]
+  [Values adjust on activity]
+    expected: FAIL
+
+  [User activation transfer through postMessages]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/user-activation/activation-transfer-without-click.tentative.html.ini
@@ -0,0 +1,7 @@
+[activation-transfer-without-click.tentative.html]
+  [Values adjust on activity]
+    expected: FAIL
+
+  [User activation transfer from inactive frame]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[url.window.html]
-  [document.open() does not change document's URL (active but not fully active document)]
-    expected:
-      if (os == "android"): FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/webappapis/update-rendering/child-document-raf-order.html.ini
@@ -0,0 +1,4 @@
+[child-document-raf-order.html]
+  [Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/idle-detection-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html.ini
@@ -0,0 +1,14 @@
+[idle-detection-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html]
+  expected: TIMEOUT
+  [Attribute allow="idle-detection" in top-level frame disallows workers in cross-origin relocation.]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame disallows cross-origin relocation.]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame allows workers in same-origin relocation.]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame allows same-origin relocation.]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/idle-detection-allowed-by-feature-policy-attribute.https.sub.html.ini
@@ -0,0 +1,14 @@
+[idle-detection-allowed-by-feature-policy-attribute.https.sub.html]
+  expected: TIMEOUT
+  [Attribute allow="idle-detection" in top-level frame can be enabled in a worker in cross-origin iframe using Feature policy "idle-detection".]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame can be enabled in cross-origin iframe using Feature policy "idle-detection".]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame can be enabled in a worker in same-origin iframe using Feature policy "idle-detection".]
+    expected: TIMEOUT
+
+  [Attribute allow="idle-detection" in top-level frame can be enabled in same-origin iframe using Feature policy "idle-detection".]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/idle-detection-allowed-by-feature-policy.https.sub.html.ini
@@ -0,0 +1,20 @@
+[idle-detection-allowed-by-feature-policy.https.sub.html]
+  expected: TIMEOUT
+  [Feature-Policy {"idle-detection" : ["*"\]} explicity set by top-level frame allows cross-origin iframes.]
+    expected: TIMEOUT
+
+  [Feature-Policy {"idle-detection" : ["*"\]} explicity set by top-level frame allows same-origin iframes.]
+    expected: TIMEOUT
+
+  [Feature-Policy {"idle-detection" : ["*"\]} explicity set by top-level frame allows the top-level document.]
+    expected: FAIL
+
+  [Feature-Policy {"idle-detection" : ["*"\]} explicity set by top-level frame allows workers in cross-origin iframes.]
+    expected: TIMEOUT
+
+  [Inherited header feature policy allows dedicated workers.]
+    expected: FAIL
+
+  [Feature-Policy {"idle-detection" : ["*"\]} explicity set by top-level frame allows workers in same-origin iframes.]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/idle-detection-default-feature-policy.https.sub.html.ini
@@ -0,0 +1,11 @@
+[idle-detection-default-feature-policy.https.sub.html]
+  expected: TIMEOUT
+  [Default "idle-detection" feature policy ["self"\] disallows cross-origin iframes.]
+    expected: TIMEOUT
+
+  [Default "idle-detection" feature policy ["self"\] allows same-origin iframes.]
+    expected: TIMEOUT
+
+  [Default "idle-detection" feature policy ["self"\] allows the top-level document.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/idle-detection-disabled-by-feature-policy.https.sub.html.ini
@@ -0,0 +1,20 @@
+[idle-detection-disabled-by-feature-policy.https.sub.html]
+  expected: TIMEOUT
+  [Feature-Policy {"idle-detection" : [\]} explicitly set by top-level frame disallows cross-origin iframes.]
+    expected: TIMEOUT
+
+  [Feature-Policy {"idle-detection" : [\]} explicitly set by top-level frame disallows query in the top-level document.]
+    expected: FAIL
+
+  [Feature-Policy {"idle-detection" : [\]} explicitly set by top-level frame disallows workers in same-origin iframes.]
+    expected: TIMEOUT
+
+  [Inherited Feature-Policy header {"idle-detection" : [\]} disallows dedicated workers.]
+    expected: FAIL
+
+  [Feature-Policy {"idle-detection" : [\]} explicitly set by top-level frame disallows same-origin iframes.]
+    expected: TIMEOUT
+
+  [Feature-Policy {"idle-detection" : [\]} explicitly set by top-level frame disallows workers in cross-origin iframes.]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/idle-detection/interceptor.https.html.ini
@@ -0,0 +1,19 @@
+[interceptor.https.html]
+  [updates once]
+    expected: FAIL
+
+  [updates twice]
+    expected: FAIL
+
+  [service unavailable]
+    expected: FAIL
+
+  [locked screen]
+    expected: FAIL
+
+  [query()]
+    expected: FAIL
+
+  [Tests the Idle Detection API]
+    expected: FAIL
+
--- a/testing/web-platform/meta/import-maps/resolving.tentative.html.ini
+++ b/testing/web-platform/meta/import-maps/resolving.tentative.html.ini
@@ -51,8 +51,11 @@
     expected: FAIL
 
   [Mapped using the "imports" key only (no scopes) / Tricky specifiers / should work for explicitly-mapped specifiers that happen to have a slash]
     expected: FAIL
 
   [Mapped using the "imports" key only (no scopes) / Tricky specifiers / should fail for attempting to get a submodule of something not declared with a trailing slash]
     expected: FAIL
 
+  [Mapped using the "imports" key only (no scopes) / overlapping entries with trailing slashes / most-specific wins]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/infrastructure/reftest/reftest_fuzzy.html.ini
@@ -0,0 +1,2 @@
+[reftest_fuzzy.html]
+  expected: FAIL
--- a/testing/web-platform/meta/infrastructure/server/__dir__.ini
+++ b/testing/web-platform/meta/infrastructure/server/__dir__.ini
@@ -1,2 +1,2 @@
-lsan-allowed: [Alloc, Create, CreateInner, MakeUnique, PLDHashTable::ChangeTable, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsStandardURL::TemplatedMutator, nsSupportsWeakReference::GetWeakReference]
+lsan-allowed: [Alloc, Create, CreateInner, MakeUnique, NewPage, PLDHashTable::ChangeTable, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::CookieSettings::Create, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsStandardURL::TemplatedMutator, nsSupportsWeakReference::GetWeakReference]
 leak-threshold: [default:51200, tab:51200]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/mathml/presentation-markup/fractions/frac-linethickness-001.html.ini
@@ -0,0 +1,2 @@
+[frac-linethickness-001.html]
+  expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[ImageCapture-MediaTrackSupportedConstraints.html]
-  [Image Capture supported constraints]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.https.html.ini
@@ -0,0 +1,4 @@
+[ImageCapture-MediaTrackSupportedConstraints.https.html]
+  [Image Capture supported constraints]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/mediacapture-streams/historical.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[historical.html]
-  [navigator.mozGetUserMedia should not exist]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/mediacapture-streams/historical.https.html.ini
@@ -0,0 +1,4 @@
+[historical.https.html]
+  [navigator.mozGetUserMedia should not exist]
+    expected: FAIL
+
--- a/testing/web-platform/meta/mozilla-sync
+++ b/testing/web-platform/meta/mozilla-sync
@@ -1,2 +1,2 @@
-local: 7095af3012b348ec6ec5ccbc28a96459154bf4d4
-upstream: 0f1c6e9b1f63e523eb241e8c0eba1cdc764fd180
+local: 8918d1a69d2b9503686e3eaf9aa6e54dc0ca55a7
+upstream: c9829b514d3177ec66e754e91745572f4a14f50d
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/navigation-timing/nav2_test_unloadEvents_with_cross_origin_redirect_chain_partial_opt_in.html.ini
@@ -0,0 +1,4 @@
+[nav2_test_unloadEvents_with_cross_origin_redirect_chain_partial_opt_in.html]
+  [Navigation Timing 2 WPT]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/orientation-event/idlharness.https.window.js.ini
@@ -0,0 +1,4 @@
+[idlharness.https.window.html]
+  [DeviceMotionEvent interface: new DeviceMotionEvent("foo") must inherit property "interval" with the proper type]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/orientation-event/idlharness.window.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[idlharness.window.html]
-  [DeviceMotionEvent interface: new DeviceMotionEvent("foo") must inherit property "interval" with the proper type]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/origin-policy/origin-policy-report-to.https.tentative.sub.html.ini
@@ -0,0 +1,4 @@
+[origin-policy-report-to.https.tentative.sub.html]
+  [Violation report status OK.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/performance-timeline/po-observe.html.ini
@@ -0,0 +1,5 @@
+[po-observe.html]
+  expected: ERROR
+  [PerformanceObserverInit.buffered should retrieve previously buffered entries]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerevents/__dir__.ini
@@ -0,0 +1,2 @@
+leak-threshold: [default:153600, tab:307200]
+lsan-allowed: [Alloc, mozilla::dom::ChromeUtils::GenerateQI, std::sys::unix::alloc::_$LT$impl$u20$core..alloc..GlobalAlloc$u20$for$u20$std..alloc..System$GT$::alloc, std::sys::unix::alloc::_$LT$impl$u20$core..alloc..GlobalAlloc$u20$for$u20$std..alloc..System$GT$::realloc]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerevents/pointerevent_mouse_capture_change_hover.html.ini
@@ -0,0 +1,11 @@
+[pointerevent_mouse_capture_change_hover.html]
+  [Mouse down and capture to green, move to blue and release capture]
+    expected: FAIL
+
+  [Mouse down at green and capture to blue.]
+    expected: FAIL
+
+  [Mouse down and capture to green.]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerevents/pointerevent_mouse_pointercapture_in_frame.html.ini
@@ -0,0 +1,19 @@
+[pointerevent_mouse_pointercapture_in_frame.html]
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): OK
+    ERROR
+  [Test pointer capture event route across the same-origin frame: Mouse down with set capture at inner frame, then release on next mouse move.]
+    expected: FAIL
+
+  [Test pointer capture event route across the same-origin frame: Mouse down at inner frame and set pointer capture.]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [Test pointer capture event route across the same-origin frame: Mouse down at outer frame body and set pointer capture.]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
+  [Test pointercapture event route across the same-origin frame: Mouse down with set capture at outer frame, then release on next mouse move.]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html.ini
@@ -0,0 +1,8 @@
+[pointerevent_mouse_pointercapture_inactivate_pointer.html]
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): TIMEOUT
+  [setPointerCapture: outer frame capture pointer active in inner frame]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): NOTRUN
+      FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerlock/mouse_buttons_back_forward.html.ini
@@ -0,0 +1,6 @@
+[mouse_buttons_back_forward.html]
+  expected: TIMEOUT
+  max-asserts: 2
+  [Tests that when pointer is locked, the mouseup is preventable.]
+    expected: NOTRUN
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/pointerlock/movementX_Y_basic.html.ini
@@ -0,0 +1,14 @@
+[movementX_Y_basic.html]
+  expected:
+    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): ERROR
+    if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): ERROR
+    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): ERROR
+    if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): ERROR
+    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): ERROR
+    if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): ERROR
+    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): ERROR
+    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): ERROR
+  [Test that movementX/Y = eNow.screenX/Y-ePrevious.screenX/Y.]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/portals/portal-activate-data.html.ini
@@ -0,0 +1,14 @@
+[portal-activate-data.html]
+  expected: TIMEOUT
+  [A string can be passed through activate data.]
+    expected: TIMEOUT
+
+  [A message port can be passed through activate data.]
+    expected: NOTRUN
+
+  [Uncloneable data has its exception propagated.]
+    expected: NOTRUN
+
+  [Errors during transfer list processing are propagated.]
+    expected: NOTRUN
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/portals/portals-activate-inside-iframe.html.ini
@@ -0,0 +1,4 @@
+[portals-activate-inside-iframe.html]
+  [activating portal inside iframe should fail]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/portals/portals-nested.html.ini
@@ -0,0 +1,5 @@
+[portals-nested.html]
+  expected: TIMEOUT
+  [nested portals shouldn't crash]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/preload/preload-xhr.html.ini
@@ -0,0 +1,6 @@
+[preload-xhr.html]
+  [Make an XHR request after loading link rel=preload.]
+    expected: FAIL
+
+  [Make an XHR request immediately after creating link rel=preload.]
+    disabled: Bug 1529173
deleted file mode 100644
--- a/testing/web-platform/meta/screen-capture/idlharness.window.js.ini
+++ /dev/null
@@ -1,31 +0,0 @@
-[idlharness.window.html]
-  [Partial interface NavigatorUserMedia: original interface defined]
-    expected: FAIL
-
-  [Navigator interface: navigator must inherit property "getDisplayMedia(MediaStreamConstraints)" with the proper type]
-    expected: FAIL
-
-  [Navigator interface: calling getDisplayMedia(MediaStreamConstraints) on navigator with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [Navigator interface: operation getDisplayMedia(MediaStreamConstraints)]
-    expected: FAIL
-
-  [MediaDevices interface: calling getDisplayMedia(MediaStreamConstraints) on navigator.mediaDevices with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [MediaDevices interface: operation getDisplayMedia(MediaStreamConstraints)]
-    expected: FAIL
-
-  [MediaDevices interface: navigator.mediaDevices must inherit property "getDisplayMedia(MediaStreamConstraints)" with the proper type]
-    expected: FAIL
-
-  [MediaDevices interface: operation getDisplayMedia(DisplayMediaStreamConstraints)]
-    expected: FAIL
-
-  [MediaDevices interface: navigator.mediaDevices must inherit property "getDisplayMedia(DisplayMediaStreamConstraints)" with the proper type]
-    expected: FAIL
-
-  [MediaDevices interface: calling getDisplayMedia(DisplayMediaStreamConstraints) on navigator.mediaDevices with too few arguments must throw TypeError]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/screen-orientation/lock-unlock-check.html.ini
@@ -0,0 +1,4 @@
+[lock-unlock-check.html]
+  [lock-unlock-check]
+    expected: FAIL
+
--- a/testing/web-platform/meta/screen-orientation/orientation-reading.html.ini
+++ b/testing/web-platform/meta/screen-orientation/orientation-reading.html.ini
@@ -1,4 +1,7 @@
 [orientation-reading.html]
   [Test that screen.orientation values change if the orientation changes]
     expected: FAIL
 
+  [Test the orientations and associated angles]
+    expected: FAIL
+
--- a/testing/web-platform/meta/scroll-animations/current-time-writing-modes.html.ini
+++ b/testing/web-platform/meta/scroll-animations/current-time-writing-modes.html.ini
@@ -9,8 +9,11 @@
     expected: FAIL
 
   [currentTime handles writing-mode: vertical-lr correctly]
     expected: FAIL
 
   [currentTime handles startScrollOffset with direction: rtl correctly]
     expected: FAIL
 
+  [currentTime handles endScrollOffset (inclusive case) with direction: rtl correctly]
+    expected: FAIL
+
--- a/testing/web-platform/meta/scroll-animations/current-time.html.ini
+++ b/testing/web-platform/meta/scroll-animations/current-time.html.ini
@@ -15,8 +15,14 @@
     expected: FAIL
 
   [currentTime adjusts correctly for the timeRange]
     expected: FAIL
 
   [currentTime handles startScrollOffset == endScrollOffset correctly]
     expected: FAIL
 
+  [currentTime handles endScrollOffset correctly (inclusive cases)]
+    expected: FAIL
+
+  [currentTime handles fill modes correctly]
+    expected: FAIL
+
--- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini
+++ b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini
@@ -1,7 +1,10 @@
 [cache-match.https.html]
   [cors-exposed header should be stored correctly.]
     expected: FAIL
 
   [Cache.match does not support cacheName option]
     expected: FAIL
 
+  [MIME type should be frozen at response construction.]
+    expected: FAIL
+
--- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini
+++ b/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini
@@ -1,7 +1,10 @@
 [cache-match.https.html]
   [cors-exposed header should be stored correctly.]
     expected: FAIL
 
   [Cache.match does not support cacheName option]
     expected: FAIL
 
+  [MIME type should be frozen at response construction.]
+    expected: FAIL
+
--- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini
+++ b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini
@@ -1,7 +1,10 @@
 [cache-match.https.html]
   [cors-exposed header should be stored correctly.]
     expected: FAIL
 
   [Cache.match does not support cacheName option]
     expected: FAIL
 
+  [MIME type should be frozen at response construction.]
+    expected: FAIL
+
--- a/testing/web-platform/meta/service-workers/service-worker/__dir__.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/__dir__.ini
@@ -1,3 +1,3 @@
 prefs: [dom.serviceWorkers.enabled:true]
-lsan-allowed: [Alloc, CompareNetwork, Create, EntrySlotOrCreate, MakeUnique, Malloc, NS_NewLoadGroup, NewChannelFromURIWithProxyFlagsInternal, NewPage, PLDHashTable::Add, Realloc, SharedMutex, Then, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::dom::PerformanceStorageWorker::Create, mozilla::dom::ServiceWorkerJobQueue::RunJob, mozilla::dom::ServiceWorkerManager::Unregister, mozilla::dom::ServiceWorkerRegistrationMainThread::Unregister, mozilla::dom::UnregisterCallback::UnregisterCallback, mozilla::dom::WorkerCSPEventListener::Create, mozilla::dom::WorkerPrivate::EnsurePerformanceCounter, mozilla::dom::WorkerPrivate::WorkerPrivate, mozilla::dom::cache::CacheOpChild::Recv__delete__, mozilla::dom::serviceWorkerScriptCache::, mozilla::net::HttpBaseChannel::HttpBaseChannel, mozilla::net::HttpChannelChild::HttpChannelChild, mozilla::net::nsHttpHandler::NewProxiedChannel, mozilla::net::nsStandardURL::TemplatedMutator, nsPermission::Create, nsTimer, nsTimer::WithEventTarget, operator]
+lsan-allowed: [Alloc, CompareNetwork, Create, EntrySlotOrCreate, MakeUnique, Malloc, NS_NewLoadGroup, NewChannelFromURIWithProxyFlagsInternal, NewPage, PLDHashTable::Add, Realloc, SharedMutex, Then, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::detail::UniqueSelector, mozilla::dom::PerformanceStorageWorker::Create, mozilla::dom::ServiceWorkerJobQueue::RunJob, mozilla::dom::ServiceWorkerManager::Unregister, mozilla::dom::ServiceWorkerRegistrationMainThread::Unregister, mozilla::dom::UnregisterCallback::UnregisterCallback, mozilla::dom::WorkerCSPEventListener::Create, mozilla::dom::WorkerPrivate::EnsurePerformanceCounter, mozilla::dom::WorkerPrivate::WorkerPrivate, mozilla::dom::cache::CacheOpChild::Recv__delete__, mozilla::dom::serviceWorkerScriptCache::, mozilla::net::HttpBaseChannel::HttpBaseChannel, mozilla::net::HttpChannelChild::HttpChannelChild, mozilla::net::nsHttpHandler::NewProxiedChannel, mozilla::net::nsStandardURL::TemplatedMutator, nsPermission::Create, nsTimer, nsTimer::WithEventTarget, operator]
 leak-threshold: [default:51200, tab:51200]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/service-workers/service-worker/waiting.https.html.ini
@@ -0,0 +1,3 @@
+[waiting.https.html]
+  [waiting is set after installation]
+    expected: FAIL
--- a/testing/web-platform/meta/service-workers/service-worker/windowclient-navigate.https.html.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/windowclient-navigate.https.html.ini
@@ -3,33 +3,8 @@
     expected: FAIL
 
   [in scope but not controlled test on active worker]
     expected: FAIL
 
   [out of scope]
     expected: FAIL
 
-  [invalid url (view-source://example.com)]
-    expected:
-      if (os == "linux") and debug and not webrender and not e10s: "FAIL"
-      if os == "android": "FAIL"
-
-  [invalid url (http://[example.com\])]
-    expected:
-      if (os == "linux") and debug and not webrender and not e10s: "FAIL"
-      if os == "android": "FAIL"
-
-  [invalid url (about:blank)]
-    expected:
-      if (os == "linux") and debug and not webrender and not e10s: "FAIL"
-      if os == "android": "FAIL"
-
-  [invalid url (file:///)]
-    expected:
-      if (os == "linux") and debug and not webrender and not e10s: "FAIL"
-      if os == "android": "FAIL"
-
-  [cross orgin url]
-    expected:
-      if (os == "linux") and debug and not webrender and not e10s: "FAIL"
-      if os == "android": "FAIL"
-
deleted file mode 100644
--- a/testing/web-platform/meta/shadow-dom/untriaged/shadow-trees/text-decoration-001.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-decoration-001.html]
-  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/reporting/sxg-reporting-navigation-ok-no-referrer.tentative.html.ini
@@ -0,0 +1,4 @@
+[sxg-reporting-navigation-ok-no-referrer.tentative.html]
+  [SXG reporting test of ok for navigation with no-referrer.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/reporting/sxg-reporting-navigation-ok-origin-referrer.tentative.html.ini
@@ -0,0 +1,4 @@
+[sxg-reporting-navigation-ok-origin-referrer.tentative.html]
+  [SXG reporting test of ok for navigation with origin referrer.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/service-workers/sxg-sw-register-after-fallback.tentative.https.html.ini
@@ -0,0 +1,4 @@
+[sxg-sw-register-after-fallback.tentative.https.html]
+  [Service worker registration after fallback]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/service-workers/sxg-sw-register.tentative.https.html.ini
@@ -0,0 +1,4 @@
+[sxg-sw-register.tentative.https.html]
+  [Service worker registration from signed exchange]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/sxg-navigation-timing.tentative.html.ini
@@ -0,0 +1,4 @@
+[sxg-navigation-timing.tentative.html]
+  [Navigation timing of SignedHTTPExchange]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/sxg-variants-match.tentative.html.ini
@@ -0,0 +1,4 @@
+[sxg-variants-match.tentative.html]
+  [SignedHTTPExchange should be loaded if Variants/Variant-Key match the request]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/signed-exchange/sxg-variants-mismatch.tentative.html.ini
@@ -0,0 +1,4 @@
+[sxg-variants-mismatch.tentative.html]
+  [SignedHTTPExchange should fallback if Variants/Variant-Key don't match the request]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/speech-api/SpeechSynthesisEvent-constructor.html.ini
@@ -0,0 +1,4 @@
+[SpeechSynthesisEvent-constructor.html]
+  [SpeechSynthesisEvent with eventInitDict having an utterance]
+    expected: FAIL
+
--- a/testing/web-platform/meta/streams/readable-streams/async-iterator.any.js.ini
+++ b/testing/web-platform/meta/streams/readable-streams/async-iterator.any.js.ini
@@ -63,16 +63,25 @@
     expected: FAIL
 
   [Async-iterating an errored stream throws]
     expected: FAIL
 
   [next()'s fulfillment value has the right shape]
     expected: FAIL
 
+  [calling next() after return() should reject]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = true]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = false]
+    expected: FAIL
+
 
 [async-iterator.any.sharedworker.html]
   [Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
     expected: FAIL
 
   [Calling return() twice rejects]
     expected: FAIL
 
@@ -134,16 +143,25 @@
     expected: FAIL
 
   [Async-iterating an errored stream throws]
     expected: FAIL
 
   [next()'s fulfillment value has the right shape]
     expected: FAIL
 
+  [calling next() after return() should reject]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = true]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = false]
+    expected: FAIL
+
 
 [async-iterator.any.worker.html]
   [Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
     expected: FAIL
 
   [Calling return() twice rejects]
     expected: FAIL
 
@@ -205,16 +223,25 @@
     expected: FAIL
 
   [Async-iterating an errored stream throws]
     expected: FAIL
 
   [next()'s fulfillment value has the right shape]
     expected: FAIL
 
+  [calling next() after return() should reject]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = true]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = false]
+    expected: FAIL
+
 
 [async-iterator.any.html]
   [Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
     expected: FAIL
 
   [Calling return() twice rejects]
     expected: FAIL
 
@@ -276,16 +303,25 @@
     expected: FAIL
 
   [Async-iterating an errored stream throws]
     expected: FAIL
 
   [next()'s fulfillment value has the right shape]
     expected: FAIL
 
+  [calling next() after return() should reject]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = true]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = false]
+    expected: FAIL
+
 
 [async-iterator.any.js]
   [Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
     expected: FAIL
 
   [Calling return() twice rejects]
     expected: FAIL
 
@@ -347,8 +383,17 @@
     expected: FAIL
 
   [Async-iterating an errored stream throws]
     expected: FAIL
 
   [next()'s fulfillment value has the right shape]
     expected: FAIL
 
+  [calling next() after return() should reject]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = true]
+    expected: FAIL
+
+  [return() should unlock the stream synchronously when preventCancel = false]
+    expected: FAIL
+
--- a/testing/web-platform/meta/streams/readable-streams/brand-checks.any.js.ini
+++ b/testing/web-platform/meta/streams/readable-streams/brand-checks.any.js.ini
@@ -3,52 +3,67 @@
     expected: FAIL
 
   [ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
     expected: FAIL
 
   [Can get ReadableStreamAsyncIteratorPrototype object indirectly]
     expected: FAIL
 
+  [ReadableStream.prototype.getIterator enforces a brand check]
+    expected: FAIL
+
 
 [brand-checks.any.serviceworker.html]
   [ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
     expected: FAIL
 
   [ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
     expected: FAIL
 
   [Can get ReadableStreamAsyncIteratorPrototype object indirectly]
     expected: FAIL
 
+  [ReadableStream.prototype.getIterator enforces a brand check]
+    expected: FAIL
+
 
 [brand-checks.any.html]
   [ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
     expected: FAIL
 
   [ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
     expected: FAIL
 
   [Can get ReadableStreamAsyncIteratorPrototype object indirectly]
     expected: FAIL
 
+  [ReadableStream.prototype.getIterator enforces a brand check]
+    expected: FAIL
+
 
 [brand-checks.any.sharedworker.html]
   [ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
     expected: FAIL
 
   [ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
     expected: FAIL
 
   [Can get ReadableStreamAsyncIteratorPrototype object indirectly]
     expected: FAIL
 
+  [ReadableStream.prototype.getIterator enforces a brand check]
+    expected: FAIL
+
 
 [brand-checks.any.js]
   [ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
     expected: FAIL
 
   [ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
     expected: FAIL
 
   [Can get ReadableStreamAsyncIteratorPrototype object indirectly]
     expected: FAIL
 
+  [ReadableStream.prototype.getIterator enforces a brand check]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-001.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-001.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-002.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-002.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-003.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-003.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-102.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-102.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-201.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-201.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-202.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-202.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/text/reftests/text-text-anchor-203.svg.ini
@@ -0,0 +1,2 @@
+[text-text-anchor-203.svg]
+  expected: FAIL
--- a/testing/web-platform/meta/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html.ini
+++ b/testing/web-platform/meta/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html.ini
@@ -30,8 +30,11 @@
     expected: FAIL
 
   [TrustedTypePolicyFactory.IsHTML cannot be redefined via defineProperty.]
     expected: FAIL
 
   [TrustedTypePolicyFactory.isURL cannot be redefined via definePropert.]
     expected: FAIL
 
+  [TrustedTypePolicyFactory.isXXX should accept anything without throwing.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/uievents/click/click_event_target.html.ini
@@ -0,0 +1,4 @@
+[click_event_target.html]
+  [Click targets the nearest common ancestor]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wake-lock/idlharness.https.any.js.ini
@@ -0,0 +1,105 @@
+[idlharness.https.any.worker.html]
+  [Stringification of new WakeLock("screen")]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "active" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface object length]
+    expected: FAIL
+
+  [WakeLock interface: attribute active]
+    expected: FAIL
+
+  [WakeLock interface: operation request(WakeLockRequestOptions)]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface object]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "request(WakeLockRequestOptions)" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [WakeLock interface: attribute onactivechange]
+    expected: FAIL
+
+  [WakeLock interface: attribute type]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "onactivechange" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface: calling request(WakeLockRequestOptions) on new WakeLock("screen") with too few arguments must throw TypeError]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "type" with the proper type]
+    expected: FAIL
+
+  [WakeLock must be primary interface of new WakeLock("screen")]
+    expected: FAIL
+
+  [WakeLock interface object name]
+    expected: FAIL
+
+
+[idlharness.https.any.html]
+  [Stringification of new WakeLock("screen")]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "active" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface object length]
+    expected: FAIL
+
+  [WakeLock interface: attribute active]
+    expected: FAIL
+
+  [WakeLock interface: operation request(WakeLockRequestOptions)]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface object]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "request(WakeLockRequestOptions)" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [WakeLock interface: attribute onactivechange]
+    expected: FAIL
+
+  [WakeLock interface: attribute type]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "onactivechange" with the proper type]
+    expected: FAIL
+
+  [WakeLock interface: calling request(WakeLockRequestOptions) on new WakeLock("screen") with too few arguments must throw TypeError]
+    expected: FAIL
+
+  [WakeLock interface: new WakeLock("screen") must inherit property "type" with the proper type]
+    expected: FAIL
+
+  [WakeLock must be primary interface of new WakeLock("screen")]
+    expected: FAIL
+
+  [WakeLock interface object name]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/wake-lock/idlharness.https.window.js.ini
+++ /dev/null
@@ -1,88 +0,0 @@
-[idlharness.https.window.html]
-  [WakeLock interface: existence and properties of interface object]
-    expected: FAIL
-
-  [WakeLock interface object length]
-    expected: FAIL
-
-  [WakeLock interface object name]
-    expected: FAIL
-
-  [WakeLock interface: existence and properties of interface prototype object]
-    expected: FAIL
-
-  [WakeLock interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
-
-  [WakeLock interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
-
-  [WakeLock interface: attribute type]
-    expected: FAIL
-
-  [WakeLock interface: attribute active]
-    expected: FAIL
-
-  [WakeLock interface: attribute onactivechange]
-    expected: FAIL
-
-  [WakeLock interface: operation createRequest()]
-    expected: FAIL
-
-  [WakeLock must be primary interface of wakelock]
-    expected: FAIL
-
-  [Stringification of wakelock]
-    expected: FAIL
-
-  [WakeLock interface: wakelock must inherit property "type" with the proper type]
-    expected: FAIL
-
-  [WakeLock interface: wakelock must inherit property "active" with the proper type]
-    expected: FAIL
-
-  [WakeLock interface: wakelock must inherit property "onactivechange" with the proper type]
-    expected: FAIL
-
-  [WakeLock interface: wakelock must inherit property "createRequest()" with the proper type]
-    expected: FAIL
-
-  [WakeLockRequest interface: existence and properties of interface object]
-    expected: FAIL
-
-  [WakeLockRequest interface object length]
-    expected: FAIL
-
-  [WakeLockRequest interface object name]
-    expected: FAIL
-
-  [WakeLockRequest interface: existence and properties of interface prototype object]
-    expected: FAIL
-
-  [WakeLockRequest interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
-
-  [WakeLockRequest interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
-
-  [WakeLockRequest interface: operation cancel()]
-    expected: FAIL
-
-  [WakeLockRequest must be primary interface of request]
-    expected: FAIL
-
-  [Stringification of request]
-    expected: FAIL
-
-  [WakeLockRequest interface: request must inherit property "cancel()" with the proper type]
-    expected: FAIL
-
-  [Navigator interface: operation getWakeLock(WakeLockType)]
-    expected: FAIL
-
-  [Navigator interface: navigator must inherit property "getWakeLock(WakeLockType)" with the proper type]
-    expected: FAIL
-
-  [Navigator interface: calling getWakeLock(WakeLockType) on navigator with too few arguments must throw TypeError]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/wake-lock/wakelock-api.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[wakelock-api.https.html]
-  [Test that the Wake Lock API is correct]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/wake-lock/wakelock-cancel-twice.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[wakelock-cancel-twice.https.html]
-  [no exception is thrown when invoking cancel() twice]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/wake-lock/wakelock-promise.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[wakelock-promise.https.html]
-  [navigator.getWakeLock() for the same Document always return same WakeLock promise]
-    expected: FAIL
-
--- a/testing/web-platform/meta/wake-lock/wakelock-type.https.html.ini
+++ b/testing/web-platform/meta/wake-lock/wakelock-type.https.html.ini
@@ -18,8 +18,11 @@
     expected: FAIL
 
   ['TypeError' is thrown when set an unsupported wake lock type]
     expected: FAIL
 
   ['TypeError' is thrown when set an empty wake lock type]
     expected: FAIL
 
+  ['TypeError' is thrown when set an invalid wake lock type]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/wake-lock/wakelockrequest-is-independent.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[wakelockrequest-is-independent.https.html]
-  [Test that the WakeLockRequest object is independent.]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/web-nfc/NFCErrorEvent_constructor.https.html.ini
@@ -0,0 +1,4 @@
+[NFCErrorEvent_constructor.https.html]
+  [NFCErrorEvent constructor without init dict]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/web-nfc/NFCReader.html.ini
@@ -0,0 +1,10 @@
+[NFCReader.html]
+  [Test that NFCReader.start fails if NFCReaderOptions.url has wrong protocol.]
+    expected: FAIL
+
+  [Test that NFCReader.start fails if NFCReaderOptions.url is invalid.]
+    expected: FAIL
+
+  [Test that NFCReader.start fails if NFCReaderOptions.url is missing components.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/web-nfc/NFCReadingEvent_constructor.https.html.ini
@@ -0,0 +1,4 @@
+[NFCReadingEvent_constructor.https.html]
+  [NFCReadingEvent constructor without init dict]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/web-nfc/NFCWriter_push.https.html.ini
@@ -0,0 +1,37 @@
+[NFCWriter_push.https.html]
+  [Reject promise with NotSupportedError if NFC message size exceeds 32KB.]
+    expected: FAIL
+
+  [NFCWriter.push should fail with TypeError when invalid target value is provided.]
+    expected: FAIL
+
+  [Reject promise with SyntaxError if 'json' record cannot be serialized.]
+    expected: FAIL
+
+  [Reject promise with SyntaxError if WebNFC Id cannot be created from provided URL.]
+    expected: FAIL
+
+  [NFCWriter.push should fail with TypeError when invalid negative timeout value is provided.]
+    expected: FAIL
+
+  [NFCWriter.push should fail with TypeError when invalid timeout is provided.]
+    expected: FAIL
+
+  [Test that WebNFC API is not accessible from iframe context.]
+    expected: FAIL
+
+  [NFCWriter.push should fail if signal's aborted flag is set.]
+    expected: FAIL
+
+  [NFCWriter.push should fail if the instance has already initiated NFC data transfer.]
+    expected: FAIL
+
+  [NFCWriter.push should fail with TimeoutError when timer expires.]
+    expected: FAIL
+
+  [Test that promise is rejected with TypeError if NDEFMessageSource is invalid.]
+    expected: FAIL
+
+  ['Test that promise is rejected with SyntaxError if NDEFMessageSource contains invalid records.]
+    expected: FAIL
+
--- a/testing/web-platform/meta/web-nfc/idlharness.https.window.js.ini
+++ b/testing/web-platform/meta/web-nfc/idlharness.https.window.js.ini
@@ -168,8 +168,56 @@
     expected: FAIL
 
   [NFCErrorEvent interface object length]
     expected: FAIL
 
   [NFCWriter interface: operation push(NDEFMessageSource, NFCPushOptions)]
     expected: FAIL
 
+  [NFCWriter interface: calling push(NDEFMessageSource, NFCPushOptions) on new NFCWriter(); with too few arguments must throw TypeError]
+    expected: FAIL
+
+  [NFCWriter interface: new NFCWriter(); must inherit property "push(NDEFMessageSource, NFCPushOptions)" with the proper type]
+    expected: FAIL
+
+  [NFCReader interface: new NFCReader(); must inherit property "stop()" with the proper type]
+    expected: FAIL
+
+  [NFCReader interface: new NFCReader(); must inherit property "onreading" with the proper type]
+    expected: FAIL
+
+  [NFCWriter must be primary interface of new NFCWriter();]
+    expected: FAIL
+
+  [NFCErrorEvent interface: new NFCErrorEvent("error", { error: new DOMException() }); must inherit property "error" with the proper type]
+    expected: FAIL
+
+  [NFCReader interface: new NFCReader(); must inherit property "start()" with the proper type]
+    expected: FAIL
+
+  [Stringification of new NFCErrorEvent("error", { error: new DOMException() });]
+    expected: FAIL
+
+  [NFCReader must be primary interface of new NFCReader();]
+    expected: FAIL
+
+  [Stringification of new NFCReader();]
+    expected: FAIL
+
+  [NFCReadingEvent interface: new NFCReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","data":"Hello World"}\]} }) must inherit property "message" with the proper type]
+    expected: FAIL
+
+  [NFCReadingEvent must be primary interface of new NFCReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","data":"Hello World"}\]} })]
+    expected: FAIL
+
+  [NFCErrorEvent must be primary interface of new NFCErrorEvent("error", { error: new DOMException() });]
+    expected: FAIL
+
+  [Stringification of new NFCWriter();]
+    expected: FAIL
+
+  [Stringification of new NFCReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","data":"Hello World"}\]} })]
+    expected: FAIL
+
+  [NFCReader interface: new NFCReader(); must inherit property "onerror" with the proper type]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/web-nfc/nfc_push.https.html.ini
+++ /dev/null
@@ -1,37 +0,0 @@
-[nfc_push.https.html]
-  [Test that promise is rejected with TypeError if NFCMessage is invalid.]
-    expected: FAIL
-
-  ['Test that promise is rejected with SyntaxError if NFCMessage contains invalid records.]
-    expected: FAIL
-
-  [nfc.push should fail with TypeError when invalid timeout is provided.]
-    expected: FAIL
-
-  [nfc.push should fail with TypeError when invalid negative timeout value is provided.]
-    expected: FAIL
-
-  [nfc.push should fail with TimeoutError when timer expires.]
-    expected: FAIL
-
-  [nfc.cancelPush should reject pending promise with AbortError.]
-    expected: FAIL
-
-  [Reject promise with NotSupportedError if NFC message size exceeds 32KB.]
-    expected: FAIL
-
-  [Reject promise with SyntaxError if WebNFC Id cannot be created from provided URL.]
-    expected: FAIL
-
-  [Reject promise with SyntaxError if 'json' record cannot be serialized.]
-    expected: FAIL
-
-  [nfc.push should fail with TypeError when invalid target value is provided.]
-    expected: FAIL
-
-  [nfc.cancelPush should fail with TypeError when invalid id value is provided.]
-    expected: FAIL
-
-  [Test that WebNFC API is not accessible from iframe context.]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/web-nfc/nfc_watch.https.html.ini
+++ /dev/null
@@ -1,37 +0,0 @@
-[nfc_watch.https.html]
-  [Test that nfc.cancelWatch fails if invalid watch ID is provided.]
-    expected: FAIL
-
-  [Test that nfc.cancelWatch fails if there are no active watchers.]
-    expected: FAIL
-
-  [Test that nfc watch success if NFC HW is enable.]
-    expected: FAIL
-
-  [Test that nfc.cancelWatch succeeds if correct watch id is provided.]
-    expected: FAIL
-
-  [Test that nfc.cancelWatch succeeds if there are active watchers.]
-    expected: FAIL
-
-  [Test that nfc.watch fails if NFCWatchOptions.url is missing components.]
-    expected: FAIL
-
-  [Test that nfc.watch fails if NFCWatchOptions.url is invalid.]
-    expected: FAIL
-
-  [Test that nfc.watch fails if NFCWatchOptions.url has wrong protocol.]
-    expected: FAIL
-
-  [Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL.]
-    expected: FAIL
-
-  [Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL with "*" wildcard character in path.]
-    expected: FAIL
-
-  [Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL with "*" wildcard character in the beginning of path component followed by subpath.]
-    expected: FAIL
-
-  [Test that nfc.watch succeeds if NFCWatchOptions.url is empty.]
-    expected: FAIL
-
--- a/testing/web-platform/meta/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html.ini
+++ b/testing/web-platform/meta/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html.ini
@@ -27,8 +27,11 @@
     expected: FAIL
 
   [< [test-audiocontextoptions-latencyHint-double\] 5 out of 10 assertions were failed.]
     expected: FAIL
 
   [# AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed.]
     expected: FAIL
 
+  [# AUDIT TASK RUNNER FINISHED: 2 out of 3 tasks were failed.]
+    expected: FAIL
+
--- a/testing/web-platform/meta/webauthn/createcredential-badargs-rp.https.html.ini
+++ b/testing/web-platform/meta/webauthn/createcredential-badargs-rp.https.html.ini
@@ -1,37 +1,45 @@
 [createcredential-badargs-rp.https.html]
   expected:
-    if (os == "android"): OK
+    if os == "android": OK
     TIMEOUT
   [Bad rp: id is object]
     expected: FAIL
 
   [Bad rp: name is object]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       TIMEOUT
 
   [Bad rp: name is null]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad rp: name is empty String]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad rp: icon is object]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad rp: icon is null]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad rp: icon is empty String]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
+  [Bad rp: icon is insecure]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      NOTRUN
+
+  [Bad rp: rp null]
+    expected: FAIL
+
--- a/testing/web-platform/meta/webauthn/createcredential-badargs-user.https.html.ini
+++ b/testing/web-platform/meta/webauthn/createcredential-badargs-user.https.html.ini
@@ -1,94 +1,99 @@
 [createcredential-badargs-user.https.html]
   expected:
-    if (os == "android"): OK
+    if os == "android": OK
     TIMEOUT
   [Bad user: id is empty ArrayBuffer]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       TIMEOUT
 
   [Bad user: ArrayBuffer id is too long (65 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: Int16Array id is too long (66 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: Int32Array id is too long (68 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: Float32Array id is too long (68 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: Float64Array id is too long (72 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: id is too long (65 bytes)]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [user missing name]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: name is object]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: name is null]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: name is empty String]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: icon is object]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: icon is null]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: icon is empty String]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: displayName is undefined]
     expected:
-      if (os == "android"): PASS
+      if os == "android": PASS
       NOTRUN
 
   [Bad user: displayName is object]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: displayName is null]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
   [Bad user: displayName is empty String]
     expected:
-      if (os == "android"): FAIL
+      if os == "android": FAIL
       NOTRUN
 
+  [Bad user: icon is insecure]
+    expected:
+      if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
+      NOTRUN
+
--- a/testing/web-platform/meta/webdriver/tests/element_send_keys/scroll_into_view.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/element_send_keys/scroll_into_view.py.ini
@@ -1,4 +1,5 @@
 [scroll_into_view.py]
   [test_contenteditable_element_outside_of_scrollable_viewport]
     disabled:
-      if (os == "win"): https://bugzilla.mozilla.org/show_bug.cgi?id=1495521
+      if os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1495521
+
--- a/testing/web-platform/meta/webdriver/tests/execute_async_script/execute_async.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/execute_async_script/execute_async.py.ini
@@ -5,8 +5,9 @@
 
   [test_abort_by_user_prompt_twice[confirm\]]
     expected: FAIL
     disabled: Bug 1459118
 
   [test_abort_by_user_prompt_twice[prompt\]]
     expected: FAIL
     disabled: Bug 1459118
+
--- a/testing/web-platform/meta/webdriver/tests/execute_script/execute.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/execute_script/execute.py.ini
@@ -5,8 +5,9 @@
 
   [test_abort_by_user_prompt_twice[confirm\]]
     expected: FAIL
     disabled: Bug 1459118
 
   [test_abort_by_user_prompt_twice[prompt\]]
     expected: FAIL
     disabled: Bug 1459118
+
--- a/testing/web-platform/meta/webdriver/tests/new_session/response.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/new_session/response.py.ini
@@ -1,6 +1,7 @@
 [response.py]
-  [test_capability_type\[proxy-dict\]]
+  [test_capability_type[proxy-dict\]]
     expected: FAIL
 
-  [test_capability_default_value\[proxy-default_value2\]]
+  [test_capability_default_value[proxy-default_value2\]]
     expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webdriver/tests/set_timeouts/set.py.ini
@@ -0,0 +1,19 @@
+[set.py]
+  [test_value_invalid_types[10-script\]]
+    expected: ERROR
+
+  [test_value_invalid_types[None-script\]]
+    expected: ERROR
+
+  [test_value_invalid_types[value1-script\]]
+    expected: ERROR
+
+  [test_value_invalid_types[False-script\]]
+    expected: ERROR
+
+  [test_value_invalid_types[value2-script\]]
+    expected: ERROR
+
+  [test_key_invalid]
+    expected: ERROR
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webdriver/tests/set_window_rect/set.py.ini
@@ -0,0 +1,19 @@
+[set.py]
+  [test_resize_to_same_size]
+    expected: ERROR
+
+  [test_move_to_same_y]
+    expected: ERROR
+
+  [test_move_to_same_x]
+    expected: ERROR
+
+  [test_resize_to_same_width]
+    expected: ERROR
+
+  [test_resize_to_same_height]
+    expected: ERROR
+
+  [test_move_to_same_position]
+    expected: ERROR
+
--- a/testing/web-platform/meta/webrtc/RTCRtpSender-transport.https.html.ini
+++ b/testing/web-platform/meta/webrtc/RTCRtpSender-transport.https.html.ini
@@ -1,3 +1,6 @@
 [RTCRtpSender-transport.https.html]
   disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1307996
 
+  [RTCRtpSender/receiver.transport has a value when connected]
+    expected: FAIL
+
--- a/testing/web-platform/meta/webrtc/idlharness.https.window.js.ini
+++ b/testing/web-platform/meta/webrtc/idlharness.https.window.js.ini
@@ -580,15 +580,49 @@
 
   [RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "iceTransport" with the proper type]
     expected: FAIL
 
   [RTCDtlsTransport interface: attribute iceTransport]
     expected: FAIL
 
   [RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit)]
-    expected: FAIL
     bug: wpt webidl needs to be updated
 
   [RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback)]
-    expected: FAIL
     bug: wpt webidl needs to be updated
 
+  [RTCError interface: attribute sentAlert]
+    expected: FAIL
+
+  [RTCError interface object name]
+    expected: FAIL
+
+  [RTCError interface object length]
+    expected: FAIL
+
+  [RTCError interface: attribute errorDetail]
+    expected: FAIL
+
+  [RTCError interface: attribute sctpCauseCode]
+    expected: FAIL
+
+  [RTCError interface: attribute httpRequestStatusCode]
+    expected: FAIL
+
+  [RTCError interface: attribute sdpLineNumber]
+    expected: FAIL
+
+  [RTCError interface: attribute receivedAlert]
+    expected: FAIL
+
+  [RTCError interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [RTCError interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [RTCError interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [RTCError interface: existence and properties of interface object]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webrtc/protocol/simulcast-offer.html.ini
@@ -0,0 +1,4 @@
+[simulcast-offer.html]
+  [createOffer() with multiple send encodings should create simulcast offer]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/websockets/unload-a-document/__dir__.ini
@@ -0,0 +1,1 @@
+leak-threshold: [gpu:51200]
--- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html.ini
+++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html.ini
@@ -1,4 +1,6 @@
 [9_cues_overlapping_completely.html]
   disabled:
-    if debug and (os == "linux") : bug1488673
-  expected: TIMEOUT
+    if debug and (os == "linux"): bug1488673
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): ERROR
+    TIMEOUT
--- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html.ini
+++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html.ini
@@ -1,4 +1,6 @@
 [9_cues_overlapping_completely_all_cues_have_same_timestamp.html]
   disabled:
-    if debug and (os == "linux") : bug1488673
-  expected: TIMEOUT
+    if debug and (os == "linux"): bug1488673
+  expected:
+    if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): ERROR
+    TIMEOUT
--- a/testing/web-platform/meta/webxr/idlharness.https.window.js.ini
+++ b/testing/web-platform/meta/webxr/idlharness.https.window.js.ini
@@ -1002,8 +1002,14 @@
     expected: FAIL
 
   [XRInputSource interface: attribute gripSpace]
     expected: FAIL
 
   [XRSession interface: attribute viewerSpace]
     expected: FAIL
 
+  [XRRigidTransform interface: operation inverse()]
+    expected: FAIL
+
+  [XRWebGLLayer interface: attribute ignoreDepthValues]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrFrame_getPose.https.html.ini
@@ -0,0 +1,7 @@
+[xrFrame_getPose.https.html]
+  [XRFrame.getPose works for immersive sessions]
+    expected: FAIL
+
+  [XRFrame.getPose works for non-immersive sessions]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrRay_constructor.https.html.ini
@@ -0,0 +1,4 @@
+[xrRay_constructor.https.html]
+  [XRRay constructors work]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrRay_matrix.https.html.ini
@@ -0,0 +1,4 @@
+[xrRay_matrix.https.html]
+  [XRRay matrix works]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrRigidTransform_constructor.https.html.ini
@@ -0,0 +1,4 @@
+[xrRigidTransform_constructor.https.html]
+  [XRRigidTransform constructor works]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrRigidTransform_matrix.https.html.ini
@@ -0,0 +1,4 @@
+[xrRigidTransform_matrix.https.html]
+  [XRRigidTransform matrix works]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/webxr/xrSession_transfer_outputContext.https.html.ini
@@ -0,0 +1,4 @@
+[xrSession_transfer_outputContext.https.html]
+  [Ensure that XRPresentationContexts are properly transfered between session]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/workers/Worker-multi-port.html.ini
@@ -0,0 +1,10 @@
+[Worker-multi-port.html]
+  [Test postMessage without sequence throws exception]
+    expected: FAIL
+
+  [Test postMessage on channel with previous failed postMessage calls.]
+    expected: FAIL
+
+  [Test postMessage with incorrect ports throws exception]
+    expected: FAIL
+
--- a/testing/web-platform/meta/workers/semantics/multiple-workers/005.html.ini
+++ b/testing/web-platform/meta/workers/semantics/multiple-workers/005.html.ini
@@ -1,6 +1,4 @@
 [005.html]
-  expected:
-    if os == "android": "ERROR"
   [dedicated worker in shared worker in dedicated worker]
     expected: FAIL
 
--- a/testing/web-platform/tests/.azure-pipelines.yml
+++ b/testing/web-platform/tests/.azure-pipelines.yml
@@ -178,17 +178,17 @@ jobs:
   - template: tools/ci/azure/checkout.yml
   - template: tools/ci/azure/install_python.yml
   - template: tools/ci/azure/pip_install.yml
     parameters:
       packages: virtualenv
   - template: tools/ci/azure/install_certs.yml
   - template: tools/ci/azure/update_hosts.yml
   - template: tools/ci/azure/update_manifest.yml
-  - script: python ./wpt run --no-manifest-update --no-restart-on-unexpected --no-fail-on-unexpected --install-fonts --test-types reftest testharness --this-chunk $(System.JobPositionInPhase) --total-chunks $(System.TotalJobsInPhase) --chunk-type hash --log-tbpl - --log-tbpl-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_$(System.JobPositionInPhase).json edge_webdriver
+  - script: python ./wpt run --no-manifest-update --no-fail-on-unexpected --install-fonts --test-types reftest testharness --this-chunk $(System.JobPositionInPhase) --total-chunks $(System.TotalJobsInPhase) --chunk-type hash --log-tbpl - --log-tbpl-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_$(System.JobPositionInPhase).json edge_webdriver
     displayName: 'Run tests'
   - task: PublishBuildArtifacts@1
     displayName: 'Publish results'
     inputs:
       artifactName: 'edge-results'
   - template: tools/ci/azure/cleanup_win10.yml
 - template: tools/ci/azure/fyi_hook.yml
   parameters:
--- a/testing/web-platform/tests/.taskcluster.yml
+++ b/testing/web-platform/tests/.taskcluster.yml
@@ -79,21 +79,23 @@ tasks:
                     ${browser.name}
                     ${browser.channel};
                   cd ~/web-platform-tests;
                   ./tools/ci/taskcluster-run.py
                     ${browser.name}
                     --
                     --channel=${browser.channel}
                     --log-wptreport=../artifacts/wpt_report.json
+                    --log-wptscreenshot=../artifacts/wpt_screenshot.txt
                     --no-fail-on-unexpected
                     --test-type=${chunk[0]}
                     --this-chunk=${chunk[1]}
                     --total-chunks=${chunk[2]};
     - $if: tasks_for == "github-pull-request"
+      # PR tasks that run the tests in various configurations
       then:
         # Taskcluster responds to a number of events issued by the GitHub API
         # which should not trigger re-validation.
         $if: event.action in ['opened', 'reopened', 'synchronize']
         then:
           $map: [{name: firefox, channel: nightly}, {name: chrome, channel: dev}]
           each(browser):
             $map:
@@ -105,24 +107,30 @@ tasks:
                   when executed in ${browser.name}.
                 extra_args: '--verify'
               - name: wpt-${browser.name}-${browser.channel}-results
                 checkout: FETCH_HEAD
                 diff_range: HEAD^
                 description: >-
                   Collect results for all tests affected by a pull request in
                   ${browser.name}.
-                extra_args: '--no-fail-on-unexpected --log-wptreport=../artifacts/wpt_report.json'
+                extra_args: >-
+                  --no-fail-on-unexpected
+                  --log-wptreport=../artifacts/wpt_report.json
+                  --log-wptscreenshot=../artifacts/wpt_screenshot.txt
               - name: wpt-${browser.name}-${browser.channel}-results-without-changes
                 checkout: FETCH_HEAD^
                 diff_range: FETCH_HEAD
                 description: >-
                   Collect results for all tests affected by a pull request in
                   ${browser.name} but without the changes in the PR.
-                extra_args: '--no-fail-on-unexpected --log-wptreport=../artifacts/wpt_report.json'
+                extra_args: >-
+                  --no-fail-on-unexpected
+                  --log-wptreport=../artifacts/wpt_report.json
+                  --log-wptscreenshot=../artifacts/wpt_screenshot.txt
             each(operation):
               taskId: {$eval: 'as_slugid(operation.name)'}
               taskGroupId: {$eval: 'as_slugid("task group")'}
               created: {$fromNow: ''}
               deadline: {$fromNow: '24 hours'}
               provisionerId: aws-provisioner-v1
               workerType:
                 $if: event.repository.full_name == 'web-platform-tests/wpt'
@@ -161,8 +169,71 @@ tasks:
                       ${browser.channel};
                     cd ~/web-platform-tests;
                     ./tools/ci/taskcluster-run.py
                       --commit-range ${operation.diff_range}
                       ${browser.name}
                       --
                       --channel=${browser.channel}
                       ${operation.extra_args};
+    - $map:
+       - name: lint
+         description: >-
+           Lint for wpt-specific requirements
+         script: tools/ci/ci_lint.sh
+         conditions:
+           push
+           pull-request
+      each(operation):
+        # Note: jsone doesn't short-circuit evaluation so all parts of the conditional are evaluated
+        # Accessing properties using the [] notation allows them to evaluate as null in case they're undefined
+        # TODO: Allow running pushes on branches other than master
+        - $if: ("push" in operation.conditions && tasks_for == "github-push" && event['ref'] == "refs/heads/master") || ("pull-request" in operation.conditions && tasks_for == "github-pull-request" && event['action'] in ['opened', 'reopened', 'synchronize'])
+          then:
+            $let:
+              checkout_ref:
+                $if: tasks_for == "github-push"
+                then:
+                  ${event.ref}
+                else:
+                  refs/pull/${event.number}/merge
+            in:
+              taskId: {$eval: 'as_slugid(operation.name)'}
+              taskGroupId: {$eval: 'as_slugid("task group")'}
+              created: {$fromNow: ''}
+              deadline: {$fromNow: '24 hours'}
+              provisionerId: aws-provisioner-v1
+              workerType:
+                $if: event.repository.full_name == 'web-platform-tests/wpt'
+                then:
+                  wpt-docker-worker
+                else:
+                  github-worker
+              metadata:
+                name: ${operation.name}
+                description: ${operation.description}
+                owner: ${event.sender.login}@users.noreply.github.com
+                source: ${event.repository.url}
+              payload:
+                image: harjgam/web-platform-tests:0.29
+                maxRunTime: 7200
+                artifacts:
+                  public/results:
+                    path: /home/test/artifacts
+                    type: directory
+                    # Fetch the GitHub-provided merge commit (rather than the pull
+                    # request branch) so that the tasks simulate the behavior of the
+                    # submitted patch after it is merged. Using the merge commit also
+                    # simplifies detection of modified files because the first parent
+                    # of the merge commit can consistently be used to summarize the
+                    # changes.
+                command:
+                  - /bin/bash
+                  - --login
+                  - -c
+                  - set -ex;
+                    ~/start.sh
+                      ${event.repository.clone_url}
+                      ${checkout_ref}
+                      FETCH_HEAD
+                      none;
+                    cd ~/web-platform-tests;
+                    ${operation.script};
--- a/testing/web-platform/tests/.travis.yml
+++ b/testing/web-platform/tests/.travis.yml
@@ -23,21 +23,16 @@ matrix:
         - JOB=manifest_upload SCRIPT=tools/ci/ci_manifest.sh
         - secure: "FrlMkMZiwggnhJbLiLxZ4imtXxuzFNozty94g1mneMPEVLrnyhb6c/g2SwN37KKU0WSDlGTz26IYnFvo1ftfSOx+sjRz0HqwW7JnrXULKYo7jiPttIcmeJxlSVeW9yS4blbLaBakytHjSnsf+za7bAaf1aS7RRAtAINgifA6Chg="
       deploy:
         provider: releases
         api_key:
           secure: "EljDx50oNpDLs7rzwIv+z1PxIgB5KMnx1W0OQkpNvltR0rBW9g/aQaE+Z/c8M/sPqN1bkvKPybKzGKjb6j9Dw3/EJhah4SskH78r3yMAe2DU/ngxqqjjfXcCc2t5MKxzHAILTAxqScPj2z+lG1jeK1Z+K5hTbSP9lk+AvS0D16w="
         file: $WPT_MANIFEST_FILE.gz
         skip_cleanup: true
-    - name: "lint"
-      # lint is run both on master and on PRs
-      os: linux
-      python: "2.7"
-      env: JOB=lint SCRIPT=tools/ci/ci_lint.sh
     - name: "update-built-tests.sh"
       if: type = pull_request
       os: linux
       python: "2.7"
       env: JOB=update_built SCRIPT=tools/ci/ci_built_diff.sh
     - name: "build-css-testsuites.sh"
       if: type = pull_request
       os: linux
@@ -57,32 +52,47 @@ matrix:
       if: type = pull_request
       os: linux
       python: "2.7"
       addons:
         apt:
           packages:
             - libnss3-tools
       env: JOB=wpt_integration TOXENV=py27 SCRIPT=tools/ci/ci_wpt.sh
+      addons:
+        apt:
+          packages:
+            - fonts-liberation
+            - libappindicator1
+            - libnss3-tools
+            - pulseaudio
     - name: "resources/ tests"
       if: type = pull_request
       os: linux
       python: "2.7"
       env: JOB=resources_unittest TOXENV=py27 SCRIPT=tools/ci/ci_resources_unittest.sh
+      addons:
+        apt:
+          packages:
+            - fonts-liberation
+            - libappindicator1
+            - libnss3-tools
+            - pulseaudio
     - name: "infrastructure/ tests"
       if: type = pull_request
       os: linux
       python: "2.7"
       env: JOB=wptrunner_infrastructure SCRIPT=tools/ci/ci_wptrunner_infrastructure.sh
       addons:
         apt:
           packages:
-            - libnss3-tools
+            - fonts-liberation
             - libappindicator1
-            - fonts-liberation
+            - libnss3-tools
+            - pulseaudio
   exclude:
     - env:  # exclude empty env from the top-level above
   allow_failures:
     - env: JOB=build_css SCRIPT=css/build-css-testsuites.sh
 script:
   - ./tools/ci/run.sh
 cache:
   directories:
--- a/testing/web-platform/tests/2dcontext/META.yml
+++ b/testing/web-platform/tests/2dcontext/META.yml
@@ -1,7 +1,6 @@
 spec: https://html.spec.whatwg.org/multipage/canvas.html#2dcontext
 suggested_reviewers:
   - AmeliaBR
   - annevk
   - kenrussell
-  - jdashg
   - fserb
--- a/testing/web-platform/tests/2dcontext/tools/tests.yaml
+++ b/testing/web-platform/tests/2dcontext/tools/tests.yaml
@@ -193,17 +193,17 @@
   expected: size 300 60
 
 - meta: |
     cases = [
         ("zero", "0", 0),
         ("empty", "", None),
         ("onlyspace", "  ", None),
         ("space", "  100", 100),
-        ("whitespace", "\n\t\f100", 100),
+        ("whitespace", "\r\n\t\f100", 100),
         ("plus", "+100", 100),
         ("minus", "-100", None),
         ("octal", "0100", 100),
         ("hex", "0x100", 0),
         ("exp", "100e1", 100),
         ("decimal", "100.999", 100),
         ("percent", "100%", 100),
         ("em", "100em", 100),
@@ -230,21 +230,23 @@
         if exp == 0:
             expected = None # can't generate zero-sized PNGs for the expected image
 
         return code, testing, expected
 
     for name, string, exp in cases:
         code = ""
         code, testing, expected = gen(name, string, exp, code)
+        # We need to replace \r with &#xD; because \r\n gets converted to \n in the HTML parser.
+        htmlString = string.replace('\r', '&#xD;')
         tests.append( {
             "name": "size.attributes.parse.%s" % name,
             "desc": "Parsing of non-negative integers",
             "testing": testing,
-            "canvas": 'width="%s" height="%s"' % (string, string),
+            "canvas": 'width="%s" height="%s"' % (htmlString, htmlString),
             "code": code,
             "expected": expected
         } )
 
     for name, string, exp in cases:
         code = "canvas.setAttribute('width', %r);\ncanvas.setAttribute('height', %r);\n" % (string, string)
         code, testing, expected = gen(name, string, exp, code)
         tests.append( {
deleted file mode 100644
--- a/testing/web-platform/tests/IndexedDB/bindings-inject-key.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>IndexedDB: ES bindings - Inject a key into a value</title>
-<meta name="help" href="https://w3c.github.io/IndexedDB/#inject-key-into-value">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support.js"></script>
-<script>
-
-indexeddb_test(
-  (t, db) => {
-    db.createObjectStore('store');
-  },
-  (t, db) => {
-    const tx = db.transaction('store', 'readwrite');
-    const request = tx.objectStore('store').put(
-        'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']);
-
-    const setter_called = false;
-    Object.defineProperty(Object.prototype, '10', {
-      configurable: true,
-      set: t.step_func((value) => { setter_called = true; }),
-    });
-    request.onerror = t.unreached_func('request should not fail');
-    request.onsuccess = t.step_func(() => {
-      const result = request.result;
-      assert_false(setter_called,
-                   'Setter should not be called for key result.');
-      assert_true(
-          result.hasOwnProperty('10'),
-          'Result should have own-property overriding prototype setter.');
-      assert_equals(result[10], 'key',
-                    'Result should have expected property.');
-
-      delete Object.prototype['10'];
-      t.done();
-    });
-  },
-  'Returning keys to script should bypass prototype setters'
-);
-
-indexeddb_test(
-  (t, db) => {
-    db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
-  },
-  (t, db) => {
-    const tx = db.transaction('store', 'readwrite');
-    tx.objectStore('store').put({});
-    const request = tx.objectStore('store').get(1);
-
-    const setter_called = false;
-    Object.defineProperty(Object.prototype, 'id', {
-      configurable: true,
-      set: t.step_func(function(value) { setter_called = true; }),
-    });
-    request.onerror = t.unreached_func('request should not fail');
-    request.onsuccess = t.step_func(function() {
-        const result = request.result;
-      assert_false(setter_called,
-                   'Setter should not be called for key result.');
-      assert_true(
-          result.hasOwnProperty('id'),
-          'Result should have own-property overriding prototype setter.');
-      assert_equals(result.id, 1,
-                    'Own property should match primary key generator value');
-
-      delete Object.prototype['id'];
-      t.done();
-    });
-  },
-  'Returning values to script should bypass prototype setters'
-);
-
-indexeddb_test(
-  (t, db) => {
-    db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
-  },
-  (t, db) => {
-    const tx = db.transaction('store', 'readwrite');
-    tx.objectStore('store').put({});
-    const request = tx.objectStore('store').get(1);
-
-    Object.prototype.a = {b: {c: 'on proto'}};
-
-    request.onerror = t.unreached_func('request should not fail');
-    request.onsuccess = t.step_func(function() {
-      const result = request.result;
-      assert_true(result.hasOwnProperty('a'),
-                  'Result should have own-properties overriding prototype.');
-      assert_true(result.a.hasOwnProperty('b'),
-                  'Result should have own-properties overriding prototype.');
-      assert_true(result.a.b.hasOwnProperty('c'),
-                  'Result should have own-properties overriding prototype.');
-      assert_equals(result.a.b.c, 1,
-                    'Own property should match primary key generator value');
-      assert_equals(Object.prototype.a.b.c, 'on proto',
-                  'Prototype should not be modified');
-      t.done();
-    });
-  },
-  'Returning values to script should bypass prototype chain'
-);
-
-</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/bindings-inject-keys-bypass-setters.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>IndexedDB: ES bindings - Inject a key into a value - Keys bypass setters</title>
+<meta name="help"
+href="https://w3c.github.io/IndexedDB/#inject-key-into-value-keys-bypass-setters">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support-promises.js"></script>
+<script>
+
+promise_test(async t => {
+  const db = await createDatabase(t, db => {
+    db.createObjectStore('store');
+  });
+
+  let setter_called = false;
+  Object.defineProperty(Object.prototype, '10', {
+    configurable: true,
+    set: value => { setter_called = true; },
+  });
+  t.add_cleanup(() => { delete Object.prototype['10']; });
+
+  const tx = db.transaction('store', 'readwrite');
+  const result = await promiseForRequest(t, tx.objectStore('store').put(
+      'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']));
+
+  assert_false(setter_called,
+               'Setter should not be called for key result.');
+  assert_true(result.hasOwnProperty('10'),
+              'Result should have own-property overriding prototype setter.');
+  assert_equals(result[10], 'key',
+                'Result should have expected property.');
+}, 'Returning keys to script should bypass prototype setters');
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/bindings-inject-values-bypass-chain.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>IndexedDB: ES bindings - Inject a key into a value - Values bypass chain</title>
+<meta name="help"
+href="https://w3c.github.io/IndexedDB/#inject-key-into-value-values-bypass-chain">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support-promises.js"></script>
+<script>
+
+promise_test(async t => {
+  const db = await createDatabase(t, db => {
+    db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
+  });
+
+  Object.prototype.a = {b: {c: 'on proto'}};
+  t.add_cleanup(() => { delete Object.prototype.a; });
+
+  const tx = db.transaction('store', 'readwrite');
+  tx.objectStore('store').put({});
+  const result = await promiseForRequest(t, tx.objectStore('store').get(1));
+
+  assert_true(result.hasOwnProperty('a'),
+              'Result should have own-properties overriding prototype.');
+  assert_true(result.a.hasOwnProperty('b'),
+              'Result should have own-properties overriding prototype.');
+  assert_true(result.a.b.hasOwnProperty('c'),
+              'Result should have own-properties overriding prototype.');
+  assert_equals(result.a.b.c, 1,
+                'Own property should match primary key generator value');
+  assert_equals(Object.prototype.a.b.c, 'on proto',
+                'Prototype should not be modified');
+}, 'Returning values to script should bypass prototype chain');
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/bindings-inject-values-bypass-setters.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>IndexedDB: ES bindings - Inject a key into a value - Values bypass
+  setters</title>
+<meta name="help"
+href="https://w3c.github.io/IndexedDB/#inject-key-into-value-values-bypass-setters">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support-promises.js"></script>
+<script>
+
+promise_test(async t => {
+  const db = await createDatabase(t, db => {
+    db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
+  });
+
+  let setter_called = false;
+  Object.defineProperty(Object.prototype, 'id', {
+    configurable: true,
+    set: value => { setter_called = true; },
+  });
+  t.add_cleanup(() => { delete Object.prototype['id']; });
+
+  const tx = db.transaction('store', 'readwrite');
+  tx.objectStore('store').put({});
+  const result = await promiseForRequest(t, tx.objectStore('store').get(1));
+
+  assert_false(setter_called,
+               'Setter should not be called for key result.');
+  assert_true(result.hasOwnProperty('id'),
+              'Result should have own-property overriding prototype setter.');
+  assert_equals(result.id, 1,
+                'Own property should match primary key generator value');
+}, 'Returning values to script should bypass prototype setters');
+
+</script>
--- a/testing/web-platform/tests/WebIDL/META.yml
+++ b/testing/web-platform/tests/WebIDL/META.yml
@@ -1,6 +1,5 @@
 spec: https://heycam.github.io/webidl/
 suggested_reviewers:
   - domenic
-  - jensl
   - tobie
   - yuki3
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/WebIDL/ecmascript-binding/global-immutable-prototype.any.js
@@ -0,0 +1,25 @@
+// META: global=window,worker
+// META: title=Immutability of the global prototype chain
+
+const objects = [];
+setup(() => {
+  for (let object = self; object; object = Object.getPrototypeOf(object)) {
+    objects.push(object);
+  }
+});
+
+test(() => {
+  for (const object of objects) {
+    assert_throws(new TypeError(), () => {
+      Object.setPrototypeOf(object, {});
+    });
+  }
+}, "Setting to a different prototype");
+
+test(() => {
+  for (const object of objects) {
+    const expected = Object.getPrototypeOf(object);
+    Object.setPrototypeOf(object, expected);
+    assert_equals(Object.getPrototypeOf(object), expected);
+  }
+}, "Setting to the same prototype");
--- a/testing/web-platform/tests/accelerometer/META.yml
+++ b/testing/web-platform/tests/accelerometer/META.yml
@@ -1,7 +1,6 @@
 spec: https://w3c.github.io/accelerometer/
 suggested_reviewers:
   - zqzhang
-  - dontcallmedom
   - riju
   - Honry
   - rakuco
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/acid/acid2/px-reference.html
@@ -0,0 +1,272 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+ <head>
+  <title>The Second Acid Test (pixel-for-pixel reference version)</title>
+  <style type="text/css">
+    *
+    {
+        margin: 0;
+        padding: 0;
+    }
+
+    html
+    {
+        font: 12px sans-serif;
+
+        overflow: hidden;
+
+        color: red;
+        background: white;
+    }
+
+    #top
+    {
+        font: 2em / 24px sans-serif;
+
+        margin: 2em 3.5em 0;
+
+        text-align: left;
+        white-space: pre;
+
+        color: navy;
+    }
+
+    .picture
+    {
+        margin: 3em 1em 1em 6em;
+    }
+
+    .line
+    {
+        height: 1em;
+
+        border: 0 solid black;
+        background: yellow;
+    }
+
+    .one
+    {
+        width: 0;
+        margin-left: 5em;
+
+        border-width: 0 2em;
+    }
+
+    .two
+    {
+        width: 4em;
+        margin-left: 3em;
+
+        border-width: 0 2em;
+    }
+
+    .three
+    {
+        width: 8em;
+        margin-left: 2em;
+
+        border-width: 0 1em;
+    }
+
+    /* the eyes, in all their three-layer glory
+
+       these need to appear with both background layers as on hidpi displays
+       the two background layers don't just create a solid yellow background */
+    .eyes
+    {
+        position: relative;
+
+        width: 12em;
+        height: 2em;
+        margin-left: 1em;
+
+        background: red;
+    }
+
+    .eyes .lower
+    {
+        position: absolute;
+        z-index: 1; /* redundant, but make stacking explicit */
+
+        width: 9em;
+        height: 2em;
+        margin-left: 1em;
+
+        border-left: solid 1em yellow;
+        background: fixed url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D');
+    }
+
+    .eyes .upper
+    {
+        position: absolute;
+        z-index: 2; /* redundant, but make stacking explicit */
+
+        width: 10em;
+        height: 2em;
+        margin-left: 0;
+
+        border: solid 1em black;
+        border-width: 0 1em;
+        background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D') fixed 1px 0;
+    }
+
+    .eyes .img
+    {
+        position: absolute;
+        z-index: 3; /* redundant, but make stacking explicit */
+
+        width: 8em;
+        height: 2em;
+        margin-left: 2em;
+
+        background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAFy7sgCAAAGsUlEQVRo3u2ZbWwcZxHHf3s%2B7LNbO3ZjXBtowprGODRX0qpNQCjmJKuVKhMl1P2AkCwhFOIKkCBSm9IXavGFKAixIAECwkmWo5MrhRI3Ub40IEwQgp6aIDg3Cd6eEqyIHEteah%2B1E69vhw%2BZtTaX8704ZzkKjHS6271nZ56ZZ%2BY%2F%2F%2BdZKF%2FCwYshx3EkkggLsD1v4FQkEZZYLCbAKyG9%2Ba9EIsG6hnUAf8x74K3aUC3j4%2BM54HcsR2oAIomwZOezkv%2FnSHpYNh%2BNCmAE7xv94zvFdd1bHsjMZmQkPSxAJP%2B%2FfuBLwK54PC7JZFKAVJmzXLBt2w%2FMvcDLwIb8QS8CeJ4nkURYIomw7J%2FYJ8BvSiiXptGGxWds2%2Fa9%2Bnaxh%2BYAD%2Bgt04NDgABTpQY2cvvSFLzw86gWeBVwC8SzlOSv2YeBPfmDBoBHgKmR9LBEEmHZfDTqGykqfkUE0nA78BzQGfSgUeP3wNeTXwXg7MwZDhw4UHL6ra2ti79%2FOvljgG8AZ4H64Lhm4MvAocxsRppGG%2FxcXihlwLIs6R%2FfKV2HO%2F26uA94pdDYUKUZUU7W1RQYXA98Gnhaf5%2FXWX0HeAHYoQonqa4sZSOsSWMCWeC9Yko%2BCQwBe4E6oNc0Tc91XTl1%2BaTsn9gnI%2Blhyc5nZWxsrBIkKSbl2tiic3tW53YDEwOKaoFBrcOfqKee53lG9xsPMjV784r%2F4lO%2FpPvyJ9iyZcuvFSaXK5XYeAZ4CDgGvB3MS4B54LQuWYPeuy4iRFsevsXqpuYoqVQKIH2bK1CuDQNo11o4XUzh%2FcDWYIe1LEtyuZx4niee54njOGKapgfsqlL%2Bl2OjEXg8nxrc1dJ0h3hbtL%2BGCtz7KPBF4CuBe9uB15VafE8hr9qylI3HgG8C2%2FK7VyHZoJj7MrBRm30qFotJMpkU27YlHo%2F7Ha5a%2BV%2FKRkSJ4KuKRLVLKapTjB1SzAVIjY2NSXY%2BKyPpYdk%2FsU9OXT4pruv6BdZbBQfKsVGnvWlIe1VB6VQO8JxC1vZYLCbZ%2BaxsPhpdZDyRRFhG0sPiOE6ldKBg2lRg4xF1YCDIIIKN7DGgD3gH%2BBXwejKZfPrs2tPs%2FvPN2bKuYR1nd7xLKBSSJeqoXKnERjPwNWAG%2BLn2rZuM%2B4Tpml6vaWlp4eLcxVusZq5lCgVgOVKJjRqdX86ffL4D5wIoZACnTpw4wRMdT96i%2FImOJxERAs4uVyqxUacF%2FPdiCj%2BjdRBRGFtwXVdG0sPSdbhTmkYbpH98p2RmM2JZlig1vl0GWo4NQ%2Fn%2Bs5pKRXfwjweaxy7TND3HcRZbfC6X8xVPVQlGy7WxVWlO5XRXFXm6EZmrQuSXYyPE3SiVoEhE6Wyr0u2rumO6zv%2B21AFdQAswC1wCMuUCXCmyWQus103Qg8qlDO0lxwOb%2Fl4FiK3AB3VS%2FuKKLtK%2FgbeAnwG%2FvUODuRw%2FFrR0H1UC75fwu8oJ%2FhFsW5VIG%2FBUgEIN6Y65O4AHu4Ap0zQ9y7LEcZyb9lRBUHQcRyzL8unZVBW5bFWAvAp%2BhDQ2g4F47dUYtlU6obXA54DnVdFLekjUGGifh4AFy7LEdV3xj3X9I66m0QZpGm2QrsOd0j%2B%2BU0bSw5KZzYjrun6HWlAd961i4FfCj0aN1Usau%2Bc1lmuXPFwvAEumUut7tQQvAb%2FXb%2FT0bCAej9cODg7yt%2Bm%2F8q2%2F7OUHZ76PnZ1k2p0mJzlykmPancbOTnL0whHs7CQfb%2B5mx2d3sH79%2BtCRI0c6FeaOr9ICrIQfLvA%2B8BGNXxi4R6HrisJVUWrxAVW2oMFf0Aczim8o3kV6enowDIPjF9%2Fk%2BMU3S3rrjzMMg56eHr%2BxP7qKFbASfojG6kpeDGs1tiW53RxwWT%2Bin5q8w4xpQK5evQpAR30H7ZH2khNvj7TTUd8BgD4rqmu1ZKX8qNeY%2BfHz4zlXDgT5E8tpCTUq7XSBC4Euv8227TV9fX1E73%2BYtvo27BmbS9cvFVTY3bSRFza9yOcf6Gfmygy7d%2B%2Fm%2FPnzF4DvrsBLhnJlJfwIKXxv1PheAE4qK6p4H9AGbNKTuhngBPBPXYRe4IemaT5kWZbR19fHNbmGnZ1k4r3U4glDR30Hm5qjbGjsImJEOHbsGHv27JFz5869o0eFq01Jq%2BmHAXwI6FFKagMTgHM7GzFDS%2BoeLSMv7zjzC9x4Y7gxFovVDAwMEI1GaWlpWSzRVCrFwYMH%2FXfxZ4AfAa8B%2F7lDaGg1%2FQgp43lfK0yqtRMuJa3ceKe5DfgYsCYAZ2ngD8CfAkzqTpW7xY%2F%2FSznyX%2FVeUb2kVmX4AAAAAElFTkSuQmCC');
+    }
+
+    /* lines six to nine are the nose
+
+       (note these are scarcely changed from the test as border anti-aliasing
+       quickly differs) */
+    .nose
+    {
+        width: 12em;
+        height: 4em;
+        margin-left: 0;
+
+        border-width: 0 1em;
+    }
+
+    .nose > div
+    {
+        height: 0;
+        padding: 1em 1em 3em;
+
+        background: yellow;
+    }
+
+    .nose div div
+    {
+        width: 2em;
+        height: 2em;
+        margin-left: 4em;
+
+        background: red;
+    }
+
+    .nose div:hover div:before
+    {
+        border-bottom-color: blue;
+    }
+
+    .nose div:hover div:after
+    {
+        border-top-color: blue;
+    }
+
+    .nose div div:before
+    {
+        display: block;
+
+        height: 0;
+
+        content: '';
+
+        border-width: 1em;
+        border-style: none solid  solid;
+        border-color: red yellow black yellow;
+    }
+
+    .nose div div:after
+    {
+        display: block;
+
+        height: 0;
+
+        content: '';
+
+        border-width: 1em;
+        border-style: solid solid  none;
+        border-color: black yellow red yellow;
+    }
+
+    /* lines ten and eleven are the smile */
+    .ten
+    {
+        width: 10em;
+        margin-left: 1em;
+
+        border-width: 0 1em;
+    }
+
+    .ten div
+    {
+        width: 6em;
+        height: 1em;
+        margin-left: 1em;
+
+        border: solid black;
+        border-width: 0 1em;
+        background: transparent;
+    }
+
+    .eleven
+    {
+        width: 10em;
+        margin-left: 1em;
+
+        border-width: 0 1em;
+    }
+
+    .eleven div
+    {
+        width: 6em;
+        height: 1em;
+        margin-left: 2em;
+
+        background: black;
+    }
+
+    /* bottom of the face */
+    .twelve
+    {
+        width: 8em;
+        margin-left: 2em;
+
+        border-width: 0 1em;
+    }
+
+    .thirteen
+    {
+        width: 4em;
+        margin-left: 3em;
+
+        border-width: 0 2em;
+    }
+
+    .fourteen
+    {
+        width: 0;
+        margin-left: 5em;
+
+        border-width: 0 2em;
+    }
+  </style>
+ </head>
+ <body>
+  <h2 id="top">Hello World!</h2>
+  <div class="picture">
+   <div class="line one"></div>
+   <div class="line two"></div>
+   <div class="line three"></div>
+
+   <div class="eyes"><div class=lower></div><div class=upper></div><div class=img></div></div>
+
+   <div class="line nose"><div><div></div></div></div>
+
+   <div class="line ten"><div></div></div>
+   <div class="line eleven"><div></div></div>
+   <div class="line twelve"></div>
+   <div class="line thirteen"></div>
+   <div class="line fourteen"></div>
+  </div>
+ </body>
+</html>
old mode 100755
new mode 100644
old mode 100755
new mode 100644
--- a/testing/web-platform/tests/acid/acid2/reftest.html
+++ b/testing/web-platform/tests/acid/acid2/reftest.html
@@ -1,15 +1,25 @@
 <!doctype html>
+<html class=reftest-wait>
 <title>Acid2 reftest</title>
-<link rel="match" href="reference.html">
+<link rel="match" href="px-reference.html">
+<script src="/common/reftest-wait.js"></script>
 <style>
 * {
   margin: 0;
   padding: 0;
   border: 0;
 }
 iframe {
   width: 400px;
   height: 300px;
 }
 </style>
-<iframe src="test.html#top"></iframe>
+<script>
+function frameLoaded(frame) {
+  let fwin = frame.contentWindow;
+  let fdoc = frame.contentDocument;
+  fdoc.querySelector("#top").scrollIntoView();
+  takeScreenshot();
+}
+</script>
+<iframe src="test.html" onload="frameLoaded(this)"></iframe>
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
--- a/testing/web-platform/tests/ambient-light/META.yml
+++ b/testing/web-platform/tests/ambient-light/META.yml
@@ -1,7 +1,6 @@
 spec: https://w3c.github.io/ambient-light/
 suggested_reviewers:
   - zqzhang
-  - dontcallmedom
   - riju
   - rakuco
   - Honry
--- a/testing/web-platform/tests/animation-worklet/animation-worklet-inside-iframe.https.html
+++ b/testing/web-platform/tests/animation-worklet/animation-worklet-inside-iframe.https.html
@@ -43,15 +43,19 @@ async_test(t => {
       document.getElementById('main_worklet').textContent
     ).then(_ => {
       // Create an animation for duplicate animator.
       const target = document.getElementById('target');
       const animation = new WorkletAnimation('duplicate_animator', new KeyframeEffect(target, [{ opacity: 0 }], { duration: 1000 }));
       animation.play();
 
       assert_equals(data, '0.4');
-      waitForAsyncAnimationFrames(1).then(t.step_func_done(() => {
+
+      // wait until local times are synced back to the main thread.
+      waitForAnimationFrameWithCondition(_ => {
+        return getComputedStyle(target).opacity != '1';
+      }).then(t.step_func_done(() => {
         assert_equals(getComputedStyle(target).opacity, '0.5');
       }));
     });
   }
 }, 'Both main frame and iframe should update the opacity of their target');
 </script>
--- a/testing/web-platform/tests/animation-worklet/animator-animate.https.html
+++ b/testing/web-platform/tests/animation-worklet/animator-animate.https.html
@@ -11,12 +11,15 @@
 
 <script>
   promise_test(async t => {
     await registerConstantLocalTimeAnimator(500);
     const effect = new KeyframeEffect(target, [{ opacity: 0 }], { duration: 1000 });
     const animation = new WorkletAnimation('constant_time', effect);
     animation.play();
 
-    await waitForAsyncAnimationFrames(1);
+    // wait until local times are synced back to the main thread.
+    await waitForAnimationFrameWithCondition(_ => {
+      return getComputedStyle(target).opacity != '1';
+    });
     assert_equals(getComputedStyle(target).opacity, "0.5");
   }, "Simple worklet animation should output values at specified local time");
 </script>
\ No newline at end of file
--- a/testing/web-platform/tests/animation-worklet/animator-with-options.https.html
+++ b/testing/web-platform/tests/animation-worklet/animator-with-options.https.html
@@ -24,12 +24,15 @@
   promise_test(async t => {
     await runInAnimationWorklet(document.getElementById('animate_with_options').textContent);
     const target = document.getElementById('target');
     const effect = new KeyframeEffect(target, [{ opacity: 0 }], { duration: 1000 });
     const options = {'time': 500};
     const animation = new WorkletAnimation('test_animator', effect, document.timeline, options);
     animation.play();
 
-    await waitForAsyncAnimationFrames(1);
+    // wait until local times are synced back to the main thread.
+    await waitForAnimationFrameWithCondition(_ => {
+      return getComputedStyle(target).opacity != '1';
+    });
     assert_equals(getComputedStyle(target).opacity, "0.5");
   }, "Animator should be able to use options to update the animation");
 </script>
\ No newline at end of file
--- a/testing/web-platform/tests/animation-worklet/common.js
+++ b/testing/web-platform/tests/animation-worklet/common.js
@@ -11,16 +11,29 @@ function registerPassthroughAnimator() {
 function registerConstantLocalTimeAnimator(localTime) {
   return runInAnimationWorklet(`
     registerAnimator('constant_time', class {
       animate(currentTime, effect) { effect.localTime = ${localTime}; }
     });
   `);
 }
 
+// TODO(majidvp): This is used to sidestep a bug where we currently animate
+// with currentTime=NaN when scroll timeline is not active. Remove once we fix
+// http://crbug.com/937456
+function registerPassthroughExceptNaNAnimator() {
+  return runInAnimationWorklet(`
+    registerAnimator('passthrough_except_nan', class {
+      animate(currentTime, effect) {
+        if (Number.isNaN(currentTime)) return;
+        effect.localTime = currentTime;
+      }
+    });
+  `);
+}
 
 function runInAnimationWorklet(code) {
   return CSS.animationWorklet.addModule(
     URL.createObjectURL(new Blob([code], {type: 'text/javascript'}))
   );
 }
 
 function waitForAsyncAnimationFrames(count) {
--- a/testing/web-platform/tests/animation-worklet/playback-rate.https.html
+++ b/testing/web-platform/tests/animation-worklet/playback-rate.https.html
@@ -10,131 +10,344 @@
 // and current_time of animations. That's why it's needed to increase FP error
 // for comparing times in these tests.
 window.assert_times_equal = (actual, expected, description) => {
   assert_approx_equals(actual, expected, 0.002, description);
 };
 </script>
 <script src="/web-animations/testcommon.js"></script>
 <script src="common.js"></script>
+<style>
+  .scroller {
+    overflow: auto;
+    height: 100px;
+    width: 100px;
+  }
+  .contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
 <body>
 <div id="log"></div>
 <script>
 'use strict';
 
-function InstantiateWorkletAnimation(test) {
+function createWorkletAnimation(test) {
   const DURATION = 10000; // ms
-  const KEYFRAMES = { height : ['100px', '50px'] };
+  const KEYFRAMES = { transform: ['translateY(100px)', 'translateY(200px)'] };
   return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
         KEYFRAMES, DURATION), document.timeline);
 }
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const animation = InstantiateWorkletAnimation(t);
+function createScroller(test) {
+  var scroller = createDiv(test);
+  scroller.innerHTML = "<div class='contents'></div>";
+  scroller.classList.add('scroller');
+  return scroller;
+}
+
+function createScrollLinkedWorkletAnimation(test) {
+  const timeline = new ScrollTimeline({
+    scrollSource: createScroller(test),
+    timeRange: 1000
+  });
+  const DURATION = 10000; // ms
+  const KEYFRAMES = { transform: ['translateY(100px)', 'translateY(200px)'] };
+  return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
+        KEYFRAMES, DURATION), timeline);
+}
 
-  animation.playbackRate = 0.5;
-  animation.play();
-  assert_equals(animation.currentTime, 0,
-    'Zero current time is not affected by playbackRate.');
-}, 'Zero current time is not affected by playbackRate set while the animation is in idle state.');
+setup(setupAndRegisterTests, {explicit_done: true});
+
+function setupAndRegisterTests() {
+  registerPassthroughAnimator().then(() => {
+
+    promise_test(async t => {
+      const animation = createWorkletAnimation(t);
+
+      animation.playbackRate = 0.5;
+      animation.play();
+      assert_equals(animation.currentTime, 0,
+        'Zero current time is not affected by playbackRate.');
+    }, 'Zero current time is not affected by playbackRate set while the ' +
+       'animation is in idle state.');
+
+    promise_test(async t => {
+      const animation = createWorkletAnimation(t);
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const animation = InstantiateWorkletAnimation(t);
+      animation.play();
+      animation.playbackRate = 0.5;
+      assert_equals(animation.currentTime, 0,
+        'Zero current time is not affected by playbackRate.');
+    }, 'Zero current time is not affected by playbackRate set while the ' +
+       'animation is in play-pending state.');
+
+    promise_test(async t => {
+      const animation = createWorkletAnimation(t);
+      const playbackRate = 2;
+
+      animation.play();
+
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      // Make sure the current time is not Zero.
+      await waitForDocumentTimelineAdvance();
 
-  animation.play();
-  animation.playbackRate = 0.5;
-  assert_equals(animation.currentTime, 0,
-    'Zero current time is not affected by playbackRate.');
-}, 'Zero current time is not affected by playbackRate set while the animation is in play-pending state.');
+      // Set playback rate while the animation is playing.
+      const prevCurrentTime = animation.currentTime;
+      animation.playbackRate = playbackRate;
+
+      assert_times_equal(animation.currentTime, prevCurrentTime,
+        'The current time should stay unaffected by setting playback rate.');
+    }, 'Non zero current time is not affected by playbackRate set while the ' +
+       'animation is in play state.');
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const animation = InstantiateWorkletAnimation(t);
-  const playbackRate = 2;
+    promise_test(async t => {
+      const animation = createWorkletAnimation(t);
+      const playbackRate = 0.2;
 
-  animation.play();
+      animation.play();
+
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
 
-  await waitForNextFrame();
+      // Set playback rate while the animation is playing.
+      const prevCurrentTime = animation.currentTime;
+      const prevTimelineTime = document.timeline.currentTime;
+      animation.playbackRate = playbackRate;
+
+      // Play the animation some more.
+      await waitForDocumentTimelineAdvance();
+
+      const currentTime = animation.currentTime;
+      const currentTimelineTime = document.timeline.currentTime;
 
-  // Set playback rate while the animation is playing.
-  const prevCurrentTime = animation.currentTime;
-  animation.playbackRate = playbackRate;
+      assert_times_equal(
+        currentTime - prevCurrentTime,
+        (currentTimelineTime - prevTimelineTime) * playbackRate,
+        'The current time should increase 0.2 times faster than timeline.');
+    }, 'The playback rate affects the rate of progress of the current time.');
+
+    promise_test(async t => {
+      const animation = createWorkletAnimation(t);
+      const playbackRate = 2;
 
-  assert_times_equal(animation.currentTime, prevCurrentTime,
-    'The current time should stay unaffected by setting playback rate.');
-}, 'Non zero current time is not affected by playbackRate set while the animation is in play state.');
+      // Set playback rate while the animation is in 'idle' state.
+      animation.playbackRate = playbackRate;
+      const prevTimelineTime = document.timeline.currentTime;
+      animation.play();
+
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      await waitForDocumentTimelineAdvance();
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const animation = InstantiateWorkletAnimation(t);
-  const playbackRate = 2;
-
-  animation.play();
+      const currentTime = animation.currentTime;
+      const timelineTime = document.timeline.currentTime;
+      assert_times_equal(
+        currentTime,
+        (timelineTime - prevTimelineTime) * playbackRate,
+        'The current time should increase two times faster than timeline.');
+    }, 'The playback rate set before the animation started playing affects ' +
+       'the rate of progress of the current time');
 
-  await waitForNextFrame();
+    promise_test(async t => {
+      const timing = { duration: 100,
+                      easing: 'linear',
+                      fill: 'none',
+                      iterations: 1
+                     };
+      // TODO(crbug.com/937382): Currently composited
+      // workletAnimation.currentTime and the corresponding
+      // effect.getComputedTiming().localTime are computed by main and
+      // compositing threads respectively and, as a result, don't match.
+      // To workaround this limitation we compare the output of two identical
+      // animations that only differ in playback rate. The expectation is that
+      // their output matches after taking their playback rates into
+      // consideration. This works since these two animations start at the same
+      // time on the same thread.
+      // Once the issue is fixed, this test needs to change so expected
+      // effect.getComputedTiming().localTime is compared against
+      // workletAnimation.currentTime.
+      const target = createDiv(t);
+      const targetRef = createDiv(t);
+      const keyframeEffect = new KeyframeEffect(
+        target, { opacity: [1, 0] }, timing);
+      const keyframeEffectRef = new KeyframeEffect(
+        targetRef, { opacity: [1, 0] }, timing);
+      const animation = new WorkletAnimation(
+        'passthrough', keyframeEffect, document.timeline);
+      const animationRef = new WorkletAnimation(
+        'passthrough', keyframeEffectRef, document.timeline);
+      const playbackRate = 2;
+      animation.playbackRate = playbackRate;
+      animation.play();
+      animationRef.play();
 
-  // Set playback rate while the animation is playing
-  const prevCurrentTime = animation.currentTime;
-  const prevTimelineTime = document.timeline.currentTime;
-  animation.playbackRate = playbackRate;
-
-  // Play the animation some more.
-  await waitForNextFrame();
+      // wait until local times are synced back to the main thread.
+      await waitForAnimationFrameWithCondition(_ => {
+        return getComputedStyle(target).opacity != '1';
+      });
 
-  const currentTime = animation.currentTime;
-  const currentTimelineTime = document.timeline.currentTime;
+      assert_times_equal(
+        keyframeEffect.getComputedTiming().localTime,
+        keyframeEffectRef.getComputedTiming().localTime * playbackRate,
+        'When playback rate is set on WorkletAnimation, the underlying ' +
+        'effect\'s timing should be properly updated.');
 
-  assert_times_equal(currentTime - prevCurrentTime, (currentTimelineTime - prevTimelineTime) * playbackRate,
-    'The current time should increase two times faster than timeline.');
+      assert_approx_equals(
+        1 - Number(getComputedStyle(target).opacity),
+        (1 - Number(getComputedStyle(targetRef).opacity)) * playbackRate,
+        0.001,
+        'When playback rate is set on WorkletAnimation, the underlying effect' +
+        ' should produce correct visual result.');
+    }, 'When playback rate is updated, the underlying effect is properly ' +
+       'updated with the current time of its WorkletAnimation and produces ' +
+       'correct visual result.');
 
-}, 'The playback rate affects the rate of progress of the current time.');
+    promise_test(async t => {
+      const animation = createScrollLinkedWorkletAnimation(t);
+      const scroller = animation.timeline.scrollSource;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const timeRange = animation.timeline.timeRange;
+      scroller.scrollTop = 0.2 * maxScroll;
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const animation = InstantiateWorkletAnimation(t);;
-  const playbackRate = 2;
+      animation.playbackRate = 0.5;
+      animation.play();
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      assert_equals(animation.currentTime, 0.2 * timeRange * 0.5,
+        'Initial current time is scaled by playbackRate.');
+    }, 'Initial current time is scaled by playbackRate set while ' +
+       'scroll-linked animation is in idle state.');
+
+    promise_test(async t => {
+      const animation = createScrollLinkedWorkletAnimation(t);
+      const scroller = animation.timeline.scrollSource;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const timeRange = animation.timeline.timeRange;
+      scroller.scrollTop = 0.2 * maxScroll;
 
-  // Set playback rate while the animation is in 'idle' state.
-  animation.playbackRate = playbackRate;
-  animation.play();
-  const prevTimelineTime = document.timeline.currentTime;
+      animation.play();
+      animation.playbackRate = 0.5;
 
-  await waitForNextFrame();
+      assert_equals(animation.currentTime, 0.2 * timeRange,
+        'Initial current time is not affected by playbackRate.');
+    }, 'Initial current time is not affected by playbackRate set while '+
+       'scroll-linked animation is in play-pending state.');
+
+    promise_test(async t => {
+      const animation = createScrollLinkedWorkletAnimation(t);
+      const scroller = animation.timeline.scrollSource;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const timeRange = animation.timeline.timeRange;
+      const playbackRate = 2;
 
-  const currentTime = animation.currentTime;
-  const timelineTime = document.timeline.currentTime;
-  assert_times_equal(currentTime, (timelineTime - prevTimelineTime) * playbackRate,
-    'The current time should increase two times faster than timeline.');
-}, 'The playback rate set before the animation started playing affects the ' +
-   'rate of progress of the current time');
+      animation.play();
+      scroller.scrollTop = 0.2 * maxScroll;
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      // Set playback rate while the animation is playing.
+      animation.playbackRate = playbackRate;
+      assert_times_equal(animation.currentTime, 0.2 * timeRange,
+        'The current time should stay unaffected by setting playback rate.');
+    }, 'The current time is not affected by playbackRate set while the ' +
+       'scroll-linked animation is in play state.');
+
+    promise_test(async t => {
+      const animation = createScrollLinkedWorkletAnimation(t);
+      const scroller = animation.timeline.scrollSource;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const playbackRate = 2;
+      const timeRange = animation.timeline.timeRange;
+
+      animation.play();
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      scroller.scrollTop = 0.1 * maxScroll;
 
-promise_test(async t => {
-  await registerPassthroughAnimator();
-  const timing = { duration: 100,
-                   easing: 'linear',
-                   fill: 'none',
-                   iterations: 1
-                 };
-  const target = createDiv(t);
-  const keyframeEffect = new KeyframeEffect(target, { opacity: [0, 1] }, timing);
-  const animation = new WorkletAnimation('passthrough', keyframeEffect, document.timeline);
-  const playbackRate = 2;
+      // Set playback rate while the animation is playing.
+      animation.playbackRate = playbackRate;
+
+      scroller.scrollTop = 0.2 * maxScroll;
+
+      assert_times_equal(
+        animation.currentTime - 0.1 * timeRange, 0.1 * timeRange * playbackRate,
+        'The current time should increase twice faster than scroll timeline.');
+    }, 'Scroll-linked animation playback rate affects the rate of progress ' +
+       'of the current time.');
+
+    promise_test(async t => {
+      const animation = createScrollLinkedWorkletAnimation(t);
+      const scroller = animation.timeline.scrollSource;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const timeRange = animation.timeline.timeRange;
+      const playbackRate = 2;
+
+      // Set playback rate while the animation is in 'idle' state.
+      animation.playbackRate = playbackRate;
+      animation.play();
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+      scroller.scrollTop = 0.2 * maxScroll;
+
+      assert_times_equal(animation.currentTime, 0.2 * timeRange * playbackRate,
+        'The current time should increase two times faster than timeline.');
+    }, 'The playback rate set before scroll-linked animation started playing ' +
+       'affects the rate of progress of the current time');
 
-  animation.play();
-  animation.playbackRate = playbackRate;
-
-  await waitForNextFrame();
-
-  assert_times_equal(keyframeEffect.getComputedTiming().localTime, animation.currentTime,
-    'When playback rate is set on WorkletAnimation, the underlying effect\'s timing should be properly updated.');
+    promise_test(async t => {
+      const scroller = createScroller(t);
+      const timeline = new ScrollTimeline({
+        scrollSource: scroller,
+        timeRange: 1000
+      });
+      const timing = { duration: 1000,
+                      easing: 'linear',
+                      fill: 'none',
+                      iterations: 1
+                    };
+      const target = createDiv(t);
+      const keyframeEffect = new KeyframeEffect(
+        target, { opacity: [1, 0] }, timing);
+      const animation = new WorkletAnimation(
+        'passthrough', keyframeEffect, timeline);
+      const playbackRate = 2;
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      const timeRange = timeline.timeRange;
 
-  assert_approx_equals(Number(getComputedStyle(target).opacity),
-    animation.currentTime / 100, 0.001,
-    'When playback rate is set on WorkletAnimation, the underlying effect should produce correct visual result.');
+      animation.play();
+      animation.playbackRate = playbackRate;
+      await waitForAnimationFrameWithCondition(_=> {
+        return animation.playState == "running"
+      });
+
+      scroller.scrollTop = 0.2 * maxScroll;
+      // wait until local times are synced back to the main thread.
+      await waitForAnimationFrameWithCondition(_ => {
+        return getComputedStyle(target).opacity != '1';
+      });
 
-}, 'When playback rate is updated, the underlying effect is properly updated ' +
-   'with the current time of its WorkletAnimation and produces correct ' +
-   'visual result.');
-
+      assert_times_equal(
+        keyframeEffect.getComputedTiming().localTime,
+        0.2 * timeRange * playbackRate,
+        'When playback rate is set on WorkletAnimation, the underlying ' +
+        'effect\'s timing should be properly updated.');
+      assert_approx_equals(
+        Number(getComputedStyle(target).opacity),
+        1 - 0.2 * timeRange * playbackRate / 1000, 0.001,
+        'When playback rate is set on WorkletAnimation, the underlying ' +
+        'effect should produce correct visual result.');
+    }, 'When playback rate is updated, the underlying effect is properly ' +
+       'updated with the current time of its scroll-linked WorkletAnimation ' +
+       'and produces correct visual result.');
+    done();
+  });
+}
 </script>
 </body>
\ No newline at end of file
--- a/testing/web-platform/tests/animation-worklet/resources/animator-iframe.html
+++ b/testing/web-platform/tests/animation-worklet/resources/animator-iframe.html
@@ -28,13 +28,17 @@ registerAnimator("duplicate_animator", c
 runInAnimationWorklet(
   document.getElementById('iframe_worklet').textContent
 ).then(_ => {
   const target = document.getElementById('iframe_target');
   // Only create an animation for iframe_animator.
   const effect = new KeyframeEffect(target, [{ opacity: 0 }], { duration: 1000 });
   const animation = new WorkletAnimation('iframe_animator', effect);
   animation.play();
-  waitForAnimationFrames(2).then(_ => {
+
+  // wait until local times are synced back to the main thread.
+  waitForAnimationFrameWithCondition(_ => {
+    return getComputedStyle(target).opacity != '1';
+  }).then(_ => {
     window.parent.postMessage(getComputedStyle(target).opacity, '*');
   });
  });
 </script>
--- a/testing/web-platform/tests/animation-worklet/scroll-timeline-writing-modes.https.html
+++ b/testing/web-platform/tests/animation-worklet/scroll-timeline-writing-modes.https.html
@@ -52,24 +52,25 @@ function createAndPlayTestAnimation(elem
         duration: 1000,
       });
 
   const timeline = new ScrollTimeline({
     scrollSource: elements.scroller,
     timeRange: 1000,
     orientation: timeline_orientation
   });
-  const animation = new WorkletAnimation('passthrough', effect, timeline);
+  const animation = new WorkletAnimation('passthrough_except_nan', effect, timeline);
   animation.play();
+  return animation;
 }
 
 setup(setupAndRegisterTests, {explicit_done: true});
 
 function setupAndRegisterTests() {
-  registerPassthroughAnimator().then(() => {
+  registerPassthroughExceptNaNAnimator().then(() => {
     // Note that block horizontal-tb is tested implicitly in the basic
     // ScrollTimeline tests (as it is the default).
     async_test(
         block_vertical_lr,
         'A block ScrollTimeline should produce the correct current time for vertical-lr');
     async_test(
         block_vertical_rl,
         'A block ScrollTimeline should produce the correct current time for vertical-rl');
@@ -85,84 +86,84 @@ function setupAndRegisterTests() {
         inline_vertical_writing_mode_rtl,
         'An inline ScrollTimeline should produce the correct current time for vertical writing mode and direction: rtl');
     done();
   });
 }
 
 function block_vertical_lr(t) {
   const elements = createTestDOM(true, 'vertical-lr', 'ltr');
-  createAndPlayTestAnimation(elements, 'block');
+  const animation = createAndPlayTestAnimation(elements, 'block');
 
   // Move the scroller to the 25% point.
   const maxScroll =
       elements.scroller.scrollWidth - elements.scroller.clientWidth;
   elements.scroller.scrollLeft = 0.25 * maxScroll;
 
-  waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
+  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
     assert_equals(
         getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
   }));
 }
 
 function block_vertical_rl(t) {
   const elements = createTestDOM(true, 'vertical-rl', 'ltr');
-  createAndPlayTestAnimation(elements, 'block');
+  const animation = createAndPlayTestAnimation(elements, 'block');
 
   // Move the scroller to the 75% point. Since it is vertical-rl, this is
   // equivalent to the 25% point for the ScrollTimeline.
   const maxScroll =
       elements.scroller.scrollWidth - elements.scroller.clientWidth;
   elements.scroller.scrollLeft = 0.75 * maxScroll;
 
-  waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
+  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
     assert_equals(
         getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
   }));
 }
 
 function inline_horizontal_tb_rtl(t) {
   const elements = createTestDOM(true, 'horizontal-tb', 'rtl');
-  createAndPlayTestAnimation(elements, 'inline');
+  const animation = createAndPlayTestAnimation(elements, 'inline');
 
   // Move the scroller to the 75% point. Since it is direction: rtl, this is
   // equivalent to the 25% point for the ScrollTimeline.
   const maxScroll =
       elements.scroller.scrollWidth - elements.scroller.clientWidth;
   elements.scroller.scrollLeft = 0.75 * maxScroll;
 
-  waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
+  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
     assert_equals(
         getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
   }));
 }
 
 function inline_vertical_writing_mode_ltr(t) {
   const elements = createTestDOM(false, 'vertical-lr', 'ltr');
-  createAndPlayTestAnimation(elements, 'inline');
+  const animation = createAndPlayTestAnimation(elements, 'inline');
 
   // Move the scroller to the 25% point.
   const maxScroll =
       elements.scroller.scrollHeight - elements.scroller.clientHeight;
   elements.scroller.scrollTop = 0.25 * maxScroll;
 
-  waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
+  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
     assert_equals(
         getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
   }));
 }
 
 function inline_vertical_writing_mode_rtl(t) {
   const elements = createTestDOM(false, 'vertical-lr', 'rtl');
-  createAndPlayTestAnimation(elements, 'inline');
+  const animation = createAndPlayTestAnimation(elements, 'inline');
 
   // Move the scroller to the 75% point. Since this is a vertical writing mode
   // and direction: rtl, this is 25% of the ScrollTimeline currentTime.
   const maxScroll =
       elements.scroller.scrollHeight - elements.scroller.clientHeight;
   elements.scroller.scrollTop = 0.75 * maxScroll;
 
-  waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
+  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
     assert_equals(
         getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
   }));
 }
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-cancel-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Reference for Canceling a playing WorkletAnimation should remove the effect</title>
+<style>
+#box {
+  width: 100px;
+  height: 100px;
+  background-color: blue;
+}
+</style>
+
+<div id="box"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-cancel.https.html
@@ -0,0 +1,45 @@
+<html class="reftest-wait">
+<title>Canceling a playing WorkletAnimation should remove the effect</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Canceling a playing animation should remove the effect">
+<link rel="match" href="worklet-animation-cancel-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: blue;
+  }
+</style>
+
+<div id="box"></div>
+
+<script>
+  registerConstantLocalTimeAnimator(500).then(_ => {
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+        {transform: 'translateY(0)'},
+        {transform: 'translateY(200px)'}
+      ], {
+        duration: 1000,
+        iterations: Infinity
+      }
+    );
+
+    const animation = new WorkletAnimation('constant_time', effect);
+    animation.play();
+
+    waitForAsyncAnimationFrames(1).then(_ => {
+      // Canceling a playing animation should remove the effect.
+      animation.cancel();
+      waitForAsyncAnimationFrames(1).then(_ => {
+        takeScreenshot();
+      });
+    });
+  });
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-creation.https.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<title>Verify that WorkletAnimation is correctly created</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+
+<style>
+  .scroller {
+    height: 100px;
+    width: 100px;
+    overflow: scroll;
+  }
+  .content {
+    height: 500px;
+    width: 500px;
+  }
+</style>
+
+<script>
+function CreateKeyframeEffect(element) {
+  return new KeyframeEffect(
+      element,
+      [
+        { transform: 'translateY(0%)' },
+        { transform: 'translateY(100%)' }
+      ],
+      { duration: 3000, fill: 'forwards' }
+  );
+}
+</script>
+<script id="simple_animate" type="text/worklet">
+  registerAnimator("test-animator", class {
+    animate(currentTime, effect) {}
+  });
+</script>
+
+<div id='element'></div>
+<div id='element2'></div>
+<div class='scroller'>
+  <div class='content'></div>
+</div>
+
+<script>
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+    let workletAnimation = new WorkletAnimation('test-animator', effect);
+    assert_equals(workletAnimation.playState, 'idle');
+    assert_equals(workletAnimation.timeline, document.timeline);
+  }, 'WorkletAnimation creation without timeline should use default documentation timeline');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+    let workletAnimation = new WorkletAnimation('test-animator', effect);
+    assert_equals(workletAnimation.playState, 'idle');
+  }, 'WorkletAnimation creation with timeline should work');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+    let options = { my_param: 'foo', my_other_param: true };
+    let workletAnimation = new WorkletAnimation(
+        'test-animator', effect, document.timeline, options);
+    assert_equals(workletAnimation.playState, 'idle');
+  }, 'WorkletAnimation creation with timeline and options should work');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+    let scroller = document.querySelector('.scroller');
+    let scrollTimeline = new ScrollTimeline(
+        { scrollSource: scroller, timeRange: 100, orientation: 'inline' });
+    let workletAnimation = new WorkletAnimation(
+        'test-animator', effect, scrollTimeline);
+    assert_equals(workletAnimation.playState, 'idle');
+  }, 'ScrollTimeline is a valid timeline for a WorkletAnimation');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let constructorFunc = function() { new WorkletAnimation(
+        'test-animator', []); };
+    assert_throws('NotSupportedError', constructorFunc);
+  }, 'If there are no effects specified, object construction should fail');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+
+    let otherDoc = document.implementation.createHTMLDocument();
+    let otherElement = otherDoc.createElement('div');
+    otherDoc.body.appendChild(otherElement);
+    let otherEffect = CreateKeyframeEffect(otherElement);
+
+    let constructorFunc = function() { new WorkletAnimation(
+        'test-animator', [ effect, otherEffect ]); };
+    assert_throws('NotSupportedError', constructorFunc);
+  }, 'If the effects are from different documents, object construction should fail');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    // TODO(crbug.com/781816): Allow KeyframeEffects with no target in AnimationWorklet.
+    let effect = CreateKeyframeEffect(null);
+    let effect2 = CreateKeyframeEffect(document.querySelector('#element'));
+
+    let constructorFunc = function() { new WorkletAnimation(
+        'test-animator', [ effect, effect2 ]); };
+    assert_throws('NotSupportedError', constructorFunc);
+
+    let constructorFunc2 = function() { new WorkletAnimation(
+        'test-animator', [ effect2, effect ]); };
+    assert_throws('NotSupportedError', constructorFunc2);
+  }, 'If an effect has no target, object construction should fail');
+
+  promise_test(async t => {
+    await runInAnimationWorklet(document.getElementById('simple_animate').textContent);
+    let effect = CreateKeyframeEffect(document.querySelector('#element'));
+    let constructorFunc = function() {
+        new WorkletAnimation('unregistered-animator', effect);
+    };
+    assert_throws('InvalidStateError', constructorFunc);
+  }, 'Constructing worklet animation for unregisested animator should throw');
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-duration-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Reference for WorkletAnimation should continue to be in effect forever, even if its duration is passed</title>
+<style>
+#box {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  transform: translateY(100px);
+}
+</style>
+
+<div id="box"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-duration.https.html
@@ -0,0 +1,40 @@
+<html>
+<title>WorkletAnimation should continue to be in effect forever, even if its duration is passed</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<link rel="match" href="worklet-animation-duration-ref.html">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+
+<div id="box"></div>
+
+<script>
+  promise_test(async t => {
+    await registerConstantLocalTimeAnimator(0.5);
+
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+        {transform: 'translateY(0px)' },
+        {transform: 'translateY(200px)' }
+      ], {
+        duration: 1,
+      }
+    );
+
+    const animation = new WorkletAnimation('constant_time', effect);
+    animation.play();
+
+    let expected_transform = "matrix(1, 0, 0, 1, 0, 100)";
+    await waitForAnimationFrameWithCondition(_ => {
+      return getComputedStyle(box).transform == expected_transform;
+    });
+
+    // The animation is specified to last for 1 millisecond
+    await new Promise(resolve => step_timeout(resolve, 500));
+
+    assert_equals(getComputedStyle(document.getElementById("box")).transform, expected_transform);
+  }, "WorkletAnimation should continue to be in effect forever, even if its duration is passed");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-start-delay-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Reference for WorkletAnimation should respect delay given in options</title>
+<style>
+.box {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+}
+</style>
+
+<div class="box"></div>
+<div style="transform: translateX(100px);" class="box"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-start-delay.https.html
@@ -0,0 +1,64 @@
+<html class="reftest-wait">
+<title>WorkletAnimation should respect delay given in options</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Worklet Animation should respect delay given in options">
+<link rel="match" href="worklet-animation-start-delay-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  .box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+</style>
+
+<div id="t0" class="box"></div>
+<div id="t1" class="box"></div>
+<div id="out"></div>
+<script id="visual_update"  type="text/worklet">
+  registerAnimator("t0_animator", class {
+    animate(currentTime, effect) {
+      effect.localTime = 500;
+    }
+  });
+
+  registerAnimator("t1_animator", class {
+    animate(currentTime, effect) {
+      effect.localTime = 5500;
+    }
+  });
+</script>
+
+<script>
+  runInAnimationWorklet(
+    document.getElementById('visual_update').textContent
+  ).then(()=>{
+    const keyframes = [
+      {transform: 'translateX(0)' },
+      {transform: 'translateX(200px)' }
+    ];
+    const options = {
+      duration: 1000,
+      delay: 5000,
+    };
+
+    const $t0 = document.getElementById('t0');
+    const $t0_effect = new KeyframeEffect($t0, keyframes, options);
+    const $t0_animation = new WorkletAnimation('t0_animator', $t0_effect);
+
+    const $t1 = document.getElementById('t1');
+    const $t1_effect = new KeyframeEffect($t1, keyframes, options);
+    const $t1_animation = new WorkletAnimation('t1_animator', $t1_effect);
+
+    $t0_animation.play();
+    $t1_animation.play();
+
+    waitForAsyncAnimationFrames(1).then(_ => {
+      takeScreenshot();
+    });
+  });
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-non-ascii-name-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Reference for WorkletAnimation name should accept non-ASCII characters</title>
+<style>
+.box {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+}
+</style>
+
+<div style="transform: translateX(50px);" class="box"></div>
+<div style="transform: translateX(150px);" class="box"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-non-ascii-name.https.html
@@ -0,0 +1,59 @@
+<html class="reftest-wait">
+<title>WorkletAnimation name should accept non-ASCII characters</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Worklet Animation name should accept non-ASCII characters">
+<link rel="match" href="worklet-animation-with-non-ascii-name-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  .box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+</style>
+
+<div id="t0" class="box"></div>
+<div id="t1" class="box"></div>
+<script id="visual_update"  type="text/worklet">
+  registerAnimator('bob', class {
+    animate(currentTime, effect) {
+      effect.localTime = 250;
+    }
+  });
+  registerAnimator('東京', class {
+    animate(currentTime, effect) {
+      effect.localTime = 750;
+    }
+  });
+</script>
+<script>
+  runInAnimationWorklet(
+    document.getElementById('visual_update').textContent
+  ).then(() => {
+    const keyframes = [
+      {transform: 'translateX(0)' },
+      {transform: 'translateX(200px)' }
+    ];
+    const options = {
+      duration: 1000
+    };
+    const $t0 = document.getElementById('t0');
+    const $t0_effect = new KeyframeEffect($t0, keyframes, options);
+    const $t0_animation = new WorkletAnimation('bob', $t0_effect);
+
+    const $t1 = document.getElementById('t1');
+    const $t1_effect = new KeyframeEffect($t1, keyframes, options);
+    const $t1_animation = new WorkletAnimation('東京', $t1_effect);
+
+    $t0_animation.play();
+    $t1_animation.play();
+
+    waitForAsyncAnimationFrames(1).then(_ => {
+      takeScreenshot();
+    });
+  });
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html
@@ -0,0 +1,77 @@
+<html class="reftest-wait">
+<title>Scroll timeline with WorkletAnimation and transition from display:none to display:block</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Scroll timeline should properly handle going from display:none to display:block">
+<link rel="match" href="worklet-animation-with-scroll-timeline-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+
+  #scroller {
+    overflow: auto;
+    height: 100px;
+    width: 100px;
+  }
+
+  .removed {
+    display: none;
+  }
+
+  #contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+<div id="scroller">
+  <div id="contents"></div>
+</div>
+
+<script>
+  registerPassthroughAnimator().then(()=>{
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+      { transform: 'translateY(0)', opacity: 1 },
+      { transform: 'translateY(200px)', opacity: 0 }
+      ], {
+        duration: 1000,
+      }
+    );
+
+    const scroller = document.getElementById('scroller');
+    scroller.classList.add('removed');
+    const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
+    const animation = new WorkletAnimation('passthrough', effect, timeline);
+    animation.play();
+
+    // Ensure that the WorkletAnimation will have been started on the compositor.
+    waitForAsyncAnimationFrames(1).then(_ => {
+      // Now return the scroller to the world, which will cause it to be composited
+      // and the animation should update on the compositor side.
+      scroller.classList.remove('removed');
+      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+      scroller.scrollTop = 0.5 * maxScroll;
+
+      waitForAsyncAnimationFrames(1).then(_ => {
+        takeScreenshot();
+      });
+    });
+  });
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Scroll timeline with WorkletAnimation using a scroller with overflow hidden</title>
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+    transform: translate(0, 100px);
+    opacity: 0.5;
+    will-change: transform; /* force compositing */
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+
+  #scroller {
+    overflow: hidden;
+    height: 100px;
+    width: 100px;
+    will-change: transform; /* force compositing */
+  }
+
+  #contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+<div id="scroller">
+  <div id="contents"></div>
+</div>
+
+<script>
+  window.addEventListener('load', function() {
+    // Move the scroller to halfway.
+    const scroller = document.getElementById("scroller");
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+  });
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html
@@ -0,0 +1,68 @@
+<html class="reftest-wait">
+<title>Scroll timeline with WorkletAnimation using a scroller with overflow hidden</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Worklet animation correctly updates values when using a overflow: hidden on the scroller being used as the source for the ScrollTimeline">
+<link rel="match" href="worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+
+  #scroller {
+    overflow: hidden;
+    height: 100px;
+    width: 100px;
+  }
+
+  #contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+<div id="scroller">
+  <div id="contents"></div>
+</div>
+
+<script>
+  registerPassthroughAnimator().then(_ => {
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+        {transform: 'translateY(0)', opacity: 1},
+        {transform: 'translateY(200px)', opacity: 0}
+      ], {
+        duration: 1000,
+      }
+    );
+
+    const scroller = document.getElementById('scroller');
+    const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
+    const animation = new WorkletAnimation('passthrough', effect, timeline);
+    animation.play();
+
+    // Move the scroller to the halfway point.
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+    waitForAnimationFrameWithCondition(_ => {
+      return getComputedStyle(box).transform != 'matrix(1, 0, 0, 1, 0, 0)';
+    }).then(_ => {
+      takeScreenshot();
+    });
+  });
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Reference for Animation Worklet with scroll timeline tests</title>
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+    transform: translate(0, 100px);
+    opacity: 0.5;
+    will-change: transform; /* force compositing */
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+
+  #scroller {
+    overflow: auto;
+    height: 100px;
+    width: 100px;
+    will-change: transform; /* force compositing */
+  }
+
+  #contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+<div id="scroller">
+  <div id="contents"></div>
+</div>
+
+<script>
+  window.addEventListener('load', function() {
+    // Move the scroller to halfway.
+    const scroller = document.getElementById("scroller");
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+  });
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Reference for Scroll timeline with WorkletAnimation using the root scroller</title>
+<style>
+  html {
+    min-height: 100%;
+    min-width: 100%;
+    padding-bottom: 100px;
+    padding-right: 100px;
+  }
+
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+    transform: translate(0, 100px);
+    opacity: 0.5;
+    will-change: transform; /* force compositing */
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+
+<script>
+  window.addEventListener('load', function() {
+    // Move the scroller to halfway.
+    const scroller = document.scrollingElement;
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+  });
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html
@@ -0,0 +1,62 @@
+<html class="reftest-wait">
+<title>Scroll timeline with WorkletAnimation using the root scroller</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Worklet animation correctly updates values when using the root scroller as the source for the ScrollTimeline">
+<link rel="match" href="worklet-animation-with-scroll-timeline-root-scroller-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  html {
+    min-height: 100%;
+    min-width: 100%;
+    padding-bottom: 100px;
+    padding-right: 100px;
+  }
+
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+
+<script>
+  registerPassthroughAnimator().then(()=>{
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+        {transform: 'translateY(0)', opacity: 1},
+        {transform: 'translateY(200px)', opacity: 0}
+      ], {
+        duration: 1000,
+      }
+    );
+
+    const scroller = document.scrollingElement;
+    const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
+    const animation = new WorkletAnimation('passthrough', effect, timeline);
+    animation.play();
+
+    // Move the scroller to the halfway point.
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+
+    waitForAnimationFrameWithCondition(_ => {
+      return getComputedStyle(box).transform != 'matrix(1, 0, 0, 1, 0, 0)';
+    }).then(_ => {
+      takeScreenshot();
+    });
+  });
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/worklet-animation-with-scroll-timeline.https.html
@@ -0,0 +1,67 @@
+<html class="reftest-wait">
+<title>Basic use of scroll timeline with WorkletAnimation</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<meta name="assert" content="Should be able to use the scroll timeline to drive the worklet animation timing">
+<link rel="match" href="worklet-animation-with-scroll-timeline-ref.html">
+
+<script src="/web-animations/testcommon.js"></script>
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+
+<style>
+  #box {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+  }
+
+  #covered {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+  }
+
+  #scroller {
+    overflow: auto;
+    height: 100px;
+    width: 100px;
+  }
+
+  #contents {
+    height: 1000px;
+    width: 100%;
+  }
+</style>
+
+<div id="box"></div>
+<div id="covered"></div>
+<div id="scroller">
+  <div id="contents"></div>
+</div>
+
+<script>
+  registerPassthroughAnimator().then(() => {
+    const box = document.getElementById('box');
+    const effect = new KeyframeEffect(box,
+      [
+      { transform: 'translateY(0)', opacity: 1},
+      { transform: 'translateY(200px)', opacity: 0}
+      ], {
+        duration: 1000,
+      }
+    );
+
+    const scroller = document.getElementById('scroller');
+    const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
+    const animation = new WorkletAnimation('passthrough', effect, timeline);
+    animation.play();
+
+    // Move the scroller to the halfway point.
+    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+    scroller.scrollTop = 0.5 * maxScroll;
+
+    waitForAsyncAnimationFrames(1).then(_ => {
+      takeScreenshot();
+    });
+  });
+</script>
\ No newline at end of file
deleted file mode 100644
--- a/testing/web-platform/tests/audio-output/setSinkId.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>Test setSinkId behavior </title>
-<div id='log'></div>
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<script>
-"use strict";
-
-const audio = new Audio();
-
-promise_test(t => audio.setSinkId(""), "setSinkId on default audio output should always work");
-
-promise_test(t => promise_rejects(t, "NotFoundError", audio.setSinkId("nonexistent_device_id")),
-  "setSinkId fails with NotFoundError on made up deviceid");
-
-promise_test(async t => {
-  const list = await navigator.mediaDevices.enumerateDevices();
-  const outputDevicesList = list.filter(({kind}) => kind == "audiooutput");
-  assert_not_equals(outputDevicesList.length, 0,
-    "media device list includes at least one audio output device");
-
-  let acceptedDevices = 0;
-  for (const {deviceId} of outputDevicesList) {
-    const {deviceId} = outputDevicesList[0];
-    const p1 = audio.setSinkId(deviceId);
-    assert_equals(audio.sinkId, "", "before it resolves, setSinkId is unchanged");
-    try {
-      let r = await p1;
-      assert_equals(acceptedDevices, 0, "only the default sink device can be set");
-      acceptedDevices++;
-      assert_equals(r, undefined, "setSinkId resolves with undefined");
-      assert_equals(audio.sinkId, deviceId, "when it resolves, setSinkId updates sinkId to the requested deviceId");
-      r = await audio.setSinkId(deviceId);
-      assert_equals(r, undefined, "resetting sinkid on same current value should always work");
-      r = await audio.setSinkId("");
-      assert_equals(r, undefined, "resetting sinkid on default audio output should always work");
-    } catch (e) {
-      assert_equals(e.name, "NotAllowedError", "Non-default devices are failing with NotAllowed error");
-    }
-  }
-}, "List device, setSinkId should be allowed on the default, the rest of the devices will get a NotAllowedError");
-
-</script>
--- a/testing/web-platform/tests/battery-status/META.yml
+++ b/testing/web-platform/tests/battery-status/META.yml
@@ -1,5 +1,4 @@
 spec: https://w3c.github.io/battery/
 suggested_reviewers:
   - anssiko
-  - dontcallmedom
   - zqzhang
--- a/testing/web-platform/tests/bluetooth/META.yml
+++ b/testing/web-platform/tests/bluetooth/META.yml
@@ -1,6 +1,5 @@
 spec: https://webbluetoothcg.github.io/web-bluetooth/
 suggested_reviewers:
   - dougt
-  - g-ortuno
   - odejesush
   - reillyeon
--- a/testing/web-platform/tests/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html
+++ b/testing/web-platform/tests/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html
@@ -1,10 +1,11 @@
 <html>
 <title>Accept-CH-Lifetime test with same-origin iframe</title>
+<meta name="timeout" content="long">
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <!--
 Apart from this webpage, the test opens another html web page. One test is run
 in this web page, and another in the second web page.
 -->
--- a/testing/web-platform/tests/client-hints/accept_ch_lifetime_subresource.tentative.https.html
+++ b/testing/web-platform/tests/client-hints/accept_ch_lifetime_subresource.tentative.https.html
@@ -1,10 +1,11 @@
 <html>
 <title>Accept-CH-Lifetime test with subresource</title>
+<meta name="timeout" content="long">
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <!--
 Apart from this webpage, the test opens another html web page. One test is run
 in this web page, and another in the second web page.
 -->
--- a/testing/web-platform/tests/client-hints/echo_client_hints_received.py
+++ b/testing/web-platform/tests/client-hints/echo_client_hints_received.py
@@ -13,8 +13,10 @@ def main(request, response):
     if "viewport-width" in request.headers:
             response.headers.set("viewport-width-received", request.headers.get("viewport-width"))
     if "rtt" in request.headers:
             response.headers.set("rtt-received", request.headers.get("rtt"))
     if "downlink" in request.headers:
             response.headers.set("downlink-received", request.headers.get("downlink"))
     if "ect" in request.headers:
             response.headers.set("ect-received", request.headers.get("ect"))
+    if "Sec-CH-Lang" in request.headers:
+            response.headers.set("lang-received", request.headers.get("Sec-CH-Lang"))
--- a/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.http.html
+++ b/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.http.html
@@ -1,10 +1,10 @@
 <html>
-<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
+<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
 <title>Accept-CH http-equiv insecure transport test</title>
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <script>
 
 // Even though this HTML file contains "Accept-CH" http-equiv headers, the
@@ -22,14 +22,15 @@ promise_test(t => {
     // Verify that the browser does not include client hints in the headers
     // when fetching the XHR from an insecure HTTP server.
     assert_false(r.headers.has("device-memory-received"), "device-memory-received");
     assert_false(r.headers.has("dpr-received"), "dpr-received");
     assert_false(r.headers.has("viewport-width-received"), "viewport-width-received");
     assert_false(r.headers.has("rtt-received"), "rtt-received");
     assert_false(r.headers.has("downlink-received"), "downlink-received");
     assert_false(r.headers.has("ect-received"), "ect-received");
+    assert_false(r.headers.has("lang-received"), "lang-received");
   });
 }, "Accept-CH http-equiv test over insecure transport");
 
 </script>
 </body>
 </html>
--- a/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.https.html
+++ b/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.https.html
@@ -1,10 +1,10 @@
 <html>
-<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
+<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
 <title>Accept-CH http-equiv cross-navigation test</title>
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <div id=test>
     <p>Apart from this webpage, the test opens another html web page. One test
     is run in this web page, and another in the second web page.
@@ -34,16 +34,16 @@ promise_test(t => {
   });
 }, "Test that the browser attaches client hints on subresources in the same navigation");
 
 // Verify that the browser does not attach client hints on resources in a
 // different navigation. This verifies that the client hint preferences were
 // not persisted for the origin.
 window.open("resources/do_not_expect_client_hints_headers.html");
 async_test(t => {
-window.addEventListener('message', function(event) {
-  t.done();
-})
+  window.addEventListener('message', t.step_func_done(e => {
+    assert_equals(e.data, 'PASS');
+  }));
 }, "Loading of resources/do_not_expect_client_hints_headers.html did not finish.");
 
 </script>
 </body>
 </html>
--- a/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.sub.https.html
+++ b/testing/web-platform/tests/client-hints/http_equiv_accept_ch.tentative.sub.https.html
@@ -1,10 +1,10 @@
 <html>
-<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
+<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
 <title>Accept-CH http-equiv same-origin and cross-origin test</title>
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <script>
 
 // Since this HTML file contains "Accept-CH" http-equiv headers the browser
@@ -33,30 +33,33 @@ promise_test(t => {
 
     assert_true(r.headers.has("downlink-received"), "downlink-received");
     var downlinkKbps  = r.headers.get("downlink-received") * 1000;
     assert_greater_than_equal(downlinkKbps, 0);
     assert_less_than_equal(downlinkKbps, 10000);
 
     assert_in_array(r.headers.get("ect-received"), ["slow-2g", "2g",
           "3g", "4g"], 'ect-received is unexpected');
+
+    assert_true(r.headers.has("lang-received"), "lang-received");
   });
 }, "Same origin Accept-CH http-equiv test");
 
 promise_test(t => {
   return fetch("https://{{domains[www]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py").then(r => {
     assert_equals(r.status, 200)
     // Verify that the browser does not include client hints in the headers
     // for a cross-origin fetch.
     assert_false(r.headers.has("device-memory-received"), "device-memory-received");
     assert_false(r.headers.has("dpr-received"), "dpr-received");
     assert_false(r.headers.has("viewport-width-received"), "viewport-width-received");
     assert_false(r.headers.has("rtt-received"), "rtt-received");
     assert_false(r.headers.has("downlink-received"), "downlink-received");
     assert_false(r.headers.has("ect-received"), "ect-received");
+    assert_false(r.headers.has("lang-received"), "lang-received");
   });
 }, "Cross-Origin Accept-CH http-equiv test");
 
 
 
 </script>
 </body>
 </html>
--- a/testing/web-platform/tests/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html
+++ b/testing/web-platform/tests/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html
@@ -1,10 +1,11 @@
 <html>
 <title>Accept-CH-Lifetime test with same-origin iframe</title>
+<meta name="timeout" content="long">
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <!--
 Apart from this webpage, the test opens another html web page. One test is run
 in this web page, and another in the second web page.
 -->
--- a/testing/web-platform/tests/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html
+++ b/testing/web-platform/tests/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html
@@ -1,10 +1,11 @@
 <html>
 <title>Accept-CH-Lifetime test with subresource</title>
+<meta name="timeout" content="long">
 <body>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <!--
 Apart from this webpage, the test opens another html web page. One test is run
 in this web page, and another in the second web page.
 -->
--- a/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-basics.https.html
+++ b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-basics.https.html
@@ -6,71 +6,58 @@
 <script>
 
 test(() => {
   assert_not_equals(navigator.clipboard, undefined);
   assert_true(navigator.clipboard instanceof Clipboard);
   assert_equals(navigator.clipboard, navigator.clipboard);
 }, "navigator.clipboard exists");
 
-/* clipboard.write(text/plain Blob) */
-
 promise_test(async () => {
   const blob = new Blob(["hello"], {type: 'text/plain'});
-  await navigator.clipboard.write(blob);
-}, "navigator.clipboard.write(text/plain Blob) succeeds");
-
-/* clipboard.write(invalid input) */
+  await navigator.clipboard.write([blob]);
+}, "navigator.clipboard.write([text/plain Blob]) succeeds");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write());
-}, "navigator.clipboard.write() fails (expect Blob)");
+}, "navigator.clipboard.write() fails (expect [Blob])");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write(null));
-}, "navigator.clipboard.write(null) fails (expect Blob)");
+}, "navigator.clipboard.write(null) fails (expect [Blob])");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write("Bad string"));
-}, "navigator.clipboard.write(DOMString) fails (expect Blob)");
-
-
-/* clipboard.writeText() */
+}, "navigator.clipboard.write(DOMString) fails (expect [Blob])");
 
 promise_test(async () => {
   await navigator.clipboard.writeText("New clipboard text");
 }, "navigator.clipboard.writeText(DOMString) succeeds");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.writeText());
 }, "navigator.clipboard.writeText() fails (expect DOMString)");
 
-/* clipboard.write(image/png Blob) */
-
 promise_test(async () => {
   const fetched = await fetch(
         'http://localhost:8001/clipboard-apis/resources/greenbox.png');
   const image = await fetched.blob();
 
-  await navigator.clipboard.write(image);
-}, "navigator.clipboard.write(image/png Blob) succeeds");
-
-/* text/plain or image/png Blob clipboard.read() */
+  await navigator.clipboard.write([image]);
+}, "navigator.clipboard.write([image/png Blob]) succeeds");
 
 promise_test(async () => {
   const result = await navigator.clipboard.read();
-  assert_true(result instanceof Blob);
+  assert_true(result instanceof Array);
+  assert_true(result[0] instanceof Blob);
   assert_equals(typeof result, "object");
 }, "navigator.clipboard.read() succeeds");
 
-
-/* clipboard.readText() */
-
 promise_test(async () => {
   const result = await navigator.clipboard.readText();
   assert_equals(typeof result, "string");
 }, "navigator.clipboard.readText() succeeds");
 
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/clipboard-apis/async-write-blobs-read-blobs-manual.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>
+  Async Clipboard write blobs -> read blobs tests
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+async function loadBlob(fileName) {
+  const fetched = await fetch(fileName);
+  return await fetched.blob();
+}
+
+promise_test(async t => {
+  const blobText = new Blob(["test text"], {type: 'text/plain'});
+  const blobImage = await loadBlob('resources/greenbox.png');
+
+  assert_equals(blobText.type, "text/plain");
+  assert_equals(blobImage.type, "image/png");
+
+  await navigator.clipboard.write([blobText, blobImage]);
+  const output = await navigator.clipboard.read();
+
+  assert_equals(output.length, 2);
+  assert_equals(output[0].type, "text/plain");
+  assert_equals(output[1].type, "image/png");
+}, "Verify write and read clipboard (multiple blobs)");
+</script>
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
--- a/testing/web-platform/tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
+++ b/testing/web-platform/tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
@@ -1,27 +1,31 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>Async Clipboard write (text/plain Blob) -> read (text/plain Blob) tests</title>
+<title>
+  Async Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) tests
+</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
     const blobInput = new Blob([textInput], {type: 'text/plain'});
 
-    await navigator.clipboard.write(blobInput);
-    const blobOutput = await navigator.clipboard.read();
+    await navigator.clipboard.write([blobInput]);
+    const blobsOutput = await navigator.clipboard.read();
+    assert_equals(blobsOutput.length, 1);
+    const blobOutput = blobsOutput[0];
     assert_equals(blobOutput.type, "text/plain");
 
     const textOutput = await (new Response(blobOutput)).text();
     assert_equals(textOutput, textInput);
   }, "Verify write and read clipboard given text: " + textInput);
 }
 
-readWriteTest("Clipboard write (text/plain Blob) -> read (text/plain Blob) test");
+readWriteTest("Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) test");
 readWriteTest("non-Latin1 text encoding test データ");
 </script>
 <p>
   Note: This is a manual test because it writes/reads to the shared system
   clipboard and thus cannot be run async with other tests that might interact
   with the clipboard.
 </p>
--- a/testing/web-platform/tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html
+++ b/testing/web-platform/tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html
@@ -1,25 +1,25 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>Async Clipboard write (text/plain Blob) -> readText tests</title>
+<title>Async Clipboard write ([text/plain Blob]) -> readText tests</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
     const blobInput = new Blob([textInput], {type: 'text/plain'});
 
-    await navigator.clipboard.write(blobInput);
+    await navigator.clipboard.write([blobInput]);
     const textOutput = await navigator.clipboard.readText();
 
     assert_equals(textOutput, textInput);
   }, "Verify write and read clipboard given text: " + textInput);
 }
 
-readWriteTest("Clipboard write (text/plain Blob) -> read text test");
+readWriteTest("Clipboard write ([text/plain Blob]) -> read text test");
 readWriteTest("non-Latin1 text encoding test データ");
 </script>
 <p>
   Note: This is a manual test because it writes/reads to the shared system
   clipboard and thus cannot be run async with other tests that might interact
   with the clipboard.
 </p>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/clipboard-apis/async-write-duplicate-mime-type-manual.https.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>
+  Async Clipboard write duplicate mime type test
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+promise_test(async t => {
+  const blobText = new Blob(["test text"], {type: 'text/plain'});
+  const blobText2 = new Blob(["test text"], {type: 'text/plain'});
+
+  assert_equals(blobText.type, "text/plain");
+  assert_equals(blobText2.type, "text/plain");
+
+
+  await promise_rejects(t, 'NotAllowedError',
+      navigator.clipboard.write([blobText, blobText2]));
+}, "Verify write and read clipboard (multiple blobs)");
+</script>
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
--- a/testing/web-platform/tests/clipboard-apis/async-write-image-read-image-manual.https.html
+++ b/testing/web-platform/tests/clipboard-apis/async-write-image-read-image-manual.https.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>
-  Async Clipboard write image/png Blob -> read image/png Blob tests
+  Async Clipboard write [image/png Blob] -> read [image/png Blob] tests
 </title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <p>
   <p>The bottom image should display the same image as the top image.</p>
   <p>Original Image:</p>
   <image id='image-to-copy' width='20' height='20'
@@ -32,29 +32,31 @@ async function getBitmapString(blob) {
 };
 
 async function loadBlob(fileName) {
   const fetched = await fetch(fileName);
   return await fetched.blob();
 }
 
 promise_test(async t => {
-  const input = await loadBlob('resources/greenbox.png');
+  const blobInput = await loadBlob('resources/greenbox.png');
 
-  assert_equals(input.type, "image/png");
-  await navigator.clipboard.write(input);
-  const output = await navigator.clipboard.read();
-  assert_equals(output.type, "image/png");
+  assert_equals(blobInput.type, "image/png");
+  await navigator.clipboard.write([blobInput]);
+  const blobsOutput = await navigator.clipboard.read();
+  assert_equals(blobsOutput.length, 1);
+  const blobOutput = blobsOutput[0];
+  assert_equals(blobOutput.type, "image/png");
 
   document.getElementById('image-on-clipboard').src =
-      window.URL.createObjectURL(output);
+      window.URL.createObjectURL(blobOutput);
 
-  const comparableInput = await getBitmapString(input);
-  const comparableOutput = await getBitmapString(output);
+  const comparableInput = await getBitmapString(blobInput);
+  const comparableOutput = await getBitmapString(blobOutput);
 
   assert_equals(comparableOutput, comparableInput);
-}, "Verify write and read clipboard (DOMString)");
+}, "Verify write and read clipboard ([image/png Blob])");
 </script>
 <p>
   Note: This is a manual test because it writes/reads to the shared system
   clipboard and thus cannot be run async with other tests that might interact
   with the clipboard.
 </p>
--- a/testing/web-platform/tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html
+++ b/testing/web-platform/tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html
@@ -1,25 +1,27 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>Async Clipboard writeText -> read (text/plain Blob) tests</title>
+<title>Async Clipboard writeText -> read ([text/plain Blob]) tests</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
     await navigator.clipboard.writeText(textInput);
-    const blobOutput = await navigator.clipboard.read();
+    const blobsOutput = await navigator.clipboard.read();
+    assert_equals(blobsOutput.length, 1);
+    const blobOutput = blobsOutput[0];
     assert_equals(blobOutput.type, "text/plain");
 
     const textOutput = await (new Response(blobOutput)).text();
     assert_equals(textOutput, textInput);
   }, "Verify write and read clipboard given text: " + textInput);
 }
 
-readWriteTest("Clipboard write text -> read (text/plain Blob) test");
+readWriteTest("Clipboard write text -> read ([text/plain Blob]) test");
 readWriteTest("non-Latin1 text encoding test データ");
 </script>
 <p>
   Note: This is a manual test because it writes/reads to the shared system
   clipboard and thus cannot be run async with other tests that might interact
   with the clipboard.
 </p>
--- a/testing/web-platform/tests/common/META.yml
+++ b/testing/web-platform/tests/common/META.yml
@@ -1,5 +1,4 @@
 suggested_reviewers:
   - zqzhang
-  - dontcallmedom
   - deniak
   - gsnedders
--- a/testing/web-platform/tests/common/sleep.py
+++ b/testing/web-platform/tests/common/sleep.py
@@ -1,12 +1,13 @@
 import time
+import timeit
 
 # sleep can be lower than requested value in some platforms: https://bugs.python.org/issue31539
 # We add padding here to compensate for that.
 sleep_padding = 15.0
 
 def sleep_at_least(sleep_in_ms):
-    sleep_until = time.time() + (sleep_in_ms / 1E3)
+    sleep_until = timeit.default_timer() + (sleep_in_ms / 1E3)
     time.sleep((sleep_in_ms + sleep_padding) / 1E3)
     # Check if the padding was sufficient; if not, sleep again.
-    while time.time() < sleep_until:
+    while timeit.default_timer() < sleep_until:
         time.sleep(sleep_padding / 1E3)
rename from testing/web-platform/tests/conformance-checkers/html-aria/live-events/test-case-live-event-1.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/live-events/test-case-live-event-1-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/597.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/597-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/598.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/598-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/599.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-general/599-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/557.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/557-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/565.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/565-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/566.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/name-computation-img/566-haswarn.html
rename from testing/web-platform/tests/conformance-checkers/html-aria/properties-global-norole/properties-global-norole-aria-label-Test-string-value.html
rename to testing/web-platform/tests/conformance-checkers/html-aria/properties-global-norole/properties-global-norole-aria-label-Test-string-value-haswarn.html
--- a/testing/web-platform/tests/conformance-checkers/messages.json
+++ b/testing/web-platform/tests/conformance-checkers/messages.json
@@ -1,15 +1,23 @@
 {
     "html-aria/author-requirements/571-haswarn.html": "The \u201ctextbox\u201d role is unnecessary for an \u201cinput\u201d element that has no \u201clist\u201d attribute and whose type is \u201ctext\u201d.",
     "html-aria/author-requirements/572-haswarn.html": "The \u201ctextbox\u201d role is unnecessary for an \u201cinput\u201d element that has no \u201clist\u201d attribute and whose type is \u201ctext\u201d.",
     "html-aria/author-requirements/573-haswarn.html": "The \u201ctextbox\u201d role is unnecessary for an \u201cinput\u201d element that has no \u201clist\u201d attribute and whose type is \u201ctext\u201d.",
     "html-aria/combobox-autocomplete-list/div-haswarn.html": "The \u201ctextbox\u201d role is unnecessary for an \u201cinput\u201d element that has no \u201clist\u201d attribute and whose type is \u201ctext\u201d.",
     "html-aria/host-language/implicit-semantics-checkbox-disparity-haswarn.html": "The \u201ccheckbox\u201d role is unnecessary for element \u201cinput\u201d whose type is \u201ccheckbox\u201d.",
     "html-aria/host-language/implicit-semantics-checkbox-role-haswarn.html": "The \u201ccheckbox\u201d role is unnecessary for element \u201cinput\u201d whose type is \u201ccheckbox\u201d.",
+    "html-aria/live-events/test-case-live-event-1-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-general/597-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-general/598-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-general/599-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-img/557-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-img/565-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/name-computation-img/566-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
+    "html-aria/properties-global-norole/properties-global-norole-aria-label-Test-string-value-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
     "html-rdfa/0019-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cdiv\u201d at this point.",
     "html-rdfa/0035-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",
     "html-rdfa/0037-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",
     "html-rdfa/0039-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",
     "html-rdfa/0041-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",
     "html-rdfa/0079-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cp\u201d at this point.",
     "html-rdfa/0085-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cp\u201d at this point.",
     "html-rdfa/0109-novalid.html": "Attribute \u201cxml:base\u201d not allowed on element \u201chtml\u201d at this point.",
--- a/testing/web-platform/tests/content-security-policy/reporting-api/reporting-api-sends-reports-on-violation.https.sub.html
+++ b/testing/web-platform/tests/content-security-policy/reporting-api/reporting-api-sends-reports-on-violation.https.sub.html
@@ -10,16 +10,46 @@
     var t1 = async_test("Test that image does not load");
     async_test(function(t2) {
     window.addEventListener("securitypolicyviolation", t2.step_func(function(e) {
         assert_equals(e.blockedURI, "{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png");
         assert_equals(e.violatedDirective, "img-src");
         t2.done();
       }));
     }, "Event is fired");
+
+    async_test(function(t3) {
+      var observer = new ReportingObserver(function(reports, observer) {
+        t3.step(function() {
+          assert_equals(reports.length, 1);
+
+          // Ensure that the contents of the report are valid.
+          var base_url = "{{location[scheme]}}://{{location[host]}}/content-security-policy/"
+          var document_url = base_url + "reporting-api/reporting-api-sends-reports-on-violation.https.sub.html";
+          assert_equals(reports[0].type, "csp-violation");
+          assert_equals(reports[0].url, document_url);
+          assert_equals(reports[0].body.documentURL, document_url);
+          assert_equals(reports[0].body.referrer, null);
+          assert_equals(reports[0].body.blockedURL,
+                        base_url + "support/fail.png");
+          assert_equals(reports[0].body.effectiveDirective, "img-src");
+          assert_equals(reports[0].body.originalPolicy,
+                        "script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group");
+          assert_equals(reports[0].body.sourceFile, document_url);
+          assert_equals(reports[0].body.sample, null);
+          assert_equals(reports[0].body.disposition, "enforce");
+          assert_equals(reports[0].body.statusCode, 0);
+          assert_equals(reports[0].body.lineNumber, 53);
+          assert_equals(reports[0].body.columnNumber, 0);
+        });
+
+        t3.done();
+      });
+      observer.observe();
+    }, "Report is observable to ReportingObserver");
   </script>
   <img src='/content-security-policy/support/fail.png'
        onload='t1.unreached_func("The image should not have loaded");'
        onerror='t1.done();'>
 
   <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
 </body>
 </html>
--- a/testing/web-platform/tests/cookies/META.yml
+++ b/testing/web-platform/tests/cookies/META.yml
@@ -1,3 +1,2 @@
 suggested_reviewers:
-  - inikulin
   - mikewest
--- a/testing/web-platform/tests/css/CSS2/META.yml
+++ b/testing/web-platform/tests/css/CSS2/META.yml
@@ -1,8 +1,7 @@
 spec: https://drafts.csswg.org/css2/
 suggested_reviewers:
   - fantasai
   - dbaron
   - svgeesus
   - kojiishi
   - frivoal
-  - bert-github
--- a/testing/web-platform/tests/css/CSS2/backgrounds/background-root-018-ref.xht
+++ b/testing/web-platform/tests/css/CSS2/backgrounds/background-root-018-ref.xht
@@ -33,17 +33,17 @@
   {
   border: gray solid medium;
   padding: 3em;
   }
 
   span
   {
   background-color: yellow;
-  font-size: large;
+  font-size: larger;
   }
   </style>
 
  </head>
 
  <body>
 
   <div id="grand-parent">
--- a/testing/web-platform/tests/css/CSS2/css1/c5510-padn-000-ref.xht
+++ b/testing/web-platform/tests/css/CSS2/css1/c5510-padn-000-ref.xht
@@ -1,17 +1,19 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>CSS Reftest Reference</title>
 <link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com"/>
 <style type="text/css">
+body {
+  color: navy;
+}
 div {
   width: 138px;
-  color: orange;
   font-size: 10px;
   line-height: 1;
 }
 div p {
   padding: 0;
   border: solid 24px yellow;
 }
 img {
--- a/testing/web-platform/tests/css/CSS2/text/white-space-003.xht
+++ b/testing/web-platform/tests/css/CSS2/text/white-space-003.xht
@@ -38,13 +38,13 @@
             #div2
             {
                 height: 1em;
                 width: 1em;
             }
         </style>
     </head>
     <body>
-        <p>Test passes if there are two black squares on the page.</p>
+        <p>Test passes if there are 2 filled black squares.</p>
         <div id="test">XX   XX</div>
         <div id="reference"><div id="div1"></div><div id="div2"></div><div id="div3"></div></div>
     </body>
 </html>
--- a/testing/web-platform/tests/css/CSS2/text/white-space-pre-element-001-ref.xht
+++ b/testing/web-platform/tests/css/CSS2/text/white-space-pre-element-001-ref.xht
@@ -4,16 +4,17 @@
         <title>CSS Test reference</title>
         <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
         <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net" />
         <style type="text/css">
             pre, div
             {
                 font-family: monospace;
                 font-size: 10pt;
+                margin: 0;
             }
             div
             {
                 white-space: pre;
             }
        </style>
     </head>
     <body>
--- a/testing/web-platform/tests/css/CSS2/text/white-space-pre-element-001.xht
+++ b/testing/web-platform/tests/css/CSS2/text/white-space-pre-element-001.xht
@@ -7,16 +7,17 @@
         <link rel="match" href="white-space-pre-element-001-ref.xht" />
         <meta name="flags" content="" />
         <meta name="assert" content="The 'pre' element and 'white-space: pre' assignment behave the same way with respect to white space." />
         <style type="text/css">
             pre, div
             {
                 font-family: monospace;
                 font-size: 10pt;
+                margin: 0;
             }
             div
             {
                 white-space: pre;
             }
        </style>
     </head>
     <body>
--- a/testing/web-platform/tests/css/CSS2/text/white-space-processing-040.xht
+++ b/testing/web-platform/tests/css/CSS2/text/white-space-processing-040.xht
@@ -11,22 +11,22 @@
         <style type="text/css">
             div
             {
                 font: 16px/1em Ahem;
             }
             #div1
             {
                 white-space: pre-wrap;
+                margin-left: -1em;
             }
             #div2
             {
                 background: black;
                 height: 1em;
-                margin-left: 1em;
                 width: 1em;
             }
         </style>
     </head>
     <body>
         <p>Test passes if there is only one box below.</p>
         <div id="div1">&#32;X</div>
         <div id="div2"></div>
--- a/testing/web-platform/tests/css/WOFF2/META.yml
+++ b/testing/web-platform/tests/css/WOFF2/META.yml
@@ -1,4 +1,3 @@
 spec: https://w3c.github.io/woff/woff2/
 suggested_reviewers:
   - svgeesus
-  - rsheeter
--- a/testing/web-platform/tests/css/css-backgrounds/META.yml
+++ b/testing/web-platform/tests/css/css-backgrounds/META.yml
@@ -1,6 +1,4 @@
 spec: https://drafts.csswg.org/css-backgrounds/
 suggested_reviewers:
   - dbaron
-  - bert-github
   - fantasai
-  - bradkemper
--- a/testing/web-platform/tests/css/css-color/META.yml
+++ b/testing/web-platform/tests/css/css-color/META.yml
@@ -1,6 +1,5 @@
 spec: https://drafts.csswg.org/css-color/
 suggested_reviewers:
   - dbaron
-  - tantek
   - svgeesus
   - tabatkins
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-display/run-in/META.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-suggested_reviewers:
-  - bert-github
--- a/testing/web-platform/tests/css/css-exclusions/META.yml
+++ b/testing/web-platform/tests/css/css-exclusions/META.yml
@@ -1,4 +1,3 @@
 spec: https://drafts.csswg.org/css-exclusions/
 suggested_reviewers:
-  - atanassov
   - astearns
--- a/testing/web-platform/tests/css/css-flexbox/META.yml
+++ b/testing/web-platform/tests/css/css-flexbox/META.yml
@@ -1,10 +1,9 @@
 spec: https://drafts.csswg.org/css-flexbox/
 suggested_reviewers:
   - kojiishi
   - plinss
   - mrego
   - cbiesinger
-  - atanassov
   - fantasai
   - rachelandrew
   - tabatkins
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-flexbox/flex-basis-010.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Flexbox Test: Indefinite % flex-basis should cause height to be ignored</title>
+<link rel="author" title="Google LLC" href="https://www.google.com">
+<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#flex-basis-property">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<style>
+  #container {
+    background-color: red;
+    display: flex;
+    width: 100px;
+    flex-direction: column;
+  }
+  #item {
+    flex: 0 0 0%;
+    height: 500px;
+    background-color: red;
+  }
+  #child {
+    height: 100px;
+    background-color: green;
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div id="container">
+    <div id="item">
+      <div id="child"></div>
+    </div>
+  </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-flexbox/flex-minimum-height-flex-items-013.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<title>CSS Flexbox: min-height: auto with nested flexboxes</title>
+<link rel="author" title="Google LLC" href="https://www.google.com/" />
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#min-size-auto" />
+<link rel="issue" href="https://bugs.chromium.org/p/chromium/issues/detail?id=933931" />
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+
+<style>
+.outer {
+  display: flex;
+  flex-direction: column;
+  height: 20px;
+  width: 100px;
+  background: red;
+}
+
+.middle {
+  display: flex;
+  flex-direction: column;
+  background: green;
+}
+
+.inner {
+  display: flex;
+  flex-direction: column;
+}
+
+.tall {
+  width: 50px;
+  height: 100px;
+  background: green;
+}
+</style>
+<body>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<div class="outer">
+  <div class="middle">
+    <div class="inner">
+      <div class="tall"></div>
+    </div>
+  </div>
+</div>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-flexbox/flex-wrap-005.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<link rel="author" title="Google LLC" href="http://www.google.com" />
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#cross-sizing" />
+<title>css-flexbox: Tests that we size items in a wrapping column flexbox as fit-content</title>
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+<meta name="assert" content="The flexbox here should have one flex line, 100px by 100px. The flex items overflow but are transparent." />
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<!-- This makes sure that we only see green if the flex items are sized correctly -->
+<div style="position: absolute; width: 100px; height: 100px; background: green;"></div>
+
+<div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 200px; height: 100px; line-height: 20px; align-content: flex-start;">
+  <div style="background-color: red; height: 100px; max-width: 50%; align-self: center;">
+    <!-- These zero-height divs give the flex item a min-content width of
+         50px and a max-content width of 250px -->
+    <div style="width: 50px; display: inline-block;"></div>
+    <div style="width: 50px; display: inline-block;"></div>
+    <div style="width: 50px; display: inline-block;"></div>
+    <div style="width: 50px; display: inline-block;"></div>
+    <div style="width: 50px; display: inline-block;"></div>
+  </div>
+</div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link rel="author" title="Google" href="https://www.google.com/" />
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#intrinsic-sizes" />
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1865" />
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.flexbox')">
+<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="0">
+  <div style="overflow: auto;">
+    <div style="width: 100px; height: 100px;"></div>
+  </div>
+</div>
+
+<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="10">
+  <div style="overflow: auto; border: 5px solid;">
+    <div style="width: 100px; height: 100px;"></div>
+  </div>
+</div>
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-flexbox/percentage-heights-quirks-node.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<title>In quirks mode a flex item should resolve its percentage height against its first ancestor with a defined height.</title>
-<link rel="help" href="https://quirks.spec.whatwg.org/#the-percentage-height-calculation-quirk">
-<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
-<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
-<div style="width: 200px; height: 200px;">
-  <div style="display: flex;">
-    <div style="width: 50%; height: 50%; background: green;"></div>
-  </div>
-</div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html
@@ -0,0 +1,17 @@
+<!-- quirks mode -->
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#the-height-property">
+<meta name="assert" content="The percentage height resolution quirk isn't applied to flexboxes.">
+<p>There should be a green square to the left of a blue square, and no red.</p>
+<div id="container" style="width:200px; height:456px;">
+  <div style="display:flex; background:blue;" data-expected-height="100">
+    <img style="width:100px; height: 50%;" src="support/1x1-green.png" data-expected-height="100">
+    <div style="width: 50px; height: 100%; background: red;" data-expected-height="0"></div>
+  </div>
+</div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+  checkLayout("#container");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/font-style-angle.html
@@ -0,0 +1,23 @@
+
+<!doctype html>
+<title>Testing font-style angle's unit type consideration</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-style-prop" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+
+body {
+    font-style: oblique 0.785398165rad;
+}
+
+</style>
+<script>
+var test_description = "font-style angle's unit type must be considered";
+promise_test(
+    t => {
+        return new Promise(test => addEventListener('load', () => test()))
+        .then(test => assert_equals(getComputedStyle(document.querySelector("body"))['font-style'], "oblique 45deg", "Invalid gCS($(\"body\"))['font-style'];"))
+    },
+    test_description
+);
+</script>
--- a/testing/web-platform/tests/css/css-grid/META.yml
+++ b/testing/web-platform/tests/css/css-grid/META.yml
@@ -1,11 +1,9 @@
 spec: https://drafts.csswg.org/css-grid/
 suggested_reviewers:
   - mrego
   - plinss
-  - jxs
   - tabatkins
   - fantasai
-  - atanassov
   - javifernandez
   - rachelandrew
   - svillar
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim-vertical-lr.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
+<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
+<style>
+.grid {
+  display: grid;
+  position: relative;
+  font-size: 0;
+  height: 0;
+  width: 0;
+  margin-bottom: 125px;
+  grid-template-rows: 50px 50px;
+  justify-items: baseline;
+}
+.item1, .item2 {
+  writing-mode: vertical-lr;
+}
+.item1 {
+  padding-left: 25px;
+  background: yellow;
+}
+.item2 {
+  padding-right: 25px;
+  background: magenta;
+}
+.item1::before, .item2::before {
+  content: '';
+  display: inline-block;
+  width: 25px;
+  height: 25px;
+  vertical-align: top;
+}
+.item2::before {
+  vertical-align: bottom;
+}
+.area {
+  position: absolute;
+  z-index: -1;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  grid-column: 1 / 2;
+  grid-row: 1 / 3;
+  background: cyan;
+}
+</style>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<div id="log"></div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 0px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="75" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 75px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="75" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 88px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="88" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 100px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 150px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, auto);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<script>
+checkLayout(".grid");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim-vertical-rl.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
+<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
+<style>
+.grid {
+  display: grid;
+  position: relative;
+  font-size: 0;
+  height: 0;
+  width: 0;
+  margin-bottom: 125px;
+  grid-template-rows: 50px 50px;
+  justify-items: baseline;
+}
+.item1, .item2 {
+  writing-mode: vertical-rl;
+}
+.item1 {
+  padding-left: 25px;
+  background: yellow;
+}
+.item2 {
+  padding-right: 25px;
+  background: magenta;
+}
+.item1::before, .item2::before {
+  content: '';
+  display: inline-block;
+  width: 25px;
+  height: 25px;
+  vertical-align: top;
+}
+.item2::before {
+  vertical-align: bottom;
+}
+.area {
+  position: absolute;
+  z-index: -1;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  grid-column: 1 / 2;
+  grid-row: 1 / 3;
+  background: cyan;
+}
+</style>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<div id="log"></div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 0px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="75" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 75px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="75" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 88px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="88" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 100px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, 150px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-columns: minmax(auto, auto);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<script>
+checkLayout(".grid");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-minimum-contribution-baseline-shim.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
+<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
+<style>
+.grid {
+  display: grid;
+  position: relative;
+  font-size: 0;
+  height: 0;
+  width: 0;
+  margin-bottom: 125px;
+  grid-template-columns: 50px 50px;
+  align-items: baseline;
+}
+.item1 {
+  padding-top: 25px;
+  background: yellow;
+}
+.item2 {
+  padding-bottom: 25px;
+  background: magenta;
+}
+.item1::before, .item2::before {
+  content: '';
+  display: inline-block;
+  width: 25px;
+  height: 25px;
+  vertical-align: bottom;
+}
+.item2::before {
+  vertical-align: top;
+}
+.area {
+  position: absolute;
+  z-index: -1;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  grid-column: 1 / 3;
+  grid-row: 1 / 2;
+  background: cyan;
+}
+</style>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<div id="log"></div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, 0px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="75"></div>
+</div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, 75px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="75"></div>
+</div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, 88px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="88"></div>
+</div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, 100px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, 150px);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<div class="grid" style="grid-template-rows: minmax(auto, auto);">
+  <div class="item1" data-offset-x="0" data-offset-y="0"></div>
+  <div class="item2" data-offset-x="50" data-offset-y="50"></div>
+  <div class="area" data-expected-width="100" data-expected-height="100"></div>
+</div>
+
+<script>
+checkLayout(".grid");
+</script>
--- a/testing/web-platform/tests/css/css-logical/META.yml
+++ b/testing/web-platform/tests/css/css-logical/META.yml
@@ -1,4 +1,3 @@
 spec: https://drafts.csswg.org/css-logical/
 suggested_reviewers:
-  - atanassov
   - fantasai
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/hit-test/clip-path-element-objectboundingbox-001.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>Hit-test of clip-path objectBoundingBox &lt;clipPath> with additional transform</title>
+<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+body {
+  margin: 0;
+}
+.box {
+  width: 100px;
+  height: 100px;
+  background-color: blue;
+  margin: 100px;
+  clip-path: url(#clip);
+}
+</style>
+<div class="box"></div>
+<svg height="0">
+  <clipPath id="clip" clipPathUnits="objectBoundingBox" transform="scale(0.01, 0.01)">
+    <polygon points="50,0 100,50 50,100 0,50"/>
+  </clipPath>
+</svg>
+<script>
+function assert_element_at(element, pointlist) {
+  for (let point of pointlist) {
+    let result = document.elementFromPoint(point[0], point[1]);
+    assert_equals(result, element, point.join(','));
+  }
+}
+
+test(function() {
+  let div = document.querySelector('.box');
+
+  // Points inside clip-path.
+  assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
+
+  // Points outside clip-path.
+  assert_element_at(document.body, [[120, 120], [180, 120], [120, 180], [180, 180]]);
+});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/hit-test/clip-path-element-objectboundingbox-002.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Hit-test of clip-path nested objectBoundingBox &lt;clipPath></title>
+<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+body {
+  margin: 0;
+}
+.box {
+  width: 200px;
+  height: 200px;
+  background-color: blue;
+  margin: 100px;
+  clip-path: url(#clip);
+}
+</style>
+<div class="box"></div>
+<svg height="0">
+  <clipPath id="nested" clipPathUnits="objectBoundingBox">
+    <circle cx="0.25" cy="0.25" r="0.25"/>
+  </clipPath>
+  <clipPath id="clip" clipPathUnits="objectBoundingBox" clip-path="url(#nested)">
+    <rect width="0.5" height="0.5"/>
+  </clipPath>
+</svg>
+<script>
+function assert_element_at(element, pointlist) {
+  for (let point of pointlist) {
+    let result = document.elementFromPoint(point[0], point[1]);
+    assert_equals(result, element, point.join(','));
+  }
+}
+
+test(function() {
+  let div = document.querySelector('.box');
+
+  // Points inside clip-path.
+  assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
+
+  // Points outside clip-path.
+  assert_element_at(document.body, [[110, 110], [190, 110], [110, 190], [190, 190]]);
+});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/hit-test/clip-path-element-userspaceonuse-001.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>Hit-test of clip-path userSpaceOnUse &lt;clipPath></title>
+<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+body {
+  margin: 0;
+}
+.box {
+  width: 100px;
+  height: 100px;
+  background-color: blue;
+  margin: 100px;
+  clip-path: url(#clip);
+}
+</style>
+<div class="box"></div>
+<svg height="0">
+  <clipPath id="clip" clipPathUnits="userSpaceOnUse">
+    <polygon points="50,0 100,50 50,100 0,50"/>
+  </clipPath>
+</svg>
+<script>
+function assert_element_at(element, pointlist) {
+  for (let point of pointlist) {
+    let result = document.elementFromPoint(point[0], point[1]);
+    assert_equals(result, element, point.join(','));
+  }
+}
+
+test(function() {
+  let div = document.querySelector('.box');
+
+  // Points inside clip-path.
+  assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
+
+  // Points outside clip-path.
+  assert_element_at(document.body, [[120, 120], [180, 120], [120, 180], [180, 180]]);
+});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/hit-test/clip-path-shape-polygon-and-box-shadow.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Hit-test of clip-path polygon combined with box-shadow</title>
+<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+body {
+  margin: 0;
+}
+.box {
+  width: 100px;
+  height: 100px;
+  background-color: blue;
+  box-shadow: -100px 0px red;
+  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
+}
+</style>
+<div class="box"></div>
+<script>
+function assert_element_at(element, pointlist) {
+  for (let point of pointlist) {
+    let result = document.elementFromPoint(point[0], point[1]);
+    assert_equals(result, element, point.join(','));
+  }
+}
+
+test(function() {
+  let div = document.querySelector('.box');
+
+  // Points inside clip-path.
+  assert_element_at(div, [[50, 50], [50, 25], [50, 75], [25, 50], [75, 50]]);
+
+  // Points outside clip-path.
+  assert_element_at(document.body, [[20, 20], [80, 20], [20, 80], [80, 80]]);
+});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-overflow/webkit-line-clamp/webkit-line-clamp-with-line-height-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+#test {
+  width: 100px;
+
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+
+  border: solid thin grey;
+  font: 20px 'Ahem';
+  line-height: 40px;
+}
+</style>
+<p>This tests the -webkit-line-clamp property with line-height applied.</p>
+<div id="test">
+  XXXX XXX
+</div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-overflow/webkit-line-clamp/webkit-line-clamp-with-line-height.tentative.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<link rel="match" href="webkit-line-clamp-with-line-height-ref.html">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2847#issuecomment-468084957">
+<meta name="assert" content="This test checks that -webkit-line-clamp calculates respects line-height when calculating its block-size.">
+<style>
+#test {
+  width: 100px;
+
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+  overflow: hidden;
+
+  border: solid thin grey;
+  font: 20px 'Ahem';
+  line-height: 40px;
+}
+</style>
+<p>This tests the -webkit-line-clamp property with line-height applied.</p>
+<div id="test">
+  XXXX XXX
+</div>
--- a/testing/web-platform/tests/css/css-position/META.yml
+++ b/testing/web-platform/tests/css/css-position/META.yml
@@ -1,3 +1,3 @@
 spec: https://drafts.csswg.org/css-position/
 suggested_reviewers:
-  - atanassov
+  - astearns
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-position/position-absolute-container-dynamic-002.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<title>CSS Position Absolute: dynamic changes to containing block height</title>
+<link rel="author" href="mailto:atotic@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=933054">
+<meta name="assert" content="Chrome regression: abspos descendant responds to containing block size change through line items">
+<style>
+
+#container {
+  position: relative;
+}
+#intermediate {
+  overflow: hidden;
+  width:200px;
+  height:200px;
+  background:red;
+}
+#block {
+  height:200px;
+  background:green;
+}
+#target {
+  position: absolute;
+  width: 200px;
+  height: 100px;
+  background:green;
+}
+</style>
+<!-- Test for crbug.com/933054
+  Relayout optimizations cause OOF descendant not to be
+  repositioned
+-->
+<div id="container">
+  <div id="intermediate">
+    <div id="block"></div>
+    <div id="target"></div>
+  </div>
+</div>
+
+<script>
+document.body.offsetTop;
+test(() => {
+  document.getElementById("block").style.height = "100px";
+  assert_equals(document.querySelector("#target").offsetTop, 100);
+}, '#target static position responded to parent relayout');
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-position/position-absolute-crash-chrome-002.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>CSS Position Absolute: Chrome chrash</title>
+<link rel="author" href="mailto:atotic@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=938224">
+<meta name="assert" content="absolute position in LI container does not crash">
+<style>
+  #container {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+  }
+  #abs {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+  }
+</style>
+<li id="container">
+  <ul>
+    <li>
+      <div id="abs">abs</div>
+    </li>
+  </ul>
+</li>
+<script>
+test(() => {
+}, 'test passes if it does not crash');
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-position/z-index-blend-will-change-overlapping-layers-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<div style="height: 100vh"></div>
+<div style="background: green; height: 100px"></div>
+<script>
+window.scrollTo(0, 100);
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-position/z-index-blend-will-change-overlapping-layers.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>z-index, will-change, mix-blend-mode on overlapping layers</title>
+<link rel="match" href="z-index-blend-will-change-overlapping-layers-ref.html">
+<link rel="help" href="https://www.w3.org/TR/CSS2/visuren.html#propdef-z-index">
+<link rel="help" href="https://drafts.csswg.org/css-will-change/#will-change">
+<link rel="help" href="https://www.w3.org/TR/compositing-1/#mix-blend-mode">
+<meta name="assert" content="Tests z-index, will-change and mix-blend-mode on overlapping layers.
+Passes if there is a green bar when the page is scrolled to the bottom.">
+<script src="/common/reftest-wait.js"></script>
+<div style="z-index: 1; position: relative; height: 100vh">
+  <div style="mix-blend-mode: multiply"></div>
+  <div style="will-change: transform; position: absolute; bottom: -100px; width: 100px; height: 100px; background: red">
+  </div>
+</div>
+<div style="z-index: 1; position: relative; background: green; height: 100px"></div>
+<script>
+requestAnimationFrame(()=>{
+  requestAnimationFrame(()=>{
+    window.scrollBy(0, 100);
+    takeScreenshot();
+  });
+});
+</script>
+</html>
--- a/testing/web-platform/tests/css/css-properties-values-api/register-property-syntax-parsing.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/register-property-syntax-parsing.html
@@ -1,9 +1,10 @@
 <!DOCTYPE HTML>
+<meta charset="utf-8">
 <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
 <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#supported-syntax-strings" />
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
 test_count = 0;
 
 function assert_valid(syntax, initialValue) {
@@ -24,19 +25,21 @@ function assert_invalid(syntax, initialV
 
 assert_valid("*", "a");
 assert_valid(" * ", "b");
 assert_valid("<length>", "2px");
 assert_valid(" <number>", "5");
 assert_valid("<percentage> ", "10%");
 assert_valid("<color>+", "red");
 assert_valid(" <length>+ | <percentage>", "2px 8px");
+assert_valid(" <length>+ | <color>#", "red, blue");
 assert_valid("<length>|<percentage>|<length-percentage>", "2px"); // Valid but silly
 assert_valid("<color> | <image> | <url> | <integer> | <angle>", "red");
 assert_valid("<time> | <resolution> | <transform-list> | <custom-ident>", "red");
+assert_valid("\t<color>\n|   foo", "foo");
 
 assert_valid("*", ":> hello");
 assert_valid("*", "([ brackets ]) { yay (??)}");
 assert_valid("*", "yep 'this is valid too'");
 assert_valid("*", "unmatched opening bracket is valid :(");
 assert_valid("*", '"');
 
 assert_valid("<length>", "0");
@@ -81,45 +84,60 @@ assert_valid("<color>", "lightgoldenrody
 assert_valid("<image>", "url(a)");
 assert_valid("<image>", "linear-gradient(yellow, blue)");
 assert_valid("<url>", "url(a)");
 
 assert_valid("banana", "banana");
 assert_valid("bAnAnA", "bAnAnA");
 assert_valid("ba-na-nya", "ba-na-nya");
 assert_valid("banana", "banan\\61");
+assert_valid("banan\\61", "banana");
 assert_valid("<custom-ident>", "banan\\61");
 assert_valid("big | bigger | BIGGER", "bigger");
 assert_valid("foo+|bar", "foo foo foo");
 assert_valid("default", "default");
 
 assert_valid("banana\t", "banana");
 assert_valid("\nbanana\r\n", "banana");
 assert_valid("ba\f\n|\tna\r|nya", "nya");
 
 assert_valid(null, "null");
 assert_valid(undefined, "undefined");
 assert_valid(["array"], "array");
 
+assert_valid("\\1F914", "🤔");
+assert_valid("hmm\\1F914", "hmm🤔");
+assert_valid("\\1F914hmm", "🤔hmm");
+assert_valid("\\1F914 hmm", "🤔hmm");
+assert_valid("\\1F914\\1F914", "🤔🤔");
+
 // Invalid syntax
 assert_invalid("banana,nya", "banana");
-assert_invalid("banan\\61", "banana");
 assert_invalid("<\\6c ength>", "10px");
 assert_invalid("<banana>", "banana");
 assert_invalid("<Number>", "10");
 assert_invalid("<length", "10px");
 assert_invalid("<LENGTH>", "10px");
 assert_invalid("< length>", "10px");
 assert_invalid("<length >", "10px");
 assert_invalid("<length> +", "10px");
+assert_invalid("<transform-list>+", "scale(2)");
+assert_invalid("<transform-list>#", "scale(2)");
 
 assert_invalid("<length>++", "10px");
+assert_invalid("<length>##", "10px");
+assert_invalid("<length>+#", "10px");
+assert_invalid("<length>#+", "10px");
 assert_invalid("<length> | *", "10px");
 assert_invalid("*|banana", "banana");
+assert_invalid("|banana", "banana");
 assert_invalid("*+", "banana");
+assert_invalid("|", "banana");
+assert_invalid(" |", "banana");
+assert_invalid("||", "banana");
 
 assert_invalid("initial", "initial");
 assert_invalid("inherit", "inherit");
 assert_invalid("unset", "unset");
 assert_invalid("<length>|initial", "10px");
 assert_invalid("<length>|INHERIT", "10px");
 assert_invalid("<percentage>|unsEt", "2%");
 
--- a/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
@@ -96,16 +96,22 @@ test(function(){
 }, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]');
 
 test_computed_value('<length>', '12px', '12px');
 test_computed_value('<length>', '13vw', length_ref('13vw'));
 test_computed_value('<length>', '14em', '140px');
 test_computed_value('<length>', '15vmin', length_ref('15vmin'));
 test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)'));
 
+test_computed_value('<length>', '1in', '96px');
+test_computed_value('<length>', '2.54cm', '96px');
+test_computed_value('<length>', '25.4mm', '96px');
+test_computed_value('<length>', '6pc', '96px');
+test_computed_value('<length>', '72pt', '96px');
+
 test_computed_value('<length-percentage>', '17em', '170px');
 test_computed_value('<length-percentage>', '18%', '18%');
 test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(-2% + 190px)');
 
 test_computed_value('<length>#', '10px, 3em', '10px, 30px');
 test_computed_value('<length>#', '4em ,9px', '40px, 9px');
 test_computed_value('<length>#', '8em', '80px');
 
--- a/testing/web-platform/tests/css/css-properties-values-api/registered-property-initial.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-initial.html
@@ -1,27 +1,34 @@
 <!DOCTYPE html>
-<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-initialvalue" />
-<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#dom-propertydescriptor-initialvalue" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#register-a-custom-property" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#substitution" />
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="./resources/utils.js"></script>
 <div id=target></div>
 <script>
 
 function test_initial_value(reg, expected) {
     let suffix = reg.inherits === true ? ', inherits' : '';
     test(function(){
         let name = generate_property(reg);
         let actual = getComputedStyle(target).getPropertyValue(name);
         assert_equals(actual, expected);
     }, `Initial value for ${reg.syntax} correctly computed [${reg.initialValue}${suffix}]`);
 }
 
 test_initial_value({ syntax: '<length>', initialValue: 'calc(10px + 15px)' }, '25px');
+test_initial_value({ syntax: '<length>', initialValue: '1in' }, '96px');
+test_initial_value({ syntax: '<length>', initialValue: '2.54cm' }, '96px');
+test_initial_value({ syntax: '<length>', initialValue: '25.4mm' }, '96px');
+test_initial_value({ syntax: '<length>', initialValue: '6pc' }, '96px');
+test_initial_value({ syntax: '<length>', initialValue: '72pt' }, '96px');
+test_initial_value({ syntax: '<percentage>', initialValue: 'calc(10% + 20%)' }, '30%');
 test_initial_value({ syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)' }, 'calc(10% + 100px)');
 test_initial_value({ syntax: '<color>', initialValue: 'pink', inherits: true }, 'rgb(255, 192, 203)');
 test_initial_value({ syntax: '<color>', initialValue: 'purple' }, 'rgb(128, 0, 128)');
 test_initial_value({ syntax: '<transform-function>', initialValue: 'rotate(42deg)' }, 'rotate(42deg)');
 test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))' }, 'scale(4)');
 test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))' }, 'scale(3) translateX(4px)');
 
 // Test that the initial value of the custom property 'reg' is successfully
@@ -37,9 +44,24 @@ function test_substituted_value(reg, pro
             target.style = '';
         }
     }, `Initial ${inherits_text} value can be substituted [${reg.initialValue}, ${property}]`);
 }
 
 test_substituted_value({ syntax: '<color>', initialValue: 'purple', inherits: true }, 'color', 'rgb(128, 0, 128)');
 test_substituted_value({ syntax: '<color>', initialValue: 'pink' }, 'background-color', 'rgb(255, 192, 203)');
 
+// Registered properties shall substitute as a token sequence equivalent to
+// their computed value.
+test_substituted_value({ syntax: 'foo', initialValue: '\tfoo\t' }, '--x', 'foo');
+test_substituted_value({ syntax: '<angle>', initialValue: '\t1turn' }, '--x', '360deg');
+test_substituted_value({ syntax: '<color>', initialValue: ' pink ' }, '--x', 'rgb(255, 192, 203)');
+test_substituted_value({ syntax: '<custom-ident>', initialValue: '\ttest' }, '--x', 'test');
+test_substituted_value({ syntax: '<integer>', initialValue: 'calc(20 + 20 + 10)' }, '--x', '50');
+test_substituted_value({ syntax: '<length-percentage>', initialValue: '\tcalc(13% + 37px)' }, '--x', 'calc(13% + 37px)');
+test_substituted_value({ syntax: '<length>', initialValue: 'calc(10px + 15px)' }, '--x', '25px');
+test_substituted_value({ syntax: '<number>', initialValue: 'calc(13 + 37)' }, '--x', '50');
+test_substituted_value({ syntax: '<percentage>', initialValue: 'calc(13% + 37%)' }, '--x', '50%');
+test_substituted_value({ syntax: '<time>', initialValue: '2000ms' }, '--x', '2s');
+test_substituted_value({ syntax: '<transform-function>', initialValue: 'scale(calc(2 + 2))' }, '--x', 'scale(4)');
+test_substituted_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2)) translateX(calc(3px + 1px))' }, '--x', 'scale(4) translateX(4px)');
+
 </script>
--- a/testing/web-platform/tests/css/css-regions/META.yml
+++ b/testing/web-platform/tests/css/css-regions/META.yml
@@ -1,5 +1,4 @@
 spec: https://drafts.csswg.org/css-regions/
 suggested_reviewers:
-  - atanassov
   - astearns
   - rachelandrew
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scroll-anchoring/parsing/overflow-anchor-computed.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Scroll Anchoring: getComputedValue().overflowAnchor</title>
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
+<meta name="assert" content="overflow-anchor computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("overflow-anchor", "auto");
+test_computed_value("overflow-anchor", "none");
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scroll-anchoring/parsing/overflow-anchor-invalid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Scroll Anchoring: parsing overflow-anchor with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
+<meta name="assert" content="overflow-anchor supports only the grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("overflow-anchor", "all");
+test_invalid_value("overflow-anchor", "auto none");
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scroll-anchoring/parsing/overflow-anchor-valid.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Scroll Anchoring: parsing overflow-anchor with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
+<meta name="assert" content="overflow-anchor supports the full grammar 'auto | none'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("overflow-anchor", "auto");
+test_valid_value("overflow-anchor", "none");
+</script>
+</body>
+</html>
--- a/testing/web-platform/tests/css/css-scrollbars/META.yml
+++ b/testing/web-platform/tests/css/css-scrollbars/META.yml
@@ -1,3 +1,3 @@
 spec: https://drafts.csswg.org/css-scrollbars/
 suggested_reviewers:
-  - tantek
+  - upsuper
--- a/testing/web-platform/tests/css/css-shapes/META.yml
+++ b/testing/web-platform/tests/css/css-shapes/META.yml
@@ -1,7 +1,5 @@
 spec: https://drafts.csswg.org/css-shapes/
 suggested_reviewers:
-  - bemjb
   - kojiishi
   - plinss
-  - atanassov
   - astearns
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-sizing/dynamic-available-size-iframe.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta name="assert" content="Checks that an absolute positioned element is positioned correctly, when the available size of its parent changes due to document resize." />
+<link rel="help" href="https://crbug.com/928672">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<script src="/common/reftest-wait.js"></script>
+<p>Test passes if there is a filled green square.</p>
+<iframe id="target" height="100" width="200" src="support/dynamic-available-size-iframe.html" style="border: none;"></iframe>
+<script>
+onload = () => {
+  requestAnimationFrame(() => requestAnimationFrame(() => {
+    target.width = '100';
+    takeScreenshot();
+  }));
+};
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-sizing/support/dynamic-available-size-iframe.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0; }
+.parent {
+  position: relative;
+  display: flex;
+  width: 100%;
+  height: 100px;
+  background: red;
+}
+
+.content {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  margin: auto;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+
+svg {
+  width: 50px;
+  height: 50px;
+}
+</style>
+<div class="parent">
+  <div class="content">
+    <svg xmlns="http://www.w3.org/2000/svg"></svg>
+  </div>
+</div>
--- a/testing/web-platform/tests/css/css-style-attr/META.yml
+++ b/testing/web-platform/tests/css/css-style-attr/META.yml
@@ -1,4 +1,3 @@
 spec: https://drafts.csswg.org/css-style-attr/
 suggested_reviewers:
-  - tantek
   - fantasai
--- a/testing/web-platform/tests/css/css-syntax/META.yml
+++ b/testing/web-platform/tests/css/css-syntax/META.yml
@@ -1,5 +1,4 @@
 spec: https://drafts.csswg.org/css-syntax/
 suggested_reviewers:
   - gregwhitworth
   - tabatkins
-  - simonsapin
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-text-decor/reference/text-decoration-underline-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<p style="text-decoration:underline">This text should be underlined.</p>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-text-decor/text-decoration-propagation-shadow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>CSS Test: text-decoration propagation into shadow DOM boxes</title>
+<link rel="help" href="https://drafts.csswg.org/css-text-decor/#line-decoration">
+<link rel="match" href="reference/text-decoration-underline-ref.html">
+<style>
+  #host { text-decoration: underline }
+</style>
+<p>
+  <div id="host">
+    <span>This text should be underlined.</span>
+  </div>
+</p>
+<script>
+  const root = host.attachShadow({mode:"open"});
+  root.appendChild(document.createElement("slot"));
+</script>
--- a/testing/web-platform/tests/css/css-text/META.yml
+++ b/testing/web-platform/tests/css/css-text/META.yml
@@ -1,9 +1,8 @@
 spec: https://drafts.csswg.org/css-text/
 suggested_reviewers:
   - kojiishi
   - plinss
   - frivoal
   - r12a
   - nox
-  - hakatashi
   - fantasai
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-text/overflow-wrap/overflow-wrap-break-word-007.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: overflow-wrap: break-word</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-overflow-wrap-break-word">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/overflow-wrap-break-word-001-ref.html">
+<meta name="assert" content="A Single leading white-space constitutes a soft breaking opportunity, honoring the 'white-space: break-spaces' property, that must prevent the word to be broken.">
+<style>
+div {
+   position: relative;
+   font-size: 20px;
+   font-family: Ahem;
+}
+.red {
+  position: absolute;
+  background: green;
+  color: red;
+  width: 100px;
+  height: 100px;
+  z-index: -1;
+  white-space: pre;
+}
+.test {
+  color: green;
+  line-height: 1em;
+  width: 5ch;
+
+  white-space: pre-wrap;
+  overflow-wrap: break-word;
+}
+</style>
+<body>
+  <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+  <div class="red"> XX  <br>XXX</div>
+  <div class="test"> XX XXX </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-text/shaping/reference/shaping-000-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: span</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+