WebDriver based WPT for the 'onmove' handler

This CL defines a new WPT to verify the 'onmove' event handler is
triggered using the Set / Get Window Rect WebDriver command. This way
we ensure that the codepath that emits the event is executed, instead
of using the eventSender to emit a fake event.

Additionally, the CL implements the testdriver-vendor.js support for
these commands.

Bug: 1466855
Change-Id: Iabdd655c06af1eb5979a02a02b3a0fd978b2f6e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5201474
Commit-Queue: Javier Fernandez <jfernandez@igalia.com>
Reviewed-by: Stefan Zager <szager@chromium.org>
Reviewed-by: Sonja Laurila <laurila@google.com>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1251765}
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc
index cbe93bb..e00732c9 100644
--- a/content/web_test/renderer/test_runner.cc
+++ b/content/web_test/renderer/test_runner.cc
@@ -39,6 +39,7 @@
 #include "content/web_test/renderer/web_frame_test_proxy.h"
 #include "gin/arguments.h"
 #include "gin/array_buffer.h"
+#include "gin/dictionary.h"
 #include "gin/handle.h"
 #include "gin/object_template_builder.h"
 #include "gin/wrappable.h"
@@ -345,6 +346,7 @@
   void SetMockScreenOrientation(const std::string& orientation);
   void SetPOSIXLocale(const std::string& locale);
   void SetMainWindowHidden(bool hidden);
+  void SetWindowRect(const gin::Dictionary& rect);
   void SetPermission(const std::string& name,
                      const std::string& value,
                      const std::string& origin,
@@ -758,6 +760,7 @@
       // to change in order to wait for the side effects of calling this.
       .SetMethod("setMainWindowHidden",
                  &TestRunnerBindings::SetMainWindowHidden)
+      .SetMethod("setWindowRect", &TestRunnerBindings::SetWindowRect)
       // Sets the permission's |name| to |value| for a given {origin, embedder}
       // tuple. Sends a message to the WebTestPermissionManager in order for it
       // to update its database.
@@ -1329,6 +1332,27 @@
   frame_->GetWebTestControlHostRemote()->SetMainWindowHidden(hidden);
 }
 
+void TestRunnerBindings::SetWindowRect(const gin::Dictionary& bounds) {
+  if (!frame_) {
+    return;
+  }
+
+  gfx::Rect rect = frame_->GetLocalRootWebFrameWidget()->WindowRect();
+
+  // https://www.w3.org/TR/webdriver2/#set-window-rect
+  int x, y, width, height;
+  if (const_cast<gin::Dictionary&>(bounds).Get("x", &x) &&
+      const_cast<gin::Dictionary&>(bounds).Get("y", &y)) {
+    rect.set_origin({x, y});
+  }
+  if (const_cast<gin::Dictionary&>(bounds).Get("width", &width) &&
+      const_cast<gin::Dictionary&>(bounds).Get("height", &height)) {
+    rect.set_size({width, height});
+  }
+
+  GetWebFrame()->View()->SetWindowRectSynchronouslyForTesting(rect);
+}
+
 void TestRunnerBindings::SetTextDirection(const std::string& direction_name) {
   if (!frame_) {
     return;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index aafdfd4..1b48a5f 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1424,6 +1424,10 @@
 
 void WebViewImpl::SetWindowRectSynchronouslyForTesting(
     const gfx::Rect& new_window_rect) {
+  // We need to call UpdateScreenRects to ensure the 'move' event is enqueued.
+  // TODO(jfernandez): Ideally updating the window rect should do that
+  // automatically.
+  web_widget_->UpdateScreenRects(new_window_rect, new_window_rect);
   web_widget_->SetWindowRectSynchronouslyForTesting(new_window_rect);
 }
 
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove.html b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove-01.tentative.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove.html
rename to third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove-01.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove-02.tentative.html b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove-02.tentative.html
new file mode 100644
index 0000000..a751f39d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/event-handler-onmove-02.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Window Object 'onmove'</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#handler-window-onmove">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<script>
+promise_test((t) => {
+  var expectedRect = {'x': 100, 'y': 200};
+  return new Promise(resolve => {
+      window.addEventListener("move", resolve);
+      test_driver.set_window_rect(expectedRect);
+  }).then(event => {
+      return test_driver.get_window_rect()
+          .then(rect => {
+              assert_equals(rect.x, expectedRect.x, "The window rect X is correct.")
+              assert_equals(rect.y, expectedRect.y, "The window rect Y is correct.")
+          });
+  });
+}, "Window move event");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt
deleted file mode 100644
index 33d33e9..0000000
--- a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] Window Position
-  promise_test: Unhandled rejection with value: object "Error: get_window_rect() is not implemented by testdriver-vendor.js"
-[FAIL] Window Size
-  promise_test: Unhandled rejection with value: object "Error: get_window_rect() is not implemented by testdriver-vendor.js"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt
deleted file mode 100644
index 5b37deb..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/infrastructure/testdriver/set_get_window_rect-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-All subtests passed and are omitted for brevity.
-See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/resources/testdriver-vendor.js b/third_party/blink/web_tests/resources/testdriver-vendor.js
index fbee782..020b89d 100644
--- a/third_party/blink/web_tests/resources/testdriver-vendor.js
+++ b/third_party/blink/web_tests/resources/testdriver-vendor.js
@@ -518,14 +518,20 @@
     }
   };
 
-  window.test_driver_internal.set_window_rect = async () => {
+  window.test_driver_internal.set_window_rect = async (rect, context) => {
     window.testRunner.setMainWindowHidden(false);
     // Wait until the new state is reflected in the document
     while (document.hidden) {
       await new Promise(resolve => setTimeout(resolve, 0));
     }
+    if (rect !== undefined)
+        window.testRunner.setWindowRect(rect);
   };
 
+  window.test_driver_internal.get_window_rect = async function() {
+      return {'x': window.screenX, 'y': window.screenY, 'width': window.outerWidth, 'height': window.outerHeight};
+  }
+
   window.test_driver_internal.get_fedcm_dialog_type = async function() {
     return internals.getFedCmDialogType();
   }