Fix out-of-bounds clicks for Android
The android action runner did not properly check for click coordinates
outside of the browser window bounds. Add an explicit adjustment for the
element bounds to trim any area that exists outside the bounds of the
browser.
Change-Id: I1c4c4236266226aaec46f1f22c9c4f9e1137f840
Reviewed-on: https://chromium-review.googlesource.com/c/crossbench/+/6233248
Commit-Queue: Kameron Lutes <kalutes@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
diff --git a/crossbench/action_runner/android_input_action_runner.py b/crossbench/action_runner/android_input_action_runner.py
index dc39c83..82d2f8a 100644
--- a/crossbench/action_runner/android_input_action_runner.py
+++ b/crossbench/action_runner/android_input_action_runner.py
@@ -61,6 +61,7 @@
if element_rect:
self._element_rect = (element_rect * self.actual_pixel_ratio).shift_by(
self._chrome_window)
+ self._element_rect = self.chrome_window.intersection(self._element_rect)
@property
def chrome_window(self) -> DisplayRectangle:
diff --git a/crossbench/action_runner/display_rectangle.py b/crossbench/action_runner/display_rectangle.py
index 2808a93..0a65de6 100644
--- a/crossbench/action_runner/display_rectangle.py
+++ b/crossbench/action_runner/display_rectangle.py
@@ -53,6 +53,25 @@
return (scrollable_top, scrollable_bottom,
scrollable_bottom - scrollable_top)
+ # Returns the sub-rectangle of |other| that exists within |self|.
+ # |other| must have the same reference origin as |self|.
+ def intersection(self, other: Self) -> DisplayRectangle:
+ assert other.left < self.right and other.top < self.bottom, (
+ "Rectangles do not intersect. Maybe you need to add 'scroll_into_view'."
+ )
+
+ width: int = other.width
+
+ if other.right > self.right:
+ width = self.right - other.left
+
+ height: int = other.height
+
+ if other.bottom > self.bottom:
+ height = self.bottom - other.top
+
+ return DisplayRectangle(other.origin, width, height)
+
@property
def left(self) -> int:
return self.origin.x
diff --git a/tests/crossbench/benchmarks/loading/action_runner/test_display_rectangle.py b/tests/crossbench/benchmarks/loading/action_runner/test_display_rectangle.py
index 0234914..892dc35 100644
--- a/tests/crossbench/benchmarks/loading/action_runner/test_display_rectangle.py
+++ b/tests/crossbench/benchmarks/loading/action_runner/test_display_rectangle.py
@@ -63,6 +63,28 @@
self.assertEqual(scrollable_bottom, 740)
self.assertEqual(max_scroll_distance, 480)
+ def test_display_rectangle_intersection_not_contained(self):
+ rect = DisplayRectangle(Point(0, 0), 10, 10)
+
+ with self.assertRaises(AssertionError):
+ rect.intersection(DisplayRectangle(Point(11, 11), 10, 10))
+
+ def test_display_rectangle_intersection_fully_contained(self):
+ big_rect = DisplayRectangle(Point(10, 10), 10, 10)
+
+ small_rect = DisplayRectangle(Point(11, 11), 1, 1)
+
+ self.assertEqual(small_rect, big_rect.intersection(small_rect))
+
+ def test_display_rectangle_intersection_partial(self):
+ big_rect = DisplayRectangle(Point(10, 10), 10, 10)
+
+ small_rect = DisplayRectangle(Point(15, 15), 10, 10)
+
+ self.assertEqual(
+ DisplayRectangle(Point(15, 15), 5, 5),
+ big_rect.intersection(small_rect))
+
if __name__ == "__main__":
test_helper.run_pytest(__file__)