diff --git a/DEPS b/DEPS
index 7288f41..282bad33 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '8cf82c04362d3393b7fd0a29788242421fc9e10d',
+  'v8_revision': '4668fa98f8923a491d8f80ff7260c9a3b3979c00',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index cbaf276..0f60e9c 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -24,22 +24,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#define EXPECT_ACTION(action, client, action_index, expected_num_actions)  \
-  do {                                                                     \
-    EXPECT_EQ(expected_num_actions, client->num_actions_());               \
-    if (action_index >= 0) {                                               \
-      ASSERT_LT(action_index, client->num_actions_()) << scheduler_.get(); \
-      EXPECT_STREQ(action, client->Action(action_index));                  \
-    }                                                                      \
-    for (int i = expected_num_actions; i < client->num_actions_(); ++i)    \
-      ADD_FAILURE() << "Unexpected action: " << client->Action(i)          \
-                    << " with state:\n"                                    \
-                    << client->StateForAction(i);                          \
-  } while (false)
+#define EXPECT_ACTIONS(...) \
+  EXPECT_THAT(client_->Actions(), ::testing::ElementsAre(__VA_ARGS__))
 
-#define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
-
-#define EXPECT_SINGLE_ACTION(action, client) EXPECT_ACTION(action, client, 0, 1)
+#define EXPECT_NO_ACTION() EXPECT_THAT(client_->Actions(), ::testing::IsEmpty())
 
 #define EXPECT_SCOPED(statements) \
   {                               \
@@ -79,8 +67,9 @@
 
   bool needs_begin_frames() { return scheduler_->begin_frames_expected(); }
   int num_draws() const { return num_draws_; }
-  int num_actions_() const { return static_cast<int>(actions_.size()); }
-  const char* Action(int i) const { return actions_[i]; }
+  const std::vector<std::string> Actions() const {
+    return std::vector<std::string>(actions_.begin(), actions_.end());
+  }
   std::string StateForAction(int i) const { return states_[i]->ToString(); }
   base::TimeTicks posted_begin_impl_frame_deadline() const {
     return posted_begin_impl_frame_deadline_;
@@ -338,14 +327,13 @@
 
     // Check the client doesn't have any actions queued when calling this
     // function.
-    EXPECT_NO_ACTION(client_);
+    EXPECT_NO_ACTION();
     EXPECT_FALSE(scheduler_->begin_frames_expected());
 
     // Start the initial CompositorFrameSink creation.
     scheduler_->SetVisible(true);
     scheduler_->SetCanDraw(true);
-    EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
-                         client_);
+    EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation");
 
     client_->Reset();
 
@@ -476,25 +464,24 @@
   scheduler_->SetVisible(true);
   scheduler_->SetCanDraw(true);
 
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
-                       client_);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation");
   client_->Reset();
   scheduler_->DidCreateAndInitializeCompositorFrameSink();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 }
 
 TEST_F(SchedulerTest, Stop) {
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // No scheduled actions are performed after Stop. WillBeginImplFrame is only
   // a notification and not an action performed by the scheduler.
   scheduler_->Stop();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   client_->Reset();
 }
 
@@ -502,31 +489,30 @@
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetVideoNeedsBeginFrames(true);
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   // WillBeginImplFrame is responsible for sending BeginFrames to video.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
 
   client_->Reset();
   scheduler_->SetVideoNeedsBeginFrames(false);
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(scheduler_->begin_frames_expected());
 }
 
@@ -535,19 +521,18 @@
 
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   // If we don't swap on the deadline, we wait for the next BeginFrame.
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
@@ -555,27 +540,27 @@
   // NotifyReadyToCommit should trigger the commit.
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   // NotifyReadyToActivate should trigger the activation.
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   // BeginImplFrame should prepare the draw.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   // BeginImplFrame deadline should draw.
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
@@ -583,14 +568,13 @@
   // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
   // to avoid excessive toggles.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   client_->Reset();
 }
 
@@ -600,23 +584,22 @@
   scheduler_->SetDeferCommits(true);
 
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   task_runner().RunPendingTasks();
   // There are no pending tasks or actions.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(scheduler_->begin_frames_expected());
 
   client_->Reset();
   scheduler_->SetDeferCommits(false);
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   // Start new BeginMainFrame after defer commit is off.
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 }
 
@@ -626,28 +609,28 @@
   scheduler_->SetDeferCommits(true);
 
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // The SetNeedsRedraw will override the SetDeferCommits(true), to allow a
   // begin frame to be needed.
   client_->Reset();
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   AdvanceFrame();
   // BeginMainFrame is not sent during the defer commit is on.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
 
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
   client_->Reset();
   AdvanceFrame();
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+  EXPECT_ACTIONS("WillBeginImplFrame");
 }
 
 TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
@@ -655,12 +638,11 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   EXPECT_TRUE(scheduler_->begin_frames_expected());
@@ -669,24 +651,24 @@
   // Now SetNeedsBeginMainFrame again. Calling here means we need a second
   // commit.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_EQ(client_->num_actions_(), 0);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   // Finish the first commit.
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Activate it.
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // Because we just swapped, the Scheduler should also request the next
@@ -696,8 +678,7 @@
   // Since another commit is needed, the next BeginImplFrame should initiate
   // the second commit.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -705,15 +686,15 @@
   // to trigger the deadline early.
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
@@ -1004,8 +985,8 @@
   // the deadline task.
   client->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   // On the deadline, the actions should have occured in the right order.
@@ -1032,8 +1013,8 @@
   // the deadline task.
   client->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   // Draw. The draw will trigger SetNeedsPrepareTiles, and
@@ -1053,13 +1034,12 @@
   // We need a BeginImplFrame where we don't swap to go idle.
   client->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_EQ(0, client->num_draws());
 
@@ -1075,8 +1055,8 @@
   // BeginImplFrame. There will be no draw, only PrepareTiles.
   client->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
@@ -1097,8 +1077,8 @@
   scheduler_->SetNeedsRedraw();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   EXPECT_TRUE(scheduler_->PrepareTilesPending());
@@ -1120,8 +1100,8 @@
   scheduler_->SetNeedsRedraw();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
@@ -1143,8 +1123,8 @@
   scheduler_->SetNeedsRedraw();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   EXPECT_TRUE(scheduler_->PrepareTilesPending());
@@ -1168,8 +1148,8 @@
   scheduler_->SetNeedsRedraw();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   EXPECT_TRUE(scheduler_->PrepareTilesPending());
@@ -1187,8 +1167,8 @@
   scheduler_->SetNeedsRedraw();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
@@ -1210,19 +1190,19 @@
 
   client_->Reset();
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 "ScheduledActionPrepareTiles");
 
   // We don't want to hinder scheduled prepare tiles for more than one frame
   // even if we call unscheduled prepare tiles many times.
@@ -1234,8 +1214,8 @@
   client_->Reset();
   scheduler_->SetNeedsRedraw();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   // No scheduled prepare tiles because we've already counted a prepare tiles in
@@ -1243,21 +1223,21 @@
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 
   client_->Reset();
   scheduler_->SetNeedsRedraw();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   // Resume scheduled prepare tiles.
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 "ScheduledActionPrepareTiles");
 }
 
 TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
@@ -1281,28 +1261,27 @@
 
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
 
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   // Scheduler won't post deadline in the mode.
   client_->Reset();
   task_runner().RunPendingTasks();  // Try to run posted deadline.
   // There is no posted deadline.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Scheduler received ready to draw signal, and posted deadline.
   scheduler_->NotifyReadyToDraw();
@@ -1320,28 +1299,27 @@
 
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
 
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   // Scheduler won't post deadline in the mode.
   client_->Reset();
   task_runner().RunPendingTasks();  // Try to run posted deadline.
   // There is no posted deadline.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Scheduler loses CompositorFrameSink, and stops waiting for ready to draw
   // signal.
@@ -1349,10 +1327,8 @@
   scheduler_->DidLoseCompositorFrameSink();
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 void SchedulerTest::AdvanceAndMissOneFrame() {
@@ -1366,11 +1342,9 @@
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
+                 "ScheduledActionActivateSyncTree");
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
   client_->Reset();
 }
@@ -1413,9 +1387,8 @@
 
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionDrawIfPossible");
 }
 
 TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) {
@@ -1527,9 +1500,8 @@
   scheduler_->SetNeedsBeginMainFrame();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame");
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -1563,9 +1535,8 @@
   scheduler_->SetNeedsBeginMainFrame();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame");
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -1576,8 +1547,7 @@
   client_->Reset();
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
   scheduler_->SetCanDraw(false);
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
@@ -1585,7 +1555,7 @@
   // Make CanDraw true after activation.
   client_->Reset();
   scheduler_->SetCanDraw(true);
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
   // Make sure we don't skip the next BeginMainFrame.
@@ -1611,9 +1581,8 @@
   scheduler_->SetNeedsRedraw();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   SendNextBeginFrame();
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
@@ -1621,9 +1590,8 @@
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                 "ScheduledActionDrawIfPossible");
 
   // Verify we skip every other frame if the swap ack consistently
   // comes back late.
@@ -1636,7 +1604,7 @@
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
     SendNextBeginFrame();
     // Verify that we skip the BeginImplFrame
-    EXPECT_NO_ACTION(client_);
+    EXPECT_NO_ACTION();
     EXPECT_FALSE(client_->IsInsideBeginImplFrame());
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
@@ -1652,24 +1620,22 @@
       task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
       scheduler_->DidReceiveCompositorFrameAck();
     }
-    EXPECT_NO_ACTION(client_);
+    EXPECT_NO_ACTION();
 
     // Verify that we start the next BeginImplFrame and continue normally
     // after having just skipped a BeginImplFrame.
     client_->Reset();
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
     SendNextBeginFrame();
-    EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-    EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+    EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
     client_->Reset();
     scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
     scheduler_->NotifyReadyToCommit();
     scheduler_->NotifyReadyToActivate();
     task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-    EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
-    EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
-    EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+    EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                   "ScheduledActionDrawIfPossible");
   }
 }
 
@@ -1737,14 +1703,13 @@
   scheduler_->SetNeedsRedraw();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   SendNextBeginFrame();
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
 
   client_->Reset();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 
   // Verify we skip every other frame if the swap ack consistently
   // comes back late.
@@ -1756,7 +1721,7 @@
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
     SendNextBeginFrame();
     // Verify that we skip the BeginImplFrame
-    EXPECT_NO_ACTION(client_);
+    EXPECT_NO_ACTION();
     EXPECT_FALSE(client_->IsInsideBeginImplFrame());
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
@@ -1764,23 +1729,22 @@
     // swap throttled.
     client_->Reset();
     scheduler_->DidReceiveCompositorFrameAck();
-    EXPECT_NO_ACTION(client_);
+    EXPECT_NO_ACTION();
 
     // Verify that we start the next BeginImplFrame and continue normally
     // after having just skipped a BeginImplFrame.
     client_->Reset();
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
     SendNextBeginFrame();
-    EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-    EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1,
-                  2);
+    EXPECT_ACTIONS("WillBeginImplFrame",
+                   "ScheduledActionBeginMainFrameNotExpectedUntil");
 
     client_->Reset();
     // Deadline should be immediate.
     EXPECT_TRUE(client_->IsInsideBeginImplFrame());
     task_runner().RunUntilTime(now_src_->NowTicks());
     EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-    EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+    EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   }
 }
 
@@ -1793,9 +1757,8 @@
   scheduler_->SetNeedsBeginMainFrame();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   SendNextBeginFrame();
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
@@ -1803,9 +1766,8 @@
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                 "ScheduledActionDrawIfPossible");
 
   // Verify impl thread consistently operates in high latency mode
   // without skipping any frames.
@@ -1817,7 +1779,7 @@
     scheduler_->SetNeedsBeginMainFrame();
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
     SendNextBeginFrame();
-    EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+    EXPECT_ACTIONS("WillBeginImplFrame");
     EXPECT_TRUE(client_->IsInsideBeginImplFrame());
     EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
@@ -1829,10 +1791,9 @@
     task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
 
     // Verify that we don't skip the actions of the BeginImplFrame
-    EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 4);
-    EXPECT_ACTION("ScheduledActionCommit", client_, 1, 4);
-    EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 4);
-    EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 4);
+    EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
+                   "ScheduledActionActivateSyncTree",
+                   "ScheduledActionDrawIfPossible");
   }
 }
 
@@ -1903,11 +1864,9 @@
   scheduler_->NotifyReadyToActivate();
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
 
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
+                 "ScheduledActionActivateSyncTree");
 
   // Draw and swap for first commit, start second commit.
   client_->Reset();
@@ -1920,11 +1879,9 @@
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
 
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionDrawIfPossible", "ScheduledActionCommit",
+                 "ScheduledActionActivateSyncTree");
 
   // Don't call scheduler_->DidReceiveCompositorFrameAck() until after next
   // frame
@@ -1936,7 +1893,7 @@
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
 
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   // Note: BeginMainFrame and swap are skipped here because of
   // swap ack backpressure, not because of latency recovery.
   EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
@@ -1961,8 +1918,7 @@
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
 
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionDrawIfPossible");
 
   // Verify we skip the BeginImplFrame second.
   client_->Reset();
@@ -1975,7 +1931,7 @@
   scheduler_->DidReceiveCompositorFrameAck();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Then verify we operate in a low latency mode.
   client_->Reset();
@@ -1992,11 +1948,9 @@
   scheduler_->DidReceiveCompositorFrameAck();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
 
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 4, 5);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                 "ScheduledActionDrawIfPossible");
 }
 
 TEST_F(
@@ -2027,12 +1981,10 @@
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->CommitPending());
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 6);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 6);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionDrawIfPossible", "ScheduledActionCommit",
+                 "ScheduledActionActivateSyncTree");
 
   // Make sure that we can finish the next commit even while swap throttled.
   client_->Reset();
@@ -2045,9 +1997,8 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionCommit");
 
   // Make sure we do not send a BeginMainFrame while swap throttled and
   // we have both a pending tree and an active tree.
@@ -2057,7 +2008,7 @@
   EXPECT_SCOPED(AdvanceFrame());
   EXPECT_FALSE(scheduler_->CommitPending());
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
 }
 
 TEST_F(
@@ -2091,11 +2042,9 @@
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_FALSE(scheduler_->CommitPending());
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 4, 5);
+  EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
+                 "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionDrawIfPossible", "ScheduledActionCommit");
 
   // Start another commit while we still have an active tree.
   client_->Reset();
@@ -2109,21 +2058,19 @@
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   scheduler_->DidReceiveCompositorFrameAck();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionDrawIfPossible");
 
   // Can't commit yet because there's still a pending tree.
   client_->Reset();
   scheduler_->NotifyReadyToCommit();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Activate the pending tree, which also unblocks the commit immediately
   // while we are in an idle state.
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree", "ScheduledActionCommit");
 }
 
 void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) {
@@ -2132,45 +2079,43 @@
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame
   // without calling SetNeedsBeginFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Can't run the deadline task because it can race with begin frame for the
   // SyntheticBFS case.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // NotifyReadyToCommit should trigger the commit.
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 
   // NotifyReadyToActivate should trigger the activation.
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   client_->Reset();
 
   // BeginImplFrame deadline should draw. The following BeginImplFrame deadline
   // should SetNeedsBeginFrame(false) to avoid excessive toggles.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 3);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible", "WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   client_->Reset();
 
   // Make sure SetNeedsBeginFrame isn't called on the client
   // when the BeginFrame is no longer needed.
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_);
+  EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
   client_->Reset();
 }
 
@@ -2195,31 +2140,30 @@
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   client_->Reset();
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   // Trigger the first BeginImplFrame and BeginMainFrame
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // NotifyReadyToCommit should trigger the pending commit.
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 
   // NotifyReadyToActivate should trigger the activation and draw.
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   client_->Reset();
 
   // Swapping will put us into a swap throttled state.
   // Run posted deadline.
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2228,7 +2172,7 @@
   scheduler_->SetNeedsBeginMainFrame();
   scheduler_->SetNeedsRedraw();
   EXPECT_SCOPED(AdvanceFrame());  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2247,13 +2191,13 @@
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Take us out of a swap throttled state.
   scheduler_->DidReceiveCompositorFrameAck();
-  EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
+  EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2285,15 +2229,13 @@
   scheduler_->SetVisible(true);
   scheduler_->SetCanDraw(true);
 
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
-                       client_);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation");
   client_->Reset();
   scheduler_->DidCreateAndInitializeCompositorFrameSink();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   scheduler_->DidLoseCompositorFrameSink();
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
-                       client_);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation");
 }
 
 TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterBeginFrameStarted) {
@@ -2301,31 +2243,27 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   // RemoveObserver(this) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
 
   client_->Reset();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest,
@@ -2334,18 +2272,17 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   // Do nothing when impl frame is in deadine pending state.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   // Run posted deadline.
@@ -2354,24 +2291,21 @@
   // OnBeginImplFrameDeadline didn't schedule CompositorFrameSink creation
   // because
   // main frame is not yet completed.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // BeginImplFrame is not started.
   client_->Reset();
   task_runner().RunUntilTime(now_src()->NowTicks() +
                              base::TimeDelta::FromMilliseconds(10));
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 2,
-                3);
+  EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                 "ScheduledActionBeginCompositorFrameSinkCreation");
 }
 
 TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterReadyToCommit) {
@@ -2379,31 +2313,28 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
 
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   // Sync tree should be forced to activate.
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   // RemoveObserver(this) is not called until the end of the frame.
   client_->Reset();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterSetNeedsPrepareTiles) {
@@ -2411,26 +2342,24 @@
 
   scheduler_->SetNeedsPrepareTiles();
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   // RemoveObserver(this) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 1,
-                4);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
+  EXPECT_ACTIONS("ScheduledActionPrepareTiles",
+                 "ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest,
@@ -2444,8 +2373,7 @@
 
   client_->Reset();
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -2453,26 +2381,25 @@
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
   // NotifyReadyToActivate should trigger the activation.
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   // RemoveObserver(this) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
   client_->Reset();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(scheduler_->begin_frames_expected());
 }
 
@@ -2481,34 +2408,31 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
 
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   client_->Reset();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 
   // Idle time between BeginFrames.
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
@@ -2516,18 +2440,17 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
@@ -2535,9 +2458,8 @@
   task_runner().RunPendingTasks();  // Run posted deadline.
 
   // Sync tree should be forced to activate.
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree", "RemoveObserver(this)",
+                 "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {
@@ -2545,18 +2467,17 @@
 
   // SetNeedsBeginMainFrame should begin the frame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
@@ -2564,7 +2485,7 @@
   task_runner().RunPendingTasks();  // Run posted deadline.
 
   // Sync tree should be forced to activate.
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 }
 
 // Tests to ensure frame sources can be successfully changed while drawing.
@@ -2573,17 +2494,17 @@
 
   // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   scheduler_->SetNeedsRedraw();
 
   // Switch to an unthrottled frame source.
@@ -2592,14 +2513,14 @@
 
   // Unthrottled frame source will immediately begin a new frame.
   task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // If we don't swap on the deadline, we wait for the next BeginFrame.
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 }
@@ -2611,12 +2532,12 @@
 
   // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
 
   // Switch to an unthrottled frame source before the frame deadline is hit.
   scheduler_->SetBeginFrameSource(unthrottled_frame_source_.get());
@@ -2627,15 +2548,15 @@
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 3);
-  // Unthrottled frame source will immediately begin a new frame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 // Unthrottled frame source will immediately begin a new frame.
+                 "WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   scheduler_->SetNeedsRedraw();
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 }
@@ -2646,17 +2567,17 @@
   SetUpScheduler(UNTHROTTLED_BFS);
 
   scheduler_->SetNeedsRedraw();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2667,39 +2588,39 @@
   // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsRedraw();
   task_runner().RunPendingTasks();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 }
 
 TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) {
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   client_->Reset();
 
   // Switch to a null frame source.
   scheduler_->SetBeginFrameSource(nullptr);
-  EXPECT_SINGLE_ACTION("RemoveObserver(this)", client_);
+  EXPECT_ACTIONS("RemoveObserver(this)");
   client_->Reset();
 
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(scheduler_->begin_frames_expected());
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
@@ -2707,28 +2628,27 @@
   // AdvanceFrame helper can't be used here because there's no deadline posted.
   scheduler_->SetNeedsRedraw();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   scheduler_->SetNeedsBeginMainFrame();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   client_->Reset();
 
   // Switch back to the same source, make sure frames continue to be produced.
   scheduler_->SetBeginFrameSource(fake_external_begin_frame_source_.get());
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   task_runner().RunPendingTasks();
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 }
 
 // This test maskes sure that switching a frame source when not observing
@@ -2738,22 +2658,21 @@
 
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
 
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   // Scheduler loses CompositorFrameSink, and stops waiting for ready to draw
   // signal.
@@ -2761,29 +2680,26 @@
   scheduler_->DidLoseCompositorFrameSink();
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   task_runner().RunPendingTasks();
-  EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0,
-                3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 
   // Changing begin frame source doesn't do anything.
   // The unthrottled source doesn't print Add/RemoveObserver like the fake one.
   client_->Reset();
   scheduler_->SetBeginFrameSource(unthrottled_frame_source_.get());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   scheduler_->DidCreateAndInitializeCompositorFrameSink();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 }
 
 // Tests to ensure that we send a ScheduledActionBeginMainFrameNotExpectedUntil
@@ -2792,14 +2708,14 @@
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsRedraw();
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 1);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   EXPECT_SCOPED(AdvanceFrame());
   task_runner().RunPendingTasks();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "ScheduledActionDrawIfPossible");
   client_->Reset();
 }
 
@@ -2809,7 +2725,7 @@
 
   // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Trigger a frame draw.
@@ -2818,24 +2734,21 @@
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   task_runner().RunPendingTasks();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 4, 5);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+                 "ScheduledActionDrawIfPossible");
   client_->Reset();
 
   // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
   // and send a SendBeginMainFrameNotExpectedSoon.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   client_->Reset();
 }
 
@@ -2844,7 +2757,7 @@
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsOneBeginImplFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Testing the case where animation ticks a fling scroll.
@@ -2854,9 +2767,9 @@
 
   // Next vsync.
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 2, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "ScheduledActionInvalidateCompositorFrameSink");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2864,7 +2777,7 @@
   scheduler_->SetNeedsRedraw();
   bool resourceless_software_draw = false;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2874,25 +2787,24 @@
 
   // Next vsync.
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Android onDraw.
   scheduler_->SetNeedsRedraw();
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Idle on next vsync, as the animation has completed.
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 4);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 }
@@ -2904,17 +2816,15 @@
   scheduler_->SetNeedsRedraw();
   bool resourceless_software_draw = false;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_ACTION("AddObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 1, 2);
+  EXPECT_ACTIONS("AddObserver(this)", "ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Idle on next vsync.
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 4);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 }
@@ -2926,7 +2836,7 @@
 
   // Request a frame, should kick the source.
   scheduler_->SetNeedsOneBeginImplFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // The incoming WillBeginImplFrame will request another one.
@@ -2934,8 +2844,8 @@
 
   // Next vsync, the first requested frame happens.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2944,8 +2854,8 @@
   // Next vsync, the second requested frame happens (the one requested inside
   // the previous frame's begin impl frame step).
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
@@ -2954,8 +2864,7 @@
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // Scheduler shuts down the source now that no begin frame is requested.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 }
 
 TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {
@@ -2967,13 +2876,12 @@
       fake_external_begin_frame_source_->next_begin_frame_number() - 1;
 
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Next vsync.
   BeginFrameArgs args = SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   bool has_damage = false;
@@ -2983,11 +2891,11 @@
   client_->Reset();
 
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Next vsync.
   args = SendNextBeginFrame();
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+  EXPECT_ACTIONS("WillBeginImplFrame");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   has_damage = false;
@@ -2997,18 +2905,18 @@
   client_->Reset();
 
   scheduler_->NotifyReadyToCommit();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   client_->Reset();
 
   // Next vsync.
   args = SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // Not confirmed yet and no damage, since not drawn yet.
@@ -3025,16 +2933,15 @@
   scheduler_->SetNeedsRedraw();
   bool resourceless_software_draw = false;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   // Idle on next vsync.
   args = SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 4);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   latest_confirmed_sequence_number = args.sequence_number;
@@ -3050,43 +2957,41 @@
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Next vsync.
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   client_->Reset();
 
   // Ask for another commit.
   scheduler_->SetNeedsBeginMainFrame();
 
   AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Allow new commit even though previous commit hasn't been drawn.
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 }
 
@@ -3109,22 +3014,22 @@
   SetUpScheduler(EXTERNAL_BFS, std::move(client));
 
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Next vsync.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   client_->Reset();
 
   // Android onDraw.
   scheduler_->SetNeedsRedraw();
   bool resourceless_software_draw = false;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 "ScheduledActionPrepareTiles");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_FALSE(scheduler_->PrepareTilesPending());
   client_->Reset();
@@ -3132,8 +3037,8 @@
   // Android onDraw.
   scheduler_->SetNeedsRedraw();
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 "ScheduledActionPrepareTiles");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_FALSE(scheduler_->PrepareTilesPending());
   client_->Reset();
@@ -3141,10 +3046,9 @@
   // Next vsync.
   EXPECT_SCOPED(AdvanceFrame());
   EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 4);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil",
+                 "RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(scheduler_->begin_frames_expected());
   client_->Reset();
 }
@@ -3154,57 +3058,57 @@
   SetUpScheduler(EXTERNAL_BFS);
 
   scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+  EXPECT_ACTIONS("AddObserver(this)");
   client_->Reset();
 
   // Next vsync.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   client_->Reset();
 
   // Android onDraw.
   scheduler_->SetNeedsRedraw();
   bool resourceless_software_draw = false;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_FALSE(scheduler_->PrepareTilesPending());
   client_->Reset();
 
   // Simulate SetNeedsBeginMainFrame due to input event.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
+  EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
   client_->Reset();
 
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
 
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
   client_->Reset();
 
   // Next vsync.
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
-  EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 3);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 2, 3);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionInvalidateCompositorFrameSink",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   client_->Reset();
 
   // Android onDraw.
   scheduler_->SetNeedsRedraw();
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_FALSE(scheduler_->PrepareTilesPending());
   client_->Reset();
 
   // Simulate SetNeedsBeginMainFrame due to input event.
   scheduler_->SetNeedsBeginMainFrame();
-  EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
+  EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
   client_->Reset();
 }
 
@@ -3218,7 +3122,7 @@
   bool resourceless_software_draw = true;
   scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
   // SynchronousCompositor has to draw regardless of visibility.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 }
@@ -3294,28 +3198,26 @@
   scheduler_->SetNeedsBeginMainFrame();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   // Lose the CompositorFrameSink and trigger the deadline.
   client_->Reset();
   scheduler_->DidLoseCompositorFrameSink();
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // The scheduler should not trigger the CompositorFrameSink creation till the
   // commit is aborted.
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_);
+  EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
 
   // Abort the commit.
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
   scheduler_->BeginMainFrameAborted(
       CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST);
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
-                       client_);
+  EXPECT_ACTIONS("ScheduledActionBeginCompositorFrameSinkCreation");
 }
 
 TEST_F(SchedulerTest, ImplSideInvalidationsInDeadline) {
@@ -3326,13 +3228,13 @@
   scheduler_->SetNeedsImplSideInvalidation();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
 
   // Deadline.
   client_->Reset();
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_SINGLE_ACTION("ScheduledActionPerformImplSideInvalidation", client_);
+  EXPECT_ACTIONS("ScheduledActionPerformImplSideInvalidation");
 }
 
 TEST_F(SchedulerTest, ImplSideInvalidationsMergedWithCommit) {
@@ -3344,8 +3246,7 @@
   scheduler_->SetNeedsImplSideInvalidation();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   // Respond with a commit. The scheduler should only perform the commit
   // actions since the impl-side invalidation request will be merged with the
@@ -3353,13 +3254,13 @@
   client_->Reset();
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
   scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+  EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_FALSE(scheduler_->needs_impl_side_invalidation());
 
   // Deadline.
   client_->Reset();
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 }
 
 TEST_F(SchedulerTest, AbortedCommitsTriggerImplSideInvalidations) {
@@ -3370,8 +3271,7 @@
   scheduler_->SetNeedsImplSideInvalidation();
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   // Abort the main frame and request another one, the impl-side invalidations
   // should not be blocked on the main frame.
@@ -3380,23 +3280,22 @@
   scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
   scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_SINGLE_ACTION("ScheduledActionPerformImplSideInvalidation", client_);
+  EXPECT_ACTIONS("ScheduledActionPerformImplSideInvalidation");
 
   // Activate the sync tree.
   client_->Reset();
   scheduler_->NotifyReadyToActivate();
-  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+  EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
 
   // Second impl frame.
   client_->Reset();
   EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   // Deadline.
   client_->Reset();
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
 }
 
 // The three letters appeneded to each version of this test mean the following:s
@@ -3486,14 +3385,14 @@
 
   BeginFrameArgs args = SendNextBeginFrame();
   EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -3512,17 +3411,17 @@
 
   args = SendNextBeginFrame();
   EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   client_->SetDrawWillHappen(false);
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
-  // Failed draw triggers SendBeginMainFrame.
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
+                 // Failed draw triggers SendBeginMainFrame.
+                 "ScheduledActionSendBeginMainFrame");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -3547,14 +3446,14 @@
   client_->Reset();
 
   BeginFrameArgs args = SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -3573,7 +3472,7 @@
 
   args = SendNextBeginFrame();
   EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -3593,8 +3492,8 @@
   client_->Reset();
 
   SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   // Until tiles were prepared, further proactive BeginFrames are expected.
   EXPECT_TRUE(scheduler_->begin_frames_expected());
@@ -3605,9 +3504,8 @@
   // during which tiles will be prepared. As a result of that, no further
   // BeginFrames will be needed, and the new BeginFrame should be dropped.
   BeginFrameArgs args = SendNextBeginFrame();
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 3);
-  EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
+  EXPECT_ACTIONS("ScheduledActionPrepareTiles", "RemoveObserver(this)",
+                 "SendBeginMainFrameNotExpectedSoon");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_FALSE(scheduler_->begin_frames_expected());
 
@@ -3636,8 +3534,8 @@
 
   // First BeginFrame is handled by StateMachine.
   BeginFrameArgs first_args = SendNextBeginFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   // State machine is no longer interested in BeginFrames, but scheduler is
   // still observing the source.
@@ -3649,7 +3547,7 @@
   // The BeginFrame should be dropped immediately, since the state machine is
   // not expecting any BeginFrames.
   BeginFrameArgs second_args = SendNextBeginFrame();
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
 
   // Latest ack should be for the dropped (and unconfirmed) BeginFrame.
   bool has_damage = false;
@@ -3659,8 +3557,7 @@
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run deadline of prior BeginFrame.
-  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+  EXPECT_ACTIONS("RemoveObserver(this)", "SendBeginMainFrameNotExpectedSoon");
 
   // We'd expect an out-of-order ack for the prior BeginFrame, confirming it.
   latest_confirmed_sequence_number = first_args.sequence_number;
@@ -3690,7 +3587,7 @@
   EXPECT_GT(now_src_->NowTicks(), args.deadline);
   fake_external_begin_frame_source_->TestOnBeginFrame(args);
 
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // Latest ack should be for the missed BeginFrame that was too late: no damage
@@ -3715,14 +3612,14 @@
                                                        source_id, 1, now_src());
   fake_external_begin_frame_source_->TestOnBeginFrame(args);
 
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionBeginMainFrameNotExpectedUntil", client_, 1, 2);
+  EXPECT_ACTIONS("WillBeginImplFrame",
+                 "ScheduledActionBeginMainFrameNotExpectedUntil");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
   client_->Reset();
 
   task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
+  EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   EXPECT_TRUE(scheduler_->begin_frames_expected());
 
@@ -3752,7 +3649,7 @@
   EXPECT_GT(now_src_->NowTicks(), args.deadline);
   fake_external_begin_frame_source_->TestOnBeginFrame(args);
 
-  EXPECT_NO_ACTION(client_);
+  EXPECT_NO_ACTION();
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   // Latest ack should be for the missed BeginFrame that was too late: no damage
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
index 1649dc0..5128efe9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
@@ -104,6 +104,7 @@
     private TintedImageButton mMenuButton;
 
     private boolean mMenuExpanded;
+    private boolean mIsFirstLayout = true;
 
     /** The controller for translate UI snackbars. */
     class TranslateSnackbarController implements SnackbarController {
@@ -187,12 +188,27 @@
 
         mTabLayout.addOnTabSelectedListener(this);
 
-        // Dismiss all menus when there is layout changed. (which will cause menu misplacement.)
+        // Dismiss all menus and end peeking animation when there is layout changed.
         mTabLayout.addOnLayoutChangeListener(new OnLayoutChangeListener() {
             @Override
             public void onLayoutChange(View v, int left, int top, int right, int bottom,
                     int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                dismissMenus();
+                if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
+                    // Dismiss all menus to prevent menu misplacement.
+                    dismissMenus();
+
+                    if (mIsFirstLayout) {
+                        // If this pages is auto-translated (mInitialStep == TRANSLATING_INFOBAR),
+                        // peeking animation will scroll to end without scrolling back to start.
+                        mTabLayout.startPeekingAnimationIfNeeded(
+                                mInitialStep == TRANSLATING_INFOBAR);
+                        mIsFirstLayout = false;
+                        return;
+                    }
+
+                    // End peeking animation because the scroll distance might be changed.
+                    mTabLayout.endPeekingAnimationIfPlaying();
+                }
             }
         });
 
@@ -200,6 +216,7 @@
         mMenuButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
+                mTabLayout.endPeekingAnimationIfPlaying();
                 recordInfobarAction(INFOBAR_OPTIONS);
                 initMenuHelper(TranslateMenu.MENU_OVERFLOW);
                 mOverflowMenuHelper.show(TranslateMenu.MENU_OVERFLOW);
@@ -294,6 +311,7 @@
 
     @Override
     public void onCloseButtonClicked() {
+        mTabLayout.endPeekingAnimationIfPlaying();
         closeInfobar(true);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
index 78f4c47..a2862f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
@@ -4,27 +4,63 @@
 
 package org.chromium.chrome.browser.infobar.translate;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.support.annotation.NonNull;
 import android.support.design.widget.TabLayout;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.animation.DecelerateInterpolator;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * TabLayout shown in the TranslateCompactInfoBar.
  */
 public class TranslateTabLayout extends TabLayout {
-    // The tab in which a spinning progress bar is showing.
+    /** The tab in which a spinning progress bar is showing. */
     private Tab mTabShowingProgressBar;
 
+    /** The amount of waiting time before starting the peeking animation. */
+    private static final long START_POSITION_WAIT_DURATION_MS = 1000;
+
+    /** The amount of waiting time before starting the second part of the peeking animation. */
+    private static final long END_POSITION_WAIT_DURATION_MS = 1000;
+
+    /** The amount of time it takes to scroll to the end during the peeking animation. */
+    private static final long SCROLL_DURATION_MS = 300;
+
+    private AnimatorSet mPeekingAnimatorSet;
+
+    /** Start padding of a Tab.  Used for width calculation only.  Will not be applied to views. */
+    private int mTabPaddingStart;
+
+    /** End padding of a Tab.  Used for width calculation only.  Will not be applied to views. */
+    private int mTabPaddingEnd;
+
     /**
      * Constructor for inflating from XML.
      */
     public TranslateTabLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.TabLayout, 0, R.style.Widget_Design_TabLayout);
+        mTabPaddingStart = mTabPaddingEnd =
+                a.getDimensionPixelSize(R.styleable.TabLayout_tabPadding, 0);
+        mTabPaddingStart =
+                a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingStart, mTabPaddingStart);
+        mTabPaddingEnd =
+                a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingEnd, mTabPaddingEnd);
     }
 
     /**
@@ -107,6 +143,7 @@
         if (mTabShowingProgressBar != null) {
             return true;
         }
+        endPeekingAnimationIfPlaying();
         return super.onInterceptTouchEvent(ev);
     }
 
@@ -132,4 +169,94 @@
         }
         super.addTab(tab, setSelected);
     }
+
+    /**
+     * Calculate and return the width of a specified tab.  Tab doesn't provide a means of getting
+     * the width so we need to calculate the width by summing up the tab paddings and content width.
+     * @param position Tab position.
+     * @return Tab's width in pixels.
+     */
+    private int getTabWidth(int position) {
+        if (getTabAt(position) == null) return 0;
+        return getTabAt(position).getCustomView().getWidth() + mTabPaddingStart + mTabPaddingEnd;
+    }
+
+    /**
+     * Calculate the total width of all tabs and return it.
+     * @return Total width of all tabs in pixels.
+     */
+    private int getTabsTotalWidth() {
+        int totalWidth = 0;
+        for (int i = 0; i < getTabCount(); i++) {
+            totalWidth += getTabWidth(i);
+        }
+        return totalWidth;
+    }
+
+    /**
+     * Calculate the maximum scroll distance (by subtracting layout width from total width of tabs)
+     * and return it.
+     * @return Maximum scroll distance in pixels.
+     */
+    private int maxScrollDistance() {
+        int scrollDistance = getTabsTotalWidth() - getWidth();
+        return scrollDistance > 0 ? scrollDistance : 0;
+    }
+
+    /**
+     * Perform the peeking animation if: >50% of second tab is invisible, or this is a "scroll to
+     * end only" animation.
+     */
+    public void startPeekingAnimationIfNeeded(boolean scrollToEndOnly) {
+        int maxScrollDistance = maxScrollDistance();
+        int widthOfSecondTab = getTabWidth(1);
+
+        if (maxScrollDistance == 0
+                || (maxScrollDistance <= widthOfSecondTab / 2 && !scrollToEndOnly)) {
+            return;
+        }
+
+        DecelerateInterpolator easeOutInterpolator = new DecelerateInterpolator();
+        boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);
+
+        // The steps of the peeking animation:
+        //   1. wait for START_POSITION_WAIT_DURATION_MS.
+        //   2. scroll to the end in SCROLL_DURATION_MS.
+        //   3. wait for END_POSITION_WAIT_DURATION_MS. (skipped if scrollToEndOnly.)
+        //   4. scroll back to the start in SCROLL_DURATION_MS. (skipped if scrollToEndOnly.)
+        mPeekingAnimatorSet = new AnimatorSet();
+        List<Animator> animators = new ArrayList<>();
+
+        ObjectAnimator scrollToEndAnimator =
+                ObjectAnimator.ofInt(this, "scrollX", isRtl ? 0 : maxScrollDistance);
+        scrollToEndAnimator.setStartDelay(START_POSITION_WAIT_DURATION_MS);
+        scrollToEndAnimator.setDuration(SCROLL_DURATION_MS);
+        scrollToEndAnimator.setInterpolator(easeOutInterpolator);
+        animators.add(scrollToEndAnimator);
+
+        if (!scrollToEndOnly) {
+            ObjectAnimator scrollToStartAnimator =
+                    ObjectAnimator.ofInt(this, "scrollX", isRtl ? maxScrollDistance : 0);
+            scrollToStartAnimator.setStartDelay(END_POSITION_WAIT_DURATION_MS);
+            scrollToStartAnimator.setDuration(SCROLL_DURATION_MS);
+            scrollToStartAnimator.setInterpolator(easeOutInterpolator);
+            animators.add(scrollToStartAnimator);
+        }
+
+        mPeekingAnimatorSet.playSequentially(animators);
+        mPeekingAnimatorSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mPeekingAnimatorSet = null;
+            }
+        });
+        mPeekingAnimatorSet.start();
+    }
+
+    /**
+     * End the peeking animation if it is playing.
+     */
+    public void endPeekingAnimationIfPlaying() {
+        if (mPeekingAnimatorSet != null) mPeekingAnimatorSet.end();
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
index 6c7fbb2..6357917 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
@@ -4,34 +4,57 @@
 
 package org.chromium.chrome.browser.appmenu;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
+
 import android.support.test.filters.SmallTest;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.test.BottomSheetTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.BottomSheetTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 
 /**
  * Tests for the app menu when Chrome Home is enabled.
  */
-public class ChromeHomeAppMenuTest extends BottomSheetTestCaseBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
+public class ChromeHomeAppMenuTest {
     private static final String TEST_URL = UrlUtils.encodeHtmlDataUri("<html>foo</html>");
     private AppMenuHandler mAppMenuHandler;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Rule
+    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
 
-        mAppMenuHandler = getActivity().getAppMenuHandler();
+    @Before
+    public void setUp() throws Exception {
+        mBottomSheetTestRule.startMainActivityOnBlankPage();
+        mAppMenuHandler = mBottomSheetTestRule.getActivity().getAppMenuHandler();
     }
 
+    @Test
     @SmallTest
     public void testPageMenu() throws IllegalArgumentException, InterruptedException {
-        loadUrl(TEST_URL);
+        mBottomSheetTestRule.loadUrl(TEST_URL);
 
         showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = getActivity().getAppMenuHandler().getAppMenu();
+        AppMenu appMenu = mAppMenuHandler.getAppMenu();
         AppMenuIconRowFooter iconRow = (AppMenuIconRowFooter) appMenu.getPromptView();
 
         assertFalse(iconRow.getForwardButtonForTests().isEnabled());
@@ -46,7 +69,7 @@
             @Override
             public void run() {
                 mAppMenuHandler.hideAppMenu();
-                getActivity().getActivityTab().goBack();
+                mBottomSheetTestRule.getActivity().getActivityTab().goBack();
             }
         });
 
@@ -55,17 +78,18 @@
         assertTrue(iconRow.getForwardButtonForTests().isEnabled());
     }
 
+    @Test
     @SmallTest
     public void testTabSwitcherMenu() throws IllegalArgumentException {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().getLayoutManager().showOverview(false);
+                mBottomSheetTestRule.getActivity().getLayoutManager().showOverview(false);
             }
         });
 
         showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = getActivity().getAppMenuHandler().getAppMenu();
+        AppMenu appMenu = mAppMenuHandler.getAppMenu();
 
         assertNull(appMenu.getPromptView());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
index a71cd9e..bafafb69 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
@@ -4,69 +4,79 @@
 
 package org.chromium.chrome.browser.suggestions;
 
-import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
 
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.view.MotionEvent;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ntp.cards.ItemViewType;
-import org.chromium.chrome.test.BottomSheetTestCaseBase;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.SuggestionsBottomSheetTestRule;
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
-import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
-import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
 import org.chromium.content.browser.test.util.TestTouchUtils;
 
 /**
  * Instrumentation tests for {@link SuggestionsBottomSheetContent}.
  */
-public class SuggestionsBottomSheetTest extends BottomSheetTestCaseBase {
-    private FakeSuggestionsSource mSuggestionsSource;
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({SuggestionsBottomSheetTestRule.ENABLE_CHROME_HOME,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        SuggestionsBottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
+public class SuggestionsBottomSheetTest {
+    @Rule
+    public SuggestionsBottomSheetTestRule mSuggestionsTestRule =
+            new SuggestionsBottomSheetTestRule();
 
-    @Override
-    protected void setUp() throws Exception {
-        mSuggestionsSource = new FakeSuggestionsSource();
-        registerCategory(mSuggestionsSource, /* category = */ 42, /* count = */ 5);
-        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(mSuggestionsSource);
-        SuggestionsBottomSheetContent.setEventReporterForTesting(
-                new DummySuggestionsEventReporter());
-        super.setUp();
+    @Before
+    public void setUp() throws InterruptedException {
+        mSuggestionsTestRule.startMainActivityOnBlankPage();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(null);
-        SuggestionsBottomSheetContent.setEventReporterForTesting(null);
-        super.tearDown();
-    }
-
+    @Test
     @RetryOnFailure
     @MediumTest
     public void testContextMenu() throws InterruptedException {
         SuggestionsRecyclerView recyclerView =
-                (SuggestionsRecyclerView) getBottomSheetContent().getContentView().findViewById(
-                        R.id.recycler_view);
+                (SuggestionsRecyclerView) mSuggestionsTestRule.getBottomSheetContent()
+                        .getContentView()
+                        .findViewById(R.id.recycler_view);
 
         ViewHolder firstCardViewHolder = RecyclerViewTestUtils.waitForView(recyclerView, 2);
         assertEquals(firstCardViewHolder.getItemViewType(), ItemViewType.SNIPPET);
 
-        assertFalse(getActivity().getBottomSheet().onInterceptTouchEvent(createTapEvent()));
+        assertFalse(mSuggestionsTestRule.getBottomSheet().onInterceptTouchEvent(createTapEvent()));
 
-        TestTouchUtils.longClickView(getInstrumentation(), firstCardViewHolder.itemView);
-        assertTrue(getActivity().getBottomSheet().onInterceptTouchEvent(createTapEvent()));
+        TestTouchUtils.longClickView(
+                InstrumentationRegistry.getInstrumentation(), firstCardViewHolder.itemView);
+        assertTrue(mSuggestionsTestRule.getBottomSheet().onInterceptTouchEvent(createTapEvent()));
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().closeContextMenu();
+                mSuggestionsTestRule.getActivity().closeContextMenu();
             }
         });
 
-        assertFalse(getActivity().getBottomSheet().onInterceptTouchEvent(createTapEvent()));
+        assertFalse(mSuggestionsTestRule.getBottomSheet().onInterceptTouchEvent(createTapEvent()));
     }
 
     private static MotionEvent createTapEvent() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
index 0822816..9d5cd6b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
@@ -5,9 +5,7 @@
 package org.chromium.chrome.browser.suggestions;
 
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
-import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory;
 
-import android.app.Instrumentation;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.espresso.Espresso;
 import android.support.test.espresso.action.ViewActions;
@@ -16,100 +14,65 @@
 import android.support.test.filters.MediumTest;
 import android.support.test.uiautomator.UiDevice;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.ScreenShooter;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
-import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
-import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
+import org.chromium.chrome.test.SuggestionsBottomSheetTestRule;
 
 /**
  * Tests for the appearance of Article Snippets.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({"enable-features=ChromeHome", ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@CommandLineFlags.Add({SuggestionsBottomSheetTestRule.ENABLE_CHROME_HOME,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        SuggestionsBottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
 @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class SuggestionsBottomSheetUiCaptureTest {
     @Rule
-    public ChromeActivityTestRule<ChromeTabbedActivity> mActivityTestRule =
-            new ChromeActivityTestRule<>(ChromeTabbedActivity.class);
+    public SuggestionsBottomSheetTestRule mSuggestionsTestRule =
+            new SuggestionsBottomSheetTestRule();
 
     @Rule
     public ScreenShooter mScreenShooter = new ScreenShooter();
 
     private static final int MAX_WINDOW_UPDATE_TIME_MS = 1000;
 
-    private Instrumentation mInstrumentation;
-
-    private ChromeTabbedActivity mActivity;
-
-    private boolean mOldChromeHomeFlagValue;
-
-    private UiDevice mDevice;
-
     @Before
     public void setup() throws InterruptedException {
-        // TODO(dgn,mdjones): Chrome restarts when the ChromeHome feature flag value changes. That
-        // crashes the test so we need to manually set the preference to match the flag before
-        // staring Chrome.
-        ChromePreferenceManager prefManager = ChromePreferenceManager.getInstance();
-        mOldChromeHomeFlagValue = prefManager.isChromeHomeEnabled();
-        prefManager.setChromeHomeEnabled(true);
-        FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource();
-        registerCategory(suggestionsSource, /* category = */ 42, /* count = */ 5);
-        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(suggestionsSource);
-        SuggestionsBottomSheetContent.setEventReporterForTesting(
-                new DummySuggestionsEventReporter());
-        mActivityTestRule.startMainActivityOnBlankPage();
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mActivity = mActivityTestRule.getActivity();
-        mDevice = UiDevice.getInstance(mInstrumentation);
+        mSuggestionsTestRule.startMainActivityOnBlankPage();
     }
 
-    @After
-    public void tearDown() throws Exception {
-        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(null);
-        SuggestionsBottomSheetContent.setEventReporterForTesting(null);
-        ChromePreferenceManager.getInstance().setChromeHomeEnabled(mOldChromeHomeFlagValue);
+    private void setSheetState(final int position) {
+        mSuggestionsTestRule.setSheetState(position, false);
+        waitForWindowUpdates();
     }
 
-    private void setBottomSheetPosition(final int position) {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                BottomSheet bottomSheet = mActivity.getBottomSheet();
-                bottomSheet.setSheetState(position, /* animate = */ false);
-            }
-        });
+    private void waitForWindowUpdates() {
         // Wait for update to start and finish.
-        mDevice.waitForWindowUpdate(null, MAX_WINDOW_UPDATE_TIME_MS);
-        mDevice.waitForIdle(MAX_WINDOW_UPDATE_TIME_MS);
+        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        device.waitForWindowUpdate(null, MAX_WINDOW_UPDATE_TIME_MS);
+        device.waitForIdle(MAX_WINDOW_UPDATE_TIME_MS);
     }
 
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
     public void testBottomSheetPosition() throws Exception {
-        setBottomSheetPosition(BottomSheet.SHEET_STATE_HALF);
+        setSheetState(BottomSheet.SHEET_STATE_HALF);
         mScreenShooter.shoot("Half");
-        setBottomSheetPosition(BottomSheet.SHEET_STATE_FULL);
+        setSheetState(BottomSheet.SHEET_STATE_FULL);
         mScreenShooter.shoot("Full");
-        setBottomSheetPosition(BottomSheet.SHEET_STATE_PEEK);
+        setSheetState(BottomSheet.SHEET_STATE_PEEK);
         mScreenShooter.shoot("Peek");
     }
 
@@ -118,11 +81,10 @@
     @Feature({"UiCatalogue"})
     public void testContextMenu() throws Exception {
         // Needs to be "Full" to for this to work on small screens in landscape.
-        setBottomSheetPosition(BottomSheet.SHEET_STATE_FULL);
+        setSheetState(BottomSheet.SHEET_STATE_FULL);
         Espresso.onView(ViewMatchers.withId(R.id.recycler_view))
                 .perform(RecyclerViewActions.actionOnItemAtPosition(2, ViewActions.longClick()));
-        mDevice.waitForWindowUpdate(null, MAX_WINDOW_UPDATE_TIME_MS);
-        mDevice.waitForIdle(MAX_WINDOW_UPDATE_TIME_MS);
+        waitForWindowUpdates();
         mScreenShooter.shoot("Context_menu");
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
index f677ef0..c55fd01 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
@@ -4,10 +4,24 @@
 
 package org.chromium.chrome.browser.widget.bottomsheet;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
+
 import android.support.test.filters.SmallTest;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent;
 import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
 import org.chromium.chrome.browser.download.DownloadSheetContent;
@@ -15,31 +29,48 @@
 import org.chromium.chrome.browser.history.HistoryManagerUtils;
 import org.chromium.chrome.browser.history.HistorySheetContent;
 import org.chromium.chrome.browser.suggestions.SuggestionsBottomSheetContent;
-import org.chromium.chrome.test.BottomSheetTestCaseBase;
+import org.chromium.chrome.test.BottomSheetTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.util.concurrent.TimeoutException;
 
 /** This class tests the functionality of the {@link BottomSheetContentController}. */
-public class BottomSheetContentControllerTest extends BottomSheetTestCaseBase {
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"enable-features=ChromeHome",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
+public class BottomSheetContentControllerTest {
+    private BottomSheetTestRule.Observer mObserver;
+    private BottomSheet mBottomSheet;
+    private BottomSheetContentController mBottomSheetContentController;
+
+    @Rule
+    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
+
+    @Before
+    public void setUp() throws Exception {
+        mBottomSheetTestRule.startMainActivityOnBlankPage();
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        mObserver = mBottomSheetTestRule.getObserver();
+        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
+        mBottomSheetContentController = mBottomSheetTestRule.getBottomSheetContentController();
     }
 
+    @Test
     @SmallTest
     public void testSelectContent() throws InterruptedException, TimeoutException {
         int contentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
         int openedCount = mObserver.mOpenedCallbackHelper.getCallCount();
         int closedCount = mObserver.mClosedCallbackHelper.getCallCount();
 
-        setSheetState(BottomSheet.SHEET_STATE_HALF, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
         mObserver.mOpenedCallbackHelper.waitForCallback(openedCount, 1);
         openedCount++;
         assertEquals(contentChangedCount, mObserver.mContentChangedCallbackHelper.getCallCount());
         assertEquals(closedCount, mObserver.mClosedCallbackHelper.getCallCount());
 
-        selectBottomSheetContent(R.id.action_history);
+        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_history);
         mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount, 1);
         contentChangedCount++;
         assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
@@ -48,7 +79,7 @@
         assertEquals(
                 R.id.action_history, mBottomSheetContentController.getSelectedItemIdForTests());
 
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
         mObserver.mClosedCallbackHelper.waitForCallback(closedCount, 1);
         mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount, 1);
         assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
@@ -56,6 +87,7 @@
         assertEquals(R.id.action_home, mBottomSheetContentController.getSelectedItemIdForTests());
     }
 
+    @Test
     @SmallTest
     public void testShowContentAndOpenSheet_Bookmarks()
             throws InterruptedException, TimeoutException {
@@ -65,7 +97,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                BookmarkUtils.showBookmarkManager(getActivity());
+                BookmarkUtils.showBookmarkManager(mBottomSheetTestRule.getActivity());
             }
         });
 
@@ -77,6 +109,7 @@
                 R.id.action_bookmarks, mBottomSheetContentController.getSelectedItemIdForTests());
     }
 
+    @Test
     @SmallTest
     public void testShowContentAndOpenSheet_Downloads()
             throws InterruptedException, TimeoutException {
@@ -86,7 +119,8 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                DownloadUtils.showDownloadManager(getActivity(), getActivity().getActivityTab());
+                ChromeTabbedActivity activity = mBottomSheetTestRule.getActivity();
+                DownloadUtils.showDownloadManager(activity, activity.getActivityTab());
             }
         });
 
@@ -98,6 +132,7 @@
                 R.id.action_downloads, mBottomSheetContentController.getSelectedItemIdForTests());
     }
 
+    @Test
     @SmallTest
     public void testShowContentAndOpenSheet_History()
             throws InterruptedException, TimeoutException {
@@ -107,8 +142,8 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                HistoryManagerUtils.showHistoryManager(
-                        getActivity(), getActivity().getActivityTab());
+                ChromeTabbedActivity activity = mBottomSheetTestRule.getActivity();
+                HistoryManagerUtils.showHistoryManager(activity, activity.getActivityTab());
             }
         });
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
index 44970a6..e965af6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
@@ -4,17 +4,34 @@
 
 package org.chromium.chrome.browser.widget.bottomsheet;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
+
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.ntp.ChromeHomeNewTabPageBase;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
 import org.chromium.chrome.browser.widget.FadingBackgroundView;
-import org.chromium.chrome.test.BottomSheetTestCaseBase;
+import org.chromium.chrome.test.BottomSheetTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.MenuUtils;
 import org.chromium.content_public.browser.LoadUrlParams;
@@ -22,13 +39,19 @@
 import java.util.concurrent.TimeoutException;
 
 /**
- * Tests for the NTP UI displayed when Chrome Home is enabled.
- *
- * TODO(twellington): Remove remaining tests for ChromeHomeNewTabPage after it's completely removed.
+ * Tests for the NTP UI displayed when Chrome Home is enabled. TODO(twellington): Remove remaining
+ * tests for ChromeHomeNewTabPage after it's completely removed.
  */
-public class BottomSheetNewTabControllerTest extends BottomSheetTestCaseBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
+public class BottomSheetNewTabControllerTest {
     private FadingBackgroundView mFadingBackgroundView;
     private TestTabModelObserver mTabModelObserver;
+    private BottomSheet mBottomSheet;
+    private ChromeTabbedActivity mActivity;
 
     /** An observer used to detect changes in the tab model. */
     private static class TestTabModelObserver extends EmptyTabModelObserver {
@@ -40,34 +63,38 @@
         }
     }
 
-    @Override
+    @Rule
+    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
+
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
+        mBottomSheetTestRule.startMainActivityOnBlankPage();
+        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
         mTabModelObserver = new TestTabModelObserver();
-        getActivity().getTabModelSelector().getModel(false).addObserver(mTabModelObserver);
-        getActivity().getTabModelSelector().getModel(true).addObserver(mTabModelObserver);
-
-        mFadingBackgroundView = getActivity().getFadingBackgroundView();
+        mActivity = mBottomSheetTestRule.getActivity();
+        mActivity.getTabModelSelector().getModel(false).addObserver(mTabModelObserver);
+        mActivity.getTabModelSelector().getModel(true).addObserver(mTabModelObserver);
+        mFadingBackgroundView = mActivity.getFadingBackgroundView();
     }
 
+    @Test
     @SmallTest
     public void testNTPOverTabSwitcher_Normal() throws InterruptedException, TimeoutException {
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
         assertFalse("Overview mode should not be showing",
-                getActivity().getLayoutManager().overviewVisible());
-        assertFalse(getActivity().getTabModelSelector().isIncognitoSelected());
+                mActivity.getLayoutManager().overviewVisible());
+        assertFalse(mActivity.getTabModelSelector().isIncognitoSelected());
 
         // Select "New tab" from the menu.
         MenuUtils.invokeCustomMenuActionSync(
-                getInstrumentation(), getActivity(), R.id.new_tab_menu_id);
+                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
 
         // The sheet should be opened at half height over the tab switcher and the tab count should
         // remain unchanged.
         validateState(false, BottomSheet.SHEET_STATE_HALF);
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
-        assertTrue("Overview mode should be showing",
-                getActivity().getLayoutManager().overviewVisible());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
+        assertTrue(
+                "Overview mode should be showing", mActivity.getLayoutManager().overviewVisible());
 
         // Load a URL in the bottom sheet.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -79,38 +106,39 @@
 
         // The sheet should now be closed and a regular tab should have been created
         validateState(false, BottomSheet.SHEET_STATE_PEEK);
-        assertEquals(2, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(2, mActivity.getTabModelSelector().getTotalTabCount());
         assertFalse("Overview mode not should be showing",
-                getActivity().getLayoutManager().overviewVisible());
-        assertFalse(getActivity().getTabModelSelector().isIncognitoSelected());
+                mActivity.getLayoutManager().overviewVisible());
+        assertFalse(mActivity.getTabModelSelector().isIncognitoSelected());
     }
 
+    @Test
     @SmallTest
     public void testNTPOverTabSwitcher_Incognito() throws InterruptedException, TimeoutException {
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
         assertFalse("Overview mode should not be showing",
-                getActivity().getLayoutManager().overviewVisible());
-        assertFalse(getActivity().getTabModelSelector().isIncognitoSelected());
+                mActivity.getLayoutManager().overviewVisible());
+        assertFalse(mActivity.getTabModelSelector().isIncognitoSelected());
 
         // Select "New incognito tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(
-                getInstrumentation(), getActivity(), R.id.new_incognito_tab_menu_id);
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivity, R.id.new_incognito_tab_menu_id);
         // The sheet should be opened at half height over the tab switcher and the tab count should
         // remain unchanged. The incognito model should now be selected.
         validateState(false, BottomSheet.SHEET_STATE_HALF);
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
-        assertTrue("Overview mode should be showing",
-                getActivity().getLayoutManager().overviewVisible());
-        assertTrue(getActivity().getTabModelSelector().isIncognitoSelected());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
+        assertTrue(
+                "Overview mode should be showing", mActivity.getLayoutManager().overviewVisible());
+        assertTrue(mActivity.getTabModelSelector().isIncognitoSelected());
 
         // Check that the normal model is selected after the sheet is closed without a URL being
         // loaded.
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        assertFalse(getActivity().getTabModelSelector().isIncognitoSelected());
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        assertFalse(mActivity.getTabModelSelector().isIncognitoSelected());
 
         // Select "New incognito tab" from the menu and load a URL.
-        MenuUtils.invokeCustomMenuActionSync(
-                getInstrumentation(), getActivity(), R.id.new_incognito_tab_menu_id);
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivity, R.id.new_incognito_tab_menu_id);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -120,28 +148,30 @@
 
         // The sheet should now be closed and an incognito tab should have been created
         validateState(false, BottomSheet.SHEET_STATE_PEEK);
-        assertEquals(2, getActivity().getTabModelSelector().getTotalTabCount());
-        assertTrue(getActivity().getActivityTab().isIncognito());
+        assertEquals(2, mActivity.getTabModelSelector().getTotalTabCount());
+        assertTrue(mActivity.getActivityTab().isIncognito());
         assertFalse("Overview mode not should be showing",
-                getActivity().getLayoutManager().overviewVisible());
-        assertTrue(getActivity().getTabModelSelector().isIncognitoSelected());
+                mActivity.getLayoutManager().overviewVisible());
+        assertTrue(mActivity.getTabModelSelector().isIncognitoSelected());
     }
 
+    @Test
     @SmallTest
     public void testNTPOverTabSwitcher_NoTabs() throws InterruptedException, TimeoutException {
         // Close all tabs.
-        ChromeTabUtils.closeAllTabs(getInstrumentation(), getActivity());
-        assertEquals(0, getActivity().getTabModelSelector().getTotalTabCount());
+        ChromeTabUtils.closeAllTabs(InstrumentationRegistry.getInstrumentation(), mActivity);
+        assertEquals(0, mActivity.getTabModelSelector().getTotalTabCount());
 
         // Select "New tab" from the menu.
         MenuUtils.invokeCustomMenuActionSync(
-                getInstrumentation(), getActivity(), R.id.new_tab_menu_id);
+                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
 
         // The sheet should be opened at full height.
         validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertEquals(0, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(0, mActivity.getTabModelSelector().getTotalTabCount());
     }
 
+    @Test
     @SmallTest
     public void testCloseNTP()
             throws IllegalArgumentException, InterruptedException, TimeoutException {
@@ -151,11 +181,12 @@
 
         // Close the new tab.
         closeNewTab();
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
         assertFalse("Overview mode should not be showing",
-                getActivity().getLayoutManager().overviewVisible());
+                mActivity.getLayoutManager().overviewVisible());
     }
 
+    @Test
     @SmallTest
     public void testCloseNTP_Incognito()
             throws IllegalArgumentException, InterruptedException, TimeoutException {
@@ -165,21 +196,21 @@
 
         // Close the new tab.
         closeNewTab();
-        assertEquals(1, getActivity().getTabModelSelector().getTotalTabCount());
+        assertEquals(1, mActivity.getTabModelSelector().getTotalTabCount());
         assertFalse("Overview mode should not be showing",
-                getActivity().getLayoutManager().overviewVisible());
+                mActivity.getLayoutManager().overviewVisible());
     }
 
     private void loadChromeHomeNewTab() throws InterruptedException {
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivity.getActivityTab();
         ChromeTabUtils.loadUrlOnUiThread(tab, UrlConstants.NTP_URL);
         ChromeTabUtils.waitForTabPageLoaded(tab, UrlConstants.NTP_URL);
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private void createNewBlankTab(final boolean incognito) throws InterruptedException {
-        MenuUtils.invokeCustomMenuActionSync(getInstrumentation(), getActivity(),
-                incognito ? R.id.new_incognito_tab_menu_id : R.id.new_tab_menu_id);
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivity, incognito ? R.id.new_incognito_tab_menu_id : R.id.new_tab_menu_id);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -191,14 +222,14 @@
 
     private void closeNewTab() throws InterruptedException, TimeoutException {
         int currentCallCount = mTabModelObserver.mDidCloseTabCallbackHelper.getCallCount();
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivity.getActivityTab();
         final ChromeHomeNewTabPageBase newTabPage = (ChromeHomeNewTabPageBase) tab.getNativePage();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 newTabPage.getCloseButtonForTests().callOnClick();
-                getActivity().getLayoutManager().getActiveLayout().finishAnimationsForTests();
+                mActivity.getLayoutManager().getActiveLayout().finishAnimationsForTests();
             }
         });
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
index 21a8ad8..2796178 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
@@ -4,34 +4,64 @@
 
 package org.chromium.chrome.browser.widget.bottomsheet;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
+
 import android.support.test.filters.MediumTest;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent;
 import org.chromium.chrome.browser.download.DownloadSheetContent;
 import org.chromium.chrome.browser.history.HistorySheetContent;
 import org.chromium.chrome.browser.suggestions.SuggestionsBottomSheetContent;
 import org.chromium.chrome.browser.util.MathUtils;
-import org.chromium.chrome.test.BottomSheetTestCaseBase;
+import org.chromium.chrome.test.BottomSheetTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.util.concurrent.TimeoutException;
 
 /** This class tests the functionality of the {@link BottomSheetObserver}. */
-public class BottomSheetObserverTest extends BottomSheetTestCaseBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
+public class BottomSheetObserverTest {
+    @Rule
+    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
+    private BottomSheetTestRule.Observer mObserver;
+
+    @Before
+    public void setUp() throws Exception {
+        mBottomSheetTestRule.startMainActivityOnBlankPage();
+        mObserver = mBottomSheetTestRule.getObserver();
+    }
+
     /**
      * Test that the onSheetClosed event is triggered if the sheet is closed without animation.
      */
+    @Test
     @MediumTest
     public void testCloseEventCalledNoAnimation() throws InterruptedException, TimeoutException {
-        setSheetState(BottomSheet.SHEET_STATE_FULL, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
 
         CallbackHelper closedCallbackHelper = mObserver.mClosedCallbackHelper;
 
         int initialOpenedCount = mObserver.mOpenedCallbackHelper.getCallCount();
 
         int closedCallbackCount = closedCallbackHelper.getCallCount();
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
         closedCallbackHelper.waitForCallback(closedCallbackCount, 1);
 
         assertEquals(initialOpenedCount, mObserver.mOpenedCallbackHelper.getCallCount());
@@ -40,16 +70,17 @@
     /**
      * Test that the onSheetClosed event is triggered if the sheet is closed with animation.
      */
+    @Test
     @MediumTest
     public void testCloseEventCalledWithAnimation() throws InterruptedException, TimeoutException {
-        setSheetState(BottomSheet.SHEET_STATE_FULL, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
 
         CallbackHelper closedCallbackHelper = mObserver.mClosedCallbackHelper;
 
         int initialOpenedCount = mObserver.mOpenedCallbackHelper.getCallCount();
 
         int closedCallbackCount = closedCallbackHelper.getCallCount();
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, true);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, true);
         closedCallbackHelper.waitForCallback(closedCallbackCount, 1);
 
         assertEquals(initialOpenedCount, mObserver.mOpenedCallbackHelper.getCallCount());
@@ -58,16 +89,17 @@
     /**
      * Test that the onSheetOpened event is triggered if the sheet is opened without animation.
      */
+    @Test
     @MediumTest
     public void testOpenedEventCalledNoAnimation() throws InterruptedException, TimeoutException {
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
 
         CallbackHelper openedCallbackHelper = mObserver.mOpenedCallbackHelper;
 
         int initialClosedCount = mObserver.mClosedCallbackHelper.getCallCount();
 
         int openedCallbackCount = openedCallbackHelper.getCallCount();
-        setSheetState(BottomSheet.SHEET_STATE_FULL, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         openedCallbackHelper.waitForCallback(openedCallbackCount, 1);
 
         assertEquals(initialClosedCount, mObserver.mClosedCallbackHelper.getCallCount());
@@ -76,16 +108,17 @@
     /**
      * Test that the onSheetOpened event is triggered if the sheet is opened with animation.
      */
+    @Test
     @MediumTest
     public void testOpenedEventCalledWithAnimation() throws InterruptedException, TimeoutException {
-        setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
 
         CallbackHelper openedCallbackHelper = mObserver.mOpenedCallbackHelper;
 
         int initialClosedCount = mObserver.mClosedCallbackHelper.getCallCount();
 
         int openedCallbackCount = openedCallbackHelper.getCallCount();
-        setSheetState(BottomSheet.SHEET_STATE_FULL, true);
+        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_FULL, true);
         openedCallbackHelper.waitForCallback(openedCallbackCount, 1);
 
         assertEquals(initialClosedCount, mObserver.mClosedCallbackHelper.getCallCount());
@@ -94,31 +127,33 @@
     /**
      * Test the onOffsetChanged event.
      */
+    @Test
     @MediumTest
     public void testOffsetChangedEvent() throws InterruptedException, TimeoutException {
         CallbackHelper callbackHelper = mObserver.mOffsetChangedCallbackHelper;
 
-        float peekHeight = mBottomSheet.getPeekRatio() * mBottomSheet.getSheetContainerHeight();
-        float fullHeight = mBottomSheet.getFullRatio() * mBottomSheet.getSheetContainerHeight();
+        BottomSheet bottomSheet = mBottomSheetTestRule.getBottomSheet();
+        float peekHeight = bottomSheet.getPeekRatio() * bottomSheet.getSheetContainerHeight();
+        float fullHeight = bottomSheet.getFullRatio() * bottomSheet.getSheetContainerHeight();
 
         // The sheet's half state is not necessarily 50% of the way to the top.
         float midPeekFull = (peekHeight + fullHeight) / 2f;
 
         // When in the peeking state, the transition value should be 0.
         int callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(peekHeight);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(peekHeight);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(0f, mObserver.getLastOffsetChangedValue(), MathUtils.EPSILON);
 
         // When in the full state, the transition value should be 1.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(fullHeight);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(fullHeight);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(1f, mObserver.getLastOffsetChangedValue(), MathUtils.EPSILON);
 
         // Halfway between peek and full should send 0.5.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(midPeekFull);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(midPeekFull);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(0.5f, mObserver.getLastOffsetChangedValue(), MathUtils.EPSILON);
     }
@@ -126,50 +161,52 @@
     /**
      * Test the onTransitionPeekToHalf event.
      */
+    @Test
     @MediumTest
     public void testPeekToHalfTransition() throws InterruptedException, TimeoutException {
         CallbackHelper callbackHelper = mObserver.mPeekToHalfCallbackHelper;
 
-        float peekHeight = mBottomSheet.getPeekRatio() * mBottomSheet.getSheetContainerHeight();
-        float halfHeight = mBottomSheet.getHalfRatio() * mBottomSheet.getSheetContainerHeight();
-        float fullHeight = mBottomSheet.getFullRatio() * mBottomSheet.getSheetContainerHeight();
+        BottomSheet bottomSheet = mBottomSheetTestRule.getBottomSheet();
+        float peekHeight = bottomSheet.getPeekRatio() * bottomSheet.getSheetContainerHeight();
+        float halfHeight = bottomSheet.getHalfRatio() * bottomSheet.getSheetContainerHeight();
+        float fullHeight = bottomSheet.getFullRatio() * bottomSheet.getSheetContainerHeight();
 
         float midPeekHalf = (peekHeight + halfHeight) / 2f;
         float midHalfFull = (halfHeight + fullHeight) / 2f;
 
         // When in the peeking state, the transition value should be 0.
         int callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(peekHeight);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(peekHeight);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(0f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON);
 
         // When in between peek and half states, the transition value should be 0.5.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(midPeekHalf);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(midPeekHalf);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(0.5f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON);
 
         // After jumping to the full state (skipping the half state), the event should have
         // triggered once more with a max value of 1.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(fullHeight);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(fullHeight);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(1f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON);
 
         // Moving from full to somewhere between half and full should not trigger the event.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(midHalfFull);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(midHalfFull);
         assertEquals(callbackCount, callbackHelper.getCallCount());
 
         // Reset the sheet to be between peek and half states.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(midPeekHalf);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(midPeekHalf);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(0.5f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON);
 
         // At the half state the event should send 1.
         callbackCount = callbackHelper.getCallCount();
-        setSheetOffsetFromBottom(halfHeight);
+        mBottomSheetTestRule.setSheetOffsetFromBottom(halfHeight);
         callbackHelper.waitForCallback(callbackCount, 1);
         assertEquals(1f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON);
     }
@@ -177,28 +214,30 @@
     /**
      * Test the onSheetContentChanged event.
      */
+    @Test
     @MediumTest
     public void testSheetContentChanged() throws InterruptedException, TimeoutException {
         CallbackHelper callbackHelper = mObserver.mContentChangedCallbackHelper;
 
         int callbackCount = callbackHelper.getCallCount();
-        selectBottomSheetContent(R.id.action_bookmarks);
+        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_bookmarks);
         callbackHelper.waitForCallback(callbackCount, 1);
-        assertTrue(getBottomSheetContent() instanceof BookmarkSheetContent);
+        assertTrue(mBottomSheetTestRule.getBottomSheetContent() instanceof BookmarkSheetContent);
 
         callbackCount++;
-        selectBottomSheetContent(R.id.action_history);
+        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_history);
         callbackHelper.waitForCallback(callbackCount, 1);
-        assertTrue(getBottomSheetContent() instanceof HistorySheetContent);
+        assertTrue(mBottomSheetTestRule.getBottomSheetContent() instanceof HistorySheetContent);
 
         callbackCount++;
-        selectBottomSheetContent(R.id.action_downloads);
+        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_downloads);
         callbackHelper.waitForCallback(callbackCount, 1);
-        assertTrue(getBottomSheetContent() instanceof DownloadSheetContent);
+        assertTrue(mBottomSheetTestRule.getBottomSheetContent() instanceof DownloadSheetContent);
 
         callbackCount++;
-        selectBottomSheetContent(R.id.action_home);
+        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_home);
         callbackHelper.waitForCallback(callbackCount, 1);
-        assertTrue(getBottomSheetContent() instanceof SuggestionsBottomSheetContent);
+        assertTrue(mBottomSheetTestRule.getBottomSheetContent()
+                           instanceof SuggestionsBottomSheetContent);
     }
 }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index a3f2521..1e03569 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -757,6 +757,9 @@
      switches::kAutoplayPolicy,
      switches::autoplay::kUserGestureRequiredForCrossOriginPolicy},
 #endif
+    {flag_descriptions::kAutoplayPolicyDocumentUserActivation,
+     switches::kAutoplayPolicy,
+     switches::autoplay::kDocumentUserActivationRequiredPolicy},
 };
 
 const FeatureEntry::Choice kForceEffectiveConnectionTypeChoices[] = {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index db5fad8..54de7a89 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3104,6 +3104,9 @@
 const char kAutoplayPolicyUserGestureRequiredForCrossOrigin[] =
     "User gesture is required for cross-origin iframes.";
 
+const char kAutoplayPolicyDocumentUserActivation[] =
+    "Document user activation is required.";
+
 const char kOmniboxDisplayTitleForCurrentUrlName[] =
     "Include title for the current URL in the omnibox";
 
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 5ccc0d6..91d0c3f4 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -52,6 +52,7 @@
 extern const char kAutoplayPolicyUserGestureRequiredForCrossOrigin[];
 extern const char kAutoplayPolicyNoUserGestureRequired[];
 extern const char kAutoplayPolicyUserGestureRequired[];
+extern const char kAutoplayPolicyDocumentUserActivation[];
 
 extern const char kBackgroundVideoTrackOptimizationName[];
 extern const char kBackgroundVideoTrackOptimizationDescription[];
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
index c5ceabbd..25b44abb 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
@@ -579,7 +579,12 @@
     // bad.
     ProcessType process_type = it->process_type();
     if (process_type <= ProcessType::IMPORTANT_APP) {
-      MEMORY_LOG(ERROR) << "Skipped killing " << it->app()->process_name();
+      if (it->app()) {
+        MEMORY_LOG(ERROR) << "Skipped killing " << it->app()->process_name();
+      } else if (it->tab()) {
+        MEMORY_LOG(ERROR) << "Skipped killing " << it->tab()->title << " ("
+                          << it->tab()->renderer_handle << ")";
+      }
       continue;
     }
     if (it->app()) {
@@ -602,7 +607,7 @@
       } else {
         MEMORY_LOG(ERROR) << "Failed to kill " << it->app()->process_name();
       }
-    } else {
+    } else if (it->tab()) {
       int64_t tab_id = it->tab()->tab_contents_id;
       // The estimation is problematic since multiple tabs may share the same
       // process, while the calculation counts memory used by the whole process.
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h
index adfda97..15f2379 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.h
+++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -30,6 +30,19 @@
 // initialize the profile.
 class StartupBrowserCreator {
  public:
+  // The type of page to be shown in a tab when the user is being welcomed back
+  // to Chrome.
+  enum class WelcomeBackPage {
+    kNone,
+#if defined(OS_WIN)
+    // chrome://welcome-win10/ if Chrome's default browser UX may be shown;
+    // otherwise, see kWelcomeStandard.
+    kWelcomeWin10,
+#endif
+    // chrome://welcome/ if sign-in is allowed; otherwise, none.
+    kWelcomeStandard,
+  };
+
   typedef std::vector<Profile*> Profiles;
 
   StartupBrowserCreator();
@@ -39,6 +52,15 @@
   // tabs shown at first run.
   void AddFirstRunTab(const GURL& url);
 
+  // Configures the instance to include the specified "welcome back" page in a
+  // tab before other tabs (e.g., those from session restore). This is used for
+  // specific launches via retention experiments for which no URLs are provided
+  // on the command line. No "welcome back" page is shown to supervised users.
+  void set_welcome_back_page(WelcomeBackPage welcome_back_page) {
+    welcome_back_page_ = welcome_back_page;
+  }
+  WelcomeBackPage welcome_back_page() const { return welcome_back_page_; }
+
   // This function is equivalent to ProcessCommandLine but should only be
   // called during actual process startup.
   bool Start(const base::CommandLine& cmd_line,
@@ -161,6 +183,9 @@
   // Additional tabs to open during first run.
   std::vector<GURL> first_run_tabs_;
 
+  // The page to be shown in a tab when welcoming a user back to Chrome.
+  WelcomeBackPage welcome_back_page_ = WelcomeBackPage::kNone;
+
   // True if the set-as-default dialog has been explicitly suppressed.
   // This information is used to allow the default browser prompt to show on
   // first-run when the dialog has been suppressed.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index b137627..f7ef4d0 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -1123,3 +1123,60 @@
 }
 
 #endif  // !defined(OS_CHROMEOS)
+
+class StartupBrowserCreatorWelcomeBackTest : public InProcessBrowserTest {
+ protected:
+  StartupBrowserCreatorWelcomeBackTest() = default;
+  void SetUpOnMainThread() override {
+    profile_ = browser()->profile();
+
+    // Keep the browser process running when all browsers are closed.
+    scoped_keep_alive_ = base::MakeUnique<ScopedKeepAlive>(
+        KeepAliveOrigin::BROWSER, KeepAliveRestartOption::DISABLED);
+
+    // Close the browser opened by InProcessBrowserTest.
+    CloseBrowserSynchronously(browser());
+    ASSERT_EQ(0U, BrowserList::GetInstance()->size());
+  }
+
+  void StartBrowser(StartupBrowserCreator::WelcomeBackPage welcome_back_page) {
+    browser_creator_.set_welcome_back_page(welcome_back_page);
+    ASSERT_TRUE(browser_creator_.Start(
+        base::CommandLine(base::CommandLine::NO_PROGRAM), base::FilePath(),
+        profile_,
+        g_browser_process->profile_manager()->GetLastOpenedProfiles()));
+    ASSERT_EQ(1U, BrowserList::GetInstance()->size());
+  }
+
+  void ExpectUrlInBrowserAtPosition(const GURL& url, int tab_index) {
+    Browser* browser = BrowserList::GetInstance()->get(0);
+    TabStripModel* tab_strip = browser->tab_strip_model();
+    EXPECT_EQ(url, tab_strip->GetWebContentsAt(tab_index)->GetURL());
+  }
+
+  void TearDownOnMainThread() override { scoped_keep_alive_.reset(); }
+
+ private:
+  Profile* profile_ = nullptr;
+  std::unique_ptr<ScopedKeepAlive> scoped_keep_alive_;
+  StartupBrowserCreator browser_creator_;
+
+  DISALLOW_COPY_AND_ASSIGN(StartupBrowserCreatorWelcomeBackTest);
+};
+
+#if defined(OS_WIN)
+IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorWelcomeBackTest, WelcomeBackWin10) {
+  ASSERT_NO_FATAL_FAILURE(
+      StartBrowser(StartupBrowserCreator::WelcomeBackPage::kWelcomeWin10));
+  ExpectUrlInBrowserAtPosition(
+      StartupTabProviderImpl::GetWin10WelcomePageUrl(false), 0);
+}
+#endif  // defined(OS_WIN)
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorWelcomeBackTest,
+                       WelcomeBackStandard) {
+  ASSERT_NO_FATAL_FAILURE(
+      StartBrowser(StartupBrowserCreator::WelcomeBackPage::kWelcomeStandard));
+  ExpectUrlInBrowserAtPosition(StartupTabProviderImpl::GetWelcomePageUrl(false),
+                               0);
+}
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index d089d9b..23684a2 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -637,9 +637,9 @@
   bool is_incognito_or_guest =
       profile_->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE;
   bool is_post_crash_launch = HasPendingUncleanExit(profile_);
-  StartupTabs tabs =
-      DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs,
-                           is_incognito_or_guest, is_post_crash_launch);
+  StartupTabs tabs = DetermineStartupTabs(
+      StartupTabProviderImpl(), cmd_line_tabs, process_startup,
+      is_incognito_or_guest, is_post_crash_launch);
 
   // Return immediately if we start an async restore, since the remainder of
   // that process is self-contained.
@@ -686,6 +686,7 @@
 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs(
     const StartupTabProvider& provider,
     const StartupTabs& cmd_line_tabs,
+    bool process_startup,
     bool is_incognito_or_guest,
     bool is_post_crash_launch) {
   // Only the New Tab Page or command line URLs may be shown in incognito mode.
@@ -715,6 +716,14 @@
   if (!distribution_tabs.empty())
     return distribution_tabs;
 
+  // This is a launch from a prompt presented to an inactive user who chose to
+  // open Chrome and is being brought to a specific URL for this one launch.
+  // Launch the browser with the desired welcome back URL in the foreground and
+  // the other ordinary URLs (e.g., a restored session) in the background.
+  StartupTabs welcome_back_tabs =
+      provider.GetWelcomeBackTabs(profile_, browser_creator_, process_startup);
+  AppendTabs(welcome_back_tabs, &tabs);
+
   // Policies for onboarding (e.g., first run) may show promotional and
   // introductory content depending on a number of system status factors,
   // including OS and whether or not this is First Run.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.h b/chrome/browser/ui/startup/startup_browser_creator_impl.h
index 17aec3a..e8b6ece 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.h
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.h
@@ -75,6 +75,8 @@
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
                            DetermineStartupTabs_NewTabPage);
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
+                           DetermineStartupTabs_WelcomeBackPage);
+  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
                            DetermineBrowserOpenBehavior_Startup);
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
                            DetermineBrowserOpenBehavior_CmdLineTabs);
@@ -141,6 +143,7 @@
   // and the interactions between those policies.
   StartupTabs DetermineStartupTabs(const StartupTabProvider& provider,
                                    const StartupTabs& cmd_line_tabs,
+                                   bool process_startup,
                                    bool is_ephemeral_profile,
                                    bool is_post_crash_launch);
 
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc
index d7a472a2..e71e914 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc
@@ -20,6 +20,7 @@
 constexpr uint32_t kPinnedTabs = 1 << 3;
 constexpr uint32_t kPreferencesTabs = 1 << 4;
 constexpr uint32_t kNewTabPageTabs = 1 << 5;
+constexpr uint32_t kWelcomeBackTab = 1 << 6;
 
 class FakeStartupTabProvider : public StartupTabProvider {
  public:
@@ -73,6 +74,15 @@
     return tabs;
   }
 
+  StartupTabs GetWelcomeBackTabs(Profile* profile,
+                                 StartupBrowserCreator* browser_creator,
+                                 bool process_startup) const override {
+    StartupTabs tabs;
+    if (process_startup && (options_ & kWelcomeBackTab))
+      tabs.emplace_back(GURL("https://welcome-back"), false);
+    return tabs;
+  }
+
  private:
   const uint32_t options_;
 };
@@ -91,7 +101,7 @@
                chrome::startup::IS_FIRST_RUN);
 
   StartupTabs output =
-      impl.DetermineStartupTabs(provider, StartupTabs(), false, false);
+      impl.DetermineStartupTabs(provider, StartupTabs(), true, false, false);
   ASSERT_EQ(4U, output.size());
   EXPECT_EQ("reset-trigger", output[0].url.host());
   EXPECT_EQ("onboarding", output[1].url.host());
@@ -111,7 +121,7 @@
 
   // Incognito case:
   StartupTabs output =
-      impl.DetermineStartupTabs(provider, StartupTabs(), true, false);
+      impl.DetermineStartupTabs(provider, StartupTabs(), true, true, false);
   ASSERT_EQ(1U, output.size());
   // Check for the actual NTP URL, rather than the sentinel returned by the
   // fake, because the Provider is ignored entirely when short-circuited by
@@ -119,7 +129,8 @@
   EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[0].url);
 
   // Crash Recovery case:
-  output = impl.DetermineStartupTabs(provider, StartupTabs(), false, true);
+  output =
+      impl.DetermineStartupTabs(provider, StartupTabs(), true, false, true);
   ASSERT_EQ(1U, output.size());
   EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[0].url);
 }
@@ -135,7 +146,7 @@
                chrome::startup::IS_FIRST_RUN);
 
   StartupTabs output =
-      impl.DetermineStartupTabs(provider, StartupTabs(), false, false);
+      impl.DetermineStartupTabs(provider, StartupTabs(), true, false, false);
   ASSERT_EQ(1U, output.size());
   EXPECT_EQ("distribution", output[0].url.host());
 }
@@ -153,7 +164,7 @@
   StartupTabs cmd_line_tabs = {StartupTab(GURL("https://cmd-line"), false)};
 
   StartupTabs output =
-      impl.DetermineStartupTabs(provider, cmd_line_tabs, false, false);
+      impl.DetermineStartupTabs(provider, cmd_line_tabs, true, false, false);
   ASSERT_EQ(2U, output.size());
   EXPECT_EQ("reset-trigger", output[0].url.host());
   EXPECT_EQ("cmd-line", output[1].url.host());
@@ -162,12 +173,14 @@
   // command line tabs.
 
   // Incognito
-  output = impl.DetermineStartupTabs(provider, cmd_line_tabs, true, false);
+  output =
+      impl.DetermineStartupTabs(provider, cmd_line_tabs, true, true, false);
   ASSERT_EQ(1U, output.size());
   EXPECT_EQ("cmd-line", output[0].url.host());
 
   // Crash Recovery
-  output = impl.DetermineStartupTabs(provider, cmd_line_tabs, false, true);
+  output =
+      impl.DetermineStartupTabs(provider, cmd_line_tabs, true, false, true);
   ASSERT_EQ(1U, output.size());
   EXPECT_EQ("cmd-line", output[0].url.host());
 }
@@ -181,14 +194,37 @@
                base::CommandLine(base::CommandLine::NO_PROGRAM),
                chrome::startup::IS_FIRST_RUN);
 
-  StartupTabs output = impl.DetermineStartupTabs(provider_allows_ntp,
-                                                 StartupTabs(), false, false);
+  StartupTabs output = impl.DetermineStartupTabs(
+      provider_allows_ntp, StartupTabs(), true, false, false);
   ASSERT_EQ(3U, output.size());
   EXPECT_EQ("reset-trigger", output[0].url.host());
   EXPECT_EQ("new-tab", output[1].url.host());
   EXPECT_EQ("pinned", output[2].url.host());
 }
 
+// The welcome back page should appear before any other session restore tabs.
+TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs_WelcomeBackPage) {
+  FakeStartupTabProvider provider_allows_ntp(kPinnedTabs | kPreferencesTabs |
+                                             kWelcomeBackTab);
+  Creator impl(base::FilePath(),
+               base::CommandLine(base::CommandLine::NO_PROGRAM),
+               chrome::startup::IS_FIRST_RUN);
+
+  StartupTabs output = impl.DetermineStartupTabs(
+      provider_allows_ntp, StartupTabs(), true, false, false);
+  ASSERT_EQ(3U, output.size());
+  EXPECT_EQ("welcome-back", output[0].url.host());
+  EXPECT_EQ("prefs", output[1].url.host());
+  EXPECT_EQ("pinned", output[2].url.host());
+
+  // No welcome back for non-startup opens.
+  output = impl.DetermineStartupTabs(provider_allows_ntp, StartupTabs(), false,
+                                     false, false);
+  ASSERT_EQ(2U, output.size());
+  EXPECT_EQ("prefs", output[0].url.host());
+  EXPECT_EQ("pinned", output[1].url.host());
+}
+
 TEST(StartupBrowserCreatorImplTest, DetermineBrowserOpenBehavior_Startup) {
   SessionStartupPref pref_default(SessionStartupPref::Type::DEFAULT);
   SessionStartupPref pref_last(SessionStartupPref::Type::LAST);
diff --git a/chrome/browser/ui/startup/startup_tab_provider.cc b/chrome/browser/ui/startup/startup_tab_provider.cc
index 9035c01..faea7a0ef 100644
--- a/chrome/browser/ui/startup/startup_tab_provider.cc
+++ b/chrome/browser/ui/startup/startup_tab_provider.cc
@@ -30,6 +30,19 @@
 
 namespace {
 
+#if defined(OS_WIN)
+// Returns false if the in-product default browser UX is suppressed by install
+// mode (e.g., Chrome Canary) or by policy.
+bool SetDefaultBrowserAllowed(PrefService* local_state) {
+  if (!shell_integration::CanSetAsDefaultBrowser())
+    return false;
+  return !local_state ||
+         !local_state->IsManagedPreference(
+             prefs::kDefaultBrowserSettingEnabled) ||
+         local_state->GetBoolean(prefs::kDefaultBrowserSettingEnabled);
+}
+#endif  // defined(OS_WIN)
+
 // Attempts to find an existing, non-empty tabbed browser for this profile.
 bool ProfileHasOtherTabbedBrowser(Profile* profile) {
   BrowserList* browser_list = BrowserList::GetInstance();
@@ -67,23 +80,12 @@
     PrefService* local_state = g_browser_process->local_state();
     bool has_seen_win10_promo =
         local_state && local_state->GetBoolean(prefs::kHasSeenWin10PromoPage);
-    // The set default browser operation can be disabled by the browser
-    // distribution (e.g. SxS Canary), or by enterprise policy. In these cases,
-    // the Win 10 promo page should not be displayed.
-    bool disabled_by_enterprise_policy =
-        local_state &&
-        local_state->IsManagedPreference(
-            prefs::kDefaultBrowserSettingEnabled) &&
-        !local_state->GetBoolean(prefs::kDefaultBrowserSettingEnabled);
-    bool set_default_browser_allowed =
-        !disabled_by_enterprise_policy &&
-        shell_integration::CanSetAsDefaultBrowser();
     bool is_default_browser =
         g_browser_process->CachedDefaultWebClientState() ==
         shell_integration::IS_DEFAULT;
     return GetWin10OnboardingTabsForState(
         is_first_run, has_seen_welcome_page, has_seen_win10_promo,
-        is_signin_allowed, is_signed_in, set_default_browser_allowed,
+        is_signin_allowed, is_signed_in, SetDefaultBrowserAllowed(local_state),
         is_default_browser, is_supervised_user);
   }
 #endif  // defined(OS_WIN)
@@ -94,6 +96,33 @@
 #endif  // defined(OS_CHROMEOS)
 }
 
+StartupTabs StartupTabProviderImpl::GetWelcomeBackTabs(
+    Profile* profile,
+    StartupBrowserCreator* browser_creator,
+    bool process_startup) const {
+  StartupTabs tabs;
+  if (!process_startup || !browser_creator)
+    return tabs;
+  switch (browser_creator->welcome_back_page()) {
+    case StartupBrowserCreator::WelcomeBackPage::kNone:
+      break;
+#if defined(OS_WIN)
+    case StartupBrowserCreator::WelcomeBackPage::kWelcomeWin10:
+      if (CanShowWin10Welcome(
+              SetDefaultBrowserAllowed(g_browser_process->local_state()),
+              profile->IsSupervised())) {
+        tabs.emplace_back(GetWin10WelcomePageUrl(false), false);
+        break;
+      }  // else fall through below.
+#endif   // defined(OS_WIN)
+    case StartupBrowserCreator::WelcomeBackPage::kWelcomeStandard:
+      if (CanShowWelcome(profile->IsSyncAllowed(), profile->IsSupervised()))
+        tabs.emplace_back(GetWelcomePageUrl(false), false);
+      break;
+  }
+  return tabs;
+}
+
 StartupTabs StartupTabProviderImpl::GetDistributionFirstRunTabs(
     StartupBrowserCreator* browser_creator) const {
   if (!browser_creator)
@@ -138,6 +167,19 @@
 }
 
 // static
+bool StartupTabProviderImpl::CanShowWelcome(bool is_signin_allowed,
+                                            bool is_supervised_user) {
+  return is_signin_allowed && !is_supervised_user;
+}
+
+// static
+bool StartupTabProviderImpl::ShouldShowWelcomeForOnboarding(
+    bool has_seen_welcome_page,
+    bool is_signed_in) {
+  return !has_seen_welcome_page && !is_signed_in;
+}
+
+// static
 StartupTabs StartupTabProviderImpl::GetStandardOnboardingTabsForState(
     bool is_first_run,
     bool has_seen_welcome_page,
@@ -145,14 +187,29 @@
     bool is_signed_in,
     bool is_supervised_user) {
   StartupTabs tabs;
-  if (!has_seen_welcome_page && is_signin_allowed && !is_signed_in &&
-      !is_supervised_user)
+  if (CanShowWelcome(is_signin_allowed, is_supervised_user) &&
+      ShouldShowWelcomeForOnboarding(has_seen_welcome_page, is_signed_in)) {
     tabs.emplace_back(GetWelcomePageUrl(!is_first_run), false);
+  }
   return tabs;
 }
 
 #if defined(OS_WIN)
 // static
+bool StartupTabProviderImpl::CanShowWin10Welcome(
+    bool set_default_browser_allowed,
+    bool is_supervised_user) {
+  return set_default_browser_allowed && !is_supervised_user;
+}
+
+// static
+bool StartupTabProviderImpl::ShouldShowWin10WelcomeForOnboarding(
+    bool has_seen_win10_promo,
+    bool is_default_browser) {
+  return !has_seen_win10_promo && !is_default_browser;
+}
+
+// static
 StartupTabs StartupTabProviderImpl::GetWin10OnboardingTabsForState(
     bool is_first_run,
     bool has_seen_welcome_page,
@@ -162,15 +219,10 @@
     bool set_default_browser_allowed,
     bool is_default_browser,
     bool is_supervised_user) {
-  StartupTabs tabs;
-
-  if (is_supervised_user)
-    return tabs;
-
-  if (set_default_browser_allowed && !has_seen_win10_promo &&
-      !is_default_browser) {
-    tabs.emplace_back(GetWin10WelcomePageUrl(!is_first_run), false);
-    return tabs;
+  if (CanShowWin10Welcome(set_default_browser_allowed, is_supervised_user) &&
+      ShouldShowWin10WelcomeForOnboarding(has_seen_win10_promo,
+                                          is_default_browser)) {
+    return {StartupTab(GetWin10WelcomePageUrl(!is_first_run), false)};
   }
 
   return GetStandardOnboardingTabsForState(is_first_run, has_seen_welcome_page,
diff --git a/chrome/browser/ui/startup/startup_tab_provider.h b/chrome/browser/ui/startup/startup_tab_provider.h
index 4fd01b67..43637ff 100644
--- a/chrome/browser/ui/startup/startup_tab_provider.h
+++ b/chrome/browser/ui/startup/startup_tab_provider.h
@@ -31,6 +31,12 @@
   virtual StartupTabs GetDistributionFirstRunTabs(
       StartupBrowserCreator* browser_creator) const = 0;
 
+  // Returns a "welcome back" tab to be shown if requested for a specific
+  // launch.
+  virtual StartupTabs GetWelcomeBackTabs(Profile* profile,
+                                         StartupBrowserCreator* browser_creator,
+                                         bool process_startup) const = 0;
+
   // Checks for the presence of a trigger indicating the need to offer a Profile
   // Reset on this profile. Returns any tabs which should be shown accordingly.
   virtual StartupTabs GetResetTriggerTabs(Profile* profile) const = 0;
@@ -59,6 +65,14 @@
   // system state relating to making those policy decisions. Exposed for
   // testing.
 
+  // Returns true if showing the standard welcome page is permissable.
+  static bool CanShowWelcome(bool is_signin_allowed, bool is_supervised_user);
+
+  // Returns true if the standard welcome page should be shown in a tab. This
+  // should only be used following a positive result from CanShowWelcome.
+  static bool ShouldShowWelcomeForOnboarding(bool has_seen_welcome_page,
+                                             bool is_signed_in);
+
   // Determines which tabs should be shown according to onboarding/first
   // run policy.
   static StartupTabs GetStandardOnboardingTabsForState(
@@ -69,6 +83,15 @@
       bool is_supervised_user);
 
 #if defined(OS_WIN)
+  // returns true if showing the Windows 10 welcome page is permissable.
+  static bool CanShowWin10Welcome(bool set_default_browser_allowed,
+                                  bool is_supervised_user);
+
+  // Returns true if the Windows 10 welcome page should be shown in a tab. This
+  // should only be used following a positive result from CanShowWin10Welcome.
+  static bool ShouldShowWin10WelcomeForOnboarding(bool has_seen_win10_promo,
+                                                  bool is_default_browser);
+
   // Determines which tabs should be shown according to onboarding/first run
   // policy, including promo content specific to Windows 10.
   static StartupTabs GetWin10OnboardingTabsForState(
@@ -130,6 +153,9 @@
 
   // StartupTabProvider:
   StartupTabs GetOnboardingTabs(Profile* profile) const override;
+  StartupTabs GetWelcomeBackTabs(Profile* profile,
+                                 StartupBrowserCreator* browser_creator,
+                                 bool process_startup) const override;
   StartupTabs GetDistributionFirstRunTabs(
       StartupBrowserCreator* browser_creator) const override;
   StartupTabs GetResetTriggerTabs(Profile* profile) const override;
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index a4dc773f..2b2612b5 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -7,7 +7,7 @@
 android_library("chrome_java_test_support") {
   testonly = true
   java_files = [
-    "javatests/src/org/chromium/chrome/test/BottomSheetTestCaseBase.java",
+    "javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java",
     "javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java",
     "javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java",
     "javatests/src/org/chromium/chrome/test/ChromeActivityTestCommon.java",
@@ -25,6 +25,7 @@
     "javatests/src/org/chromium/chrome/test/omaha/MockRequestGenerator.java",
     "javatests/src/org/chromium/chrome/test/partnercustomizations/TestPartnerBrowserCustomizationsDelayedProvider.java",
     "javatests/src/org/chromium/chrome/test/partnercustomizations/TestPartnerBrowserCustomizationsProvider.java",
+    "javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java",
     "javatests/src/org/chromium/chrome/test/TestContentProvider.java",
     "javatests/src/org/chromium/chrome/test/util/ActivityUtils.java",
     "javatests/src/org/chromium/chrome/test/util/ApplicationData.java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java
similarity index 76%
rename from chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestCaseBase.java
rename to chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java
index ce1f2b08..d94dfcb 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestCaseBase.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java
@@ -4,15 +4,12 @@
 
 package org.chromium.chrome.test;
 
-import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_PHONE;
-
 import android.support.v7.widget.RecyclerView;
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent;
@@ -21,16 +18,11 @@
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
 
 /**
- * Base class for instrumentation tests using the bottom sheet.
+ * Junit4 rule for tests testing the Chrome Home bottom sheet.
  */
-@CommandLineFlags.Add({"enable-features=ChromeHome"})
-@Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public abstract class BottomSheetTestCaseBase extends ChromeTabbedActivityTestBase {
-    /** A handle to the sheet's observer. */
-    protected TestBottomSheetObserver mObserver;
-
+public class BottomSheetTestRule extends ChromeTabbedActivityTestRule {
     /** An observer used to record events that occur with respect to the bottom sheet. */
-    protected static class TestBottomSheetObserver extends EmptyBottomSheetObserver {
+    public static class Observer extends EmptyBottomSheetObserver {
         /** A {@link CallbackHelper} that can wait for the bottom sheet to be closed. */
         public final CallbackHelper mClosedCallbackHelper = new CallbackHelper();
 
@@ -90,24 +82,30 @@
         }
     }
 
+    public static final String ENABLE_CHROME_HOME =
+            "enable-features=" + ChromeFeatureList.CHROME_HOME;
+
+    /** A handle to the sheet's observer. */
+    private Observer mObserver;
+
     /** A handle to the bottom sheet. */
-    protected BottomSheet mBottomSheet;
+    private BottomSheet mBottomSheet;
 
     /** A handle to the {@link BottomSheetContentController}. */
-    protected BottomSheetContentController mBottomSheetContentController;
+    private BottomSheetContentController mBottomSheetContentController;
 
     private boolean mOldChromeHomeFlagValue;
-    @Override
-    protected void setUp() throws Exception {
+
+    protected void beforeStartingActivity() {
         // TODO(dgn,mdjones): Chrome restarts when the ChromeHome feature flag value changes. That
         // crashes the test so we need to manually set the preference to match the flag before
-        // Chrome initialises via super.setUp()
+        // staring Chrome.
         ChromePreferenceManager prefManager = ChromePreferenceManager.getInstance();
         mOldChromeHomeFlagValue = prefManager.isChromeHomeEnabled();
         prefManager.setChromeHomeEnabled(true);
+    }
 
-        super.setUp();
-
+    protected void afterStartingActivity() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -124,27 +122,46 @@
         mBottomSheet = getActivity().getBottomSheet();
         mBottomSheetContentController = getActivity().getBottomSheetContentController();
 
-        mObserver = new TestBottomSheetObserver();
+        mObserver = new Observer();
         mBottomSheet.addObserver(mObserver);
     }
 
     @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    protected void afterActivityFinished() {
+        super.afterActivityFinished();
+        ChromePreferenceManager.getInstance().setChromeHomeEnabled(mOldChromeHomeFlagValue);
     }
 
+    // TODO (aberent): The Chrome test rules currently bypass ActivityTestRule.launchActivity, hence
+    // don't call beforeActivityLaunched and afterActivityLaunched as defined in the
+    // ActivityTestRule interface. To work round this override the methods that start activities.
+    // See https://crbug.com/726444.
     @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        ChromePreferenceManager.getInstance().setChromeHomeEnabled(mOldChromeHomeFlagValue);
+    public void startMainActivityOnBlankPage() throws InterruptedException {
+        beforeStartingActivity();
+        super.startMainActivityOnBlankPage();
+        afterStartingActivity();
+    }
+
+    public Observer getObserver() {
+        return mObserver;
+    }
+
+    public BottomSheet getBottomSheet() {
+        return mBottomSheet;
+    }
+
+    public BottomSheetContentController getBottomSheetContentController() {
+        return mBottomSheetContentController;
     }
 
     /**
      * Set the bottom sheet's state on the UI thread.
+     *
      * @param state The state to set the sheet to.
      * @param animate If the sheet should animate to the provided state.
      */
-    protected void setSheetState(final int state, final boolean animate) {
+    public void setSheetState(final int state, final boolean animate) {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -155,9 +172,10 @@
 
     /**
      * Set the bottom sheet's offset from the bottom of the screen on the UI thread.
+     *
      * @param offset The offset from the bottom that the sheet should be.
      */
-    protected void setSheetOffsetFromBottom(final float offset) {
+    public void setSheetOffsetFromBottom(final float offset) {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -166,15 +184,15 @@
         });
     }
 
-    protected BottomSheetContent getBottomSheetContent() {
+    public BottomSheetContent getBottomSheetContent() {
         return getActivity().getBottomSheet().getCurrentSheetContent();
     }
 
     /**
      * @param itemId The id of the MenuItem corresponding to the {@link BottomSheetContent} to
-     *               select.
+     *            select.
      */
-    protected void selectBottomSheetContent(final int itemId) {
+    public void selectBottomSheetContent(final int itemId) {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java
new file mode 100644
index 0000000..e2fe630
--- /dev/null
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.test;
+
+import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory;
+
+import org.chromium.chrome.browser.suggestions.SuggestionsBottomSheetContent;
+import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
+import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
+
+/**
+ * Junit4 rule for tests testing suggestions on the Chrome Home bottom sheet.
+ */
+public class SuggestionsBottomSheetTestRule extends BottomSheetTestRule {
+    @Override
+    protected void beforeStartingActivity() {
+        FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource();
+        registerCategory(suggestionsSource, /* category = */ 42, /* count = */ 5);
+        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(suggestionsSource);
+        SuggestionsBottomSheetContent.setEventReporterForTesting(
+                new DummySuggestionsEventReporter());
+        super.beforeStartingActivity();
+    }
+
+    @Override
+    protected void afterActivityFinished() {
+        super.afterActivityFinished();
+        SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(null);
+        SuggestionsBottomSheetContent.setEventReporterForTesting(null);
+    }
+}
diff --git a/components/metrics/stability_metrics_helper.cc b/components/metrics/stability_metrics_helper.cc
index f625487..82b31d2 100644
--- a/components/metrics/stability_metrics_helper.cc
+++ b/components/metrics/stability_metrics_helper.cc
@@ -170,8 +170,6 @@
 
 void StabilityMetricsHelper::LogLoadStarted() {
   base::RecordAction(base::UserMetricsAction("PageLoad"));
-  // TODO(asvitkine): Check if this is used for anything and if not, remove.
-  LOCAL_HISTOGRAM_BOOLEAN("Chrome.UmaPageloadCounter", true);
   IncrementPrefValue(prefs::kStabilityPageLoadCount);
   IncrementLongPrefsValue(prefs::kUninstallMetricsPageLoadCount);
   // We need to save the prefs, as page load count is a critical stat, and it
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc
index bc7bfccd..8bc011e5 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -113,7 +113,7 @@
     : id_(id),
       object_store_ids_(object_store_ids),
       mode_(mode),
-      connection_(std::move(connection)),
+      connection_(connection),
       transaction_(backing_store_transaction),
       ptr_factory_(this) {
   IDB_ASYNC_TRACE_BEGIN("IndexedDBTransaction::lifetime", this);
diff --git a/content/browser/net_info_browsertest.cc b/content/browser/net_info_browsertest.cc
index e4eec85..e62acb5 100644
--- a/content/browser/net_info_browsertest.cc
+++ b/content/browser/net_info_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <cmath>  // For std::modf.
 #include <map>
 #include <string>
 
@@ -92,7 +93,13 @@
 
   double RunScriptExtractDouble(const std::string& script) {
     double data = 0.0;
-    EXPECT_TRUE(base::StringToDouble(RunScriptExtractString(script), &data));
+    EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), script, &data));
+    return data;
+  }
+
+  int RunScriptExtractInt(const std::string& script) {
+    int data = 0;
+    EXPECT_TRUE(ExecuteScriptAndExtractInt(shell(), script, &data));
     return data;
   }
 };
@@ -164,7 +171,8 @@
 }
 
 // Verify that when the network quality notifications are not sent, the
-// Javascript API returns invalid estimate.
+// Javascript API returns a valid estimate that is multiple of 25 msec and 25
+// kbps.
 IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
                        NetworkQualityEstimatorNotInitialized) {
   base::HistogramTester histogram_tester;
@@ -177,9 +185,22 @@
   EXPECT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
 
-  EXPECT_EQ(0, RunScriptExtractDouble("getRtt()"));
-  EXPECT_EQ(std::numeric_limits<double>::infinity(),
-            RunScriptExtractDouble("getDownlink()"));
+  EXPECT_EQ(0, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(0, RunScriptExtractInt("getRtt()") % 25);
+
+  double downlink_mbps = RunScriptExtractDouble("getDownlink()");
+  EXPECT_LE(0, downlink_mbps);
+
+  // Verify that |downlink_mbps| is a multiple of 25 kbps. For example, a value
+  // of 1.250 mbps satisfies that constraint, but a value of 1.254 mbps does
+  // not.
+  double fraction_part, int_part;
+  fraction_part = std::modf(downlink_mbps, &int_part);
+  // If |fraction_part| is a multiple of 0.025, it implies |downlink_mbps| is
+  // also a multiple of 0.025, and hence |downlink_mbps| is a multiple of 25
+  // kbps.
+  EXPECT_EQ(0, static_cast<int>(fraction_part * 1000) % 25);
+
   EXPECT_EQ("4g", RunScriptExtractString("getEffectiveType()"));
 }
 
@@ -249,7 +270,7 @@
       histogram_tester.GetAllSamples("NQE.RenderThreadNotified").empty());
 
   EXPECT_EQ(network_quality_1.transport_rtt().InMilliseconds(),
-            RunScriptExtractDouble("getRtt()"));
+            RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(
       static_cast<double>(network_quality_1.downstream_throughput_kbps()) /
           1000,
@@ -262,7 +283,7 @@
       network_quality_2);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(network_quality_2.transport_rtt().InMilliseconds(),
-            RunScriptExtractDouble("getRtt()"));
+            RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(
       static_cast<double>(network_quality_2.downstream_throughput_kbps()) /
           1000,
@@ -289,7 +310,7 @@
   EXPECT_TRUE(embedded_test_server()->Start());
   EXPECT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
-  EXPECT_EQ(200, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(200, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(0.300, RunScriptExtractDouble("getDownlink()"));
 
   net::nqe::internal::NetworkQuality network_quality_2(
@@ -298,7 +319,7 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_2);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1225, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(1225, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.325, RunScriptExtractDouble("getDownlink()"));
 
   net::nqe::internal::NetworkQuality network_quality_3(
@@ -307,7 +328,7 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_3);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(0, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(0, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(0, RunScriptExtractDouble("getDownlink()"));
 }
 
@@ -329,7 +350,7 @@
   EXPECT_TRUE(embedded_test_server()->Start());
   EXPECT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
-  EXPECT_EQ(1200, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(1200, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.300, RunScriptExtractDouble("getDownlink()"));
 
   // All the 3 metrics change by less than 10%. So, the observers are not
@@ -340,7 +361,7 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_2);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1200, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(1200, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.300, RunScriptExtractDouble("getDownlink()"));
 
   // Transport RTT has changed by more than 10% from the last notified value of
@@ -351,7 +372,7 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_3);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(2300, RunScriptExtractDouble("getRtt()"));
+  EXPECT_EQ(2300, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.400, RunScriptExtractDouble("getDownlink()"));
 }
 
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index ee956813..2a5d922 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -466,6 +466,11 @@
   } else if (autoplay_policy ==
              switches::autoplay::kUserGestureRequiredForCrossOriginPolicy) {
     prefs.autoplay_policy = AutoplayPolicy::kUserGestureRequiredForCrossOrigin;
+  } else if (autoplay_policy ==
+             switches::autoplay::kDocumentUserActivationRequiredPolicy) {
+    prefs.autoplay_policy = AutoplayPolicy::kDocumentUserActivationRequired;
+  } else {
+    NOTREACHED();
   }
 
   const std::string touch_enabled_switch =
diff --git a/content/child/web_data_consumer_handle_impl.cc b/content/child/web_data_consumer_handle_impl.cc
index 66f50752..8d00e99 100644
--- a/content/child/web_data_consumer_handle_impl.cc
+++ b/content/child/web_data_consumer_handle_impl.cc
@@ -38,7 +38,7 @@
     scoped_refptr<Context> context,
     Client* client)
     : context_(context),
-      handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC),
+      handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL),
       client_(client) {
   if (client_)
     StartWatching();
@@ -77,6 +77,8 @@
                                     &size_to_pass, flags_to_pass);
   if (rv == MOJO_RESULT_OK)
     *read_size = size_to_pass;
+  if (rv == MOJO_RESULT_OK || rv == MOJO_RESULT_SHOULD_WAIT)
+    handle_watcher_.ArmOrNotify();
 
   return HandleReadResult(rv);
 }
@@ -103,6 +105,8 @@
 
 Result WebDataConsumerHandleImpl::ReaderImpl::EndRead(size_t read_size) {
   MojoResult rv = mojo::EndReadDataRaw(context_->handle().get(), read_size);
+  if (rv == MOJO_RESULT_OK)
+    handle_watcher_.ArmOrNotify();
   return rv == MOJO_RESULT_OK ? kOk : kUnexpectedError;
 }
 
@@ -128,6 +132,7 @@
   handle_watcher_.Watch(
       context_->handle().get(), MOJO_HANDLE_SIGNAL_READABLE,
       base::Bind(&ReaderImpl::OnHandleGotReadable, base::Unretained(this)));
+  handle_watcher_.ArmOrNotify();
 }
 
 void WebDataConsumerHandleImpl::ReaderImpl::OnHandleGotReadable(MojoResult) {
diff --git a/content/child/web_data_consumer_handle_impl_unittest.cc b/content/child/web_data_consumer_handle_impl_unittest.cc
index 17eae33..fdc1b43 100644
--- a/content/child/web_data_consumer_handle_impl_unittest.cc
+++ b/content/child/web_data_consumer_handle_impl_unittest.cc
@@ -310,6 +310,94 @@
   EXPECT_EQ(WebDataConsumerHandle::Result::kDone, rv);
 }
 
+class CountDidGetReadableClient : public blink::WebDataConsumerHandle::Client {
+ public:
+  ~CountDidGetReadableClient() override {}
+  void DidGetReadable() override { num_did_get_readable_called_++; }
+  int num_did_get_readable_called() { return num_did_get_readable_called_; }
+
+ private:
+  int num_did_get_readable_called_ = 0;
+};
+
+TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
+  static constexpr size_t kBlockSize = kDataPipeCapacity / 3;
+  static constexpr size_t kTotalSize = kBlockSize * 3;
+
+  std::unique_ptr<CountDidGetReadableClient> client =
+      base::MakeUnique<CountDidGetReadableClient>();
+  std::unique_ptr<WebDataConsumerHandleImpl> handle(
+      new WebDataConsumerHandleImpl(std::move(consumer_)));
+  std::unique_ptr<WebDataConsumerHandle::Reader> reader(
+      handle->ObtainReader(client.get()));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0, client->num_did_get_readable_called());
+
+  // Push three blocks.
+  {
+    std::string expected;
+    int index = 0;
+    for (size_t i = 0; i < kTotalSize; ++i) {
+      expected += static_cast<char>(index + 'a');
+      index = (37 * index + 11) % 26;
+    }
+    uint32_t size = expected.size();
+    MojoResult rv = mojo::WriteDataRaw(producer_.get(), expected.data(), &size,
+                                       MOJO_WRITE_DATA_FLAG_NONE);
+    EXPECT_EQ(MOJO_RESULT_OK, rv);
+    EXPECT_EQ(kTotalSize, size);
+  }
+  base::RunLoop().RunUntilIdle();
+  // |client| is notified the pipe gets ready.
+  EXPECT_EQ(1, client->num_did_get_readable_called());
+
+  // Read a block.
+  {
+    char buffer[kBlockSize];
+    size_t size = 0;
+    Result rv = reader->Read(&buffer, sizeof(buffer),
+                             WebDataConsumerHandle::kFlagNone, &size);
+    EXPECT_EQ(Result::kOk, rv);
+    EXPECT_EQ(sizeof(buffer), size);
+  }
+  base::RunLoop().RunUntilIdle();
+  // |client| is notified the pipe is still ready.
+  EXPECT_EQ(2, client->num_did_get_readable_called());
+
+  // Read one more block.
+  {
+    const void* buffer = nullptr;
+    size_t size = sizeof(buffer);
+    Result rv =
+        reader->BeginRead(&buffer, WebDataConsumerHandle::kFlagNone, &size);
+    EXPECT_EQ(Result::kOk, rv);
+    EXPECT_TRUE(buffer);
+    EXPECT_EQ(kTotalSize - kBlockSize, size);
+    base::RunLoop().RunUntilIdle();
+    // |client| is NOT notified until EndRead is called.
+    EXPECT_EQ(2, client->num_did_get_readable_called());
+
+    rv = reader->EndRead(kBlockSize);
+    EXPECT_EQ(Result::kOk, rv);
+  }
+  base::RunLoop().RunUntilIdle();
+  // |client| is notified the pipe is still ready.
+  EXPECT_EQ(3, client->num_did_get_readable_called());
+
+  // Read the final block.
+  {
+    char buffer[kBlockSize];
+    size_t size = 0;
+    Result rv = reader->Read(&buffer, sizeof(buffer),
+                             WebDataConsumerHandle::kFlagNone, &size);
+    EXPECT_EQ(Result::kOk, rv);
+    EXPECT_EQ(sizeof(buffer), size);
+  }
+  base::RunLoop().RunUntilIdle();
+  // |client| is NOT notified because the pipe doesn't have any data.
+  EXPECT_EQ(3, client->num_did_get_readable_called());
+}
+
 }  // namespace
 
 }  // namespace content
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index 25b9c8c8..befe55e 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -81,7 +81,7 @@
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(
     content::AutoplayPolicy,
     content::AutoplayPolicy::kNoUserGestureRequired,
-    content::AutoplayPolicy::kUserGestureRequiredForCrossOrigin)
+    content::AutoplayPolicy::kDocumentUserActivationRequired)
 
 IPC_STRUCT_TRAITS_BEGIN(blink::WebPoint)
   IPC_STRUCT_TRAITS_MEMBER(x)
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h
index 80816ae..901b50ea 100644
--- a/content/public/common/web_preferences.h
+++ b/content/public/common/web_preferences.h
@@ -72,6 +72,7 @@
   kNoUserGestureRequired,
   kUserGestureRequired,
   kUserGestureRequiredForCrossOrigin,
+  kDocumentUserActivationRequired,
 };
 
 // The ISO 15924 script code for undetermined script aka Common. It's the
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index b0d3c28..9967866 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1035,6 +1035,10 @@
       settings->SetAutoplayPolicy(
           WebSettings::AutoplayPolicy::kUserGestureRequiredForCrossOrigin);
       break;
+    case AutoplayPolicy::kDocumentUserActivationRequired:
+      settings->SetAutoplayPolicy(
+          WebSettings::AutoplayPolicy::kDocumentUserActivationRequired);
+      break;
   }
 
   settings->SetViewportEnabled(prefs.viewport_enabled);
diff --git a/content/test/data/net_info.html b/content/test/data/net_info.html
index 58f4702..1da26e4 100644
--- a/content/test/data/net_info.html
+++ b/content/test/data/net_info.html
@@ -7,7 +7,7 @@
 }
 
 function getDownlinkMax() {
-  sendValueToTest(navigator.connection.downlinkMax.toString());
+  sendValueToTest(navigator.connection.downlinkMax);
 }
 
 function getOnLine() {
@@ -19,11 +19,11 @@
 }
 
 function getRtt() {
-  sendValueToTest(navigator.connection.rtt.toString());
+sendValueToTest(navigator.connection.rtt);
 }
 
 function getDownlink() {
-  sendValueToTest(navigator.connection.downlink.toString());
+  sendValueToTest(navigator.connection.downlink);
 }
 
 function sendValueToTest(value) {
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index a93b4ebf..06f9524 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -780,7 +780,7 @@
       mailbox_manager_(mailbox_manager),
       image_manager_(new gles2::ImageManager()),
       watchdog_(watchdog),
-      discardable_manager_(std::move(discardable_manager)),
+      discardable_manager_(discardable_manager),
       is_gpu_host_(is_gpu_host),
       weak_factory_(this) {
   DCHECK(gpu_channel_manager_);
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index aad4a7e..af8c995 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -164,6 +164,10 @@
 
 namespace autoplay {
 
+// Autoplay policy that requires a document user activation.
+const char kDocumentUserActivationRequiredPolicy[] =
+    "document-user-activation-required";
+
 // Autoplay policy that does not require any user gesture.
 const char kNoUserGestureRequiredPolicy[] = "no-user-gesture-required";
 
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index b33e9529..abbeb5a8 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -92,6 +92,7 @@
 
 namespace autoplay {
 
+MEDIA_EXPORT extern const char kDocumentUserActivationRequiredPolicy[];
 MEDIA_EXPORT extern const char kNoUserGestureRequiredPolicy[];
 MEDIA_EXPORT extern const char kUserGestureRequiredPolicy[];
 MEDIA_EXPORT extern const char kUserGestureRequiredForCrossOriginPolicy[];
diff --git a/services/preferences/README.md b/services/preferences/README.md
index 7831ca2..a74dd931 100644
--- a/services/preferences/README.md
+++ b/services/preferences/README.md
@@ -10,15 +10,15 @@
 and have a type. E.g., the "browser.enable_spellchecking" pref stores a boolean
 indicating whether spell-checking is enabled.
 
-The prefs service persists prefs to disk and communicates updates to them
-between services, including Chrome itself. There's one service instance per
-profile and prefs are persisted on a pre-profile basis.
+The pref service persists prefs to disk and communicates updates to prefs
+between services, including Chrome itself. There is a pref service instance per
+profile (prefs are persisted on a per-profile basis).
 
 ## Using the service
 
 The service is used through a client library that offers clients fast and
-synchronous access to prefs. To connect to the pref service and start reading
-and writing prefs simply use the `ConnectToPrefService` factory function:
+synchronous access to prefs. To connect to the service and start reading and
+writing prefs simply use the `ConnectToPrefService` factory function:
 
 ``` cpp
 #include "services/preferences/public/cpp/pref_service_factory.h"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index f0f33500..ad8f3e7 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -43,7 +43,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -82,7 +82,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -121,7 +121,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -308,7 +308,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -427,7 +427,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -820,7 +820,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -928,7 +928,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1087,7 +1087,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1127,7 +1127,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1284,12 +1284,11 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
           ],
-          "hard_timeout": 120,
           "output_links": [
             {
               "link": [
@@ -1574,7 +1573,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1613,7 +1612,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1652,7 +1651,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1839,7 +1838,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -1958,7 +1957,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -2351,7 +2350,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -2459,7 +2458,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -2618,7 +2617,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -2658,7 +2657,7 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
@@ -2846,12 +2845,11 @@
           ],
           "dimension_sets": [
             {
-              "android_devices": "1",
+              "android_devices": "4",
               "device_os": "KTU84P",
               "device_type": "hammerhead"
             }
           ],
-          "hard_timeout": 120,
           "output_links": [
             {
               "link": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 7ea2e39..9271457d 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -24142,7 +24142,6 @@
 crbug.com/591099 vr/requestPresent_resolve_then_reject.html [ Crash ]
 crbug.com/591099 vr/requestPresent_resolve_webgl2.html [ Crash ]
 crbug.com/591099 vr/stageParameters_match.html [ Crash ]
-crbug.com/591099 web-animations-api/time-consistent-across-frames.html [ Crash ]
 crbug.com/591099 webaudio/BiquadFilter/tail-time-lowpass.html [ Timeout ]
 crbug.com/591099 webaudio/internals/audiocontext-lock-threading-race.html [ Failure ]
 crbug.com/591099 webaudio/internals/cycle-connection-gc.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
index cf460d3..ba48982 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
@@ -3400,7 +3400,6 @@
 Bug(none) vr/requestPresent_resolve_then_reject.html [ Timeout ]
 Bug(none) vr/requestPresent_resolve_webgl2.html [ Timeout ]
 Bug(none) vr/stageParameters_match.html [ Timeout ]
-Bug(none) web-animations-api/animation-finish-promise-gc.html [ Timeout ]
 Bug(none) webaudio/Analyser/realtimeanalyser-basic.html [ Timeout ]
 Bug(none) webaudio/Analyser/realtimeanalyser-fft-scaling.html [ Timeout ]
 Bug(none) webaudio/Analyser/realtimeanalyser-fft-sizing.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations
index b85495d..03420a8 100644
--- a/third_party/WebKit/LayoutTests/MSANExpectations
+++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -53,11 +53,13 @@
 # These tests use OpenGl, which crashes on MSAN builds due to missing instrumentation
 crbug.com/555703 [ Linux ] virtual/media-gpu-accelerated [ Skip ]
 
-# These tests are just a tad bit too slow on MSAN bots, give them more time.
-crbug.com/729136 [ Linux ] external/wpt/encoding/textdecoder-fatal-single-byte.html [ Slow ]
-crbug.com/729136 [ Linux ] fast/css/css-selector-deeply-nested.html [ Slow ]
-crbug.com/729136 [ Linux ] http/tests/inspector/forced-layout-in-microtask.html [ Slow ]
-crbug.com/729136 [ Linux ] http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html [ Slow ]
-crbug.com/729136 [ Linux ] inspector/components/file-path-scoring.html [ Slow ]
-crbug.com/729136 [ Linux ] inspector/elements/styles-4/styles-should-not-force-sync-style-recalc.html [ Slow ]
-crbug.com/729136 [ Linux ] webaudio/mixing.html [ Slow ]
+# These tests are just a tad bit too slow on MSAN bots and time out. Setting
+# them as "Slow" doesn't seem to help the problem (see discussion on bug), so
+# marking them as "Timeout" while crbug.com/729136 is worked out.
+crbug.com/729136 [ Linux ] external/wpt/encoding/textdecoder-fatal-single-byte.html [ Timeout ]
+crbug.com/729136 [ Linux ] fast/css/css-selector-deeply-nested.html [ Timeout ]
+crbug.com/729136 [ Linux ] http/tests/inspector/forced-layout-in-microtask.html [ Timeout ]
+crbug.com/729136 [ Linux ] http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html [ Timeout ]
+crbug.com/729136 [ Linux ] inspector/components/file-path-scoring.html [ Timeout ]
+crbug.com/729136 [ Linux ] inspector/elements/styles-4/styles-should-not-force-sync-style-recalc.html [ Timeout ]
+crbug.com/729136 [ Linux ] webaudio/mixing.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/SmokeTests b/third_party/WebKit/LayoutTests/SmokeTests
index 79cb720..cef78f3 100644
--- a/third_party/WebKit/LayoutTests/SmokeTests
+++ b/third_party/WebKit/LayoutTests/SmokeTests
@@ -1022,7 +1022,6 @@
 virtual/without-smil/svg/animations/exposed/effect.html
 wake_lock/wakelock-api.html
 wake_lock/wakelock-in-nested-frame.html
-web-animations-api/the-effect-value-of-a-keyframe-effect.html
 webaudio/AudioBufferSource/audiobuffersource-ended.html
 webaudio/AudioBufferSource/audiobuffersource-playbackrate-zero.html
 webaudio/AudioNode/channel-mode-interp-basic.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-in-raf.html b/third_party/WebKit/LayoutTests/animations/animation-cancel-in-raf.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-in-raf.html
rename to third_party/WebKit/LayoutTests/animations/animation-cancel-in-raf.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-in-raf.html b/third_party/WebKit/LayoutTests/animations/animation-finish-in-raf.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/animation-finish-in-raf.html
rename to third_party/WebKit/LayoutTests/animations/animation-finish-in-raf.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-promise-gc.html b/third_party/WebKit/LayoutTests/animations/animation-finish-promise-gc.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/animation-finish-promise-gc.html
rename to third_party/WebKit/LayoutTests/animations/animation-finish-promise-gc.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-reject-script-forbidden.html b/third_party/WebKit/LayoutTests/animations/animation-ready-reject-script-forbidden.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/animation-ready-reject-script-forbidden.html
rename to third_party/WebKit/LayoutTests/animations/animation-ready-reject-script-forbidden.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html b/third_party/WebKit/LayoutTests/animations/animation-state-changes-negative-playback-rate.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html
rename to third_party/WebKit/LayoutTests/animations/animation-state-changes-negative-playback-rate.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/playState-changes.html b/third_party/WebKit/LayoutTests/animations/animation-state-changes-positive-playback-rate.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/playState-changes.html
rename to third_party/WebKit/LayoutTests/animations/animation-state-changes-positive-playback-rate.html
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/the-effect-value-of-a-keyframe-effect.html b/third_party/WebKit/LayoutTests/animations/the-effect-value-of-a-keyframe-effect.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/web-animations-api/the-effect-value-of-a-keyframe-effect.html
rename to third_party/WebKit/LayoutTests/animations/the-effect-value-of-a-keyframe-effect.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-typed-om/styleMap-update-function-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css-typed-om/styleMap-update-function-expected.txt
index cf2fdcd..1fd125f1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css-typed-om/styleMap-update-function-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/css-typed-om/styleMap-update-function-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL styleMap objects provide an 'update' function Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
+FAIL styleMap objects provide an 'update' function element.styleMap.update is not a function
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-forms-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-forms-expected.txt
index 793fe3fc..f1503f3b5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-forms-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-forms-expected.txt
@@ -101,11 +101,13 @@
 FAIL input.inputMode: setAttribute() to "kana\0" assert_equals: IDL get expected "" but got "kana\0"
 FAIL input.inputMode: setAttribute() to "ana" assert_equals: IDL get expected "" but got "ana"
 FAIL input.inputMode: setAttribute() to "KANA" assert_equals: IDL get expected "kana" but got "KANA"
+FAIL input.inputMode: setAttribute() to "Kana" assert_equals: IDL get expected "" but got "Kana"
 PASS input.inputMode: setAttribute() to "katakana" 
 FAIL input.inputMode: setAttribute() to "xkatakana" assert_equals: IDL get expected "" but got "xkatakana"
 FAIL input.inputMode: setAttribute() to "katakana\0" assert_equals: IDL get expected "" but got "katakana\0"
 FAIL input.inputMode: setAttribute() to "atakana" assert_equals: IDL get expected "" but got "atakana"
 FAIL input.inputMode: setAttribute() to "KATAKANA" assert_equals: IDL get expected "katakana" but got "KATAKANA"
+FAIL input.inputMode: setAttribute() to "KataKana" assert_equals: IDL get expected "" but got "KataKana"
 PASS input.inputMode: setAttribute() to "numeric" 
 FAIL input.inputMode: setAttribute() to "xnumeric" assert_equals: IDL get expected "" but got "xnumeric"
 FAIL input.inputMode: setAttribute() to "numeric\0" assert_equals: IDL get expected "" but got "numeric\0"
@@ -171,11 +173,13 @@
 FAIL input.inputMode: IDL set to "kana\0" assert_equals: IDL get expected "" but got "kana\0"
 FAIL input.inputMode: IDL set to "ana" assert_equals: IDL get expected "" but got "ana"
 FAIL input.inputMode: IDL set to "KANA" assert_equals: IDL get expected "kana" but got "KANA"
+FAIL input.inputMode: IDL set to "Kana" assert_equals: IDL get expected "" but got "Kana"
 PASS input.inputMode: IDL set to "katakana" 
 FAIL input.inputMode: IDL set to "xkatakana" assert_equals: IDL get expected "" but got "xkatakana"
 FAIL input.inputMode: IDL set to "katakana\0" assert_equals: IDL get expected "" but got "katakana\0"
 FAIL input.inputMode: IDL set to "atakana" assert_equals: IDL get expected "" but got "atakana"
 FAIL input.inputMode: IDL set to "KATAKANA" assert_equals: IDL get expected "katakana" but got "KATAKANA"
+FAIL input.inputMode: IDL set to "KataKana" assert_equals: IDL get expected "" but got "KataKana"
 PASS input.inputMode: IDL set to "numeric" 
 FAIL input.inputMode: IDL set to "xnumeric" assert_equals: IDL get expected "" but got "xnumeric"
 FAIL input.inputMode: IDL set to "numeric\0" assert_equals: IDL get expected "" but got "numeric\0"
@@ -214,11 +218,19 @@
 FAIL input.type: setAttribute() to "datetime" assert_equals: IDL get expected "datetime" but got "text"
 PASS input.type: 3 tests
 FAIL input.type: setAttribute() to "DATETIME" assert_equals: IDL get expected "datetime" but got "text"
-PASS input.type: 125 tests
+PASS input.type: 15 tests
+FAIL input.type: setAttribute() to "weeK" assert_equals: IDL get expected "text" but got "week"
+PASS input.type: 30 tests
+FAIL input.type: setAttribute() to "checKbox" assert_equals: IDL get expected "text" but got "checkbox"
+PASS input.type: 80 tests
 FAIL input.type: IDL set to "datetime" assert_equals: IDL get expected "datetime" but got "text"
 PASS input.type: 3 tests
 FAIL input.type: IDL set to "DATETIME" assert_equals: IDL get expected "datetime" but got "text"
-PASS input.type: 75 tests
+PASS input.type: 15 tests
+FAIL input.type: IDL set to "weeK" assert_equals: IDL get expected "text" but got "week"
+PASS input.type: 30 tests
+FAIL input.type: IDL set to "checKbox" assert_equals: IDL get expected "text" but got "checkbox"
+PASS input.type: 30 tests
 PASS input.defaultValue (<input value>): 32 tests
 PASS input.align: 32 tests
 PASS input.useMap: 32 tests
@@ -389,11 +401,13 @@
 FAIL textarea.inputMode: setAttribute() to "kana\0" assert_equals: IDL get expected "" but got "kana\0"
 FAIL textarea.inputMode: setAttribute() to "ana" assert_equals: IDL get expected "" but got "ana"
 FAIL textarea.inputMode: setAttribute() to "KANA" assert_equals: IDL get expected "kana" but got "KANA"
+FAIL textarea.inputMode: setAttribute() to "Kana" assert_equals: IDL get expected "" but got "Kana"
 PASS textarea.inputMode: setAttribute() to "katakana" 
 FAIL textarea.inputMode: setAttribute() to "xkatakana" assert_equals: IDL get expected "" but got "xkatakana"
 FAIL textarea.inputMode: setAttribute() to "katakana\0" assert_equals: IDL get expected "" but got "katakana\0"
 FAIL textarea.inputMode: setAttribute() to "atakana" assert_equals: IDL get expected "" but got "atakana"
 FAIL textarea.inputMode: setAttribute() to "KATAKANA" assert_equals: IDL get expected "katakana" but got "KATAKANA"
+FAIL textarea.inputMode: setAttribute() to "KataKana" assert_equals: IDL get expected "" but got "KataKana"
 PASS textarea.inputMode: setAttribute() to "numeric" 
 FAIL textarea.inputMode: setAttribute() to "xnumeric" assert_equals: IDL get expected "" but got "xnumeric"
 FAIL textarea.inputMode: setAttribute() to "numeric\0" assert_equals: IDL get expected "" but got "numeric\0"
@@ -459,11 +473,13 @@
 FAIL textarea.inputMode: IDL set to "kana\0" assert_equals: IDL get expected "" but got "kana\0"
 FAIL textarea.inputMode: IDL set to "ana" assert_equals: IDL get expected "" but got "ana"
 FAIL textarea.inputMode: IDL set to "KANA" assert_equals: IDL get expected "kana" but got "KANA"
+FAIL textarea.inputMode: IDL set to "Kana" assert_equals: IDL get expected "" but got "Kana"
 PASS textarea.inputMode: IDL set to "katakana" 
 FAIL textarea.inputMode: IDL set to "xkatakana" assert_equals: IDL get expected "" but got "xkatakana"
 FAIL textarea.inputMode: IDL set to "katakana\0" assert_equals: IDL get expected "" but got "katakana\0"
 FAIL textarea.inputMode: IDL set to "atakana" assert_equals: IDL get expected "" but got "atakana"
 FAIL textarea.inputMode: IDL set to "KATAKANA" assert_equals: IDL get expected "katakana" but got "KATAKANA"
+FAIL textarea.inputMode: IDL set to "KataKana" assert_equals: IDL get expected "" but got "KataKana"
 PASS textarea.inputMode: IDL set to "numeric" 
 FAIL textarea.inputMode: IDL set to "xnumeric" assert_equals: IDL get expected "" but got "xnumeric"
 FAIL textarea.inputMode: IDL set to "numeric\0" assert_equals: IDL get expected "" but got "numeric\0"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-metadata-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-metadata-expected.txt
index 163040a1..4ec7d04 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-metadata-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-metadata-expected.txt
@@ -52,13 +52,15 @@
 FAIL link.as: setAttribute() to "serviceworker" assert_equals: IDL get expected "serviceworker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: setAttribute() to "SERVICEWORKER" assert_equals: IDL get expected "serviceworker" but got ""
+PASS link.as: setAttribute() to "serviceworKer" 
 FAIL link.as: setAttribute() to "sharedworker" assert_equals: IDL get expected "sharedworker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: setAttribute() to "SHAREDWORKER" assert_equals: IDL get expected "sharedworker" but got ""
-PASS link.as: 15 tests
+PASS link.as: 17 tests
 FAIL link.as: setAttribute() to "worker" assert_equals: IDL get expected "worker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: setAttribute() to "WORKER" assert_equals: IDL get expected "worker" but got ""
+PASS link.as: setAttribute() to "worKer" 
 FAIL link.as: setAttribute() to "xslt" assert_equals: IDL get expected "xslt" but got ""
 PASS link.as: 3 tests
 FAIL link.as: setAttribute() to "XSLT" assert_equals: IDL get expected "xslt" but got ""
@@ -83,13 +85,15 @@
 FAIL link.as: IDL set to "serviceworker" assert_equals: IDL get expected "serviceworker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: IDL set to "SERVICEWORKER" assert_equals: IDL get expected "serviceworker" but got ""
+PASS link.as: IDL set to "serviceworKer" 
 FAIL link.as: IDL set to "sharedworker" assert_equals: IDL get expected "sharedworker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: IDL set to "SHAREDWORKER" assert_equals: IDL get expected "sharedworker" but got ""
-PASS link.as: 15 tests
+PASS link.as: 17 tests
 FAIL link.as: IDL set to "worker" assert_equals: IDL get expected "worker" but got ""
 PASS link.as: 3 tests
 FAIL link.as: IDL set to "WORKER" assert_equals: IDL get expected "worker" but got ""
+PASS link.as: IDL set to "worKer" 
 FAIL link.as: IDL set to "xslt" assert_equals: IDL get expected "xslt" but got ""
 PASS link.as: 3 tests
 FAIL link.as: IDL set to "XSLT" assert_equals: IDL get expected "xslt" but got ""
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
index 1d9348ac..3fe9a25 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
@@ -228,6 +228,7 @@
 FAIL menuitem.type: setAttribute() to "checkbox\0" assert_equals: IDL get expected (string) "command" but got (undefined) undefined
 FAIL menuitem.type: setAttribute() to "heckbox" assert_equals: IDL get expected (string) "command" but got (undefined) undefined
 FAIL menuitem.type: setAttribute() to "CHECKBOX" assert_equals: IDL get expected (string) "checkbox" but got (undefined) undefined
+FAIL menuitem.type: setAttribute() to "checKbox" assert_equals: IDL get expected (string) "command" but got (undefined) undefined
 FAIL menuitem.type: setAttribute() to "radio" assert_equals: IDL get expected (string) "radio" but got (undefined) undefined
 FAIL menuitem.type: setAttribute() to "xradio" assert_equals: IDL get expected (string) "command" but got (undefined) undefined
 FAIL menuitem.type: setAttribute() to "radio\0" assert_equals: IDL get expected (string) "command" but got (undefined) undefined
@@ -258,6 +259,7 @@
 FAIL menuitem.type: IDL set to "checkbox\0" assert_equals: getAttribute() expected "checkbox\0" but got "RADIO"
 FAIL menuitem.type: IDL set to "heckbox" assert_equals: getAttribute() expected "heckbox" but got "RADIO"
 FAIL menuitem.type: IDL set to "CHECKBOX" assert_equals: getAttribute() expected "CHECKBOX" but got "RADIO"
+FAIL menuitem.type: IDL set to "checKbox" assert_equals: getAttribute() expected "checKbox" but got "RADIO"
 FAIL menuitem.type: IDL set to "radio" assert_equals: getAttribute() expected "radio" but got "RADIO"
 FAIL menuitem.type: IDL set to "xradio" assert_equals: getAttribute() expected "xradio" but got "RADIO"
 FAIL menuitem.type: IDL set to "radio\0" assert_equals: getAttribute() expected "radio\0" but got "RADIO"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection.js b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection.js
index b50e99b..d1b3abe 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection.js
@@ -675,6 +675,10 @@
                 domTests.push(data.keywords[i].toUpperCase());
                 idlTests.push(data.keywords[i].toUpperCase());
             }
+            if (data.keywords[i] != data.keywords[i].replace(/k/g, "\u212A")) {
+                domTests.push(data.keywords[i].replace(/k/g, "\u212A"));
+                idlTests.push(data.keywords[i].replace(/k/g, "\u212A"));
+            }
         }
 
         // Per spec, the expected DOM values are the same as the value we set
@@ -821,6 +825,10 @@
     }
 };
 
+function toASCIILowerCase(str) {
+    return str.replace(/[A-Z]/g, function(m) { return m.toLowerCase(); });
+}
+
 /**
  * If we have an enumerated attribute limited to the array of values in
  * keywords, with nonCanon being a map of non-canonical values to their
@@ -831,7 +839,7 @@
 ReflectionTests.enumExpected = function(keywords, nonCanon, invalidVal, contentVal) {
     var ret = invalidVal;
     for (var i = 0; i < keywords.length; i++) {
-        if (String(contentVal).toLowerCase() == keywords[i].toLowerCase()) {
+        if (toASCIILowerCase(String(contentVal)) === toASCIILowerCase(keywords[i])) {
             ret = keywords[i];
             break;
         }
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint-expected.txt b/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint-expected.txt
index 0b0e1531..54ddb494 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint-expected.txt
@@ -1,11 +1,11 @@
-CONSOLE MESSAGE: line 14: --length: [CSSStyleValue=10px]
-CONSOLE MESSAGE: line 14: --length-initial: [CSSStyleValue=20px]
+CONSOLE MESSAGE: line 14: --length: [CSSUnitValue=10px]
+CONSOLE MESSAGE: line 14: --length-initial: [CSSUnitValue=20px]
 CONSOLE MESSAGE: line 14: --number: [CSSStyleValue=10]
 This tests the style information in the paint callback.
 
 See the devtools console for test output. The console should log:
 
---length: [CSSStyleValue=10px]
---length-initial: [CSSStyleValue=20px]
+--length: [CSSUnitValue=10px]
+--length-initial: [CSSUnitValue=20px]
 --number: [CSSStyleValue=10]
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint.html b/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint.html
index 9ce145c..7aaaed0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint.html
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/registered-properties-in-custom-paint.html
@@ -35,8 +35,8 @@
 </script>
 <p>This tests the style information in the paint callback.</p>
 <p>See the devtools console for test output. The console should log:</p>
---length: [CSSStyleValue=10px]<br>
---length-initial: [CSSStyleValue=20px]<br>
+--length: [CSSUnitValue=10px]<br>
+--length-initial: [CSSUnitValue=20px]<br>
 --number: [CSSStyleValue=10]<br>
 
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo-expected.txt b/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo-expected.txt
index ec74df4..cd068567 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo-expected.txt
@@ -1,10 +1,10 @@
 CONSOLE MESSAGE: line 14: color: [CSSStyleValue=rgb(255, 0, 0)]
-CONSOLE MESSAGE: line 14: line-height: [CSSStyleValue=2px]
+CONSOLE MESSAGE: line 14: line-height: [CSSUnitValue=2px]
 Foo
 This tests the style information in the paint callback.
 
 See the devtools console for test output. The console should log:
 
 color: [CSSStyleValue=rgb(255, 0, 0)]
-line-height: [CSSStyleValue=2px]
+line-height: [CSSUnitValue=2px]
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo.html b/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo.html
index a0ff935..f5b45f94 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo.html
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/style-first-letter-pseudo.html
@@ -32,6 +32,6 @@
 <p>This tests the style information in the paint callback.</p>
 <p>See the devtools console for test output. The console should log:</p>
 color: [CSSStyleValue=rgb(255, 0, 0)]<br>
-line-height: [CSSStyleValue=2px]<br>
+line-height: [CSSUnitValue=2px]<br>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-item-selection-dialog-filtering.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-item-selection-dialog-filtering.js
index 7fc09aec..16f0dd9d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-item-selection-dialog-filtering.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-item-selection-dialog-filtering.js
@@ -33,10 +33,9 @@
         function dump()
         {
             TestRunner.addResult("Query:" + JSON.stringify(filteredSelectionDialog._value()));
-            var items = filteredSelectionDialog._items;
             var output = [];
-            for (var i = 0; i < items.length(); ++i)
-                output.push(provider.itemKeyAt(items.itemAtIndex(i)));
+            for (var item of filteredSelectionDialog._items)
+                output.push(provider.itemKeyAt(item));
             TestRunner.addResult("Output:" + JSON.stringify(output));
         }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-list-widget-providers.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-list-widget-providers.js
index 13b4d98..3630f19 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-list-widget-providers.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/filtered-list-widget-providers.js
@@ -50,10 +50,9 @@
       TestRunner.addResult('Output: ' + filteredListWidget._notFoundElement.textContent);
       return;
     }
-    var items = filteredListWidget._items;
     var output = [];
-    for (var i = 0; i < items.length(); ++i)
-      output.push(filteredListWidget._provider.itemKeyAt(items.itemAtIndex(i)));
+    for (var item of filteredListWidget._items)
+      output.push(filteredListWidget._provider.itemKeyAt(item));
     TestRunner.addResult('Output:' + JSON.stringify(output));
   }
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-equal-height.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-equal-height.js
index 67b85b7..f0bcd078 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-equal-height.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-equal-height.js
@@ -39,7 +39,7 @@
 function dumpList()
 {
   var height = list.element.offsetHeight;
-  TestRunner.addResult(`----list[length=${model.length()}][height=${height}]----`);
+  TestRunner.addResult(`----list[length=${model.length}][height=${height}]----`);
   for (var child of list.element.children) {
     var offsetTop = child.getBoundingClientRect().top - list.element.getBoundingClientRect().top;
     var offsetBottom = child.getBoundingClientRect().bottom - list.element.getBoundingClientRect().top;
@@ -53,7 +53,7 @@
 }
 
 TestRunner.addResult('Adding 0, 1, 2');
-model.replaceAllItems([0, 1, 2]);
+model.replaceAll([0, 1, 2]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 0');
@@ -85,7 +85,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 0 with 5, 6, 7');
-model.replaceItemsInRange(0, 1, [5, 6, 7]);
+model.replaceRange(0, 1, [5, 6, 7]);
 dumpList();
 
 TestRunner.addResult('ArrowUp');
@@ -93,7 +93,7 @@
 dumpList();
 
 TestRunner.addResult('Pushing 10');
-model.pushItem(10);
+model.insert(model.length, 10);
 dumpList();
 
 TestRunner.addResult('Selecting 10');
@@ -101,19 +101,19 @@
 dumpList();
 
 TestRunner.addResult('Popping 10');
-model.popItem();
+model.remove(model.length - 1);
 dumpList();
 
 TestRunner.addResult('Removing 2');
-model.removeItemAtIndex(4);
+model.remove(4);
 dumpList();
 
 TestRunner.addResult('Inserting 8');
-model.insertItemAtIndex(1, 8);
+model.insert(1, 8);
 dumpList();
 
 TestRunner.addResult('Replacing with 0...20');
-model.replaceAllItems([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
+model.replaceAll([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
 dumpList();
 
 TestRunner.addResult('Resizing');
@@ -147,11 +147,11 @@
 dumpList();
 
 TestRunner.addResult('Replacing 7 with 27');
-model.replaceItemsInRange(7, 8, [27]);
+model.replaceRange(7, 8, [27]);
 dumpList();
 
 TestRunner.addResult('Replacing 18, 19 with 28, 29');
-model.replaceItemsInRange(18, 20, [28, 29]);
+model.replaceRange(18, 20, [28, 29]);
 dumpList();
 
 TestRunner.addResult('PageDown');
@@ -159,7 +159,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 1, 2, 3 with [31-43]');
-model.replaceItemsInRange(1, 4, [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]);
+model.replaceRange(1, 4, [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 13 (center)');
@@ -195,7 +195,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing all but 29 with []');
-model.replaceItemsInRange(0, 29, []);
+model.replaceRange(0, 29, []);
 dumpList();
 
 TestRunner.addResult('ArrowDown');
@@ -208,11 +208,11 @@
 dumpList();
 
 TestRunner.addResult('Pushing 8');
-newModel.pushItem(8);
+newModel.insert(newModel.length, 8);
 dumpList();
 
 TestRunner.addResult('Pushing 9 to old model');
-model.pushItem(9);
+model.insert(model.length, 9);
 dumpList();
 
 TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-non-viewport.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-non-viewport.js
index fe6e78e..f63dce4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-non-viewport.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-non-viewport.js
@@ -38,7 +38,7 @@
 function dumpList()
 {
   var height = list.element.offsetHeight;
-  TestRunner.addResult(`----list[length=${model.length()}][height=${height}]----`);
+  TestRunner.addResult(`----list[length=${model.length}][height=${height}]----`);
   for (var child of list.element.children) {
     var offsetTop = child.getBoundingClientRect().top - list.element.getBoundingClientRect().top;
     var offsetBottom = child.getBoundingClientRect().bottom - list.element.getBoundingClientRect().top;
@@ -52,7 +52,7 @@
 }
 
 TestRunner.addResult('Adding 0, 1, 2');
-model.replaceAllItems([0, 1, 2]);
+model.replaceAll([0, 1, 2]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 0');
@@ -64,7 +64,7 @@
 dumpList();
 
 TestRunner.addResult('Adding 3-20');
-model.replaceItemsInRange(3, 3, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
+model.replaceRange(3, 3, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 19');
@@ -76,7 +76,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 0, 1 with 25-36');
-model.replaceItemsInRange(0, 2, [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]);
+model.replaceRange(0, 2, [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 18');
@@ -84,11 +84,11 @@
 dumpList();
 
 TestRunner.addResult('Replacing 25-36 with 0-1');
-model.replaceItemsInRange(0, 12, [0, 1]);
+model.replaceRange(0, 12, [0, 1]);
 dumpList();
 
 TestRunner.addResult('Replacing 16-18 with 45');
-model.replaceItemsInRange(16, 19, [45]);
+model.replaceRange(16, 19, [45]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 4');
@@ -96,7 +96,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 45 with 16-18');
-model.replaceItemsInRange(16, 17, [16, 17, 18]);
+model.replaceRange(16, 17, [16, 17, 18]);
 dumpList();
 
 TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-various-height.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-various-height.js
index 763d01ef..b6fce6c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-various-height.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-control-various-height.js
@@ -38,7 +38,7 @@
 function dumpList()
 {
   var height = list.element.offsetHeight;
-  TestRunner.addResult(`----list[length=${model.length()}][height=${height}]----`);
+  TestRunner.addResult(`----list[length=${model.length}][height=${height}]----`);
   for (var child of list.element.children) {
     var offsetTop = child.getBoundingClientRect().top - list.element.getBoundingClientRect().top;
     var offsetBottom = child.getBoundingClientRect().bottom - list.element.getBoundingClientRect().top;
@@ -53,7 +53,7 @@
 }
 
 TestRunner.addResult('Adding 0, 1, 2');
-model.replaceAllItems([0, 1, 2]);
+model.replaceAll([0, 1, 2]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 0');
@@ -65,7 +65,7 @@
 dumpList();
 
 TestRunner.addResult('Adding 3-20');
-model.replaceItemsInRange(3, 3, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
+model.replaceRange(3, 3, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 11');
@@ -85,7 +85,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 0, 1 with 25-36');
-model.replaceItemsInRange(0, 2, [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]);
+model.replaceRange(0, 2, [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 18');
@@ -93,11 +93,11 @@
 dumpList();
 
 TestRunner.addResult('Replacing 25-36 with 0-1');
-model.replaceItemsInRange(0, 12, [0, 1]);
+model.replaceRange(0, 12, [0, 1]);
 dumpList();
 
 TestRunner.addResult('Replacing 16-18 with 45');
-model.replaceItemsInRange(16, 19, [45]);
+model.replaceRange(16, 19, [45]);
 dumpList();
 
 TestRunner.addResult('Scrolling to 4');
@@ -105,7 +105,7 @@
 dumpList();
 
 TestRunner.addResult('Replacing 45 with 16-18');
-model.replaceItemsInRange(16, 17, [16, 17, 18]);
+model.replaceRange(16, 17, [16, 17, 18]);
 dumpList();
 
 TestRunner.addResult('Resizing');
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-model.js b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-model.js
index 9fbf6c8..6b1ad69 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-model.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/list-model.js
@@ -1,50 +1,45 @@
 TestRunner.addResult('Test ListModel API.');
 
-var list = new UI.ListModel();
-list.addEventListener(UI.ListModel.Events.ItemsReplaced, event => {
+var model = new UI.ListModel();
+model.addEventListener(UI.ListModel.Events.ItemsReplaced, event => {
   var data = event.data;
-  var inserted = [];
-  for (var index = data.index; index < data.index + data.inserted; index++)
-    inserted.push(list.itemAtIndex(index));
+  var inserted = model.slice(data.index, data.index + data.inserted);
   TestRunner.addResult(`Replaced [${data.removed.join(', ')}] at index ${data.index} with [${inserted.join(', ')}]`);
-  var all = [];
-  for (var index = 0; index < list.length(); index++)
-    all.push(list.itemAtIndex(index));
-  TestRunner.addResult(`Resulting list: [${all.join(', ')}]`);
+  TestRunner.addResult(`Resulting list: [${model.join(', ')}]`);
   TestRunner.addResult('');
 });
 
 TestRunner.addResult('Adding 0, 1, 2');
-list.replaceAllItems([0, 1, 2]);
+model.replaceAll([0, 1, 2]);
 
 TestRunner.addResult('Replacing 0 with 5, 6, 7');
-list.replaceItemsInRange(0, 1, [5, 6, 7]);
+model.replaceRange(0, 1, [5, 6, 7]);
 
 TestRunner.addResult('Pushing 10');
-list.pushItem(10);
+model.insert(model.length, 10);
 
 TestRunner.addResult('Popping 10');
-list.popItem();
+model.remove(model.length - 1);
 
 TestRunner.addResult('Removing 2');
-list.removeItemAtIndex(4);
+model.remove(4);
 
 TestRunner.addResult('Inserting 8');
-list.insertItemAtIndex(1, 8);
+model.insert(1, 8);
 
 TestRunner.addResult('Replacing with 0...20');
-list.replaceAllItems([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
+model.replaceAll([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
 
 TestRunner.addResult('Replacing 7 with 27');
-list.replaceItemsInRange(7, 8, [27]);
+model.replaceRange(7, 8, [27]);
 
 TestRunner.addResult('Replacing 18, 19 with 28, 29');
-list.replaceItemsInRange(18, 20, [28, 29]);
+model.replaceRange(18, 20, [28, 29]);
 
 TestRunner.addResult('Replacing 1, 2, 3 with [31-43]');
-list.replaceItemsInRange(1, 4, [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]);
+model.replaceRange(1, 4, [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]);
 
 TestRunner.addResult('Replacing all but 29 with []');
-list.replaceItemsInRange(0, 29, []);
+model.replaceRange(0, 29, []);
 
 TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js
index 9210a99a..ba85bd8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js
@@ -395,7 +395,7 @@
 InspectorTest.changeExecutionContext = function(namePrefix)
 {
     var selector = Console.ConsoleView.instance()._consoleContextSelector;
-    for (var executionContext of selector._items._items) {
+    for (var executionContext of selector._items) {
         if (selector._titleFor(executionContext).startsWith(namePrefix)) {
             UI.context.setFlavor(SDK.ExecutionContext, executionContext);
             return;
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-context-selector.html b/third_party/WebKit/LayoutTests/inspector/console/console-context-selector.html
index f94132f..f6ef0dd 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-context-selector.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-context-selector.html
@@ -98,7 +98,7 @@
     var consoleView = Console.ConsoleView.instance();
     var selector = consoleView._consoleContextSelector;
     InspectorTest.addResult('Console context selector:');
-    for (var executionContext of selector._items._items) {
+    for (var executionContext of selector._items) {
       var selected = UI.context.flavor(SDK.ExecutionContext) === executionContext;
       var text = '____'.repeat(selector._depthFor(executionContext)) + selector._titleFor(executionContext);
       var disabled = !selector.isItemSelectable(executionContext);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-change-variable.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-change-variable.html
index 4cb7fb0..c108b13 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-change-variable.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-change-variable.html
@@ -45,7 +45,7 @@
     function step2(callFrames)
     {
         var pane = self.runtime.sharedInstance(Sources.CallStackSidebarPane);
-        pane._list.selectItem(pane._list._model.itemAtIndex(1));
+        pane._list.selectItem(pane._list._model.at(1));
         InspectorTest.deprecatedRunAfterPendingDispatches(step3);
     }
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.html
index e4ced82..2f79426 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.html
@@ -77,7 +77,7 @@
     function step3()
     {
         var pane = self.runtime.sharedInstance(Sources.CallStackSidebarPane);
-        pane._list.selectItem(pane._list._model.itemAtIndex(1));
+        pane._list.selectItem(pane._list._model.at(1));
         InspectorTest.deprecatedRunAfterPendingDispatches(step4);
     }
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-while-paused.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-while-paused.html
index a4702a5..502eb980 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-while-paused.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/debugger-eval-while-paused.html
@@ -37,7 +37,7 @@
     {
         InspectorTest.addResult("Evaluated script on the top frame: " + result);
         var pane = self.runtime.sharedInstance(Sources.CallStackSidebarPane);
-        pane._list.selectItem(pane._list._model.itemAtIndex(1));
+        pane._list.selectItem(pane._list._model.at(1));
         InspectorTest.deprecatedRunAfterPendingDispatches(step4);
     }
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width-expected.txt
deleted file mode 100644
index 89ff063..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Getting a 10px border-top-width returns a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS getAll for border-top-width returns a single value 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties-expected.txt
index 58d279a..ce26aafa 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties-expected.txt
@@ -1,13 +1,13 @@
 This is a testharness.js-based test.
-FAIL Getting a length type registered property returns a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
+PASS Getting a length type registered property returns a CSSUnitValue 
 FAIL Getting a URL image type registered property returns a CSSURLImageValue assert_equals: expected "loaded" but got "unloaded"
-FAIL Getting a width with a length type var value returns a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
+PASS Getting a width with a length type var value returns a CSSUnitValue 
 PASS Getting a background-image with a URL image type var value returns a CSSURLImageValue 
-FAIL Getting an inherited length type registered property returns a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting a non-inherited length type registered property returns a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
+PASS Getting an inherited length type registered property returns a CSSUnitValue 
+PASS Getting a non-inherited length type registered property returns a CSSUnitValue 
 FAIL Getting a height with a calc type containing var values returns a CSSCalcValue CSSCalcValue is not defined
-FAIL Getting the value of a registered property that isn't set on the element returns the initial value for the property assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
+PASS Getting the value of a registered property that isn't set on the element returns the initial value for the property 
 PASS Getting the value of a property that isn't registered returns null 
-FAIL getAll for a length type registered property returns a single value assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
+PASS getAll for a length type registered property returns a single value 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left-expected.txt
deleted file mode 100644
index 3dca2c8..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Getting a 10px left results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS getAll for left returns a single value 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height-expected.txt
deleted file mode 100644
index 9b65fc7d..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Getting a 10px lineHeight results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS getAll for lineHeight returns a single value 
-FAIL Getting a 10% lineHeight results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting a number lineHeight results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting a calc lineHeight results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Getting a normal lineHeight results in a CSSKeywordValue 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements-expected.txt
deleted file mode 100644
index 0c575d5..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL get on Computed StyleMap of pseudo element returns correct styles assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS getAll on Computed StyleMap of pseudo element returns list of correct styles 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width-expected.txt
deleted file mode 100644
index 0b4dc8a..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Getting a 10px width results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS getAll for width returns a single value 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete-expected.txt
deleted file mode 100644
index da46ae98..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS delete() removes the value from the property when set in element.style 
-FAIL delete() removes the value from the property when set in element.styleMap Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS delete() works when mixed case is used for the property name 
-PASS delete() does nothing if the property isn't set 
-PASS Attempting to delete an invalid property throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll-expected.txt
deleted file mode 100644
index b324edd..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL getAll() returns a list of values Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL getAll is case-insensitive for the property name Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS getAll() returns an empty list if the property isn't set 
-PASS getAll() throws if you try to get an invalid property 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getProperties-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getProperties-expected.txt
deleted file mode 100644
index 976078d..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getProperties-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-PASS getProperties returns an empty list when no properties have been set 
-FAIL getProperties returns the name of a property if it is set Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Accessing another property doesn't add a spurious result Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL property name does not appear in result after deletion Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL getProperties returns multiple properties if they are set. Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS getProperties returns expected values for custom properties 
-PASS getProperties returns expected values when @apply is used 
-PASS getProperties returns only one @apply when multiple things are applied 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration-expected.txt
deleted file mode 100644
index 4a5553e..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-PASS Iteration over empty StyleMap returns empty iterator 
-FAIL Iterator for single entry returns iterator with a single value assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Iterator for single key returns iterator with a single value 
-FAIL Iterator for single value returns iterator with a single value assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Iterating entries over border element expansion 
-PASS Variable values come out as CSSUnparsedValues 
-PASS Custom properties set on the element come out as CSSStyleValues 
-PASS @apply rules come out as CSSStyleValues 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification-expected.txt
deleted file mode 100644
index 660082f..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL Adding a property while iterating over entries() doesn't affect iterator assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Adding a property while iterating over values() doesn't affect current iterator assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Adding a property while iterating over keys() doesn't affect iterator 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet-expected.txt
deleted file mode 100644
index 1f4073d..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL Setting and getting round trips Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting and getting is not case sensitive Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Changes to element.style are reflected in the element.styleMap 
-FAIL Changes to element.styleMap are reflected in element.style Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Attempting to set an invalid type for a property throws 
-FAIL Attempting to set an invalid type for a property does not change the value Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Attempting to set an invalid property throws 
-PASS Getting a property that isn't set returns null 
-PASS Getting a property that doesn't exist throws 
-PASS Setting null to a property does not crash 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-bottom-width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-bottom-width-expected.txt
deleted file mode 100644
index 6e5767a..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-bottom-width-expected.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting border-bottom-width to thin 
-PASS Setting border-bottom-width to medium 
-PASS Setting border-bottom-width to thick 
-PASS Setting border-bottom-width to initial 
-PASS Setting border-bottom-width to inherit 
-PASS Setting border-bottom-width to unset 
-PASS Setting border-bottom-width to CSSUnitValue with value 1px 
-PASS Setting border-bottom-width to CSSUnitValue with value 3em 
-PASS Setting border-bottom-width to CSSUnitValue with value 4ex 
-PASS Setting border-bottom-width to CSSUnitValue with value 5ch 
-PASS Setting border-bottom-width to CSSUnitValue with value 6rem 
-PASS Setting border-bottom-width to CSSUnitValue with value 7vw 
-PASS Setting border-bottom-width to CSSUnitValue with value 8vh 
-PASS Setting border-bottom-width to CSSUnitValue with value 9vmin 
-PASS Setting border-bottom-width to CSSUnitValue with value 10vmax 
-PASS Setting border-bottom-width to CSSUnitValue with value 11cm 
-PASS Setting border-bottom-width to CSSUnitValue with value 12mm 
-PASS Setting border-bottom-width to CSSUnitValue with value 13in 
-PASS Setting border-bottom-width to CSSUnitValue with value 14pc 
-PASS Setting border-bottom-width to CSSUnitValue with value 15pt 
-PASS Setting border-bottom-width to invalid value CSSUnitValue "1" throws 
-PASS Setting border-bottom-width to invalid value CSSUnitValue "2%" throws 
-PASS Setting border-bottom-width to invalid value null throws 
-PASS Setting border-bottom-width to invalid value undefined throws 
-PASS Setting border-bottom-width to invalid value true throws 
-PASS Setting border-bottom-width to invalid value false throws 
-PASS Setting border-bottom-width to invalid value 1 throws 
-PASS Setting border-bottom-width to invalid value hello throws 
-PASS Setting border-bottom-width to invalid value [object Object] throws 
-PASS Setting border-bottom-width to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting border-bottom-width when it is set to thin 
-PASS Getting border-bottom-width when it is set to medium 
-PASS Getting border-bottom-width when it is set to thick 
-PASS Getting border-bottom-width when it is set to initial 
-PASS Getting border-bottom-width when it is set to inherit 
-PASS Getting border-bottom-width when it is set to unset 
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-bottom-width with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued border-bottom-width assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete border-bottom-width removes the value from the styleMap 
-PASS border-bottom-width shows up in getProperties 
-PASS Setting border-bottom-width to a sequence throws 
-PASS Appending to border-bottom-width throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-left-width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-left-width-expected.txt
deleted file mode 100644
index 07c58078..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-left-width-expected.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting border-left-width to thin 
-PASS Setting border-left-width to medium 
-PASS Setting border-left-width to thick 
-PASS Setting border-left-width to initial 
-PASS Setting border-left-width to inherit 
-PASS Setting border-left-width to unset 
-PASS Setting border-left-width to CSSUnitValue with value 1px 
-PASS Setting border-left-width to CSSUnitValue with value 3em 
-PASS Setting border-left-width to CSSUnitValue with value 4ex 
-PASS Setting border-left-width to CSSUnitValue with value 5ch 
-PASS Setting border-left-width to CSSUnitValue with value 6rem 
-PASS Setting border-left-width to CSSUnitValue with value 7vw 
-PASS Setting border-left-width to CSSUnitValue with value 8vh 
-PASS Setting border-left-width to CSSUnitValue with value 9vmin 
-PASS Setting border-left-width to CSSUnitValue with value 10vmax 
-PASS Setting border-left-width to CSSUnitValue with value 11cm 
-PASS Setting border-left-width to CSSUnitValue with value 12mm 
-PASS Setting border-left-width to CSSUnitValue with value 13in 
-PASS Setting border-left-width to CSSUnitValue with value 14pc 
-PASS Setting border-left-width to CSSUnitValue with value 15pt 
-PASS Setting border-left-width to invalid value CSSUnitValue "1" throws 
-PASS Setting border-left-width to invalid value CSSUnitValue "2%" throws 
-PASS Setting border-left-width to invalid value null throws 
-PASS Setting border-left-width to invalid value undefined throws 
-PASS Setting border-left-width to invalid value true throws 
-PASS Setting border-left-width to invalid value false throws 
-PASS Setting border-left-width to invalid value 1 throws 
-PASS Setting border-left-width to invalid value hello throws 
-PASS Setting border-left-width to invalid value [object Object] throws 
-PASS Setting border-left-width to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting border-left-width when it is set to thin 
-PASS Getting border-left-width when it is set to medium 
-PASS Getting border-left-width when it is set to thick 
-PASS Getting border-left-width when it is set to initial 
-PASS Getting border-left-width when it is set to inherit 
-PASS Getting border-left-width when it is set to unset 
-FAIL Getting border-left-width with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-left-width with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued border-left-width assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete border-left-width removes the value from the styleMap 
-PASS border-left-width shows up in getProperties 
-PASS Setting border-left-width to a sequence throws 
-PASS Appending to border-left-width throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-right-width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-right-width-expected.txt
deleted file mode 100644
index 7ec8012..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-right-width-expected.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting border-right-width to thin 
-PASS Setting border-right-width to medium 
-PASS Setting border-right-width to thick 
-PASS Setting border-right-width to initial 
-PASS Setting border-right-width to inherit 
-PASS Setting border-right-width to unset 
-PASS Setting border-right-width to CSSUnitValue with value 1px 
-PASS Setting border-right-width to CSSUnitValue with value 3em 
-PASS Setting border-right-width to CSSUnitValue with value 4ex 
-PASS Setting border-right-width to CSSUnitValue with value 5ch 
-PASS Setting border-right-width to CSSUnitValue with value 6rem 
-PASS Setting border-right-width to CSSUnitValue with value 7vw 
-PASS Setting border-right-width to CSSUnitValue with value 8vh 
-PASS Setting border-right-width to CSSUnitValue with value 9vmin 
-PASS Setting border-right-width to CSSUnitValue with value 10vmax 
-PASS Setting border-right-width to CSSUnitValue with value 11cm 
-PASS Setting border-right-width to CSSUnitValue with value 12mm 
-PASS Setting border-right-width to CSSUnitValue with value 13in 
-PASS Setting border-right-width to CSSUnitValue with value 14pc 
-PASS Setting border-right-width to CSSUnitValue with value 15pt 
-PASS Setting border-right-width to invalid value CSSUnitValue "1" throws 
-PASS Setting border-right-width to invalid value CSSUnitValue "2%" throws 
-PASS Setting border-right-width to invalid value null throws 
-PASS Setting border-right-width to invalid value undefined throws 
-PASS Setting border-right-width to invalid value true throws 
-PASS Setting border-right-width to invalid value false throws 
-PASS Setting border-right-width to invalid value 1 throws 
-PASS Setting border-right-width to invalid value hello throws 
-PASS Setting border-right-width to invalid value [object Object] throws 
-PASS Setting border-right-width to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting border-right-width when it is set to thin 
-PASS Getting border-right-width when it is set to medium 
-PASS Getting border-right-width when it is set to thick 
-PASS Getting border-right-width when it is set to initial 
-PASS Getting border-right-width when it is set to inherit 
-PASS Getting border-right-width when it is set to unset 
-FAIL Getting border-right-width with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-right-width with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued border-right-width assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete border-right-width removes the value from the styleMap 
-PASS border-right-width shows up in getProperties 
-PASS Setting border-right-width to a sequence throws 
-PASS Appending to border-right-width throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-top-width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-top-width-expected.txt
deleted file mode 100644
index 6f455ec..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/border-top-width-expected.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting border-top-width to thin 
-PASS Setting border-top-width to medium 
-PASS Setting border-top-width to thick 
-PASS Setting border-top-width to initial 
-PASS Setting border-top-width to inherit 
-PASS Setting border-top-width to unset 
-PASS Setting border-top-width to CSSUnitValue with value 1px 
-PASS Setting border-top-width to CSSUnitValue with value 3em 
-PASS Setting border-top-width to CSSUnitValue with value 4ex 
-PASS Setting border-top-width to CSSUnitValue with value 5ch 
-PASS Setting border-top-width to CSSUnitValue with value 6rem 
-PASS Setting border-top-width to CSSUnitValue with value 7vw 
-PASS Setting border-top-width to CSSUnitValue with value 8vh 
-PASS Setting border-top-width to CSSUnitValue with value 9vmin 
-PASS Setting border-top-width to CSSUnitValue with value 10vmax 
-PASS Setting border-top-width to CSSUnitValue with value 11cm 
-PASS Setting border-top-width to CSSUnitValue with value 12mm 
-PASS Setting border-top-width to CSSUnitValue with value 13in 
-PASS Setting border-top-width to CSSUnitValue with value 14pc 
-PASS Setting border-top-width to CSSUnitValue with value 15pt 
-PASS Setting border-top-width to invalid value CSSUnitValue "1" throws 
-PASS Setting border-top-width to invalid value CSSUnitValue "2%" throws 
-PASS Setting border-top-width to invalid value null throws 
-PASS Setting border-top-width to invalid value undefined throws 
-PASS Setting border-top-width to invalid value true throws 
-PASS Setting border-top-width to invalid value false throws 
-PASS Setting border-top-width to invalid value 1 throws 
-PASS Setting border-top-width to invalid value hello throws 
-PASS Setting border-top-width to invalid value [object Object] throws 
-PASS Setting border-top-width to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting border-top-width when it is set to thin 
-PASS Getting border-top-width when it is set to medium 
-PASS Getting border-top-width when it is set to thick 
-PASS Getting border-top-width when it is set to initial 
-PASS Getting border-top-width when it is set to inherit 
-PASS Getting border-top-width when it is set to unset 
-FAIL Getting border-top-width with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting border-top-width with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued border-top-width assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete border-top-width removes the value from the styleMap 
-PASS border-top-width shows up in getProperties 
-PASS Setting border-top-width to a sequence throws 
-PASS Appending to border-top-width throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/bottom-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/bottom-expected.txt
deleted file mode 100644
index 91920da..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/bottom-expected.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting bottom to auto 
-PASS Setting bottom to initial 
-PASS Setting bottom to inherit 
-PASS Setting bottom to unset 
-FAIL Setting bottom to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting bottom to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting bottom to invalid value CSSUnitValue "1" throws 
-PASS Setting bottom to invalid value null throws 
-PASS Setting bottom to invalid value undefined throws 
-PASS Setting bottom to invalid value true throws 
-PASS Setting bottom to invalid value false throws 
-PASS Setting bottom to invalid value 1 throws 
-PASS Setting bottom to invalid value hello throws 
-PASS Setting bottom to invalid value [object Object] throws 
-PASS Setting bottom to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting bottom when it is set to auto 
-PASS Getting bottom when it is set to initial 
-PASS Getting bottom when it is set to inherit 
-PASS Getting bottom when it is set to unset 
-FAIL Getting bottom with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting bottom with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued bottom assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete bottom removes the value from the styleMap 
-FAIL bottom shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting bottom to a sequence throws 
-PASS Appending to bottom throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/height-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/height-expected.txt
deleted file mode 100644
index 9ae5281a..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/height-expected.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting height to max-content 
-PASS Setting height to min-content 
-PASS Setting height to fit-content 
-PASS Setting height to auto 
-PASS Setting height to initial 
-PASS Setting height to inherit 
-PASS Setting height to unset 
-FAIL Setting height to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting height to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting height to invalid value CSSUnitValue "1" throws 
-PASS Setting height to invalid value null throws 
-PASS Setting height to invalid value undefined throws 
-PASS Setting height to invalid value true throws 
-PASS Setting height to invalid value false throws 
-PASS Setting height to invalid value 1 throws 
-PASS Setting height to invalid value hello throws 
-PASS Setting height to invalid value [object Object] throws 
-PASS Setting height to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting height when it is set to max-content 
-PASS Getting height when it is set to min-content 
-PASS Getting height when it is set to fit-content 
-PASS Getting height when it is set to auto 
-PASS Getting height when it is set to initial 
-PASS Getting height when it is set to inherit 
-PASS Getting height when it is set to unset 
-FAIL Getting height with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting height with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued height assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete height removes the value from the styleMap 
-FAIL height shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting height to a sequence throws 
-PASS Appending to height throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/left-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/left-expected.txt
deleted file mode 100644
index d30797c..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/left-expected.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting left to auto 
-PASS Setting left to initial 
-PASS Setting left to inherit 
-PASS Setting left to unset 
-FAIL Setting left to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting left to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting left to invalid value CSSUnitValue "1" throws 
-PASS Setting left to invalid value null throws 
-PASS Setting left to invalid value undefined throws 
-PASS Setting left to invalid value true throws 
-PASS Setting left to invalid value false throws 
-PASS Setting left to invalid value 1 throws 
-PASS Setting left to invalid value hello throws 
-PASS Setting left to invalid value [object Object] throws 
-PASS Setting left to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting left when it is set to auto 
-PASS Getting left when it is set to initial 
-PASS Getting left when it is set to inherit 
-PASS Getting left when it is set to unset 
-FAIL Getting left with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting left with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued left assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete left removes the value from the styleMap 
-FAIL left shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting left to a sequence throws 
-PASS Appending to left throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/right-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/right-expected.txt
deleted file mode 100644
index 11ecc93..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/right-expected.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting right to auto 
-PASS Setting right to initial 
-PASS Setting right to inherit 
-PASS Setting right to unset 
-FAIL Setting right to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting right to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting right to invalid value CSSUnitValue "1" throws 
-PASS Setting right to invalid value null throws 
-PASS Setting right to invalid value undefined throws 
-PASS Setting right to invalid value true throws 
-PASS Setting right to invalid value false throws 
-PASS Setting right to invalid value 1 throws 
-PASS Setting right to invalid value hello throws 
-PASS Setting right to invalid value [object Object] throws 
-PASS Setting right to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting right when it is set to auto 
-PASS Getting right when it is set to initial 
-PASS Getting right when it is set to inherit 
-PASS Getting right when it is set to unset 
-FAIL Getting right with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting right with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued right assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete right removes the value from the styleMap 
-FAIL right shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting right to a sequence throws 
-PASS Appending to right throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/top-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/top-expected.txt
deleted file mode 100644
index 0fdde1b..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/top-expected.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting top to auto 
-PASS Setting top to initial 
-PASS Setting top to inherit 
-PASS Setting top to unset 
-FAIL Setting top to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting top to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting top to invalid value CSSUnitValue "1" throws 
-PASS Setting top to invalid value null throws 
-PASS Setting top to invalid value undefined throws 
-PASS Setting top to invalid value true throws 
-PASS Setting top to invalid value false throws 
-PASS Setting top to invalid value 1 throws 
-PASS Setting top to invalid value hello throws 
-PASS Setting top to invalid value [object Object] throws 
-PASS Setting top to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting top when it is set to auto 
-PASS Getting top when it is set to initial 
-PASS Getting top when it is set to inherit 
-PASS Getting top when it is set to unset 
-FAIL Getting top with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting top with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued top assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete top removes the value from the styleMap 
-FAIL top shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting top to a sequence throws 
-PASS Appending to top throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/width-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/width-expected.txt
deleted file mode 100644
index ad48a96..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/width-expected.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting width to max-content 
-PASS Setting width to min-content 
-PASS Setting width to fit-content 
-PASS Setting width to auto 
-PASS Setting width to initial 
-PASS Setting width to inherit 
-PASS Setting width to unset 
-FAIL Setting width to CSSUnitValue with value 1px Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 3em Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 4ex Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 5ch Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 6rem Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 7vw Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 8vh Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 9vmin Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 10vmax Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 11cm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 12mm Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 13in Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 14pc Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-FAIL Setting width to CSSUnitValue with value 15pt Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting width to invalid value CSSUnitValue "1" throws 
-PASS Setting width to invalid value null throws 
-PASS Setting width to invalid value undefined throws 
-PASS Setting width to invalid value true throws 
-PASS Setting width to invalid value false throws 
-PASS Setting width to invalid value 1 throws 
-PASS Setting width to invalid value hello throws 
-PASS Setting width to invalid value [object Object] throws 
-PASS Setting width to invalid value CSSKeywordValue "notAKeyword" throws 
-PASS Getting width when it is set to max-content 
-PASS Getting width when it is set to min-content 
-PASS Getting width when it is set to fit-content 
-PASS Getting width when it is set to auto 
-PASS Getting width when it is set to initial 
-PASS Getting width when it is set to inherit 
-PASS Getting width when it is set to unset 
-FAIL Getting width with a CSSUnitValue whose value is 1px assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 3em assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 4ex assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 5ch assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 6rem assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 7vw assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 8vh assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 9vmin assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 10vmax assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 11cm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 12mm assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 13in assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 14pc assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Getting width with a CSSUnitValue whose value is 15pt assert_equals: typeof result expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL getAll for single-valued width assert_equals: Returned type is incorrect: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Delete width removes the value from the styleMap 
-FAIL width shows up in getProperties Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
-PASS Setting width to a sequence throws 
-PASS Appending to width throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective-expected.txt
deleted file mode 100644
index f77501c..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Perspective read from a StyleMap is correct assert_equals: expected "CSSTransformValue" but got "CSSStyleValue"
-PASS Set Perspective into the inline StylePropertyMap 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic-expected.txt
deleted file mode 100644
index e83104ac..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Parsing 10px results in a CSSUnitValue assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-PASS Parsing returns null on failure 
-PASS Passing in empty string to parse for the property name throws 
-PASS Passing in an invalid property name throws 
-PASS Attempting to parse a value for a shorthand property throws 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic.html b/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic.html
index f681952..9740340 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/styleValue-parse-basic.html
@@ -9,7 +9,7 @@
   assert_not_equals(result, null);
   assert_equals(result.constructor.name, CSSUnitValue.name);
   assert_equals(result.value, 10);
-  assert_equals(result.type, 'px');
+  assert_equals(result.unit, 'px');
 }, 'Parsing 10px results in a CSSUnitValue');
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-event.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-event.html
deleted file mode 100644
index 57260498..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-event.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Canceling an animation: cancel event</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#canceling-an-animation-section">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<body>
-<script>
-var anim1 = document.body.animate([], 100000);
-var anim2 = document.body.animate([], 100000);
-
-var cancelTest = async_test('Cancelling animation should fire a cancel event.');
-var fired = false;
-
-anim1.oncancel = function(event) {
-  cancelTest.step(function() {
-    assert_equals(event.target, anim1, 'Target of cancel event should be anim1.');
-    assert_equals(event.currentTime, null, 'currentTime of cancel event should be null.');
-    assert_equals(event.timelineTime, document.timeline.currentTime, 'Event timelineTime should be same as document.timeline.currentTime.');
-  });
-  fired = true;
-};
-
-anim2.onfinish = function() {
-  cancelTest.step(function() {
-    assert_true(fired, 'anim1.oncancel should be called.');
-  });
-  cancelTest.done();
-};
-
-anim1.cancel();
-anim2.finish();
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-ready-finished-ordering.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-ready-finished-ordering.html
deleted file mode 100644
index db0be86a..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-cancel-ready-finished-ordering.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Cancel an animation: ready/finished ordering</title
-<link rel="help" href="https://w3c.github.io/web-animations/#canceling-an-animation-section">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  var ready = false;
-  animation.ready.catch(function() {
-    t.step(function() {
-      ready = true;
-    });
-  });
-  animation.finished.catch(function() {
-    t.step(function() {
-      assert_true(ready);
-    });
-    t.done();
-  });
-  animation.cancel();
-}, 'The ready promise should be rejected before the finished promise');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only-expected.txt
deleted file mode 100644
index 23ba0b3..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL animation.effect should be read-only assert_approx_equals: expected 1000 +/- 0.0005 but got 1500
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only.html
deleted file mode 100644
index 3927547..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-read-only.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test that extending effect should not cause a change in start time</title>
-<link rel="https://w3c.github.io/web-animations/#the-animation-interface">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<script>
-test(function() {
-  var animation = document.documentElement.animate([], 1000);
-  animation.effect.timing.duration = 1500;
-  assert_times_equal(animation.effect.timing.duration, 1000);
-}, 'animation.effect should be read-only');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-defaults.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-defaults.html
deleted file mode 100644
index b3196d20..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-defaults.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<meta charset='utf-8'>
-<title>Default values for AnimationEffectTiming objects</title>
-<link rel='help' href='https://w3c.github.io/web-animations/#the-animationeffecttimingproperties-dictionary'>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<body>
-    <div id='e'></div>
-</body>
-
-<script>
-var keyframeEffectBasic = new KeyframeEffect(null, []);
-var specifiedTimingBasic = keyframeEffectBasic.timing;
-
-test(function() {
-    assert_equals(specifiedTimingBasic.constructor, AnimationEffectTiming);
-    assert_equals(specifiedTimingBasic.delay, 0);
-    assert_equals(specifiedTimingBasic.endDelay, 0);
-    assert_equals(specifiedTimingBasic.fill, 'auto');
-    assert_equals(specifiedTimingBasic.iterationStart, 0);
-    assert_equals(specifiedTimingBasic.iterations, 1);
-    assert_equals(specifiedTimingBasic.duration, 'auto');
-    assert_equals(specifiedTimingBasic.direction, 'normal');
-    assert_equals(specifiedTimingBasic.easing, 'linear');
-}, 'AnimationEffectTiming objects should have the specified default values');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-easing.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-easing.html
deleted file mode 100644
index f66af31..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-effect-timing-easing.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationEffectTiming easing tests</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#the-animationeffecttiming-interface">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-var animate_with_easing = function(inputEasing) {
-  return document.documentElement.animate([], { easing : inputEasing });
-};
-
-var assert_animate_with_easing_succeeds = function(inputEasing, expectedEasing) {
-  var animation = animate_with_easing(inputEasing);
-  assert_equals(animation.effect.timing.easing, expectedEasing);
-};
-
-var assert_animate_with_easing_roundtrips = function(inputEasing) {
-  assert_animate_with_easing_succeeds(inputEasing, inputEasing);
-};
-
-var assert_animate_with_easing_throws = function(inputEasing) {
-  assert_throws(
-      {name: 'TypeError'},
-      function() { animate_with_easing(inputEasing); },
-      'with inputEasing=\'' + inputEasing + '\'');
-};
-
-test(function() {
-  assert_animate_with_easing_roundtrips('ease');
-  assert_animate_with_easing_roundtrips('linear');
-  assert_animate_with_easing_roundtrips('ease-in');
-  assert_animate_with_easing_roundtrips('ease-out');
-  assert_animate_with_easing_roundtrips('ease-in-out');
-  assert_animate_with_easing_roundtrips('cubic-bezier(0.1, 5, 0.23, 0)');
-}, 'Valid linear and cubic-bezier easing functions should come out the same as they went in');
-
-test(function() {
-  assert_animate_with_easing_succeeds('step-start', 'steps(1, start)');
-  assert_animate_with_easing_succeeds('step-middle', 'steps(1, middle)');
-  assert_animate_with_easing_succeeds('step-end', 'steps(1)');
-  assert_animate_with_easing_succeeds('steps(3, start)', 'steps(3, start)');
-  assert_animate_with_easing_succeeds('steps(3, middle)', 'steps(3, middle)');
-  assert_animate_with_easing_succeeds('steps(3, end)', 'steps(3)');
-  assert_animate_with_easing_succeeds('steps(3)', 'steps(3)');
-}, 'Valid step-function easings serialize as steps(<int>) or steps(<int>, start)');
-
-test(function() {
-  assert_animate_with_easing_succeeds('eAse\\2d iN-ouT', 'ease-in-out');
-}, 'Should accept arbitrary casing and escape chararcters');
-
-test(function() {
-  assert_animate_with_easing_throws('');
-  assert_animate_with_easing_throws('initial');
-  assert_animate_with_easing_throws('inherit');
-  assert_animate_with_easing_throws('unset');
-  assert_animate_with_easing_throws('steps(3, nowhere)');
-  assert_animate_with_easing_throws('steps(-3, end)');
-  assert_animate_with_easing_throws('cubic-bezier(0.1, 0, 4, 0.4)');
-  assert_animate_with_easing_throws('function (a){return a}');
-  assert_animate_with_easing_throws('function (x){return x}');
-  assert_animate_with_easing_throws('function(x, y){return 0.3}');
-  assert_animate_with_easing_throws('7');
-}, 'Invalid easing values should throw a TypeError');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-event-cancelled.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-event-cancelled.html
deleted file mode 100644
index afd891f..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-event-cancelled.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Canceling an animation: finish event</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#canceling-an-animation-section">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<body>
-<script>
-async_test(t => {
-  var anim1 = document.body.animate([], 100000);
-  var anim2 = document.body.animate([], 100000);
-
-  var success = false;
-  anim2.finished.catch(function() {
-    success = true;
-  });
-
-  anim1.finished.then(function() {
-    assert_true(success, 'anim2 finished promise should be rejected on cancelation');
-    t.done();
-  });
-
-  anim2.cancel();
-  anim1.finish();
-}, 'Animation finished promise should be rejected when animation canceled');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-ready-finished-ordering.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-ready-finished-ordering.html
deleted file mode 100644
index ea77ea1b..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-finish-ready-finished-ordering.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Finishing an animation: ready/finished ordering</title
-<link rel="help" href="https://w3c.github.io/web-animations/#finishing-an-animation-section">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<script>
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  var ready = false;
-  animation.ready.then(function() {
-    t.step(function() {
-      ready = true;
-    });
-  });
-  animation.finished.then(function() {
-    t.step(function() {
-      assert_true(ready);
-    });
-    t.done();
-  });
-  animation.finish();
-}, 'The ready promise should be resolved before the finished promise');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-onfinish.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-onfinish.html
deleted file mode 100644
index 5643b1b..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-onfinish.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Tests for the finish event</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#the-current-finished-promise">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<body>
-<script>
-'use strict';
-function validateFinishEvent(t, event, animation) {
-  t.step(function() {
-    assert_equals(event, animation, 'Animation should be target');
-    assert_times_equal(event.currentTime, animation.currentTime, 'Event currentTime should be animation currentTime');
-  });
-}
-
-async_test(function(t) {
-  var div = createDiv(t);
-  var animation = div.animate(null, 70.0);
-  animation.finished.then(function(event) {
-    t.unreached_func("Seeking to finish should not queue finished event");
-  })
-  animation.finish();
-  animation.currentTime = 0;
-  animation.pause();
-  t.done();
-}, "animation.finished doesn't run when the animation seeks to finish");
-
-async_test(function(t) {
-  var div = createDiv(t);
-  var animation = div.animate(null, 70.0);
-  animation.finished.then(function (event) {
-    t.unreached_func("Seeking past finish should not queue finished event");
-  })
-  animation.currentTime = 80.0;
-  animation.currentTime = 0;
-  animation.pause();
-  t.done();
-}, "animation.finished doesn't run when the animation seeks past finish");
-
-async_test(function(t) {
-  var div = createDiv(t);
-  var animation = div.animate(null, 90.0);
-  animation.finished.then(function(event) {
-    validateFinishEvent(t, event, animation);
-    t.done();
-  })
-  animation.finish();
-}, "animation.finished runs when the animation completes with .finish()");
-
-async_test(function(t) {
-  var div = createDiv(t);
-  var animation = div.animate(null, 100);
-  animation.finished.then(function(event) {
-    validateFinishEvent(t, event, animation);
-    t.done();
-  })
-}, "animation.finished runs when the animation completes");
-
-// TODO(alancutter): Change this to a promise_test.
-async_test(function(t) {
-  var animation1 = createDiv(t).animate(null, 0.05);
-  animation1.finished.then(function(event) {
-    validateFinishEvent(t, event, animation1);
-    animation1.currentTime = 0;
-    return animation1.finished;
-  }).then(function(event) {
-    var animation2 = createDiv(t).animate(null, 0.05);
-    // TODO(alancutter): Move this .then to the outer promise chain.
-    animation2.finished.then(function(event) {
-      validateFinishEvent(t, event, animation2);
-      animation2.play();
-      return animation2.finished;
-    })
-    return animation2.finished;
-  }).then(function(event) {
-    t.done();
-  })
-}, "animation.finished calls can be chained");
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-play-after-finish-restarts.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-play-after-finish-restarts.html
deleted file mode 100644
index 18e511b..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-play-after-finish-restarts.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animation resets when play() called after finish()</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#play-an-animation">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<div id='element'></div>
-
-<script>
-var element = document.getElementById('element');
-
-test(function() {
-    var animation = element.animate([{left: '0px'}, {left: '100px'}], 10);
-    animation.finish();
-    assert_equals(getComputedStyle(element).left, 'auto');
-
-    animation.play();
-    assert_equals(getComputedStyle(element).left, '0px');
-}, 'Calling play() after finish() causes the animation to reset');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-playbackRate.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-playbackRate.html
deleted file mode 100644
index e52a100..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-playbackRate.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animation.currentTime doesn't update if playbackRate is 0</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#the-current-time-of-an-animation">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-
-<div id="div"></div>
-
-<script>
-
-promise_test(function(t) {
-  var animation = div.animate(null, 100 * MS_PER_SEC);
-  animation.playbackRate = 0;
-
-  return animation.ready.then(function() {
-    return waitForAnimationFrames(1);
-  }).then(function() {
-    assert_times_equal(animation.currentTime, 0);
-  });
-}, 'animation.currentTime should be constant if there is a 0 playback rate');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise-expected.txt
deleted file mode 100644
index 58e3f773..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-CONSOLE ERROR: line 29: Uncaught (in promise) AbortError: The user aborted a request.
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = The user aborted a request.
-PASS The ready attribute should be a Promise 
-PASS The ready promise should be resolved when an animation is in the idle play state 
-PASS The ready promise should be replaced when the animation is cancelled 
-PASS The ready promise should be replaced when the animation enters the pending state 
-PASS A pending ready promise should be rejected when the animation is cancelled 
-PASS A pending ready promise should be resolved and not replaced when the animation enters the running state 
-PASS A pending ready promise should be resolved and not replaced when the animation enters the finished state 
-PASS A pending ready promise should be resolved and not replaced when the animation enters the paused state 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise.html
deleted file mode 100644
index 5e32953..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-ready-promise.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test Animation.ready attribute</title>
-<link rel="https://w3c.github.io/web-animations/#the-animation-interface">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-
-<script>
-test(function() {
-  var animation = document.documentElement.animate([], 100000);
-  assert_true(animation.ready instanceof Promise);
-}, 'The ready attribute should be a Promise');
-
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  animation.cancel();
-  animation.ready.then(function(p) {
-    t.step(function() {
-      assert_equals(p, animation);
-    });
-    t.done();
-  });
-}, 'The ready promise should be resolved when an animation is in the idle play state');
-
-test(function() {
-  var animation = document.documentElement.animate([], 100000);
-  var promise = animation.ready;
-  animation.cancel();
-  assert_not_equals(animation.ready, promise);
-}, 'The ready promise should be replaced when the animation is cancelled');
-
-test(function() {
-  var animation = document.documentElement.animate([], 100000);
-  animation.cancel();
-  var promise = animation.ready;
-  animation.play();
-  assert_not_equals(animation.ready, promise);
-}, 'The ready promise should be replaced when the animation enters the pending state');
-
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  animation.ready.then(function() {
-    t.step(function() {
-      assert_unreached();
-    });
-  }, function(e) {
-    t.step(function() {
-      assert_equals(e.code, DOMException.ABORT_ERR);
-    });
-    t.done();
-  });
-  animation.cancel();
-}, 'A pending ready promise should be rejected when the animation is cancelled');
-
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  var promise = animation.ready;
-  promise.then(function(p) {
-    t.step(function() {
-      assert_equals(p, animation);
-      assert_equals(animation.ready, promise);
-    });
-    t.done();
-  });
-}, 'A pending ready promise should be resolved and not replaced when the animation enters the running state');
-
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  var promise = animation.ready;
-  animation.finish();
-  promise.then(function(p) {
-    t.step(function() {
-      assert_equals(p, animation);
-      assert_equals(animation.ready, promise);
-    });
-    t.done();
-  });
-}, 'A pending ready promise should be resolved and not replaced when the animation enters the finished state');
-
-async_test(function(t) {
-  var animation = document.documentElement.animate([], 100000);
-  var promise = animation.ready;
-  animation.pause();
-  promise.then(function(p) {
-    t.step(function() {
-      assert_equals(p, animation);
-      assert_equals(animation.ready, promise);
-    });
-    t.done();
-  });
-}, 'A pending ready promise should be resolved and not replaced when the animation enters the paused state');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-reverse-end-exclusive.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-reverse-end-exclusive.html
deleted file mode 100644
index 2a9d1e6e..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-reverse-end-exclusive.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animation Reverse End Exclusive</title>
-<link rel="help" ­href="https://w3c.github.io/web-animations/#speed-control">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-test(function() {
-  document.documentElement.style.opacity = 1;
-  var animation = document.documentElement.animate([{opacity: 0.5}, {opacity: 0.5}], 100000);
-  animation.playbackRate = -1;
-  animation.currentTime = 0;
-  assert_equals(getComputedStyle(document.documentElement).opacity, "1");
-}, "An animation which is not filling backwards should not be in effect at time 0 when playing backwards");
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline-expected.txt
deleted file mode 100644
index c368d02..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Animations are retriggered if timeline time changes promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline.html
deleted file mode 100644
index 091e3bfe..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-set-timeline.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animations are retriggered if timeline time changes</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#set-the-timeline-of-an-animation">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-
-<div id="div"></div>
-
-<script>
-
-promise_test(function(t) {
-  var animation = div.animate([], 10);
-
-  return animation.ready.then(function() {
-    animation.timeline = new DocumentTimeline(-5);
-    animation.startTime = document.timeline.currentTime;
-    assert_times_equal(animation.currentTime, 5);
-    assert_equals(animation.playState, "running");
-
-    animation.timeline = new DocumentTimeline(-15);
-    animation.startTime = document.timeline.currentTime;
-    assert_times_equal(animation.currentTime, 10);
-    assert_equals(animation.playState, "finished");
-
-    animation.timeline = new DocumentTimeline(0);
-    animation.startTime = document.timeline.currentTime;
-    assert_times_equal(animation.currentTime, 0);
-    assert_equals(animation.playState, "running");
-
-    animation.timeline = new DocumentTimeline(-5);
-    animation.startTime = document.timeline.currentTime;
-    assert_times_equal(animation.currentTime, 5);
-    assert_equals(animation.playState, "running");
-  });
-}, 'Animations are retriggered if timeline time changes');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-update-effect.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-update-effect.html
deleted file mode 100644
index 56acf2d..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/animation-update-effect.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Element style is updated when the Animation's effect is update</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#set-the-target-effect-of-an-animation">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<div id='element'></div>
-
-<script>
-var element = document.getElementById('element');
-
-test(function() {
-    var animation = element.animate([{left: '0px'}, {left: '100px'}], 10);
-    assert_equals(getComputedStyle(element).left, '0px');
-
-    var effect = animation.effect
-    animation.effect = null;
-    assert_equals(getComputedStyle(element).left, 'auto');
-
-    animation.effect = effect;
-    assert_equals(getComputedStyle(element).left, '0px');
-}, 'Element style updated after clear and set effect');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/delay-endDelay-phases.html b/third_party/WebKit/LayoutTests/web-animations-api/delay-endDelay-phases.html
deleted file mode 100644
index 4bd14b1..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/delay-endDelay-phases.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test combinations of delay and endDelay</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#the-animationeffecttiming-interface">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<body></body>
-<script>
-function testTiming({timing, expectations}, description) {
-  test(t => {
-    for (let {at, expect} of expectations) {
-      let target =  createDiv(t);
-      let animation = target.animate({opacity: [0, 1]}, timing);
-      animation.currentTime = at;
-      assert_times_equal(Number(getComputedStyle(target).opacity), expect, 'at ' + at);
-      animation.cancel();
-    }
-  }, description);
-}
-
-testTiming({
-  timing: {
-    duration: 10,
-    delay: 1,
-    endDelay: 1,
-    fill: 'both',
-  },
-  expectations: [
-    { at: 0, expect: 0 },
-    { at: 1, expect: 0 },
-    { at: 2, expect: 0.1 },
-    { at: 10, expect: 0.9 },
-    { at: 11, expect: 1 },
-    { at: 12, expect: 1 },
-  ],
-}, 'delay and endDelay both positive');
-
-testTiming({
-  timing: {
-    duration: 10,
-    delay: 1,
-    endDelay: -1,
-    fill: 'both',
-  },
-  expectations: [
-    { at: 0, expect: 0 },
-    { at: 1, expect: 0 },
-    { at: 2, expect: 0.1 },
-    { at: 9, expect: 0.8 },
-    { at: 10, expect: 0.9 },
-    { at: 11, expect: 0.9 },
-  ],
-}, 'Positive delay and negative endDelay');
-
-testTiming({
-  timing: {
-    duration: 10,
-    delay: -1,
-    endDelay: 1,
-    fill: 'both',
-  },
-  expectations: [
-    { at: -2, expect: 0 },
-    { at: -1, expect: 0 },
-    { at: 0, expect: 0.1 },
-    { at: 1, expect: 0.2 },
-    { at: 8, expect: 0.9 },
-    { at: 9, expect: 1 },
-    { at: 10, expect: 1 },
-  ],
-}, 'Negative delay and positive endDelay');
-
-testTiming({
-  timing: {
-    duration: 10,
-    delay: -1,
-    endDelay: -1,
-    fill: 'both',
-  },
-  expectations: [
-    { at: -2, expect: 0 },
-    { at: -1, expect: 0 },
-    { at: 0, expect: 0.1 },
-    { at: 1, expect: 0.2 },
-    { at: 7, expect: 0.8 },
-    { at: 8, expect: 0.9 },
-    { at: 9, expect: 0.9 },
-    { at: 10, expect: 0.9 },
-  ],
-}, 'delay and endDelay both negative');
-
-testTiming({
-  timing: {
-    duration: 10,
-    delay: 1,
-    endDelay: -12,
-    fill: 'both',
-  },
-  expectations: [
-    { at: -2, expect: 0 },
-    { at: -1, expect: 0 },
-    { at: 0, expect: 0 },
-    { at: 5, expect: 0 },
-    { at: 10, expect: 0 },
-    { at: 11, expect: 0 },
-    { at: 12, expect: 0 },
-  ],
-}, 'Negative endDelay that eclipses delay and duration');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/effect-of-keyframeeffect-on-getComputedTiming.html b/third_party/WebKit/LayoutTests/web-animations-api/effect-of-keyframeeffect-on-getComputedTiming.html
deleted file mode 100644
index ec6f4026..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/effect-of-keyframeeffect-on-getComputedTiming.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!DOCTYPE html>
-<title>Things</title>
-<link rel="https://w3c.github.io/web-animations/#the-computedtimingproperties-dictionary">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-
-<body>
-    <div id='e'></div>
-</body>
-
-<script>
-var element = document.getElementById('e');
-var keyframes = [{opacity: '1', offset: 0}, {opacity: '0', offset: 1}];
-
-test(function() {
-    var keyframeEffect = new KeyframeEffect(element, keyframes);
-    assert_equals(keyframeEffect.getComputedTiming().localTime, null);
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, null);
-}, 'localTime and currentIteration are null when the KeyframeEffect is not associated with an Animation');
-
-test(function() {
-    var animation = element.animate(keyframes, {fill: 'both', duration: 2000, iterations: 3});
-    var keyframeEffect = animation.effect;
-    animation.currentTime = -1000;
-    assert_times_equal(keyframeEffect.getComputedTiming().localTime, -1000, 'localTime');
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, 0);
-    animation.currentTime = 1000;
-    assert_times_equal(keyframeEffect.getComputedTiming().localTime, 1000);
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, 0);
-    animation.currentTime = 5000;
-    assert_times_equal(keyframeEffect.getComputedTiming().localTime, 5000);
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, 2);
-    animation.currentTime = 7000;
-    assert_times_equal(keyframeEffect.getComputedTiming().localTime, 7000);
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, 2);
-}, 'ComputedTimingProperties.localTime and ComputedTimingProperties.currentIteration return reasonable values when an keyframeEffect is in effect');
-
-test(function() {
-    var animation = element.animate(keyframes);
-    var keyframeEffect = animation.effect;
-    animation.currentTime = -1;
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, null);
-    animation.currentTime = 1;
-    assert_equals(keyframeEffect.getComputedTiming().currentIteration, null);
-}, 'ComputedTimingProperties.currentIteration is null when keyframeEffect is not in effect');
-
-test(function() {
-    var keyframeEffect = new KeyframeEffect(element, keyframes, 2);
-    assert_times_equal(keyframeEffect.getComputedTiming().endTime, 2);
-    assert_times_equal(keyframeEffect.getComputedTiming().duration, 2);
-    assert_times_equal(keyframeEffect.getComputedTiming().activeDuration, 2);
-}, 'ComputedTimingProperties startTime, endTime, duration, activeDuration are sensible for a simple keyframeEffect');
-
-test(function() {
-  var keyframeEffect = new KeyframeEffect(element, keyframes, {duration: 3, iterations: 4, delay: 5});
-  assert_times_equal(keyframeEffect.getComputedTiming().endTime, 17);
-  assert_times_equal(keyframeEffect.getComputedTiming().duration, 3);
-  assert_times_equal(keyframeEffect.getComputedTiming().activeDuration, 12);
-}, 'ComputedTimingProperties startTime, endTime, duration, activeDuration are sensible for keyframeEffects with delays and iterations');
-
-test(function() {
-  var keyframeEffect = new KeyframeEffect(element, keyframes, {delay: 1});
-  assert_times_equal(keyframeEffect.getComputedTiming().duration, 0);
-}, 'ComputedTimingProperties duration is calculated when no duration is specified');
-
-test(function() {
-  var timing = new KeyframeEffect(element, keyframes).timing;
-  for (var attr of ['delay', 'endDelay', 'iterationStart']) {
-    assert_throws(new TypeError, function() { timing[attr] = NaN; }, attr);
-    assert_throws(new TypeError, function() { timing[attr] = Infinity; }, attr);
-  }
-}, 'Restricted double attributes on the AnimationEffectTiming interface throws for non-finite values.');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/element-animate-list-of-keyframes.html b/third_party/WebKit/LayoutTests/web-animations-api/element-animate-list-of-keyframes.html
deleted file mode 100644
index 351cea3..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/element-animate-list-of-keyframes.html
+++ /dev/null
@@ -1,289 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<style>
-.anim {
-    position: absolute;
-    left: 10px;
-    height: 90px;
-    width: 100px;
-    background-color: black;
-}
-</style>
-
-<body>
-</body>
-
-<script>
-var addAnimDiv = function() {
-    var element = document.createElement('div');
-    element.className = 'anim';
-    document.body.appendChild(element);
-    return element;
-};
-
-var assertEquivalentFramesSyntax = function(testParams) {
-    var e1 = addAnimDiv();
-    var e2 = addAnimDiv();
-    var e1Style = getComputedStyle(e1);
-    var e2Style = getComputedStyle(e2);
-    var options = {duration: testParams.duration, fill: "forwards"};
-    var player1 = e1.animate(testParams.listOfKeyframes, options);
-    var player2 = e2.animate(testParams.keyframeWithListOfValues, options);
-    player1.pause();
-    player2.pause();
-    for (var i = 0; i < testParams.expectationList.length; i++) {
-        var expected = testParams.expectationList[i];
-        player1.currentTime = expected.at;
-        player2.currentTime = expected.at;
-        for (var property in expected.is) {
-            assert_equals(e1Style.getPropertyValue(property), expected.is[property]);
-            assert_equals(e2Style.getPropertyValue(property), expected.is[property]);
-        }
-    }
-};
-
-test(function() {
-    var element = addAnimDiv();
-    var elementStyle = getComputedStyle(element);
-    var player = element.animate([
-        {left: '10px', opacity: '1', offset: 0},
-        {left: '100px', opacity: '0', offset: 1}
-    ], 1);
-    player.pause();
-    player.currentTime = 0.5;
-    assert_equals(elementStyle.left, '55px');
-    assert_equals(elementStyle.opacity, '0.5');
-}, 'Calling animate() should start an animation.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '10px', opacity: '1'},
-            {left: '100px', opacity: '0'},
-            {left: '150px', opacity: '1'}
-        ],
-        keyframeWithListOfValues: {
-            left: ['10px', '100px', '150px'],
-            opacity: ['1', '0', '1']
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '10px', opacity: '1'}},
-            {at: 0.25, is: {left: '55px', opacity: '0.5'}},
-            {at: 0.5, is: {left: '100px', opacity: '0'}},
-            {at: 0.75, is: {left: '125px', opacity: '0.5'}},
-            {at: 1, is: {left: '150px', opacity: '1'}}
-        ]
-    });
-}, 'Calling animate() with alternative list syntax should give same result.');
-
-test(function() {
-    var element = addAnimDiv();
-    var elementStyle = getComputedStyle(element);
-    var player = element.animate([
-        {backgroundColor: 'green', offset: 0},
-        {backgroundColor: 'purple', offset: 1}
-    ], 1);
-    player.pause();
-    player.currentTime = 0.5;
-    assert_equals(elementStyle.backgroundColor, 'rgb(64, 64, 64)');
-}, 'Calling animate() should start an animation. CamelCase property names should be parsed.');
-
-test(function() {
-    var element = addAnimDiv();
-    var elementStyle = getComputedStyle(element);
-    var player = element.animate([
-        {left: '10px', offset: '0'},
-        {left: '100px', offset: '1'}
-    ], 1);
-    player.pause();
-    player.currentTime = 0.5;
-    assert_equals(elementStyle.left, '55px');
-}, 'Offsets may be specified as strings.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '0px', easing: 'steps(2, start)'},
-            {left: '100px', easing: 'steps(2, start)'},
-            {left: '300px'}
-        ],
-        keyframeWithListOfValues: {
-            left: ['0px', '100px', '300px'],
-            easing: 'steps(2, start)'
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '50px'}},
-            {at: 0.25, is: {left: '100px'}},
-            {at: 0.5, is: {left: '200px'}},
-            {at: 0.75, is: {left: '300px'}}
-        ]
-    });
-}, 'When using the alternative list syntax, all keyframes have the same timing function.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '0px', offset: 0.5},
-            {left: '100px', offset: 0.5}
-        ],
-        keyframeWithListOfValues: {
-            left: ['0px', '100px'],
-            offset: 0.5
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '10px'}},
-            {at: 0.25, is: {left: '5px'}},
-            {at: 0.49, is: {left: '0.2px'}},
-            {at: 0.5, is: {left: '100px'}},
-            {at: 0.75, is: {left: '55px'}},
-            {at: 1, is: {left: '10px'}}
-        ]
-    });
-}, 'When using the alternative list syntax, offset is applied to all specified keyframes.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '0px', composite: 'add'},
-            {left: '100px', composite: 'add'}
-        ],
-        keyframeWithListOfValues: {
-            left: ['0px', '100px'],
-            composite: 'add'
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '10px'}},
-            {at: 0.5, is: {left: '60px'}},
-            {at: 1, is: {left: '110px'}}
-        ]
-    });
-}, 'When using the alternative list syntax, composite is applied to all keyframes.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '0px', offset: 0},
-            {opacity: '0', offset: 0},
-            {left: '10px', offset: 0.33},
-            {opacity: '0.4', offset: 0.5},
-            {left: '40px', offset: 0.67},
-            {left: '100px', offset: 1},
-            {opacity: '1', offset: 1}
-        ],
-        keyframeWithListOfValues: {
-            left: ['0px', '10px', '40px', '100px'],
-            opacity: ['0', '0.4', '1']
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '0px', opacity: '0'}},
-            {at: 0.5, is: {left: '25px', opacity: '0.4'}},
-            {at: 1, is: {left: '100px', opacity: '1'}}
-        ]
-    });
-}, 'When using the alternative list syntax, properties can have different length lists.');
-
-test(function() {
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '100px'}
-        ],
-        keyframeWithListOfValues: {
-            left: ['100px']
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '10px'}},
-            {at: 0.5, is: {left: '55px'}},
-            {at: 1, is: {left: '100px'}}
-        ]
-    });
-    assertEquivalentFramesSyntax({
-        listOfKeyframes: [
-            {left: '100px'}
-        ],
-        keyframeWithListOfValues: {
-            left: '100px'
-        },
-        duration: 1,
-        expectationList: [
-            {at: 0, is: {left: '10px'}},
-            {at: 0.5, is: {left: '55px'}},
-            {at: 1, is: {left: '100px'}}
-        ]
-    });
-}, 'The list of keyframes can have one element.');
-
-test(function() {
-    var element = addAnimDiv();
-    var keyframes = [
-        {left: ['10px', '100px']},
-        {left: ['5px', '50px']}
-    ];
-    assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1); });
-}, 'Should throw when mixing two different list syntaxes.');
-
-test(function() {
-    var element = addAnimDiv();
-    var keyframes = [
-        {opacity: '0.5', offset: 0.5},
-        {opacity: '0.9', offset: 1},
-        {opacity: '0', offset: 0}
-    ];
-    assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1); });
-}, 'Should throw when keyframes have unsorted offsets.');
-
-test(function() {
-    var element = addAnimDiv();
-    var keyframes = [
-        {opacity: '1', offset: -1},
-        {opacity: '1', offset: NaN},
-        {opacity: '1', offset: 2},
-        {opacity: '0.5', offset: 1},
-        {opacity: '0', offset: 0}
-    ];
-    assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1); });
-}, 'Should throw when keyframes has offsets outside the range [0.0, 1.0].');
-
-test(function() {
-    var element = addAnimDiv();
-    var keyframes = [
-        {opacity: '0.5'},
-        {opacity: '1', offset: 1},
-        {opacity: '0', offset: 0}
-    ];
-    assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1); });
-}, 'Should throw when keyframes are not loosely sorted and any have no offset.');
-
-test(function() {
-    var element = addAnimDiv();
-    var keyframes = [
-        {opacity: '0.5', offset: null},
-        {opacity: '1', offset: 1},
-        {opacity: '0', offset: 0}
-    ];
-    assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1); });
-}, 'Should throw when keyframes are not loosely sorted and any have null offset.');
-
-var keyframesWithInvalid = [
-        {width: '0px', backgroundColor: 'octarine', offset: 0},
-        {width: '1000px', foo: 'bar', offset: 1}];
-
-test(function() {
-    var element = addAnimDiv();
-    var elementStyle = getComputedStyle(element);
-    var player = element.animate(keyframesWithInvalid, {duration: 1, fill: 'forwards'});
-    player.pause();
-    player.currentTime = 1;
-    assert_equals(elementStyle.width, '1000px');
-    assert_equals(elementStyle.backgroundColor, 'rgb(0, 0, 0)');
-    assert_equals(elementStyle.foo, undefined);
-}, 'Calling animate() with a pre-constructed keyframes list should start an animation. Invalid style declarations should be ignored.');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/element-animate-null-effect.html b/third_party/WebKit/LayoutTests/web-animations-api/element-animate-null-effect.html
deleted file mode 100644
index c315164..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/element-animate-null-effect.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>element.animate() accepts a null effect</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#animatable">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<body>
-<script>
-"use strict";
-
-test(function(t) {
-  var element = createDiv(t);
-  assert_true(element.animate(null) != null);
-  assert_true(element.animate(null, 1) != null);
-  assert_true(element.animate(null, {duration: 1}) != null);
-}, 'Animate should accept a null effect.');
-</script>
-</body>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/fill-forward-negative-end-delay.html b/third_party/WebKit/LayoutTests/web-animations-api/fill-forward-negative-end-delay.html
deleted file mode 100644
index 1082d657..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/fill-forward-negative-end-delay.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Tests for effect clipping via negative end delay</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#calculating-the-active-time">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<body>
-<script>
-'use strict';
-
-test(function(t) {
-  var animation = createDiv(t).animate(null, {
-    fill: 'forwards',
-    duration: 1,
-    endDelay: -1,
-  });
-  animation.currentTime = 10;
-  assert_equals(animation.effect.getComputedTiming().progress, 0,
-      'Progress should be zero since we clip to the start of the animation');
-}, 'Negative end delay clipping into the start of the animation');
-
-test(function(t) {
-  var animation = createDiv(t).animate(null, {
-    fill: 'forwards',
-    duration: 1,
-    iterations: 2,
-    endDelay: -1,
-  });
-  animation.currentTime = 10;
-  assert_equals(animation.effect.getComputedTiming().progress, 1,
-      'Progress should be 1 since we clip to the end of the first iteration ' +
-      'and the second iteration does not have a chance to start');
-}, 'Negative end delay clipping to the end of the the first iteration');
-
-test(function(t) {
-  var animation = createDiv(t).animate(null, {
-    fill: 'forwards',
-    duration: 1,
-    iterations: 2,
-    endDelay: -0.75,
-  });
-  animation.currentTime = 10;
-  assert_equals(animation.effect.getComputedTiming().progress, 0.25,
-      'Progress should be 0.25 since we clip part way through the second iteration');
-}, 'Negative end delay clipping part way into the second iteration');
-
-test(function(t) {
-  var animation = createDiv(t).animate(null, {
-    fill: 'forwards',
-    duration: 1,
-    iterations: 0,
-    endDelay: -1,
-  });
-  animation.currentTime = 10;
-  assert_equals(animation.effect.getComputedTiming().progress, 0,
-      'Progress should be 0 since there are no iterations to make progress in');
-}, 'Negative end delay clipping into zero iterations');
-
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes-expected.txt
deleted file mode 100644
index cb3ff3a..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom iterator with basic keyframes. effect.getKeyframes is not a function
-FAIL easing and offset are ignored on iterable objects. effect.getKeyframes is not a function
-FAIL Custom iterator with multiple properties specified. effect.getKeyframes is not a function
-FAIL Custom iterator with offset specified. effect.getKeyframes is not a function
-PASS Custom iterator with non object keyframe should throw. 
-FAIL Custom iterator with value list in keyframe should give bizarre string representation of list. effect.getKeyframes is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes.html b/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes.html
deleted file mode 100644
index 1cd20ff..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/keyframe-effect-iterable-keyframes.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!DOCTYPE html>
-<meta charset='utf-8'>
-<title>Test that KeyframeEffect can take iterable objects as keyframes</title>
-<link rel='help' href='https://w3c.github.io/web-animations/#processing-a-keyframes-argument'>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<body></body>
-<script>
-function assertAnimationEffect({keyframes, expect}) {
-  var effect = new KeyframeEffect(null, keyframes);
-  var frames = effect.getKeyframes();
-  for (let i = 0; i < expect.length; i++) {
-    assert_equals(frames[i].computedOffset, expect[i].at);
-    for (var property in expect[i].is)
-      assert_equals(frames[i][property], expect[i].is[property], 
-	  `${property} is ${expect[i].is[property]} at ${expect[i].at}`);
-  }
-  return frames;
-}
-
-function createIterable(iterations) {
-  return {
-    [Symbol.iterator]() {
-      var i = 0;
-      return {next: () => iterations[i++]};
-    },
-  };
-}
-
-test(() => {
-  assertAnimationEffect({
-    keyframes: createIterable([
-      {done: false, value: {left: '100px'}},
-      {done: false, value: {left: '300px'}},
-      {done: false, value: {left: '200px'}},
-      {done: true},
-    ]),
-    expect: [
-      {at: 0, is: {left: '100px'}},
-      {at: 0.5, is: {left: '300px'}},
-      {at: 1, is: {left: '200px'}},
-    ],
-  });
-}, 'Custom iterator with basic keyframes.');
-
-test(() => {
-  var keyframes = createIterable([
-    {done: false, value: {left: '100px'}},
-    {done: false, value: {left: '300px'}},
-    {done: false, value: {left: '200px'}},
-    {done: true},
-  ]);
-  keyframes.easing = 'ease-in-out';
-  keyframes.offset = '0.1';
-  let frames = assertAnimationEffect({
-    keyframes,
-    expect: [
-      {at: 0, is: {left: '100px'}},
-      {at: 0.5, is: {left: '300px'}},
-      {at: 1, is: {left: '200px'}},
-    ],
-  });
-  assert_equals(frames[0].easing, 'linear');
-  assert_equals(frames[0].offset, null);
-}, 'easing and offset are ignored on iterable objects.');
-
-test(() => {
-  assertAnimationEffect({
-    keyframes: createIterable([
-      {done: false, value: {left: '100px', top: '200px'}},
-      {done: false, value: {left: '300px'}},
-      {done: false, value: {left: '200px', top: '100px'}},
-      {done: true},
-    ]),
-    expect: [
-      {at: 0, is: {left: '100px', top: '200px'}},
-      {at: 0.5, is: {left: '300px'}},
-      {at: 1, is: {left: '200px', top: '100px'}},
-    ],
-  });
-}, 'Custom iterator with multiple properties specified.');
-
-test(() => {
-  assertAnimationEffect({
-    keyframes: createIterable([
-      {done: false, value: {left: '100px'}},
-      {done: false, value: {left: '250px', offset: 0.75}},
-      {done: false, value: {left: '200px'}},
-      {done: true},
-    ]),
-    expect: [
-      {at: 0, is: {left: '100px'}},
-      {at: 0.75, is: {left: '250px'}},
-      {at: 1, is: {left: '200px'}},
-    ],
-  });
-}, 'Custom iterator with offset specified.');
-
-test(() => {
-  assert_throws({name: 'TypeError'}, () => {
-    assertAnimationEffect({
-      keyframes: createIterable([
-        {done: false, value: {left: '100px'}},
-        {done: false, value: 1234},
-        {done: false, value: {left: '200px'}},
-        {done: true},
-      ]),
-      expect: [],
-    });
-  });
-}, 'Custom iterator with non object keyframe should throw.');
-
-test(() => {
-  assertAnimationEffect({
-    keyframes: createIterable([
-      {done: false, value: {left: ['100px', '200px']}},
-      {done: true},
-    ]),
-    expect: [{at: 1, is: {left: "100px,200px"}}],
-  });
-}, 'Custom iterator with value list in keyframe should give bizarre string representation of list.');
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/reject-hyphen.html b/third_party/WebKit/LayoutTests/web-animations-api/reject-hyphen.html
deleted file mode 100644
index a98ce47..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/reject-hyphen.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<style>
-
-div { font-size: 10px; }
-
-</style>
-<div id='element'></div>
-<script>
-
-var element = document.getElementById('element');
-
-test(function() {
-    element.animate({'font-size': '20px'}, {fill: 'forwards'});
-    assert_equals(getComputedStyle(element).fontSize, '10px');
-
-    element.animate({'fontSize': '30px'}, {fill: 'forwards'});
-    assert_equals(getComputedStyle(element).fontSize, '30px');
-}, 'Hyphenated propery names are ignored.');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/startTime-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/startTime-expected.txt
deleted file mode 100644
index 420d718..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/startTime-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL startTime of a newly created (idle) animation is unresolved Animation is not defined
-FAIL startTime of a play-pending animation is unresolved Animation is not defined
-FAIL startTime of a pause-pending animation is unresolved Animation is not defined
-PASS startTime of a play-pending animation created using Element.animate shortcut is unresolved 
-PASS startTime is resolved when running 
-PASS startTime and currentTime are unresolved when animation is cancelled 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/startTime.html b/third_party/WebKit/LayoutTests/web-animations-api/startTime.html
deleted file mode 100644
index 588d0245..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/startTime.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animation.startTime tests</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-starttime">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-<link rel="stylesheet" href="../resources/testharness.css">
-<body>
-<div>This test is a copy of LayoutTests/external/wpt/web-animations/interfaces/Animation/startTime.html. Make sure to upstream this to the w3c test suite as it contains an added test that would fit well there.</div>
-<div id="log"></div>
-<script>
-'use strict';
-
-test(function(t) {
-  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
-                                document.timeline);
-  assert_equals(animation.startTime, null, 'startTime is unresolved');
-}, 'startTime of a newly created (idle) animation is unresolved');
-
-test(function(t) {
-  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
-                                document.timeline);
-  animation.play();
-  assert_equals(animation.startTime, null, 'startTime is unresolved');
-}, 'startTime of a play-pending animation is unresolved');
-
-test(function(t) {
-  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
-                                document.timeline);
-  animation.pause();
-  assert_equals(animation.startTime, null, 'startTime is unresolved');
-}, 'startTime of a pause-pending animation is unresolved');
-
-test(function(t) {
-  var animation = createDiv(t).animate(null);
-  assert_equals(animation.startTime, null, 'startTime is unresolved');
-}, 'startTime of a play-pending animation created using Element.animate'
-   + ' shortcut is unresolved');
-
-promise_test(function(t) {
-  var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
-  return animation.ready.then(function() {
-    assert_greater_than(animation.startTime, 0, 'startTime when running');
-  });
-}, 'startTime is resolved when running');
-
-test(function() {
-  var player = document.documentElement.animate([], 100000);
-  player.cancel();
-  assert_equals(player.startTime, null);
-  assert_equals(player.currentTime, null);
-}, "startTime and currentTime are unresolved when animation is cancelled");
-
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/time-consistent-across-frames.html b/third_party/WebKit/LayoutTests/web-animations-api/time-consistent-across-frames.html
deleted file mode 100644
index 254097eb..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/time-consistent-across-frames.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Model liveness: currentTime will not change in a task (frames)</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#model-liveness">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../external/wpt/web-animations/testcommon.js"></script>
-
-<iframe id=frame></iframe>
-
-<script>
-var handle = async_test('Document timeline should tick consistently across frames');
-var baseTime = document.timeline.currentTime;
-var frameBaseTime = frame.contentDocument.timeline.currentTime;
-setTimeout(() => {
-  // Ensure that time in this task has advanced sufficiently for implementations
-  // that might bind the currentTime lazily.
-  var start = performance.now();
-  while (performance.now() - start < 30);
-  var delta = document.timeline.currentTime - baseTime;
-
-  // Advance time further before querying the frame's time.
-  var start = performance.now();
-  while (performance.now() - start < 30);
-  var frameDelta = frame.contentDocument.timeline.currentTime - frameBaseTime;
-
-  handle.step(() => assert_times_equal(delta, frameDelta));
-  handle.done();
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/timeline-time.html b/third_party/WebKit/LayoutTests/web-animations-api/timeline-time.html
deleted file mode 100644
index 76c3aaa..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/timeline-time.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Document timeline is increasing</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#the-documents-default-timeline">
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<script>
-test(function() {
-  var startTime = document.timeline.currentTime;
-  assert_greater_than_equal(startTime, 0);
-  var start = performance.now();
-  while (performance.now() < start + 250)
-    /* wait */;
-  assert_equals(document.timeline.currentTime, startTime);
-}, 'document.timeline.currentTime should not change within a script block.');
-
-(function() {
-  var timeoutTest = async_test('document.timeline.currentTime time should change after a script timeout');
-  var startTime = document.timeline.currentTime;
-
-  setTimeout(function() {
-    timeoutTest.step(function() {
-      assert_greater_than(document.timeline.currentTime, startTime);
-    });
-    timeoutTest.done();
-  }, 100);
-})();
-
-(function() {
-  var rafTest = async_test('document.timeline.currentTime time should be the same for all RAF callbacks in a frame');
-  var startTime = document.timeline.currentTime;
-  var firstRafTime;
-
-  requestAnimationFrame(function() {
-    rafTest.step(function() {
-      assert_greater_than_equal(document.timeline.currentTime, startTime);
-      firstRafTime = document.timeline.currentTime;
-    });
-  });
-
-  requestAnimationFrame(function() {
-    rafTest.step(function() {
-      assert_equals(document.timeline.currentTime, firstRafTime);
-    });
-    rafTest.done();
-  });
-})();
-
-(function() {
-  var timeoutTest = async_test('document.timeline.currentTime time should use the same reference as performance.now()');
-
-  setTimeout(function() {
-    timeoutTest.step(function() {
-      assert_less_than(Math.abs(document.timeline.currentTime - performance.now()), 1000);
-    });
-    timeoutTest.done();
-  }, 0);
-})();
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/2-keyframes-with-offsets.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/2-keyframes-with-offsets.html
deleted file mode 100644
index 02cfdd02..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/2-keyframes-with-offsets.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="resources/keyframes-test.js"></script>
-<script>
-test(function() {
-  assertAnimationStyles([
-    {opacity: '0.25', left: '25px', offset: 0},
-    {opacity: '0.75', left: '75px'},
-  ], {
-    0.5: {opacity: '0.5', left: '50px'},
-  });
-  assertAnimationStyles([
-    {opacity: '0.25', left: '25px'},
-    {opacity: '0.75', left: '75px', offset: 1},
-  ], {
-    0.5: {opacity: '0.5', left: '50px'},
-  });
-},
-'element.animate() with 2 keyframes and 1 offset specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
-  assert: [
-    'element.animate() should start an animation when two keyframes',
-    'are provided with matching properties and one offset is specified.',
-  ],
-  author: 'Alan Cutter',
-});
-
-test(function() {
-  assertAnimationStyles([
-    {opacity: '0.25', left: '25px', offset: 0},
-    {opacity: '0.75', left: '75px', offset: 1},
-  ], {
-    0.5: {opacity: '0.5', left: '50px'},
-  });
-
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      {opacity: '0.75', left: '75px', offset: 1},
-      {opacity: '0.25', left: '25px', offset: 0},
-    ], {
-      0.5: {opacity: '0.5', left: '50px'},
-    });
-  });
-},
-'element.animate() with 2 keyframes and 2 offsets specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
-  assert: [
-    'element.animate() should start an animation when two keyframes',
-    'are provided with matching properties and both offsets specified.',
-  ],
-  author: 'Alan Cutter',
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/3-keyframes-with-offsets.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/3-keyframes-with-offsets.html
deleted file mode 100644
index d55a1d2..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/3-keyframes-with-offsets.html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!DOCTYPE html>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="resources/keyframes-test.js"></script>
-<script>
-var keyframeA = {opacity: '0.5', left: '50px'};
-var keyframeB = {opacity: '0', left: '0px'};
-var keyframeC = {opacity: '0.75', left: '75px'};
-
-var keyframeBExpectations = {
-  0: {opacity: '0.5', left: '50px'},
-  0.25: {opacity: '0.25', left: '25px'},
-  0.5: {opacity: '0', left: '0px'}, // Corresponds to keyframeB (offset unspecified).
-  0.75: {opacity: '0.375', left: '37.5px'},
-  1: {opacity: '0.75', left: '75px'},
-};
-
-var offsetKeyframeA = {opacity: keyframeA.opacity, left: keyframeA.left, offset: 0};
-var offsetKeyframeB = {opacity: keyframeB.opacity, left: keyframeB.left, offset: 0.25};
-var offsetKeyframeC = {opacity: keyframeC.opacity, left: keyframeC.left, offset: 1};
-
-var offsetKeyframeBExpectations = {
-  0: {opacity: '0.5', left: '50px'},
-  0.125: {opacity: '0.25', left: '25px'},
-  0.25: {opacity: '0', left: '0px'}, // Corresponds to offsetKeyframeB (offset 0.25).
-  0.5: {opacity: '0.25', left: '25px'},
-  0.75: {opacity: '0.5', left: '50px'},
-  1: {opacity: '0.75', left: '75px'},
-};
-
-test(function() {
-  assertAnimationStyles([
-    offsetKeyframeA,
-    keyframeB,
-    keyframeC,
-  ], keyframeBExpectations, 'with first offset specified');
-  assertAnimationStyles([
-    keyframeA,
-    offsetKeyframeB,
-    keyframeC,
-  ], offsetKeyframeBExpectations, 'with second offset specified');
-  assertAnimationStyles([
-    keyframeA,
-    keyframeB,
-    offsetKeyframeC,
-  ], keyframeBExpectations, 'with third offset specified');
-},
-'element.animate() with 3 keyframes and 1 offset specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
-  assert: [
-    'element.animate() should start an animation when three keyframes',
-    'are provided with matching properties and one offset specified.',
-    'The keyframes must maintain their ordering and get distributed',
-    'correctly.',
-  ],
-  author: 'Alan Cutter',
-});
-
-test(function() {
-  assertAnimationStyles([
-    keyframeA,
-    offsetKeyframeB,
-    offsetKeyframeC,
-  ], offsetKeyframeBExpectations, 'with first offset unspecified');
-  assertAnimationStyles([
-    offsetKeyframeA,
-    keyframeB,
-    offsetKeyframeC,
-  ], keyframeBExpectations, 'with second offset unspecified');
-  assertAnimationStyles([
-    offsetKeyframeA,
-    offsetKeyframeB,
-    keyframeC,
-  ], offsetKeyframeBExpectations, 'with third offset unspecified');
-},
-'element.animate() with 3 keyframes and 2 offsets specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
-  assert: [
-    'element.animate() should start an animation when three keyframes',
-    'are provided with matching properties and two offsets specified.',
-    'The keyframes must maintain their ordering and get distributed',
-    'correctly.',
-  ],
-  author: 'Alan Cutter',
-});
-
-test(function() {
-  assertAnimationStyles([
-    offsetKeyframeA,
-    offsetKeyframeB,
-    offsetKeyframeC,
-  ], offsetKeyframeBExpectations, 'with ordered offsets');
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      offsetKeyframeA,
-      offsetKeyframeC,
-      offsetKeyframeB,
-    ], offsetKeyframeBExpectations, 'with unordered offsets (1)');
-  });
-
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      offsetKeyframeB,
-      offsetKeyframeA,
-      offsetKeyframeC,
-    ], offsetKeyframeBExpectations, 'with unordered offsets (2)');
-  });
-
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      offsetKeyframeB,
-      offsetKeyframeC,
-      offsetKeyframeA,
-    ], offsetKeyframeBExpectations, 'with unordered offsets (3)');
-  });
-
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      offsetKeyframeC,
-      offsetKeyframeA,
-      offsetKeyframeB,
-    ], offsetKeyframeBExpectations, 'with unordered offsets (4)');
-  });
-
-  assert_throws({name: 'TypeError'}, function() {
-    assertAnimationStyles([
-      offsetKeyframeC,
-      offsetKeyframeB,
-      offsetKeyframeA,
-    ], offsetKeyframeBExpectations, 'with unordered offsets (5)');
-  });
-},
-'element.animate() with 3 keyframes and 3 offsets specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
-  assert: [
-    'element.animate() should start an animation when three keyframes',
-    'are provided with matching properties and all offsets specified.',
-    'The keyframes must maintain their ordering and get distributed',
-    'correctly.',
-  ],
-  author: 'Alan Cutter',
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations-expected.txt b/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations-expected.txt
deleted file mode 100644
index ec75744..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL getAnimations() normal behaviour (without delays) document.getAnimations is not a function
-FAIL getAnimations() with animation delays document.getAnimations is not a function
-FAIL getAnimations() with in effect animations document.getAnimations is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations.html
deleted file mode 100644
index 761e7a5..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/get-animations.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Get Animations</title>
-<link rel="help" ­href="https://w3c.github.io/web-animations/#dom-document-getanimations">
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<div id='container'>
-    <div id='element'></div>
-</div>
-
-<script>
-
-var container = document.getElementById('container');
-var element = document.getElementById('element');
-
-test(function() {
-    assert_equals(document.getAnimations().length, 0);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 0);
-
-    var animation = element.animate([], 1000);
-    assert_equals(document.getAnimations().length, 1);
-    assert_equals(document.getAnimations()[0], animation);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 1);
-    assert_equals(element.getAnimations()[0], animation);
-
-    var animation2 = container.animate([], 1000);
-    assert_equals(document.getAnimations().length, 2);
-    assert_equals(document.getAnimations()[0], animation);
-    assert_equals(document.getAnimations()[1], animation2);
-    assert_equals(container.getAnimations().length, 1);
-    assert_equals(container.getAnimations()[0], animation2);
-    assert_equals(element.getAnimations().length, 1);
-    assert_equals(element.getAnimations()[0], animation);
-
-    animation.finish();
-    assert_equals(document.getAnimations().length, 1);
-    assert_equals(document.getAnimations()[0], animation2);
-    assert_equals(container.getAnimations().length, 1);
-    assert_equals(container.getAnimations()[0], animation2);
-    assert_equals(element.getAnimations().length, 0);
-
-    animation2.finish();
-    assert_equals(document.getAnimations().length, 0);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 0);
-
-}, 'getAnimations() normal behaviour (without delays)');
-
-test(function() {
-    assert_equals(document.getAnimations().length, 0);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 0);
-
-    var animation = element.animate([], {duration: 1000, delay: 500});
-    assert_equals(document.getAnimations().length, 1);
-    assert_equals(document.getAnimations()[0], animation);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 1);
-    assert_equals(element.getAnimations()[0], animation);
-
-    animation.finish();
-    assert_equals(document.getAnimations().length, 0);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 0);
-
-}, 'getAnimations() with animation delays');
-
-test(function() {
-    assert_equals(document.getAnimations().length, 0);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 0);
-
-    var animation = element.animate([], {duration: 1000, delay: 500, fill: 'both'});
-    assert_equals(document.getAnimations().length, 1);
-    assert_equals(document.getAnimations()[0], animation);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 1);
-    assert_equals(element.getAnimations()[0], animation);
-
-    animation.finish();
-    assert_equals(document.getAnimations().length, 1);
-    assert_equals(container.getAnimations().length, 0);
-    assert_equals(element.getAnimations().length, 1);
-
-}, 'getAnimations() with in effect animations');
-
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframe-properties.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframe-properties.html
deleted file mode 100644
index 07d6efc..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframe-properties.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<meta charset='utf-8'>
-<title>Web Animations API: Keyframe Property tests</title>
-<link rel='help' href='https://w3c.github.io/web-animations/#processing-a-keyframes-argument'>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<div id="div"></div>
-<script>
-
-test(function() {
-  var keyframe = {};
-  Object.defineProperty(keyframe, 'width', {value: '200px'});
-  Object.defineProperty(keyframe, 'height', {
-    value: '100px',
-    enumerable: true});
-  assert_equals(keyframe.width, '200px', 'width of keyframe is readable');
-  assert_equals(keyframe.height, '100px', 'height of keyframe is readable');
-  try {
-    div.animate([keyframe, {height: '200px'}], 1);
-  } catch (e) {
-    assert_unreached("Mismatched properties - both or neither properties on keyframe were considered.");
-  }
-}, 'Only enumerable properties on keyframes are considered');
-
-test(function() {
-  var KeyframeParent = function() { this.width = "100px"; };
-  KeyframeParent.prototype = { height: "100px" };
-  var Keyframe = function() { this.top = "100px"; };
-  Keyframe.prototype = Object.create(KeyframeParent.prototype);
-  Object.defineProperty(Keyframe.prototype, "left", {
-    value: '100px',
-    enumerable: 'true'});
-  var keyframe = new Keyframe();
-  try {
-    div.animate([keyframe, {top: '200px'}], 1);
-  } catch (e) {
-    assert_unreached("Mismatched properties - left, width or height considered on first keyframe.");
-  }
-}, 'Only properties defined directly on keyframes are considered');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframes-with-null-offsets.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframes-with-null-offsets.html
deleted file mode 100644
index 179b0b7..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/keyframes-with-null-offsets.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test keyframes with null offsets</title>
-<link rel="help" ­href="https://w3c.github.io/web-animations/#keyframes-section">
-
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="resources/keyframes-test.js"></script>
-<script>
-test(function() {
-  assertAnimationStyles([
-    {opacity: '0.5', left: '50px'},
-    {opacity: '0', left: '0px', offset: null},
-    {opacity: '0.75', left: '75px', offset: null},
-  ], {
-    0: {opacity: '0.5', left: '50px'},
-    0.25: {opacity: '0.25', left: '25px'},
-    0.5: {opacity: '0', left: '0px'},
-    0.75: {opacity: '0.375', left: '37.5px'},
-    1: {opacity: '0.75', left: '75px'},
-  }, 'Null and missing offsets behave identically');
-  assertAnimationStyles([
-    {opacity: '0.5', left: '50px', offset: null},
-    {opacity: '0', left: '0px', offset: 0.25},
-    {opacity: '0.75', left: '75px', offset: null},
-  ], {
-    0: {opacity: '0.5', left: '50px'},
-    0.125: {opacity: '0.25', left: '25px'},
-    0.25: {opacity: '0', left: '0px'},
-    0.5: {opacity: '0.25', left: '25px'},
-    0.75: {opacity: '0.5', left: '50px'},
-    1: {opacity: '0.75', left: '75px'},
-  }, 'Null and explicit offsets behave as with missing and explicit offsets.');
-},
-'element.animate() with null offsets specified',
-{
-  help: 'http://dev.w3.org/fxtf/web-animations/#the-keyframe-dictionary',
-  assert: [
-    'element.animate() should start an animation when keyframes are specified with',
-    'null offsets. The behaviour should be identical to not specifying the offsets.',
-  ],
-  author: 'Alan Cutter',
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/resources/keyframes-test.js b/third_party/WebKit/LayoutTests/web-animations-api/w3c/resources/keyframes-test.js
deleted file mode 100644
index 4613a32..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/resources/keyframes-test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-(function(){
-'use strict'
-
-function createElement() {
-  var element = document.createElement('div');
-  document.documentElement.appendChild(element);
-  return element;
-}
-
-function heldTiming(progress) {
-  return {
-    duration: 1000,
-    fill: 'forwards',
-    delay: -progress * 1000,
-  };
-}
-
-function assertAnimationStyles(keyframes, expectations, description) {
-  for (var progress in expectations) {
-    var element = createElement();
-    element.animate(keyframes, heldTiming(progress));
-    var computedStyle = getComputedStyle(element);
-    for (var property in expectations[progress]) {
-      assert_equals(computedStyle[property], expectations[progress][property],
-          property + ' at ' + (progress * 100) + '%' + (description ? ' ' + description : ''));
-    }
-  }
-}
-
-window.assertAnimationStyles = assertAnimationStyles;
-})();
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/w3c/simple-keyframes.html b/third_party/WebKit/LayoutTests/web-animations-api/w3c/simple-keyframes.html
deleted file mode 100644
index 8b25404c..0000000
--- a/third_party/WebKit/LayoutTests/web-animations-api/w3c/simple-keyframes.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Animate() with no offsets</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#keyframe-animation-effects">
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../external/wpt/web-animations/testcommon.js"></script>
-<body>
-<script>
-'use strict';
-test(function(t) {
-  var keyframes = [
-    {opacity: '0.25', left: '25px'},
-    {opacity: '0.75', left: '75px'},
-  ];
-  var expectations = {
-    0.5: {opacity: '0.5', left: '50px'},
-  };
-  for (var progress in expectations) {
-    var element = createDiv(t);
-    element.animate(keyframes, {
-      duration: 1000,
-      fill: 'forwards',
-      delay: -progress * 1000,
-    });
-    var computedStyle = getComputedStyle(element);
-    for (var property in expectations[progress]) {
-      assert_equals(computedStyle[property], expectations[progress][property],
-          property + ' at ' + (progress * 100) + '%');
-    }
-  }
-}, 'element.animate() with 2 keyframes');
-
-test(function(t) {
-  var keyframes =[
-    {opacity: '0', left: '0px'},
-    {opacity: '0.25', left: '25px'},
-    {opacity: '0.75', left: '75px'},
-  ];
-  var expectations = {
-    0.25: {opacity: '0.125', left: '12.5px'},
-    0.75: {opacity: '0.5', left: '50px'},
-  };
-  for (var progress in expectations) {
-    var element = createDiv(t);
-    element.animate(keyframes, {
-      duration: 1000,
-      fill: 'forwards',
-      delay: -progress * 1000,
-    });
-    var computedStyle = getComputedStyle(element);
-    for (var property in expectations[progress]) {
-      assert_equals(computedStyle[property], expectations[progress][property],
-          property + ' at ' + (progress * 100) + '%');
-    }
-  }
-}, 'element.animate() with 3 keyframes');
-</script>
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 363b23f..c40adf5 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1193,7 +1193,6 @@
     "dom/DocumentTest.cpp",
     "dom/ElementTest.cpp",
     "dom/ElementVisibilityObserverTest.cpp",
-    "dom/ExecutionContextTaskTest.cpp",
     "dom/IdleDeadlineTest.cpp",
     "dom/LayoutTreeBuilderTraversalTest.cpp",
     "dom/MockScriptElementBase.h",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 3802ea9..38b07c9 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -904,6 +904,7 @@
       api_methods: ["parseSingleValue"],
       converter: "ConvertLengthOrAuto",
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
@@ -1274,6 +1275,7 @@
       converter: "ConvertLengthSizing",
       is_descriptor: true,
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto", "fit-content", "min-content", "max-content"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
@@ -1338,6 +1340,7 @@
       api_methods: ["parseSingleValue"],
       converter: "ConvertLengthOrAuto",
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
@@ -1798,6 +1801,7 @@
       api_methods: ["parseSingleValue"],
       converter: "ConvertLengthOrAuto",
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
@@ -2166,6 +2170,7 @@
       api_methods: ["parseSingleValue"],
       converter: "ConvertLengthOrAuto",
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
@@ -2734,6 +2739,7 @@
       converter: "ConvertLengthSizing",
       is_descriptor: true,
       interpolable: true,
+      typedom_types: ["Length", "Percent"],
       keywords: ["auto", "fit-content", "min-content", "max-content"],
       field_template: "external",
       include_paths: ["platform/Length.h"],
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
index 01f4905..02c3281a 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
@@ -4,6 +4,9 @@
 
 #include "core/css/cssom/CSSNumericValue.h"
 
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/cssom/CSSUnitValue.h"
+
 namespace blink {
 
 CSSNumericValue* CSSNumericValue::parse(const String& css_text,
@@ -12,4 +15,12 @@
   return nullptr;
 }
 
+CSSNumericValue* CSSNumericValue::FromCSSValue(const CSSPrimitiveValue& value) {
+  if (value.IsCalculated()) {
+    // TODO(meade): Implement this case.
+    return nullptr;
+  }
+  return CSSUnitValue::FromCSSValue(value);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.h b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.h
index 55af653..6344c2f 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.h
@@ -22,10 +22,7 @@
 
  public:
   static CSSNumericValue* parse(const String& css_text, ExceptionState&);
-  static CSSNumericValue* FromCSSValue(const CSSValue&) {
-    // TODO(meade): Implement.
-    return nullptr;
-  }
+  static CSSNumericValue* FromCSSValue(const CSSPrimitiveValue&);
 
   virtual CSSNumericValue* add(const CSSNumericValue*, ExceptionState&) {
     // TODO(meade): Implement.
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
index 2fd1ac8..1907495 100644
--- a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
@@ -7,6 +7,7 @@
 #include "core/css/CSSImageValue.h"
 #include "core/css/CSSValue.h"
 #include "core/css/cssom/CSSKeywordValue.h"
+#include "core/css/cssom/CSSNumericValue.h"
 #include "core/css/cssom/CSSOMTypes.h"
 #include "core/css/cssom/CSSStyleValue.h"
 #include "core/css/cssom/CSSStyleVariableReferenceValue.h"
@@ -19,11 +20,6 @@
 
 namespace {
 
-CSSStyleValue* CreateStyleValueFromPrimitiveValue(
-    const CSSPrimitiveValue& primitive_value) {
-  return nullptr;
-}
-
 CSSStyleValue* CreateStyleValueWithPropertyInternal(CSSPropertyID property_id,
                                                     const CSSValue& value) {
   switch (property_id) {
@@ -41,7 +37,7 @@
       value.IsCustomIdentValue())
     return CSSKeywordValue::FromCSSValue(value);
   if (value.IsPrimitiveValue())
-    return CreateStyleValueFromPrimitiveValue(ToCSSPrimitiveValue(value));
+    return CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value));
   if (value.IsVariableReferenceValue())
     return CSSUnparsedValue::FromCSSValue(ToCSSVariableReferenceValue(value));
   if (value.IsImageValue()) {
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn
index 9940172..318118e4 100644
--- a/third_party/WebKit/Source/core/dom/BUILD.gn
+++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -155,7 +155,6 @@
     "ExceptionCode.h",
     "ExecutionContext.cpp",
     "ExecutionContext.h",
-    "ExecutionContextTask.h",
     "FirstLetterPseudoElement.cpp",
     "FirstLetterPseudoElement.h",
     "FlexibleArrayBufferView.h",
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index 1e8a3c9..ffd506dd 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -178,19 +178,34 @@
   return true;
 }
 
-bool ContainerNode::CollectChildrenAndRemoveFromOldParentWithCheck(
+bool ContainerNode::CollectChildrenAndRemoveFromOldParentWithOptionalRecheck(
     const Node* next,
     const Node* old_child,
     Node& new_child,
     NodeVector& new_children,
     ExceptionState& exception_state) const {
+  Document& new_doc = new_child.GetDocument();
+  Document& this_doc = GetDocument();
+  uint64_t original_version_for_new_node = new_doc.DomTreeVersion();
+  uint64_t original_version_for_this = this_doc.DomTreeVersion();
   CollectChildrenAndRemoveFromOldParent(new_child, new_children,
                                         exception_state);
   if (exception_state.HadException() || new_children.IsEmpty())
     return false;
+  // We can skip the following hierarchy check if we have no DOM mutations other
+  // than one in CollectChildrenAndRemoveFromOldParent(). We can detect it by
+  //  - DOM tree version of |new_doc| was increased by at most one.
+  //  - If |this| and |new_child| are in different documents, Document for
+  //    |this| must not be changed.
+  if (new_doc.DomTreeVersion() <= original_version_for_new_node + 1) {
+    if (&new_doc == &this_doc)
+      return true;
+    if (this_doc.DomTreeVersion() == original_version_for_this)
+      return true;
+  }
 
-  // We need this extra check because collectChildrenAndRemoveFromOldParent()
-  // can fire various events.
+  // We need this extra check because synchronous event handlers triggered
+  // while CollectChildrenAndRemoveFromOldParent() modified DOM trees.
   for (const auto& child : new_children) {
     if (child->parentNode()) {
       // A new child was added to another parent before adding to this
@@ -310,7 +325,7 @@
   DCHECK(new_child);
 
   NodeVector targets;
-  if (!CollectChildrenAndRemoveFromOldParentWithCheck(
+  if (!CollectChildrenAndRemoveFromOldParentWithOptionalRecheck(
           ref_child, nullptr, *new_child, targets, exception_state))
     return new_child;
 
@@ -454,9 +469,11 @@
   // 10. Adopt node into parent’s node document.
   // TODO(tkent): Actually we do only RemoveChild() as a part of 'adopt'
   // operation.
-  // Though the following CollectChildrenAndRemoveFromOldParentWithCheck() also
-  // calls RemoveChild(), we'd like to call RemoveChild() here to make a
-  // separated MutationRecord.
+  //
+  // Though the following
+  // CollectChildrenAndRemoveFromOldParentWithOptionalRecheck() also calls
+  // RemoveChild(), we'd like to call RemoveChild() here to make a separated
+  // MutationRecord.
   if (ContainerNode* new_child_parent = new_child->parentNode()) {
     new_child_parent->RemoveChild(new_child, exception_state);
     if (exception_state.HadException())
@@ -488,7 +505,7 @@
 
     // 13. Let nodes be node’s children if node is a DocumentFragment node, and
     // a list containing solely node otherwise.
-    if (!CollectChildrenAndRemoveFromOldParentWithCheck(
+    if (!CollectChildrenAndRemoveFromOldParentWithOptionalRecheck(
             next, old_child, *new_child, targets, exception_state))
       return old_child;
 
@@ -722,7 +739,7 @@
   DCHECK(new_child);
 
   NodeVector targets;
-  if (!CollectChildrenAndRemoveFromOldParentWithCheck(
+  if (!CollectChildrenAndRemoveFromOldParentWithOptionalRecheck(
           nullptr, nullptr, *new_child, targets, exception_state))
     return new_child;
 
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.h b/third_party/WebKit/Source/core/dom/ContainerNode.h
index 28a512a2..397c2e2 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.h
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.h
@@ -412,11 +412,12 @@
   bool HasRestyleFlagInternal(DynamicRestyleFlags) const;
   bool HasRestyleFlagsInternal() const;
 
-  bool CollectChildrenAndRemoveFromOldParentWithCheck(const Node* next,
-                                                      const Node* old_child,
-                                                      Node& new_child,
-                                                      NodeVector&,
-                                                      ExceptionState&) const;
+  bool CollectChildrenAndRemoveFromOldParentWithOptionalRecheck(
+      const Node* next,
+      const Node* old_child,
+      Node& new_child,
+      NodeVector&,
+      ExceptionState&) const;
   inline bool CheckAcceptChildGuaranteedNodeTypes(const Node& new_child,
                                                   const Node* old_child,
                                                   ExceptionState&) const;
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 071ff8f9..ff4bf9a2 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -79,7 +79,6 @@
 #include "core/dom/ElementRegistrationOptions.h"
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/dom/ExecutionContextTask.h"
 #include "core/dom/FrameRequestCallback.h"
 #include "core/dom/IntersectionObserverController.h"
 #include "core/dom/LayoutTreeBuilderTraversal.h"
@@ -216,6 +215,7 @@
 #include "core/timing/Performance.h"
 #include "core/workers/SharedWorkerRepositoryClient.h"
 #include "core/xml/parser/XMLDocumentParser.h"
+#include "platform/CrossThreadFunctional.h"
 #include "platform/DateComponents.h"
 #include "platform/EventDispatchForbiddenScope.h"
 #include "platform/Histogram.h"
@@ -4632,13 +4632,6 @@
   sensitive_input_service_ptr->AllPasswordFieldsInInsecureContextInvisible();
 }
 
-void Document::RunExecutionContextTask(
-    std::unique_ptr<ExecutionContextTask> task,
-    bool is_instrumented) {
-  probe::AsyncTask async_task(this, task.get(), nullptr, is_instrumented);
-  task->PerformTask(this);
-}
-
 void Document::RegisterEventFactory(
     std::unique_ptr<EventFactoryBase> event_factory) {
   DCHECK(!EventFactories().Contains(event_factory.get()));
@@ -6045,22 +6038,6 @@
   frame_->Console().AddMessage(console_message);
 }
 
-void Document::PostTask(TaskType task_type,
-                        const WebTraceLocation& location,
-                        std::unique_ptr<ExecutionContextTask> task,
-                        const String& task_name_for_instrumentation) {
-  if (!task_name_for_instrumentation.IsEmpty()) {
-    probe::AsyncTaskScheduled(this, task_name_for_instrumentation, task.get());
-  }
-
-  TaskRunnerHelper::Get(task_type, this)
-      ->PostTask(location,
-                 CrossThreadBind(&Document::RunExecutionContextTask,
-                                 WrapCrossThreadWeakPersistent(this),
-                                 WTF::Passed(std::move(task)),
-                                 !task_name_for_instrumentation.IsEmpty()));
-}
-
 void Document::TasksWereSuspended() {
   GetScriptRunner()->Suspend();
 
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 92c1459..b95f82ec 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1000,12 +1000,6 @@
   bool IsDNSPrefetchEnabled() const { return is_dns_prefetch_enabled_; }
   void ParseDNSPrefetchControlHeader(const String&);
 
-  void PostTask(TaskType,
-                const WebTraceLocation&,
-                std::unique_ptr<ExecutionContextTask>,
-                const String& task_name_for_instrumentation = g_empty_string)
-      override;  // Executes the task on context's thread asynchronously.
-
   void TasksWereSuspended() final;
   void TasksWereResumed() final;
   bool TasksNeedSuspension() final;
@@ -1448,9 +1442,6 @@
   void SendSensitiveInputVisibility();
   void SendSensitiveInputVisibilityInternal();
 
-  void RunExecutionContextTask(std::unique_ptr<ExecutionContextTask>,
-                               bool instrumenting);
-
   bool HaveImportsLoaded() const;
 
   DocumentLifecycle lifecycle_;
diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
index a410675..b9eaf18e 100644
--- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp
+++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -308,6 +308,32 @@
 
 }  // anonymous namespace
 
+TEST_F(DocumentTest, DomTreeVersionForRemoval) {
+  // ContainerNode::CollectChildrenAndRemoveFromOldParentWithCheck assumes this
+  // behavior.
+  Document& doc = GetDocument();
+  {
+    DocumentFragment* fragment = DocumentFragment::Create(doc);
+    fragment->appendChild(Element::Create(HTMLNames::divTag, &doc));
+    fragment->appendChild(Element::Create(HTMLNames::spanTag, &doc));
+    uint64_t original_version = doc.DomTreeVersion();
+    fragment->RemoveChildren();
+    EXPECT_EQ(original_version + 1, doc.DomTreeVersion())
+        << "RemoveChildren() should increase DomTreeVersion by 1.";
+  }
+
+  {
+    DocumentFragment* fragment = DocumentFragment::Create(doc);
+    Node* child = Element::Create(HTMLNames::divTag, &doc);
+    child->appendChild(Element::Create(HTMLNames::spanTag, &doc));
+    fragment->appendChild(child);
+    uint64_t original_version = doc.DomTreeVersion();
+    fragment->removeChild(child);
+    EXPECT_EQ(original_version + 1, doc.DomTreeVersion())
+        << "removeChild() should increase DomTreeVersion by 1.";
+  }
+}
+
 // This tests that we properly resize and re-layout pages for printing in the
 // presence of media queries effecting elements in a subtree layout boundary
 TEST_F(DocumentTest, PrintRelayout) {
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 1441ab9..5edb42b4 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -30,7 +30,6 @@
 #include <memory>
 #include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "core/dom/ExecutionContextTask.h"
 #include "core/dom/SuspendableObject.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/events/ErrorEvent.h"
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 2cd6b6b..ba67b54 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -49,7 +49,6 @@
 class ErrorEvent;
 class EventQueue;
 class EventTarget;
-class ExecutionContextTask;
 class LocalDOMWindow;
 class SuspendableObject;
 class PublicURLManager;
@@ -95,12 +94,6 @@
   virtual void DisableEval(const String& error_message) = 0;
   virtual LocalDOMWindow* ExecutingWindow() const { return nullptr; }
   virtual String UserAgent() const = 0;
-  // Executes the task on context's thread asynchronously.
-  virtual void PostTask(
-      TaskType,
-      const WebTraceLocation&,
-      std::unique_ptr<ExecutionContextTask>,
-      const String& task_name_for_instrumentation = g_empty_string) = 0;
 
   // Gets the DOMTimerCoordinator which maintains the "active timer
   // list" of tasks created by setTimeout and setInterval. The
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h b/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
deleted file mode 100644
index 2d7f986..0000000
--- a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ExecutionContextTask_h
-#define ExecutionContextTask_h
-
-#include <type_traits>
-#include "core/CoreExport.h"
-#include "platform/CrossThreadFunctional.h"
-#include "platform/wtf/Allocator.h"
-#include "platform/wtf/Functional.h"
-#include "platform/wtf/Noncopyable.h"
-#include "platform/wtf/PtrUtil.h"
-#include "platform/wtf/text/WTFString.h"
-
-namespace blink {
-
-class ExecutionContext;
-
-class CORE_EXPORT ExecutionContextTask {
-  WTF_MAKE_NONCOPYABLE(ExecutionContextTask);
-  USING_FAST_MALLOC(ExecutionContextTask);
-
- public:
-  ExecutionContextTask() {}
-  virtual ~ExecutionContextTask() {}
-  virtual void PerformTask(ExecutionContext*) = 0;
-
-  void PerformTaskIfContextIsValid(ExecutionContext* context) {
-    if (context)
-      PerformTask(context);
-  }
-};
-
-namespace internal {
-
-template <WTF::FunctionThreadAffinity threadAffinity>
-void RunCallClosureTask(
-    std::unique_ptr<Function<void(), threadAffinity>> closure,
-    ExecutionContext*) {
-  (*closure)();
-}
-
-template <WTF::FunctionThreadAffinity threadAffinity>
-void RunCallClosureTask(
-    std::unique_ptr<Function<void(ExecutionContext*), threadAffinity>> closure,
-    ExecutionContext* execution_context) {
-  (*closure)(execution_context);
-}
-
-template <typename T, WTF::FunctionThreadAffinity threadAffinity>
-class CallClosureTask final : public ExecutionContextTask {
- public:
-  static std::unique_ptr<CallClosureTask> Create(
-      std::unique_ptr<Function<T, threadAffinity>> closure) {
-    return WTF::WrapUnique(new CallClosureTask(std::move(closure)));
-  }
-
- private:
-  explicit CallClosureTask(std::unique_ptr<Function<T, threadAffinity>> closure)
-      : closure_(std::move(closure)) {}
-
-  void PerformTask(ExecutionContext* execution_context) override {
-    RunCallClosureTask(std::move(closure_), execution_context);
-  }
-
-  std::unique_ptr<Function<T, threadAffinity>> closure_;
-};
-
-// Do not use |create| other than in createCrossThreadTask and
-// createSameThreadTask.
-// See http://crbug.com/390851
-template <typename T, WTF::FunctionThreadAffinity threadAffinity>
-std::unique_ptr<CallClosureTask<T, threadAffinity>> CreateCallClosureTask(
-    std::unique_ptr<Function<T, threadAffinity>> closure) {
-  return CallClosureTask<T, threadAffinity>::Create(std::move(closure));
-}
-
-}  // namespace internal
-
-// createSameThreadTask() is deprecated and removed.
-// Use WTF::bind() and post it to WebTaskRunner obtained by
-// TaskRunnerHelper::get() when posting a task within a single thread.
-
-// createCrossThreadTask() is deprecated and will be removed.
-// Use crossThreadBind() and post it to an appropriate task runner
-// when posting a task to another thread.
-// See https://crbug.com/625927 for details.
-//
-// createCrossThreadTask(...) is ExecutionContextTask version of
-// crossThreadBind().
-// Using WTF::bind() directly is not thread-safe due to temporary objects, see
-// https://crbug.com/390851 for details.
-//
-// Example:
-//     void func1(int, const String&);
-//     createCrossThreadTask(func1, 42, str);
-// func1(42, str2) will be called, where |str2| is a deep copy of
-// |str| (created by str.isolatedCopy()).
-//
-// Don't (if you pass the task across threads):
-//     bind(func1, 42, str);
-//     bind(func1, 42, str.isolatedCopy());
-//
-// For functions:
-//     void functionEC(MP1, ..., MPn, ExecutionContext*);
-//     void function(MP1, ..., MPn);
-//     class C {
-//         void memberEC(MP1, ..., MPn, ExecutionContext*);
-//         void member(MP1, ..., MPn);
-//     };
-// We create tasks represented by std::unique_ptr<ExecutionContextTask>:
-//     createCrossThreadTask(functionEC, const P1& p1, ..., const Pn& pn);
-//     createCrossThreadTask(memberEC, C* ptr, const P1& p1, ..., const Pn& pn);
-//     createCrossThreadTask(function, const P1& p1, ..., const Pn& pn);
-//     createCrossThreadTask(member, C* ptr, const P1& p1, ..., const Pn& pn);
-// (|ptr| can also be WeakPtr<C> or other pointer-like types)
-// and then the following are called on the target thread:
-//     functionEC(p1, ..., pn, context);
-//     ptr->memberEC(p1, ..., pn, context);
-//     function(p1, ..., pn);
-//     ptr->member(p1, ..., pn);
-//
-// ExecutionContext:
-//     |context| is supplied by the target thread.
-//
-// Deep copies by crossThreadBind():
-//     |ptr|, |p1|, ..., |pn| are processed by crossThreadBind() and thus
-//     CrossThreadCopier.
-//     You don't have to call manually e.g. isolatedCopy().
-//     To pass things that cannot be copied by CrossThreadCopier
-//     (e.g. pointers), use crossThreadUnretained() explicitly.
-
-template <typename FunctionType, typename... P>
-std::unique_ptr<ExecutionContextTask> CreateCrossThreadTask(
-    FunctionType function,
-    P&&... parameters) {
-  return internal::CreateCallClosureTask(
-      CrossThreadBind(function, std::forward<P>(parameters)...));
-}
-
-}  // namespace blink
-
-#endif
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContextTaskTest.cpp b/third_party/WebKit/Source/core/dom/ExecutionContextTaskTest.cpp
deleted file mode 100644
index fda9540..0000000
--- a/third_party/WebKit/Source/core/dom/ExecutionContextTaskTest.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/dom/ExecutionContextTask.h"
-
-#include "platform/heap/Handle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-class GCObject : public GarbageCollectedFinalized<GCObject> {
- public:
-  static int counter_;
-  GCObject() { ++counter_; }
-  ~GCObject() { --counter_; }
-  DEFINE_INLINE_TRACE() {}
-  void Run(GCObject*) {}
-};
-
-int GCObject::counter_ = 0;
-
-static void FunctionWithGarbageCollected(GCObject*) {}
-
-static void FunctionWithExecutionContext(GCObject*, ExecutionContext*) {}
-
-class CrossThreadTaskTest : public testing::Test {
- protected:
-  void SetUp() override { GCObject::counter_ = 0; }
-  void TearDown() override {
-    ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack,
-                                           BlinkGC::kGCWithSweep,
-                                           BlinkGC::kForcedGC);
-    ASSERT_EQ(0, GCObject::counter_);
-  }
-};
-
-TEST_F(CrossThreadTaskTest, CreateForGarbageCollectedMethod) {
-  std::unique_ptr<ExecutionContextTask> task1 = CreateCrossThreadTask(
-      &GCObject::Run, WrapCrossThreadPersistent(new GCObject),
-      WrapCrossThreadPersistent(new GCObject));
-  std::unique_ptr<ExecutionContextTask> task2 = CreateCrossThreadTask(
-      &GCObject::Run, WrapCrossThreadPersistent(new GCObject),
-      WrapCrossThreadPersistent(new GCObject));
-  ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack,
-                                         BlinkGC::kGCWithSweep,
-                                         BlinkGC::kForcedGC);
-  EXPECT_EQ(4, GCObject::counter_);
-}
-
-TEST_F(CrossThreadTaskTest, CreateForFunctionWithGarbageCollected) {
-  std::unique_ptr<ExecutionContextTask> task1 = CreateCrossThreadTask(
-      &FunctionWithGarbageCollected, WrapCrossThreadPersistent(new GCObject));
-  std::unique_ptr<ExecutionContextTask> task2 = CreateCrossThreadTask(
-      &FunctionWithGarbageCollected, WrapCrossThreadPersistent(new GCObject));
-  ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack,
-                                         BlinkGC::kGCWithSweep,
-                                         BlinkGC::kForcedGC);
-  EXPECT_EQ(2, GCObject::counter_);
-}
-
-TEST_F(CrossThreadTaskTest, CreateForFunctionWithExecutionContext) {
-  std::unique_ptr<ExecutionContextTask> task1 = CreateCrossThreadTask(
-      &FunctionWithExecutionContext, WrapCrossThreadPersistent(new GCObject));
-  std::unique_ptr<ExecutionContextTask> task2 = CreateCrossThreadTask(
-      &FunctionWithExecutionContext, WrapCrossThreadPersistent(new GCObject));
-  ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack,
-                                         BlinkGC::kGCWithSweep,
-                                         BlinkGC::kForcedGC);
-  EXPECT_EQ(2, GCObject::counter_);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn
index d48ab91..5bca983b 100644
--- a/third_party/WebKit/Source/core/editing/BUILD.gn
+++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -217,6 +217,8 @@
     "markers/SpellingMarker.h",
     "markers/SpellingMarkerListImpl.cpp",
     "markers/SpellingMarkerListImpl.h",
+    "markers/StyleableMarker.cpp",
+    "markers/StyleableMarker.h",
     "markers/TextMatchMarker.cpp",
     "markers/TextMatchMarker.h",
     "markers/TextMatchMarkerListImpl.cpp",
diff --git a/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
index 33eb315..1f2e2e9 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -466,8 +466,8 @@
 
     GetDocument().Markers().AddCompositionMarker(
         ephemeral_line_range, underline.GetColor(),
-        underline.Thick() ? CompositionMarker::Thickness::kThick
-                          : CompositionMarker::Thickness::kThin,
+        underline.Thick() ? StyleableMarker::Thickness::kThick
+                          : StyleableMarker::Thickness::kThin,
         underline.BackgroundColor());
   }
 }
@@ -692,7 +692,7 @@
   if (underlines.IsEmpty()) {
     GetDocument().Markers().AddCompositionMarker(
         EphemeralRange(composition_range_), Color::kBlack,
-        CompositionMarker::Thickness::kThin,
+        StyleableMarker::Thickness::kThin,
         LayoutTheme::GetTheme().PlatformDefaultCompositionBackgroundColor());
     return;
   }
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarker.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarker.cpp
index 23a52f5..0fb0d913 100644
--- a/third_party/WebKit/Source/core/editing/markers/CompositionMarker.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarker.cpp
@@ -11,25 +11,14 @@
                                      Color underline_color,
                                      Thickness thickness,
                                      Color background_color)
-    : DocumentMarker(start_offset, end_offset),
-      underline_color_(underline_color),
-      background_color_(background_color),
-      thickness_(thickness) {}
+    : StyleableMarker(start_offset,
+                      end_offset,
+                      underline_color,
+                      thickness,
+                      background_color) {}
 
 DocumentMarker::MarkerType CompositionMarker::GetType() const {
   return DocumentMarker::kComposition;
 }
 
-Color CompositionMarker::UnderlineColor() const {
-  return underline_color_;
-}
-
-bool CompositionMarker::IsThick() const {
-  return thickness_ == Thickness::kThick;
-}
-
-Color CompositionMarker::BackgroundColor() const {
-  return background_color_;
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarker.h b/third_party/WebKit/Source/core/editing/markers/CompositionMarker.h
index a88674c..28b028e4 100644
--- a/third_party/WebKit/Source/core/editing/markers/CompositionMarker.h
+++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarker.h
@@ -5,7 +5,7 @@
 #ifndef CompositionMarker_h
 #define CompositionMarker_h
 
-#include "core/editing/markers/DocumentMarker.h"
+#include "core/editing/markers/StyleableMarker.h"
 
 namespace blink {
 
@@ -14,10 +14,8 @@
 // transparent), whether the underline should be thick or not, and what
 // background color should be used under the marked text (also possibly
 // transparent).
-class CORE_EXPORT CompositionMarker final : public DocumentMarker {
+class CORE_EXPORT CompositionMarker final : public StyleableMarker {
  public:
-  enum class Thickness { kThin, kThick };
-
   CompositionMarker(unsigned start_offset,
                     unsigned end_offset,
                     Color underline_color,
@@ -27,16 +25,7 @@
   // DocumentMarker implementations
   MarkerType GetType() const final;
 
-  // CompositionMarker-specific
-  Color UnderlineColor() const;
-  bool IsThick() const;
-  Color BackgroundColor() const;
-
  private:
-  const Color underline_color_;
-  const Color background_color_;
-  const Thickness thickness_;
-
   DISALLOW_COPY_AND_ASSIGN(CompositionMarker);
 };
 
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp
index 8f14333..15f58c7 100644
--- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp
@@ -16,7 +16,7 @@
 
   DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) {
     return new CompositionMarker(start_offset, end_offset, Color::kBlack,
-                                 CompositionMarker::Thickness::kThin,
+                                 StyleableMarker::Thickness::kThin,
                                  Color::kBlack);
   }
 
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerTest.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerTest.cpp
index 3db1f7e..942e84a 100644
--- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerTest.cpp
@@ -12,22 +12,27 @@
 
 TEST_F(CompositionMarkerTest, MarkerType) {
   DocumentMarker* marker = new CompositionMarker(
-      0, 1, Color::kTransparent, CompositionMarker::Thickness::kThin,
+      0, 1, Color::kTransparent, StyleableMarker::Thickness::kThin,
       Color::kTransparent);
   EXPECT_EQ(DocumentMarker::kComposition, marker->GetType());
 }
 
+TEST_F(CompositionMarkerTest, IsStyleableMarker) {
+  DocumentMarker* marker = new CompositionMarker(
+      0, 1, Color::kTransparent, StyleableMarker::Thickness::kThin,
+      Color::kTransparent);
+  EXPECT_TRUE(IsStyleableMarker(*marker));
+}
+
 TEST_F(CompositionMarkerTest, ConstructorAndGetters) {
-  CompositionMarker* marker =
-      new CompositionMarker(0, 1, Color::kDarkGray,
-                            CompositionMarker::Thickness::kThin, Color::kGray);
+  CompositionMarker* marker = new CompositionMarker(
+      0, 1, Color::kDarkGray, StyleableMarker::Thickness::kThin, Color::kGray);
   EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
   EXPECT_FALSE(marker->IsThick());
   EXPECT_EQ(Color::kGray, marker->BackgroundColor());
 
-  CompositionMarker* thick_marker =
-      new CompositionMarker(0, 1, Color::kDarkGray,
-                            CompositionMarker::Thickness::kThick, Color::kGray);
+  CompositionMarker* thick_marker = new CompositionMarker(
+      0, 1, Color::kDarkGray, StyleableMarker::Thickness::kThick, Color::kGray);
   EXPECT_EQ(true, thick_marker->IsThick());
 }
 
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
index 46271dca..5295203b 100644
--- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
@@ -153,7 +153,7 @@
 void DocumentMarkerController::AddCompositionMarker(
     const EphemeralRange& range,
     Color underline_color,
-    CompositionMarker::Thickness thickness,
+    StyleableMarker::Thickness thickness,
     Color background_color) {
   DCHECK(!document_->NeedsLayoutTreeUpdate());
   AddMarkerInternal(range, [underline_color, thickness, background_color](
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.h b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.h
index f889da7..92e7532 100644
--- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.h
+++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.h
@@ -62,7 +62,7 @@
   void AddTextMatchMarker(const EphemeralRange&, TextMatchMarker::MatchStatus);
   void AddCompositionMarker(const EphemeralRange&,
                             Color underline_color,
-                            CompositionMarker::Thickness,
+                            StyleableMarker::Thickness,
                             Color background_color);
 
   void MoveMarkers(Node* src_node, int length, Node* dst_node);
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp
index 77438cb..fb1fcc9d 100644
--- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp
@@ -220,10 +220,10 @@
   GetDocument().UpdateStyleAndLayout();
   MarkerController().AddCompositionMarker(
       EphemeralRange(Position(text, 0), Position(text, 1)), Color::kBlack,
-      CompositionMarker::Thickness::kThin, Color::kBlack);
+      StyleableMarker::Thickness::kThin, Color::kBlack);
   MarkerController().AddCompositionMarker(
       EphemeralRange(Position(text, 1), Position(text, 3)), Color::kBlack,
-      CompositionMarker::Thickness::kThick, Color::kBlack);
+      StyleableMarker::Thickness::kThick, Color::kBlack);
 
   EXPECT_EQ(2u, MarkerController().Markers().size());
 }
diff --git a/third_party/WebKit/Source/core/editing/markers/StyleableMarker.cpp b/third_party/WebKit/Source/core/editing/markers/StyleableMarker.cpp
new file mode 100644
index 0000000..3ed789a
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/markers/StyleableMarker.cpp
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/editing/markers/StyleableMarker.h"
+
+namespace blink {
+
+StyleableMarker::StyleableMarker(unsigned start_offset,
+                                 unsigned end_offset,
+                                 Color underline_color,
+                                 Thickness thickness,
+                                 Color background_color)
+    : DocumentMarker(start_offset, end_offset),
+      underline_color_(underline_color),
+      background_color_(background_color),
+      thickness_(thickness) {}
+
+Color StyleableMarker::UnderlineColor() const {
+  return underline_color_;
+}
+
+bool StyleableMarker::IsThick() const {
+  return thickness_ == Thickness::kThick;
+}
+
+Color StyleableMarker::BackgroundColor() const {
+  return background_color_;
+}
+
+bool IsStyleableMarker(const DocumentMarker& marker) {
+  DocumentMarker::MarkerType type = marker.GetType();
+  return type == DocumentMarker::kComposition;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/StyleableMarker.h b/third_party/WebKit/Source/core/editing/markers/StyleableMarker.h
new file mode 100644
index 0000000..6109234e
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/markers/StyleableMarker.h
@@ -0,0 +1,47 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleableMarker_h
+#define StyleableMarker_h
+
+#include "core/editing/markers/DocumentMarker.h"
+
+namespace blink {
+
+// An abstract subclass of DocumentMarker to be subclassed by DocumentMarkers
+// that should be renderable with customizable formatting.
+class CORE_EXPORT StyleableMarker : public DocumentMarker {
+ public:
+  enum class Thickness { kThin, kThick };
+
+  StyleableMarker(unsigned start_offset,
+                  unsigned end_offset,
+                  Color underline_color,
+                  Thickness,
+                  Color background_color);
+
+  // StyleableMarker-specific
+  Color UnderlineColor() const;
+  bool IsThick() const;
+  Color BackgroundColor() const;
+
+ private:
+  const Color underline_color_;
+  const Color background_color_;
+  const Thickness thickness_;
+
+  DISALLOW_COPY_AND_ASSIGN(StyleableMarker);
+};
+
+bool CORE_EXPORT IsStyleableMarker(const DocumentMarker&);
+
+DEFINE_TYPE_CASTS(StyleableMarker,
+                  DocumentMarker,
+                  marker,
+                  IsStyleableMarker(*marker),
+                  IsStyleableMarker(marker));
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/html/LinkResource.cpp b/third_party/WebKit/Source/core/html/LinkResource.cpp
index ba9af69e..823dd42 100644
--- a/third_party/WebKit/Source/core/html/LinkResource.cpp
+++ b/third_party/WebKit/Source/core/html/LinkResource.cpp
@@ -34,12 +34,9 @@
 #include "core/dom/Document.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/imports/HTMLImportsController.h"
-#include "platform/weborigin/SecurityPolicy.h"
 
 namespace blink {
 
-using namespace HTMLNames;
-
 LinkResource::LinkResource(HTMLLinkElement* owner) : owner_(owner) {}
 
 LinkResource::~LinkResource() {}
@@ -57,29 +54,19 @@
   return imports_controller->Master()->GetFrame();
 }
 
+Document& LinkResource::GetDocument() {
+  return owner_->GetDocument();
+}
+
+AtomicString LinkResource::GetCharset() const {
+  AtomicString charset = owner_->getAttribute(HTMLNames::charsetAttr);
+  if (charset.IsEmpty() && owner_->GetDocument().GetFrame())
+    charset = owner_->GetDocument().characterSet();
+  return charset;
+}
+
 DEFINE_TRACE(LinkResource) {
   visitor->Trace(owner_);
 }
 
-LinkRequestBuilder::LinkRequestBuilder(HTMLLinkElement* owner)
-    : owner_(owner), url_(owner->GetNonEmptyURLAttribute(hrefAttr)) {
-  charset_ = owner_->getAttribute(charsetAttr);
-  if (charset_.IsEmpty() && owner_->GetDocument().GetFrame())
-    charset_ = owner_->GetDocument().characterSet();
-}
-
-FetchParameters LinkRequestBuilder::Build(bool low_priority) const {
-  ResourceRequest resource_request(owner_->GetDocument().CompleteURL(url_));
-  ReferrerPolicy referrer_policy = owner_->GetReferrerPolicy();
-  if (referrer_policy != kReferrerPolicyDefault) {
-    resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
-        referrer_policy, url_, owner_->GetDocument().OutgoingReferrer()));
-  }
-  FetchParameters params(resource_request, owner_->localName(), charset_);
-  if (low_priority)
-    params.SetDefer(FetchParameters::kLazyLoad);
-  params.SetContentSecurityPolicyNonce(owner_->nonce());
-  return params;
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/LinkResource.h b/third_party/WebKit/Source/core/html/LinkResource.h
index a00bba2a..2974add 100644
--- a/third_party/WebKit/Source/core/html/LinkResource.h
+++ b/third_party/WebKit/Source/core/html/LinkResource.h
@@ -33,12 +33,10 @@
 
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
-#include "platform/loader/fetch/FetchParameters.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
+class Document;
 class HTMLLinkElement;
 class LocalFrame;
 
@@ -64,26 +62,14 @@
   DECLARE_VIRTUAL_TRACE();
 
  protected:
+  void Load();
+
+  Document& GetDocument();
+  AtomicString GetCharset() const;
+
   Member<HTMLLinkElement> owner_;
 };
 
-class LinkRequestBuilder {
-  STACK_ALLOCATED();
-
- public:
-  explicit LinkRequestBuilder(HTMLLinkElement* owner);
-
-  bool IsValid() const { return !url_.IsEmpty() && url_.IsValid(); }
-  const KURL& Url() const { return url_; }
-  const AtomicString& Charset() const { return charset_; }
-  FetchParameters Build(bool low_priority) const;
-
- private:
-  Member<HTMLLinkElement> owner_;
-  KURL url_;
-  AtomicString charset_;
-};
-
 }  // namespace blink
 
 #endif  // LinkResource_h
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.cpp b/third_party/WebKit/Source/core/html/LinkStyle.cpp
index 7da5475..0dd8b39 100644
--- a/third_party/WebKit/Source/core/html/LinkStyle.cpp
+++ b/third_party/WebKit/Source/core/html/LinkStyle.cpp
@@ -4,7 +4,9 @@
 
 #include "core/html/LinkStyle.h"
 
+#include "core/HTMLNames.h"
 #include "core/css/StyleSheetContents.h"
+#include "core/dom/Document.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/LocalFrameClient.h"
 #include "core/frame/SubresourceIntegrity.h"
@@ -13,8 +15,14 @@
 #include "core/html/HTMLLinkElement.h"
 #include "core/loader/resource/CSSStyleSheetResource.h"
 #include "platform/Histogram.h"
+#include "platform/loader/fetch/FetchParameters.h"
+#include "platform/loader/fetch/ResourceRequest.h"
 #include "platform/network/mime/ContentType.h"
 #include "platform/network/mime/MIMETypeRegistry.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/ReferrerPolicy.h"
+#include "platform/weborigin/SecurityPolicy.h"
+#include "platform/wtf/text/AtomicString.h"
 
 namespace blink {
 
@@ -41,10 +49,6 @@
 
 LinkStyle::~LinkStyle() {}
 
-Document& LinkStyle::GetDocument() {
-  return owner_->GetDocument();
-}
-
 enum StyleSheetCacheStatus {
   kStyleSheetNewEntry,
   kStyleSheetInDiskCache,
@@ -72,7 +76,7 @@
   // See the comment in PendingScript.cpp about why this check is necessary
   // here, instead of in the resource fetcher. https://crbug.com/500701.
   if (!cached_style_sheet->ErrorOccurred() &&
-      !owner_->FastGetAttribute(HTMLNames::integrityAttr).IsEmpty() &&
+      !owner_->FastGetAttribute(integrityAttr).IsEmpty() &&
       !cached_style_sheet->IntegrityMetadata().IsEmpty()) {
     ResourceIntegrityDisposition disposition =
         cached_style_sheet->IntegrityDisposition();
@@ -90,9 +94,8 @@
         size = cached_style_sheet->ResourceBuffer()->size();
       }
       check_result = SubresourceIntegrity::CheckSubresourceIntegrity(
-          owner_->FastGetAttribute(HTMLNames::integrityAttr),
-          owner_->GetDocument(), data, size, KURL(base_url, href),
-          *cached_style_sheet);
+          owner_->FastGetAttribute(integrityAttr), GetDocument(), data, size,
+          KURL(base_url, href), *cached_style_sheet);
       disposition = check_result ? ResourceIntegrityDisposition::kPassed
                                  : ResourceIntegrityDisposition::kFailed;
 
@@ -111,7 +114,7 @@
   }
 
   CSSParserContext* parser_context = CSSParserContext::Create(
-      owner_->GetDocument(), base_url, referrer_policy, charset);
+      GetDocument(), base_url, referrer_policy, charset);
 
   if (StyleSheetContents* restored_sheet =
           const_cast<CSSStyleSheetResource*>(cached_style_sheet)
@@ -146,7 +149,7 @@
   SetCrossOriginStylesheetStatus(sheet_.Get());
 
   style_sheet->ParseAuthorStyleSheet(cached_style_sheet,
-                                     owner_->GetDocument().GetSecurityOrigin());
+                                     GetDocument().GetSecurityOrigin());
 
   loading_ = false;
   style_sheet->NotifyLoadedSheet(cached_style_sheet);
@@ -203,7 +206,7 @@
 
   if (pending_sheet_type_ == kNonBlocking)
     return;
-  owner_->GetDocument().GetStyleEngine().AddPendingSheet(style_engine_context_);
+  GetDocument().GetStyleEngine().AddPendingSheet(style_engine_context_);
 }
 
 void LinkStyle::RemovePendingSheet() {
@@ -215,13 +218,12 @@
     return;
   if (type == kNonBlocking) {
     // Tell StyleEngine to re-compute styleSheets of this m_owner's treescope.
-    owner_->GetDocument().GetStyleEngine().ModifiedStyleSheetCandidateNode(
-        *owner_);
+    GetDocument().GetStyleEngine().ModifiedStyleSheetCandidateNode(*owner_);
     return;
   }
 
-  owner_->GetDocument().GetStyleEngine().RemovePendingSheet(
-      *owner_, style_engine_context_);
+  GetDocument().GetStyleEngine().RemovePendingSheet(*owner_,
+                                                    style_engine_context_);
 }
 
 void LinkStyle::SetDisabledState(bool disabled) {
@@ -270,19 +272,19 @@
     // Record the security origin the CORS access check succeeded at, if cross
     // origin.  Only origins that are script accessible to it may access the
     // stylesheet's rules.
-    sheet->SetAllowRuleAccessFromOrigin(
-        owner_->GetDocument().GetSecurityOrigin());
+    sheet->SetAllowRuleAccessFromOrigin(GetDocument().GetSecurityOrigin());
   }
   fetch_following_cors_ = false;
 }
 
 // TODO(yoav): move that logic to LinkLoader
 LinkStyle::LoadReturnValue LinkStyle::LoadStylesheetIfNeeded(
-    const LinkRequestBuilder& builder,
+    const KURL& url,
+    const AtomicString& charset,
     const String& type) {
   if (disabled_state_ == kDisabled || !owner_->RelAttribute().IsStyleSheet() ||
       !StyleSheetTypeIsSupported(type) || !ShouldLoadResource() ||
-      !builder.Url().IsValid())
+      !url.IsValid())
     return kNotNeeded;
 
   if (GetResource()) {
@@ -316,20 +318,32 @@
                   owner_->IsCreatedByParser();
   AddPendingSheet(blocking ? kBlocking : kNonBlocking);
 
+  ResourceRequest resource_request(GetDocument().CompleteURL(url));
+  ReferrerPolicy referrer_policy = owner_->GetReferrerPolicy();
+  if (referrer_policy != kReferrerPolicyDefault) {
+    resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
+        referrer_policy, url, GetDocument().OutgoingReferrer()));
+  }
+
+  FetchParameters params(resource_request, owner_->localName(), charset);
+
   // Load stylesheets that are not needed for the layout immediately with low
   // priority.  When the link element is created by scripts, load the
   // stylesheets asynchronously but in high priority.
-  bool low_priority = !media_query_matches || owner_->IsAlternate();
-  FetchParameters params = builder.Build(low_priority);
-  CrossOriginAttributeValue cross_origin = GetCrossOriginAttributeValue(
-      owner_->FastGetAttribute(HTMLNames::crossoriginAttr));
+  if (!media_query_matches || owner_->IsAlternate())
+    params.SetDefer(FetchParameters::kLazyLoad);
+
+  params.SetContentSecurityPolicyNonce(owner_->nonce());
+
+  CrossOriginAttributeValue cross_origin =
+      GetCrossOriginAttributeValue(owner_->FastGetAttribute(crossoriginAttr));
   if (cross_origin != kCrossOriginAttributeNotSet) {
     params.SetCrossOriginAccessControl(GetDocument().GetSecurityOrigin(),
                                        cross_origin);
     SetFetchFollowingCORS();
   }
 
-  String integrity_attr = owner_->FastGetAttribute(HTMLNames::integrityAttr);
+  String integrity_attr = owner_->FastGetAttribute(integrityAttr);
   if (!integrity_attr.IsEmpty()) {
     IntegrityMetadataSet metadata_set;
     SubresourceIntegrity::ParseIntegrityAttribute(integrity_attr, metadata_set);
@@ -356,16 +370,17 @@
   String type = owner_->TypeValue().DeprecatedLower();
   String as = owner_->AsValue().DeprecatedLower();
   String media = owner_->Media().DeprecatedLower();
-  LinkRequestBuilder builder(owner_);
 
-  if (owner_->RelAttribute().GetIconType() != kInvalidIcon &&
-      builder.Url().IsValid() && !builder.Url().IsEmpty()) {
+  const KURL& href = owner_->GetNonEmptyURLAttribute(hrefAttr);
+  AtomicString charset = GetCharset();
+
+  if (owner_->RelAttribute().GetIconType() != kInvalidIcon && href.IsValid() &&
+      !href.IsEmpty()) {
     if (!owner_->ShouldLoadLink())
       return;
-    if (!GetDocument().GetSecurityOrigin()->CanDisplay(builder.Url()))
+    if (!GetDocument().GetSecurityOrigin()->CanDisplay(href))
       return;
-    if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource(
-            builder.Url()))
+    if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource(href))
       return;
     if (GetDocument().GetFrame() &&
         GetDocument().GetFrame()->Loader().Client()) {
@@ -374,11 +389,10 @@
     }
   }
 
-  if (!owner_->LoadLink(type, as, media, owner_->GetReferrerPolicy(),
-                        builder.Url()))
+  if (!owner_->LoadLink(type, as, media, owner_->GetReferrerPolicy(), href))
     return;
 
-  if (LoadStylesheetIfNeeded(builder, type) == kNotNeeded && sheet_) {
+  if (LoadStylesheetIfNeeded(href, charset, type) == kNotNeeded && sheet_) {
     // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
     ClearSheet();
     GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.h b/third_party/WebKit/Source/core/html/LinkStyle.h
index 2b6b282..32680b6 100644
--- a/third_party/WebKit/Source/core/html/LinkStyle.h
+++ b/third_party/WebKit/Source/core/html/LinkStyle.h
@@ -11,11 +11,13 @@
 #include "core/loader/resource/StyleSheetResource.h"
 #include "core/loader/resource/StyleSheetResourceClient.h"
 #include "platform/loader/fetch/ResourceOwner.h"
+#include "platform/wtf/Forward.h"
 
 namespace blink {
 
 class HTMLLinkElement;
-//
+class KURL;
+
 // LinkStyle handles dynamically change-able link resources, which is
 // typically @rel="stylesheet".
 //
@@ -23,7 +25,6 @@
 // types might better be handled by a separate class, but dynamically
 // changing @rel makes it harder to move such a design so we are
 // sticking current way so far.
-//
 class LinkStyle final : public LinkResource, ResourceOwner<StyleSheetResource> {
   USING_GARBAGE_COLLECTED_MIXIN(LinkStyle);
 
@@ -66,7 +67,8 @@
                         const CSSStyleSheetResource*) override;
   String DebugName() const override { return "LinkStyle"; }
   enum LoadReturnValue { kLoaded, kNotNeeded, kBail };
-  LoadReturnValue LoadStylesheetIfNeeded(const LinkRequestBuilder&,
+  LoadReturnValue LoadStylesheetIfNeeded(const KURL&,
+                                         const AtomicString&,
                                          const String& type);
 
   enum DisabledState { kUnset, kEnabledViaScript, kDisabled };
@@ -76,7 +78,6 @@
   void ClearSheet();
   void AddPendingSheet(PendingSheetType);
   void RemovePendingSheet();
-  Document& GetDocument();
 
   void SetCrossOriginStylesheetStatus(CSSStyleSheet*);
   void SetFetchFollowingCORS() {
diff --git a/third_party/WebKit/Source/core/html/imports/LinkImport.cpp b/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
index 55433387..eefcb06 100644
--- a/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
+++ b/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
@@ -30,12 +30,19 @@
 
 #include "core/html/imports/LinkImport.h"
 
+#include "core/HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/imports/HTMLImportChild.h"
 #include "core/html/imports/HTMLImportLoader.h"
 #include "core/html/imports/HTMLImportTreeRoot.h"
 #include "core/html/imports/HTMLImportsController.h"
+#include "platform/loader/fetch/FetchParameters.h"
+#include "platform/loader/fetch/ResourceRequest.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/ReferrerPolicy.h"
+#include "platform/weborigin/SecurityPolicy.h"
+#include "platform/wtf/text/AtomicString.h"
 
 namespace blink {
 
@@ -64,24 +71,35 @@
   if (!ShouldLoadResource())
     return;
 
-  if (!owner_->GetDocument().ImportsController()) {
+  if (!GetDocument().ImportsController()) {
     // The document should be the master.
-    Document& master = owner_->GetDocument();
+    Document& master = GetDocument();
     DCHECK(master.GetFrame());
     master.CreateImportsController();
   }
 
-  LinkRequestBuilder builder(owner_);
-  if (!builder.IsValid()) {
+  KURL url = owner_->GetNonEmptyURLAttribute(HTMLNames::hrefAttr);
+  if (url.IsEmpty() || !url.IsValid()) {
     DidFinish();
     return;
   }
 
-  HTMLImportsController* controller = owner_->GetDocument().ImportsController();
-  HTMLImportLoader* loader = owner_->GetDocument().ImportLoader();
+  HTMLImportsController* controller = GetDocument().ImportsController();
+  HTMLImportLoader* loader = GetDocument().ImportLoader();
   HTMLImport* parent = loader ? static_cast<HTMLImport*>(loader->FirstImport())
                               : static_cast<HTMLImport*>(controller->Root());
-  child_ = controller->Load(parent, this, builder.Build(false));
+
+  ResourceRequest resource_request(GetDocument().CompleteURL(url));
+  ReferrerPolicy referrer_policy = owner_->GetReferrerPolicy();
+  if (referrer_policy != kReferrerPolicyDefault) {
+    resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
+        referrer_policy, url, GetDocument().OutgoingReferrer()));
+  }
+
+  FetchParameters params(resource_request, owner_->localName(), GetCharset());
+  params.SetContentSecurityPolicyNonce(owner_->nonce());
+
+  child_ = controller->Load(parent, this, params);
   if (!child_) {
     DidFinish();
     return;
@@ -120,7 +138,7 @@
 
 void LinkImport::OwnerRemoved() {
   if (owner_)
-    owner_->GetDocument().GetStyleEngine().HtmlImportAddedOrRemoved();
+    GetDocument().GetStyleEngine().HtmlImportAddedOrRemoved();
 }
 
 DEFINE_TRACE(LinkImport) {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index dab7c64..eb94152 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1009,10 +1009,11 @@
 }
 
 bool ComputedStyle::HasWillChangeCompositingHint() const {
-  for (size_t i = 0;
-       i < rare_non_inherited_data_->will_change_data_->properties_.size();
+  for (size_t i = 0; i < rare_non_inherited_data_->will_change_data_
+                             ->will_change_properties_.size();
        ++i) {
-    switch (rare_non_inherited_data_->will_change_data_->properties_[i]) {
+    switch (rare_non_inherited_data_->will_change_data_
+                ->will_change_properties_[i]) {
       case CSSPropertyOpacity:
       case CSSPropertyTransform:
       case CSSPropertyAliasWebkitTransform:
@@ -1030,7 +1031,7 @@
 
 bool ComputedStyle::HasWillChangeTransformHint() const {
   for (const auto& property :
-       rare_non_inherited_data_->will_change_data_->properties_) {
+       rare_non_inherited_data_->will_change_data_->will_change_properties_) {
     switch (property) {
       case CSSPropertyTransform:
       case CSSPropertyAliasWebkitTransform:
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 3602e9f..794c07a 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1539,27 +1539,29 @@
 
   // will-change
   const Vector<CSSPropertyID>& WillChangeProperties() const {
-    return rare_non_inherited_data_->will_change_data_->properties_;
+    return rare_non_inherited_data_->will_change_data_->will_change_properties_;
   }
   bool WillChangeContents() const {
-    return rare_non_inherited_data_->will_change_data_->contents_;
+    return rare_non_inherited_data_->will_change_data_->will_change_contents_;
   }
   bool WillChangeScrollPosition() const {
-    return rare_non_inherited_data_->will_change_data_->scroll_position_;
+    return rare_non_inherited_data_->will_change_data_
+        ->will_change_scroll_position_;
   }
   bool SubtreeWillChangeContents() const {
     return SubtreeWillChangeContentsInternal();
   }
   void SetWillChangeProperties(const Vector<CSSPropertyID>& properties) {
-    SET_NESTED_VAR(rare_non_inherited_data_, will_change_data_, properties_,
-                   properties);
+    SET_NESTED_VAR(rare_non_inherited_data_, will_change_data_,
+                   will_change_properties_, properties);
   }
   void SetWillChangeContents(bool b) {
-    SET_NESTED_VAR(rare_non_inherited_data_, will_change_data_, contents_, b);
+    SET_NESTED_VAR(rare_non_inherited_data_, will_change_data_,
+                   will_change_contents_, b);
   }
   void SetWillChangeScrollPosition(bool b) {
     SET_NESTED_VAR(rare_non_inherited_data_, will_change_data_,
-                   scroll_position_, b);
+                   will_change_scroll_position_, b);
   }
   void SetSubtreeWillChangeContents(bool b) {
     SetSubtreeWillChangeContentsInternal(b);
diff --git a/third_party/WebKit/Source/core/style/StyleWillChangeData.cpp b/third_party/WebKit/Source/core/style/StyleWillChangeData.cpp
index 472ced1e..6ec6f29c 100644
--- a/third_party/WebKit/Source/core/style/StyleWillChangeData.cpp
+++ b/third_party/WebKit/Source/core/style/StyleWillChangeData.cpp
@@ -7,12 +7,12 @@
 namespace blink {
 
 StyleWillChangeData::StyleWillChangeData()
-    : contents_(false), scroll_position_(false) {}
+    : will_change_contents_(false), will_change_scroll_position_(false) {}
 
 StyleWillChangeData::StyleWillChangeData(const StyleWillChangeData& o)
     : RefCounted<StyleWillChangeData>(),
-      properties_(o.properties_),
-      contents_(o.contents_),
-      scroll_position_(o.scroll_position_) {}
+      will_change_properties_(o.will_change_properties_),
+      will_change_contents_(o.will_change_contents_),
+      will_change_scroll_position_(o.will_change_scroll_position_) {}
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/style/StyleWillChangeData.h b/third_party/WebKit/Source/core/style/StyleWillChangeData.h
index 5180dfc..a0e9dca0 100644
--- a/third_party/WebKit/Source/core/style/StyleWillChangeData.h
+++ b/third_party/WebKit/Source/core/style/StyleWillChangeData.h
@@ -23,15 +23,16 @@
   }
 
   bool operator==(const StyleWillChangeData& o) const {
-    return properties_ == o.properties_ && contents_ == o.contents_ &&
-           scroll_position_ == o.scroll_position_;
+    return will_change_properties_ == o.will_change_properties_ &&
+           will_change_contents_ == o.will_change_contents_ &&
+           will_change_scroll_position_ == o.will_change_scroll_position_;
   }
 
   bool operator!=(const StyleWillChangeData& o) const { return !(*this == o); }
 
-  Vector<CSSPropertyID> properties_;
-  unsigned contents_ : 1;
-  unsigned scroll_position_ : 1;
+  Vector<CSSPropertyID> will_change_properties_;
+  unsigned will_change_contents_ : 1;
+  unsigned will_change_scroll_position_ : 1;
 
  private:
   StyleWillChangeData();
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 3bb55e1..9ebdafbe 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -1061,12 +1061,12 @@
   return true;
 }
 
-static WTF::Optional<CompositionMarker::Thickness> ThicknessFrom(
+static WTF::Optional<StyleableMarker::Thickness> ThicknessFrom(
     const String& thickness) {
   if (EqualIgnoringASCIICase(thickness, "thin"))
-    return CompositionMarker::Thickness::kThin;
+    return StyleableMarker::Thickness::kThin;
   if (EqualIgnoringASCIICase(thickness, "thick"))
-    return CompositionMarker::Thickness::kThick;
+    return StyleableMarker::Thickness::kThick;
   return WTF::nullopt;
 }
 
@@ -1078,7 +1078,7 @@
   DCHECK(range);
   range->OwnerDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
 
-  WTF::Optional<CompositionMarker::Thickness> thickness =
+  WTF::Optional<StyleableMarker::Thickness> thickness =
       ThicknessFrom(thickness_value);
   if (!thickness) {
     exception_state.ThrowDOMException(
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
index 7298afb..9ee4973 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
@@ -4,7 +4,6 @@
 
 #include "core/testing/NullExecutionContext.h"
 
-#include "core/dom/ExecutionContextTask.h"
 #include "core/events/Event.h"
 #include "core/frame/DOMTimer.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
@@ -29,11 +28,6 @@
       is_secure_context_(true),
       queue_(new NullEventQueue()) {}
 
-void NullExecutionContext::PostTask(TaskType,
-                                    const WebTraceLocation&,
-                                    std::unique_ptr<ExecutionContextTask>,
-                                    const String&) {}
-
 void NullExecutionContext::SetIsSecureContext(bool is_secure_context) {
   is_secure_context_ = is_secure_context;
 }
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.h b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
index fe41a7bc..e37205e 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.h
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
@@ -30,12 +30,6 @@
   void DisableEval(const String&) override {}
   String UserAgent() const override { return String(); }
 
-  void PostTask(
-      TaskType,
-      const WebTraceLocation&,
-      std::unique_ptr<ExecutionContextTask>,
-      const String& task_name_for_instrumentation = g_empty_string) override;
-
   EventTarget* ErrorEventTarget() override { return nullptr; }
   EventQueue* GetEventQueue() const override { return queue_.Get(); }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
index 38529037..bbdfded 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
@@ -5,7 +5,6 @@
 #include "core/workers/WorkerOrWorkletGlobalScope.h"
 
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
-#include "core/dom/ExecutionContextTask.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/frame/Deprecation.h"
 #include "core/inspector/ConsoleMessage.h"
@@ -73,26 +72,6 @@
   script_controller_->DisableEval(error_message);
 }
 
-void WorkerOrWorkletGlobalScope::PostTask(
-    TaskType type,
-    const WebTraceLocation& location,
-    std::unique_ptr<ExecutionContextTask> task,
-    const String& task_name_for_instrumentation) {
-  if (!GetThread())
-    return;
-
-  bool is_instrumented = !task_name_for_instrumentation.IsEmpty();
-  if (is_instrumented) {
-    probe::AsyncTaskScheduled(this, "Worker task", task.get());
-  }
-
-  TaskRunnerHelper::Get(type, this)
-      ->PostTask(location, CrossThreadBind(&WorkerOrWorkletGlobalScope::RunTask,
-                                           WrapCrossThreadWeakPersistent(this),
-                                           WTF::Passed(std::move(task)),
-                                           is_instrumented));
-}
-
 bool WorkerOrWorkletGlobalScope::CanExecuteScripts(
     ReasonForCallingCanExecuteScripts) {
   return !IsJSExecutionForbidden();
@@ -110,12 +89,4 @@
   ExecutionContext::Trace(visitor);
 }
 
-void WorkerOrWorkletGlobalScope::RunTask(
-    std::unique_ptr<ExecutionContextTask> task,
-    bool is_instrumented) {
-  DCHECK(GetThread()->IsCurrentThread());
-  probe::AsyncTask async_task(this, task.get(), nullptr, is_instrumented);
-  task->PerformTask(this);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
index b29ff47..63686cdf 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
@@ -25,11 +25,6 @@
   bool IsWorkerOrWorkletGlobalScope() const final { return true; }
   bool IsJSExecutionForbidden() const final;
   void DisableEval(const String& error_message) final;
-  void PostTask(
-      TaskType,
-      const WebTraceLocation&,
-      std::unique_ptr<ExecutionContextTask>,
-      const String& task_name_for_instrumentation = g_empty_string) final;
   bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) final;
 
   virtual ScriptWrappable* GetScriptWrappable() const = 0;
@@ -71,8 +66,6 @@
   virtual void ReportDeprecation(WebFeature) = 0;
 
  private:
-  void RunTask(std::unique_ptr<ExecutionContextTask>, bool is_instrumented);
-
   CrossThreadPersistent<WorkerClients> worker_clients_;
   Member<WorkerFetchContext> fetch_context_;
   Member<WorkerOrWorkletScriptController> script_controller_;
diff --git a/third_party/WebKit/Source/devtools/front_end/Tests.js b/third_party/WebKit/Source/devtools/front_end/Tests.js
index c09309dc..91d725f 100644
--- a/third_party/WebKit/Source/devtools/front_end/Tests.js
+++ b/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -847,10 +847,10 @@
 
     function onExecutionContexts() {
       var consoleView = Console.ConsoleView.instance();
-      var items = consoleView._consoleContextSelector._items;
+      var selector = consoleView._consoleContextSelector;
       var values = [];
-      for (var i = 0; i < items.length(); ++i)
-        values.push(consoleView._consoleContextSelector._titleFor(items.itemAtIndex(i)));
+      for (var item of selector._items)
+        values.push(selector._titleFor(item));
       test.assertEquals('top', values[0]);
       test.assertEquals('Simple content script', values[1]);
       test.releaseControl();
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleContextSelector.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleContextSelector.js
index 665bdda..77123fc0 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleContextSelector.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleContextSelector.js
@@ -99,7 +99,7 @@
   }
 
   _updateGlasspaneSize() {
-    var maxHeight = this._rowHeight * (Math.min(this._items.length(), 9));
+    var maxHeight = this._rowHeight * (Math.min(this._items.length, 9));
     this._glassPane.setMaxContentSize(new UI.Size(315, maxHeight));
     this._list.viewportResized();
   }
@@ -130,7 +130,7 @@
         var currentExecutionContext = this._list.selectedItem();
         if (!currentExecutionContext)
           break;
-        var nextExecutionContext = this._items.itemAtIndex(this._list.selectedIndex() + 1);
+        var nextExecutionContext = this._items.at(this._list.selectedIndex() + 1);
         if (nextExecutionContext && this._depthFor(currentExecutionContext) < this._depthFor(nextExecutionContext))
           handled = this._list.selectNextItem(false, false);
         break;
@@ -140,9 +140,9 @@
           break;
         var depth = this._depthFor(currentExecutionContext);
         for (var i = this._list.selectedIndex() - 1; i >= 0; i--) {
-          if (this._depthFor(this._items.itemAtIndex(i)) < depth) {
+          if (this._depthFor(this._items.at(i)) < depth) {
             handled = true;
-            this._list.selectItem(this._items.itemAtIndex(i), false);
+            this._list.selectItem(this._items.at(i), false);
             break;
           }
         }
@@ -154,18 +154,18 @@
         handled = this._list.selectItemNextPage(false);
         break;
       case 'Home':
-        for (var i = 0; i < this._items.length(); i++) {
-          if (this.isItemSelectable(this._items.itemAtIndex(i))) {
-            this._list.selectItem(this._items.itemAtIndex(i));
+        for (var i = 0; i < this._items.length; i++) {
+          if (this.isItemSelectable(this._items.at(i))) {
+            this._list.selectItem(this._items.at(i));
             handled = true;
             break;
           }
         }
         break;
       case 'End':
-        for (var i = this._items.length() - 1; i >= 0; i--) {
-          if (this.isItemSelectable(this._items.itemAtIndex(i))) {
-            this._list.selectItem(this._items.itemAtIndex(i));
+        for (var i = this._items.length - 1; i >= 0; i--) {
+          if (this.isItemSelectable(this._items.at(i))) {
+            this._list.selectItem(this._items.at(i));
             handled = true;
             break;
           }
@@ -195,8 +195,8 @@
         if (event.key.length === 1) {
           var selectedIndex = this._list.selectedIndex();
           var letter = event.key.toUpperCase();
-          for (var i = 0; i < this._items.length(); i++) {
-            var context = this._items.itemAtIndex((selectedIndex + i + 1) % this._items.length());
+          for (var i = 0; i < this._items.length; i++) {
+            var context = this._items.at((selectedIndex + i + 1) % this._items.length);
             if (this._titleFor(context).toUpperCase().startsWith(letter)) {
               this._list.selectItem(context);
               break;
@@ -299,7 +299,7 @@
     if (!executionContext.target().hasJSCapability())
       return;
 
-    this._items.insertItemWithComparator(executionContext, executionContext.runtimeModel.executionContextComparator());
+    this._items.insertWithComparator(executionContext, executionContext.runtimeModel.executionContextComparator());
 
     if (executionContext === UI.context.flavor(SDK.ExecutionContext))
       this._updateSelectionTitle();
@@ -320,7 +320,7 @@
    */
   _onExecutionContextChanged(event) {
     var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    if (this._items.indexOfItem(executionContext) === -1)
+    if (this._items.indexOf(executionContext) === -1)
       return;
     this._executionContextDestroyed(executionContext);
     this._executionContextCreated(executionContext);
@@ -331,10 +331,11 @@
    * @param {!SDK.ExecutionContext} executionContext
    */
   _executionContextDestroyed(executionContext) {
-    if (this._items.indexOfItem(executionContext) === -1)
+    var index = this._items.indexOf(executionContext);
+    if (index === -1)
       return;
     this._disposeExecutionContextBadge(executionContext);
-    this._items.removeItem(executionContext);
+    this._items.remove(index);
     this._updateGlasspaneSize();
   }
 
@@ -352,7 +353,7 @@
    */
   _executionContextChangedExternally(event) {
     var executionContext = /** @type {?SDK.ExecutionContext} */ (event.data);
-    if (!executionContext || this._items.indexOfItem(executionContext) === -1)
+    if (!executionContext || this._items.indexOf(executionContext) === -1)
       return;
     this._list.selectItem(executionContext);
     this._updateSelectedContext();
@@ -386,11 +387,7 @@
    * @return {boolean}
    */
   _hasTopContext() {
-    for (var i = 0; i < this._items.length(); i++) {
-      if (this._isTopContext(this._items.itemAtIndex(i)))
-        return true;
-    }
-    return false;
+    return this._items.some(executionContext => this._isTopContext(executionContext));
   }
 
   /**
@@ -406,9 +403,9 @@
    * @param {!SDK.RuntimeModel} runtimeModel
    */
   modelRemoved(runtimeModel) {
-    for (var i = 0; i < this._items.length(); i++) {
-      if (this._items.itemAtIndex(i).runtimeModel === runtimeModel)
-        this._executionContextDestroyed(this._items.itemAtIndex(i));
+    for (var i = 0; i < this._items.length; i++) {
+      if (this._items.at(i).runtimeModel === runtimeModel)
+        this._executionContextDestroyed(this._items.at(i));
     }
   }
 
@@ -523,8 +520,7 @@
    */
   _callFrameSelectedInModel(event) {
     var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    for (var i = 0; i < this._items.length(); i++) {
-      var executionContext = this._items.itemAtIndex(i);
+    for (var executionContext of this._items) {
       if (executionContext.debuggerModel === debuggerModel) {
         this._disposeExecutionContextBadge(executionContext);
         this._list.refreshItem(executionContext);
@@ -537,8 +533,7 @@
    */
   _frameNavigated(event) {
     var frameId = event.data.id;
-    for (var i = 0; i < this._items.length(); i++) {
-      var executionContext = this._items.itemAtIndex(i);
+    for (var executionContext of this._items) {
       if (frameId === executionContext.frameId) {
         this._disposeExecutionContextBadge(executionContext);
         this._list.refreshItem(executionContext);
diff --git a/third_party/WebKit/Source/devtools/front_end/quick_open/FilteredListWidget.js b/third_party/WebKit/Source/devtools/front_end/quick_open/FilteredListWidget.js
index e7deb52..2a0fd62 100644
--- a/third_party/WebKit/Source/devtools/front_end/quick_open/FilteredListWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/quick_open/FilteredListWidget.js
@@ -152,7 +152,7 @@
   }
 
   _attachProvider() {
-    this._items.replaceAllItems([]);
+    this._items.replaceAll([]);
     this._list.invalidateItemHeight();
     if (this._provider) {
       this._provider.setRefreshCallback(this._itemsLoaded.bind(this, this._provider));
@@ -435,7 +435,7 @@
     filteredItems = [].concat(bestItems, overflowItems, filteredItems);
     this._updateNotFoundMessage(!!filteredItems.length);
     var oldHeight = this._list.element.offsetHeight;
-    this._items.replaceAllItems(filteredItems);
+    this._items.replaceAll(filteredItems);
     if (filteredItems.length)
       this._list.selectItem(filteredItems[0]);
     if (this._list.element.offsetHeight !== oldHeight)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
index 34c729a..ef7578b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
@@ -70,7 +70,7 @@
     if (!details) {
       this._notPausedMessageElement.classList.remove('hidden');
       this._blackboxedMessageElement.classList.add('hidden');
-      this._items.replaceAllItems([]);
+      this._items.replaceAll([]);
       this._debuggerModel = null;
       UI.context.setFlavor(SDK.DebuggerModel.CallFrame, null);
       return;
@@ -141,7 +141,7 @@
       this._blackboxedMessageElement.classList.remove('hidden');
     }
 
-    this._items.replaceAllItems(items);
+    this._items.replaceAll(items);
     this._list.selectNextItem(true /* canWrap */, false /* center */);
   }
 
@@ -359,8 +359,7 @@
 
   _copyStackTrace() {
     var text = [];
-    for (var i = 0; i < this._items.length(); i++) {
-      var item = this._items.itemAtIndex(i);
+    for (var item of this._items) {
       if (item.promiseCreationFrame)
         continue;
       var itemText = this._itemTitle(item);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
index f193a3f..0abf5a4 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
@@ -108,7 +108,7 @@
    * @param {!SDK.DebuggerModel} debuggerModel
    */
   modelAdded(debuggerModel) {
-    this._items.pushItem(debuggerModel);
+    this._items.insert(this._items.length, debuggerModel);
     var currentTarget = UI.context.flavor(SDK.Target);
     if (currentTarget === debuggerModel.target())
       this._list.selectItem(debuggerModel);
@@ -119,7 +119,7 @@
    * @param {!SDK.DebuggerModel} debuggerModel
    */
   modelRemoved(debuggerModel) {
-    this._items.removeItem(debuggerModel);
+    this._items.remove(this._items.indexOf(debuggerModel));
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineHistoryManager.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineHistoryManager.js
index fd45eb8..059d2a92 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineHistoryManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineHistoryManager.js
@@ -280,7 +280,7 @@
     var listModel = new UI.ListModel();
     this._listControl = new UI.ListControl(listModel, this, UI.ListMode.NonViewport);
     this._listControl.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    listModel.replaceAllItems(models);
+    listModel.replaceAll(models);
 
     contentElement.appendChild(this._listControl.element);
     contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js b/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
index 39be6fd..8299d30 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
@@ -95,7 +95,7 @@
    */
   setModel(model) {
     this._itemToElement.clear();
-    var length = this._model.length();
+    var length = this._model.length;
     this._model.removeEventListener(UI.ListModel.Events.ItemsReplaced, this._replacedItemsInRange, this);
     this._model = model;
     this._model.addEventListener(UI.ListModel.Events.ItemsReplaced, this._replacedItemsInRange, this);
@@ -118,7 +118,7 @@
 
     if (this._selectedIndex >= to) {
       this._selectedIndex += data.inserted - (to - from);
-      this._selectedItem = this._model.itemAtIndex(this._selectedIndex);
+      this._selectedItem = this._model.at(this._selectedIndex);
     } else if (this._selectedIndex >= from) {
       var index = this._findFirstSelectable(from + data.inserted, +1, false);
       if (index === -1)
@@ -131,7 +131,7 @@
    * @param {T} item
    */
   refreshItem(item) {
-    var index = this._model.indexOfItem(item);
+    var index = this._model.indexOf(item);
     if (index === -1) {
       console.error('Item to refresh is not present');
       return;
@@ -166,9 +166,9 @@
       return;
     }
     this._fixedHeight = 0;
-    if (this._model.length()) {
+    if (this._model.length) {
       this._itemToElement.clear();
-      this._invalidate(0, this._model.length(), this._model.length());
+      this._invalidate(0, this._model.length, this._model.length);
     }
   }
 
@@ -183,7 +183,7 @@
       return null;
     var element = /** @type {!Element} */ (node);
     var index = this._model.findIndex(item => this._itemToElement.get(item) === element);
-    return index !== -1 ? this._model.itemAtIndex(index) : null;
+    return index !== -1 ? this._model.at(index) : null;
   }
 
   /**
@@ -191,7 +191,7 @@
    * @param {boolean=} center
    */
   scrollItemIntoView(item, center) {
-    var index = this._model.indexOfItem(item);
+    var index = this._model.indexOf(item);
     if (index === -1) {
       console.error('Attempt to scroll onto missing item');
       return;
@@ -221,7 +221,7 @@
   selectItem(item, center, dontScroll) {
     var index = -1;
     if (item !== null) {
-      index = this._model.indexOfItem(item);
+      index = this._model.indexOf(item);
       if (index === -1) {
         console.error('Attempt to select missing item');
         return;
@@ -245,7 +245,7 @@
   selectPreviousItem(canWrap, center) {
     if (this._selectedIndex === -1 && !canWrap)
       return false;
-    var index = this._selectedIndex === -1 ? this._model.length() - 1 : this._selectedIndex - 1;
+    var index = this._selectedIndex === -1 ? this._model.length - 1 : this._selectedIndex - 1;
     index = this._findFirstSelectable(index, -1, !!canWrap);
     if (index !== -1) {
       this._scrollIntoView(index, center);
@@ -280,7 +280,7 @@
   selectItemPreviousPage(center) {
     if (this._mode === UI.ListMode.NonViewport)
       return false;
-    var index = this._selectedIndex === -1 ? this._model.length() - 1 : this._selectedIndex;
+    var index = this._selectedIndex === -1 ? this._model.length - 1 : this._selectedIndex;
     index = this._findPageSelectable(index, -1);
     if (index !== -1) {
       this._scrollIntoView(index, center);
@@ -369,7 +369,7 @@
    * @return {number}
    */
   _totalHeight() {
-    return this._offsetAtIndex(this._model.length());
+    return this._offsetAtIndex(this._model.length);
   }
 
   /**
@@ -379,15 +379,15 @@
   _indexAtOffset(offset) {
     if (this._mode === UI.ListMode.NonViewport)
       throw 'There should be no offset conversions in non-viewport mode';
-    if (!this._model.length() || offset < 0)
+    if (!this._model.length || offset < 0)
       return 0;
     if (this._mode === UI.ListMode.VariousHeightItems) {
       return Math.min(
-          this._model.length() - 1, this._variableOffsets.lowerBound(offset, undefined, 0, this._model.length()));
+          this._model.length - 1, this._variableOffsets.lowerBound(offset, undefined, 0, this._model.length));
     }
     if (!this._fixedHeight)
       this._measureHeight();
-    return Math.min(this._model.length() - 1, Math.floor(offset / this._fixedHeight));
+    return Math.min(this._model.length - 1, Math.floor(offset / this._fixedHeight));
   }
 
   /**
@@ -395,7 +395,7 @@
    * @return {!Element}
    */
   _elementAtIndex(index) {
-    var item = this._model.itemAtIndex(index);
+    var item = this._model.at(index);
     var element = this._itemToElement.get(item);
     if (!element) {
       element = this._delegate.createElementForItem(item);
@@ -411,7 +411,7 @@
   _offsetAtIndex(index) {
     if (this._mode === UI.ListMode.NonViewport)
       throw 'There should be no offset conversions in non-viewport mode';
-    if (!this._model.length())
+    if (!this._model.length)
       return 0;
     if (this._mode === UI.ListMode.VariousHeightItems)
       return this._variableOffsets[index];
@@ -421,7 +421,7 @@
   }
 
   _measureHeight() {
-    this._fixedHeight = this._delegate.heightForItem(this._model.itemAtIndex(0));
+    this._fixedHeight = this._delegate.heightForItem(this._model.at(0));
     if (!this._fixedHeight)
       this._fixedHeight = UI.measurePreferredSize(this._elementAtIndex(0), this.element).height;
   }
@@ -437,7 +437,7 @@
     if (oldElement === undefined)
       oldElement = this._itemToElement.get(oldItem) || null;
     this._selectedIndex = index;
-    this._selectedItem = index === -1 ? null : this._model.itemAtIndex(index);
+    this._selectedItem = index === -1 ? null : this._model.at(index);
     var newItem = this._selectedItem;
     var newElement = this._selectedIndex !== -1 ? this._elementAtIndex(index) : null;
     this._delegate.selectedItemChanged(oldItem, newItem, /** @type {?Element} */ (oldElement), newElement);
@@ -450,7 +450,7 @@
    * @return {number}
    */
   _findFirstSelectable(index, direction, canWrap) {
-    var length = this._model.length();
+    var length = this._model.length;
     if (!length)
       return -1;
     for (var step = 0; step <= length; step++) {
@@ -459,7 +459,7 @@
           return -1;
         index = (index + length) % length;
       }
-      if (this._delegate.isItemSelectable(this._model.itemAtIndex(index)))
+      if (this._delegate.isItemSelectable(this._model.at(index)))
         return index;
       index += direction;
     }
@@ -476,8 +476,8 @@
     var startOffset = this._offsetAtIndex(index);
     // Compensate for zoom rounding errors with -1.
     var viewportHeight = this.element.offsetHeight - 1;
-    while (index >= 0 && index < this._model.length()) {
-      if (this._delegate.isItemSelectable(this._model.itemAtIndex(index))) {
+    while (index >= 0 && index < this._model.length) {
+      if (this._delegate.isItemSelectable(this._model.at(index))) {
         if (Math.abs(this._offsetAtIndex(index) - startOffset) >= viewportHeight)
           return index;
         lastSelectable = index;
@@ -515,11 +515,9 @@
     }
 
     if (this._mode === UI.ListMode.VariousHeightItems) {
-      this._reallocateVariableOffsets(this._model.length() + 1, from + 1);
-      for (var i = from + 1; i <= this._model.length(); i++) {
-        this._variableOffsets[i] =
-            this._variableOffsets[i - 1] + this._delegate.heightForItem(this._model.itemAtIndex(i - 1));
-      }
+      this._reallocateVariableOffsets(this._model.length + 1, from + 1);
+      for (var i = from + 1; i <= this._model.length; i++)
+        this._variableOffsets[i] = this._variableOffsets[i - 1] + this._delegate.heightForItem(this._model.at(i - 1));
     }
 
     var viewportHeight = this.element.offsetHeight;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ListModel.js b/third_party/WebKit/Source/devtools/front_end/ui/ListModel.js
index 5ebd819..4de3d846f 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ListModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ListModel.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 /**
+ * @implements {Iterable<T>}
  * @template T
  */
 UI.ListModel = class extends Common.Object {
@@ -15,9 +16,16 @@
   }
 
   /**
+   * @return {!Iterator<T>}
+   */
+  [Symbol.iterator]() {
+    return this._items[Symbol.iterator]();
+  }
+
+  /**
    * @return {number}
    */
-  length() {
+  get length() {
     return this._items.length;
   }
 
@@ -25,84 +33,32 @@
    * @param {number} index
    * @return {T}
    */
-  itemAtIndex(index) {
+  at(index) {
     return this._items[index];
   }
 
   /**
-   * @param {T} item
+   * @param {function(T):boolean} callback
+   * @return {boolean}
    */
-  pushItem(item) {
-    this.replaceItemsInRange(this._items.length, this._items.length, [item]);
+  every(callback) {
+    return this._items.every(callback);
   }
 
   /**
-   * @return {T}
+   * @param {function(T):boolean} callback
+   * @return {!Array<T>}
    */
-  popItem() {
-    return this.removeItemAtIndex(this._items.length - 1);
+  filter(callback) {
+    return this._items.filter(callback);
   }
 
   /**
-   * @param {number} index
-   * @param {T} item
+   * @param {function(T):boolean} callback
+   * @return {T|undefined}
    */
-  insertItemAtIndex(index, item) {
-    this.replaceItemsInRange(index, index, [item]);
-  }
-
-  /**
-   * @param {T} item
-   * @param {function(T, T):number} comparator
-   */
-  insertItemWithComparator(item, comparator) {
-    var index = this._items.lowerBound(item, comparator);
-    this.insertItemAtIndex(index, item);
-  }
-
-  /**
-   * @param {T} item
-   * @return {number}
-   */
-  indexOfItem(item) {
-    return this._items.indexOf(item);
-  }
-
-  /**
-   * @param {number} index
-   * @return {T}
-   */
-  removeItemAtIndex(index) {
-    var result = this._items[index];
-    this.replaceItemsInRange(index, index + 1, []);
-    return result;
-  }
-
-  /**
-   * @param {T} item
-   */
-  removeItem(item) {
-    var index = this._items.indexOf(item);
-    if (index === -1) {
-      console.error('Attempt to remove non-existing item');
-      return;
-    }
-    this.removeItemAtIndex(index);
-  }
-
-  /**
-   * @param {!Array<T>} items
-   */
-  replaceAllItems(items) {
-    this.replaceItemsInRange(0, this._items.length, items);
-  }
-
-  /**
-   * @param {number} index
-   * @param {T} item
-   */
-  replaceItemAtIndex(index, item) {
-    this.replaceItemsInRange(index, index + 1, [item]);
+  find(callback) {
+    return this._items.find(callback);
   }
 
   /**
@@ -114,11 +70,69 @@
   }
 
   /**
+   * @param {T} value
+   * @param {number=} fromIndex
+   * @return {number}
+   */
+  indexOf(value, fromIndex) {
+    return this._items.indexOf(value, fromIndex);
+  }
+
+  /**
+   * @param {number} index
+   * @param {T} value
+   */
+  insert(index, value) {
+    this._items.splice(index, 0, value);
+    this._replaced(index, [], 1);
+  }
+
+  /**
+   * @param {T} value
+   * @param {function(T, T):number} comparator
+   */
+  insertWithComparator(value, comparator) {
+    this.insert(this._items.lowerBound(value, comparator), value);
+  }
+
+  /**
+   * @param {string=} separator
+   * @return {string}
+   */
+  join(separator) {
+    return this._items.join(separator);
+  }
+
+  /**
+   * @param {number} index
+   * @return {T}
+   */
+  remove(index) {
+    var result = this._items[index];
+    this._items.splice(index, 1);
+    this._replaced(index, [result], 0);
+    return result;
+  }
+
+  /**
+   * @param {number} index
+   * @param {T} value
+   * @return {T}
+   */
+  replace(index, value) {
+    var oldValue = this._items[index];
+    this._items[index] = value;
+    this._replaced(index, [oldValue], 1);
+    return oldValue;
+  }
+
+  /**
    * @param {number} from
    * @param {number} to
    * @param {!Array<T>} items
+   * @return {!Array<T>} removed
    */
-  replaceItemsInRange(from, to, items) {
+  replaceRange(from, to, items) {
     var removed;
     if (items.length < 10000) {
       removed = this._items.splice(from, to - from, ...items);
@@ -129,8 +143,46 @@
       var after = this._items.slice(to);
       this._items = [].concat(before, items, after);
     }
+    this._replaced(from, removed, items.length);
+    return removed;
+  }
+
+  /**
+   * @param {!Array<T>} items
+   * @return {!Array<T>}
+   */
+  replaceAll(items) {
+    var oldItems = this._items.slice();
+    this._items = items;
+    this._replaced(0, oldItems, items.length);
+    return oldItems;
+  }
+
+  /**
+   * @param {number=} from
+   * @param {number=} to
+   * @return {!Array<T>}
+   */
+  slice(from, to) {
+    return this._items.slice(from, to);
+  }
+
+  /**
+   * @param {function(T):boolean} callback
+   * @return {boolean}
+   */
+  some(callback) {
+    return this._items.some(callback);
+  }
+
+  /**
+   * @param {number} index
+   * @param {!Array<T>} removed
+   * @param {number} inserted
+   */
+  _replaced(index, removed, inserted) {
     this.dispatchEventToListeners(
-        UI.ListModel.Events.ItemsReplaced, {index: from, removed: removed, inserted: items.length});
+        UI.ListModel.Events.ItemsReplaced, {index: index, removed: removed, inserted: inserted});
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
index 7c3badc..619905c 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
@@ -318,7 +318,7 @@
       this._updateMaxSize(completions);
       this._glassPane.setContentAnchorBox(anchorBox);
       this._list.invalidateItemHeight();
-      this._items.replaceAllItems(completions);
+      this._items.replaceAll(completions);
 
       if (selectHighestPriority) {
         var highestPriorityItem = completions[0];
diff --git a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
index 816d418..32741c13 100644
--- a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
+++ b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
@@ -77,13 +77,15 @@
 // Rounds |downlink_mbps| to the nearest 25 kbps as per the NetInfo spec. The
 // returned value is in Mbps.
 double RoundMbps(const Optional<double>& downlink_mbps) {
+  double downlink_kbps = 0;
   if (!downlink_mbps.has_value()) {
     // Throughput is unavailable. So, return the fastest value.
-    return std::numeric_limits<double>::infinity();
+    downlink_kbps = (std::numeric_limits<double>::max());
+  } else {
+    downlink_kbps = downlink_mbps.value() * 1000;
   }
 
-  DCHECK_LE(0, downlink_mbps.value());
-  double downlink_kbps = downlink_mbps.value() * 1000;
+  DCHECK_LE(0, downlink_kbps);
   double downlink_kbps_rounded = std::round(downlink_kbps / 25) * 25;
   return downlink_kbps_rounded / 1000;
 }
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
index 7e6ca63..7d69328 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -26,7 +26,6 @@
 
 #include "platform/graphics/BitmapImage.h"
 
-#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/Timer.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/BitmapImageMetrics.h"
@@ -46,16 +45,6 @@
 
 namespace blink {
 
-namespace {
-
-ColorBehavior DefaultColorBehavior() {
-  if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
-    return ColorBehavior::Tag();
-  return ColorBehavior::TransformToGlobalTarget();
-}
-
-}  // namespace
-
 PassRefPtr<BitmapImage> BitmapImage::CreateWithOrientationForTesting(
     const SkBitmap& bitmap,
     ImageOrientation orientation) {
@@ -159,8 +148,7 @@
 
   // We are caching frame snapshots.  This is OK even for partially decoded
   // frames, as they are cleared by dataChanged() when new data arrives.
-  sk_sp<SkImage> image =
-      source_.CreateFrameAtIndex(index, DefaultColorBehavior());
+  sk_sp<SkImage> image = source_.CreateFrameAtIndex(index);
   cached_frame_ = image;
   cached_frame_index_ = index;
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageSource.cpp b/third_party/WebKit/Source/platform/graphics/ImageSource.cpp
index ccac03fb..fa265c7 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageSource.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageSource.cpp
@@ -27,14 +27,14 @@
 
 #include "platform/graphics/ImageSource.h"
 
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/DeferredImageDecoder.h"
 #include "platform/image-decoders/ImageDecoder.h"
 #include "third_party/skia/include/core/SkImage.h"
 
 namespace blink {
 
-ImageSource::ImageSource()
-    : decoder_color_behavior_(ColorBehavior::TransformToGlobalTarget()) {}
+ImageSource::ImageSource() {}
 
 ImageSource::~ImageSource() {}
 
@@ -56,9 +56,13 @@
     return true;
   }
 
+  ColorBehavior color_behavior =
+      RuntimeEnabledFeatures::colorCorrectRenderingEnabled()
+          ? ColorBehavior::Tag()
+          : ColorBehavior::TransformToGlobalTarget();
   decoder_ = DeferredImageDecoder::Create(data, all_data_received,
                                           ImageDecoder::kAlphaPremultiplied,
-                                          decoder_color_behavior_);
+                                          color_behavior);
 
   // Insufficient data is not a failure.
   return decoder_ || !ImageDecoder::HasSufficientDataToSniffImageType(*data);
@@ -107,22 +111,10 @@
   return decoder_ ? decoder_->FrameCount() : 0;
 }
 
-sk_sp<SkImage> ImageSource::CreateFrameAtIndex(
-    size_t index,
-    const ColorBehavior& color_behavior) {
+sk_sp<SkImage> ImageSource::CreateFrameAtIndex(size_t index) {
   if (!decoder_)
     return nullptr;
 
-  if (color_behavior != decoder_color_behavior_) {
-    decoder_ = DeferredImageDecoder::Create(Data(), all_data_received_,
-                                            ImageDecoder::kAlphaPremultiplied,
-                                            color_behavior);
-    decoder_color_behavior_ = color_behavior;
-    // The data has already been validated, so changing the color behavior
-    // should always result in a valid decoder.
-    DCHECK(decoder_);
-  }
-
   return decoder_->CreateFrameAtIndex(index);
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageSource.h b/third_party/WebKit/Source/platform/graphics/ImageSource.h
index f530753b..a6a9eac2 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageSource.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageSource.h
@@ -91,7 +91,7 @@
   size_t FrameCount() const;
 
   // Attempts to create the requested frame.
-  sk_sp<SkImage> CreateFrameAtIndex(size_t, const ColorBehavior&);
+  sk_sp<SkImage> CreateFrameAtIndex(size_t);
 
   float FrameDurationAtIndex(size_t) const;
   bool FrameHasAlphaAtIndex(
@@ -106,7 +106,6 @@
 
  private:
   std::unique_ptr<DeferredImageDecoder> decoder_;
-  ColorBehavior decoder_color_behavior_;
   bool all_data_received_ = false;
 };
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 3c69344..e5c5bcc 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -7471,6 +7471,9 @@
 </histogram>
 
 <histogram name="Chrome.UmaPageloadCounter" enum="BooleanHit">
+  <obsolete>
+    Deprecated 6/2017. No longer tracked.
+  </obsolete>
   <owner>asvitkine@chromium.org</owner>
   <summary>
     Records when a page load happens, based on the same logic as the PageLoad
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index d92b240..9c2332d3 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -246,8 +246,8 @@
     return CreateStorySetFromPath(path, SKIPPED_FILE)
 
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class BlinkPerfBindings(_BlinkPerfBenchmark):
   tag = 'bindings'
@@ -288,8 +288,8 @@
         '--enable-color-correct-rendering',
     ])
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class BlinkPerfDOM(_BlinkPerfBenchmark):
   tag = 'dom'
@@ -324,8 +324,8 @@
 
 
 @benchmark.Disabled('win')  # crbug.com/488493
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class BlinkPerfParser(_BlinkPerfBenchmark):
   tag = 'parser'
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py
index 551db0c..c34714a 100644
--- a/tools/perf/benchmarks/dromaeo.py
+++ b/tools/perf/benchmarks/dromaeo.py
@@ -126,8 +126,8 @@
     return ps
 
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class DromaeoDomCoreAttr(_DromaeoBenchmark):
   """Dromaeo DOMCore attr JavaScript benchmark.
@@ -147,8 +147,8 @@
         pass # http://dromaeo.com?dom-attr not disabled.
     return StoryExpectations()
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class DromaeoDomCoreModify(_DromaeoBenchmark):
   """Dromaeo DOMCore modify JavaScript benchmark.
@@ -169,8 +169,8 @@
     return StoryExpectations()
 
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class DromaeoDomCoreQuery(_DromaeoBenchmark):
   """Dromaeo DOMCore query JavaScript benchmark.
@@ -191,8 +191,8 @@
     return StoryExpectations()
 
 
-@benchmark.Owner(emails=['yukishiino@chromium.org',
-                         'bashi@chromium.org',
+@benchmark.Owner(emails=['jbroman@chromium.org',
+                         'yukishiino@chromium.org',
                          'haraken@chromium.org'])
 class DromaeoDomCoreTraverse(_DromaeoBenchmark):
   """Dromaeo DOMCore traverse JavaScript benchmark.
diff --git a/ui/arc/notification/arc_notification_content_view.cc b/ui/arc/notification/arc_notification_content_view.cc
index a8c8254..f7b2355 100644
--- a/ui/arc/notification/arc_notification_content_view.cc
+++ b/ui/arc/notification/arc_notification_content_view.cc
@@ -10,7 +10,6 @@
 #include "components/exo/notification_surface.h"
 #include "components/exo/surface.h"
 #include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_node_data.h"
 #include "ui/arc/notification/arc_notification_view.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -253,7 +252,6 @@
   // Create a layer as an anchor to insert surface copy during a slide.
   SetPaintToLayer();
   UpdatePreferredSize();
-  UpdateAccessibleName();
 }
 
 ArcNotificationContentView::~ArcNotificationContentView() {
@@ -487,14 +485,6 @@
   return false;
 }
 
-void ArcNotificationContentView::UpdateAccessibleName() {
-  // Don't update the accessible name when we are about to be destroyed.
-  if (!item_)
-    return;
-
-  accessible_name_ = item_->GetAccessibleName();
-}
-
 void ArcNotificationContentView::ViewHierarchyChanged(
     const views::View::ViewHierarchyChangedDetails& details) {
   views::Widget* widget = GetWidget();
@@ -635,12 +625,6 @@
   return false;
 }
 
-void ArcNotificationContentView::GetAccessibleNodeData(
-    ui::AXNodeData* node_data) {
-  node_data->role = ui::AX_ROLE_BUTTON;
-  node_data->SetName(accessible_name_);
-}
-
 void ArcNotificationContentView::ButtonPressed(views::Button* sender,
                                                const ui::Event& event) {
   if (item_ && !item_->GetPinned() && sender == close_button_.get()) {
@@ -677,7 +661,6 @@
 }
 
 void ArcNotificationContentView::OnItemUpdated() {
-  UpdateAccessibleName();
   UpdatePinnedState();
   UpdateSnapshot();
   if (ShouldUpdateControlButtonsColor())
diff --git a/ui/arc/notification/arc_notification_content_view.h b/ui/arc/notification/arc_notification_content_view.h
index d51adddf..16ff30c 100644
--- a/ui/arc/notification/arc_notification_content_view.h
+++ b/ui/arc/notification/arc_notification_content_view.h
@@ -86,7 +86,6 @@
   void ActivateToast();
   void StartControlButtonsColorAnimation();
   bool ShouldUpdateControlButtonsColor() const;
-  void UpdateAccessibleName();
 
   // views::NativeViewHost
   void ViewHierarchyChanged(
@@ -99,7 +98,6 @@
   void OnBlur() override;
   views::FocusTraversable* GetFocusTraversable() override;
   bool HandleAccessibleAction(const ui::AXActionData& action) override;
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   // views::ButtonListener
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
@@ -155,8 +153,6 @@
 
   std::unique_ptr<gfx::LinearAnimation> control_button_color_animation_;
 
-  base::string16 accessible_name_;
-
   DISALLOW_COPY_AND_ASSIGN(ArcNotificationContentView);
 };
 
diff --git a/ui/arc/notification/arc_notification_item.h b/ui/arc/notification/arc_notification_item.h
index 4024b3d..154772c 100644
--- a/ui/arc/notification/arc_notification_item.h
+++ b/ui/arc/notification/arc_notification_item.h
@@ -77,8 +77,6 @@
   virtual const std::string& GetNotificationKey() const = 0;
   // Returns the notification ID used in the Chrome message center.
   virtual const std::string& GetNotificationId() const = 0;
-  // Returnes the accessible name of the notification.
-  virtual const base::string16& GetAccessibleName() const = 0;
 };
 
 }  // namespace arc
diff --git a/ui/arc/notification/arc_notification_item_impl.cc b/ui/arc/notification/arc_notification_item_impl.cc
index b0edb550..1ee85a86f 100644
--- a/ui/arc/notification/arc_notification_item_impl.cc
+++ b/ui/arc/notification/arc_notification_item_impl.cc
@@ -77,14 +77,8 @@
   rich_data.priority = ConvertAndroidPriority(data->priority);
   if (data->small_icon)
     rich_data.small_image = gfx::Image::CreateFrom1xBitmap(*data->small_icon);
-  if (data->accessible_name.has_value()) {
-    accessible_name_ = base::UTF8ToUTF16(*data->accessible_name);
-  } else {
-    accessible_name_ = base::JoinString(
-        {base::UTF8ToUTF16(data->title), base::UTF8ToUTF16(data->message)},
-        base::ASCIIToUTF16("\n"));
-  }
-  rich_data.accessible_name = accessible_name_;
+  if (data->accessible_name.has_value())
+    rich_data.accessible_name = base::UTF8ToUTF16(*data->accessible_name);
 
   message_center::NotifierId notifier_id(
       message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId);
@@ -201,8 +195,4 @@
   return notification_id_;
 }
 
-const base::string16& ArcNotificationItemImpl::GetAccessibleName() const {
-  return accessible_name_;
-}
-
 }  // namespace arc
diff --git a/ui/arc/notification/arc_notification_item_impl.h b/ui/arc/notification/arc_notification_item_impl.h
index 9f69b57..2fbf3147 100644
--- a/ui/arc/notification/arc_notification_item_impl.h
+++ b/ui/arc/notification/arc_notification_item_impl.h
@@ -48,7 +48,6 @@
   mojom::ArcNotificationShownContents GetShownContents() const override;
   const std::string& GetNotificationKey() const override;
   const std::string& GetNotificationId() const override;
-  const base::string16& GetAccessibleName() const override;
 
  private:
   // Return true if it's on the thread this instance is created on.
@@ -69,8 +68,6 @@
       mojom::ArcNotificationShownContents::CONTENTS_SHOWN;
   // The reference counter of the window.
   int window_ref_count_ = 0;
-  // The accessible name of the latest notification.
-  base::string16 accessible_name_;
 
   base::ObserverList<Observer> observers_;
 
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index 713c796..5ca9cfc7 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -40,6 +40,7 @@
       "wayland_xkb_keyboard_layout_engine.cc",
       "wayland_xkb_keyboard_layout_engine.h",
     ]
+    configs += [ "//ui/events/ozone:xkbcommon" ]
   }
 
   deps = [