bug 1499360: webdriver: write in-view centre point tests; r=whimboo
authorAndreas Tolfsen <ato@sny.no>
Mon, 22 Oct 2018 14:21:29 +0000
changeset 442318 d51f52d435daa3f87b398a7ca69879da8306b54a
parent 442317 ae99f2ef94642b9ec79b4eb92a9a27c2fd192d39
child 442319 6afa28099f1ec6f3533128f3f8ac596c622a09a6
push id34904
push userarchaeopteryx@coole-files.de
push dateMon, 22 Oct 2018 17:25:25 +0000
treeherdermozilla-central@af3fd0a2c2e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswhimboo
bugs1499360
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1499360: webdriver: write in-view centre point tests; r=whimboo These tests are not exhaustive, but covers some of the main use cases and known edge cases. Depends on D8880 Differential Revision: https://phabricator.services.mozilla.com/D8881
testing/web-platform/tests/webdriver/tests/element_click/center_point.py
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/element_click/center_point.py
@@ -0,0 +1,87 @@
+import math
+import pytest
+
+from tests.support.asserts import assert_error, assert_success
+from tests.support.inline import inline
+
+
+def element_click(session, element):
+    return session.transport.send(
+        "POST", "session/{session_id}/element/{element_id}/click".format(
+            session_id=session.session_id,
+            element_id=element.id))
+
+
+def center_point(element):
+    """Calculates the in-view center point of a web element."""
+    inner_width, inner_height = element.session.execute_script(
+        "return [window.innerWidth, window.innerHeight]")
+    rect = element.rect
+
+    # calculate the intersection of the rect that is inside the viewport
+    visible = {
+        "left": max(0, min(rect["x"], rect["x"] + rect["width"])),
+        "right": min(inner_width, max(rect["x"], rect["x"] + rect["width"])),
+        "top": max(0, min(rect["y"], rect["y"] + rect["height"])),
+        "bottom": min(inner_height, max(rect["y"], rect["y"] + rect["height"])),
+    }
+
+    # arrive at the centre point of the visible rectangle
+    x = (visible["left"] + visible["right"]) / 2.0
+    y = (visible["top"] + visible["bottom"]) / 2.0
+
+    # convert to CSS pixels, as centre point can be float
+    return (math.floor(x), math.floor(y))
+
+
+def square(size):
+    return inline("""
+        <style>
+        body {{ margin: 0 }}
+
+        div {{
+          background: blue;
+          width: {size}px;
+          height: {size}px;
+        }}
+        </style>
+
+        <div id=target></div>
+
+        <script>
+        window.clicks = [];
+        let div = document.querySelector("div");
+        div.addEventListener("click", ({{clientX, clientY}}) => window.clicks.push([clientX, clientY]));
+        </script>
+        """.format(size=size))
+
+
+def assert_one_click(session):
+    """Asserts there has only been one click, and returns that."""
+    clicks = session.execute_script("return window.clicks")
+    assert len(clicks) == 1
+    return tuple(clicks[0])
+
+
+def test_entirely_in_view(session):
+    session.url = square(444)
+    element = session.find.css("#target", all=False)
+
+    response = element_click(session, element)
+    assert_success(response)
+
+    click_point = assert_one_click(session)
+    assert click_point == (222, 222)
+
+
+@pytest.mark.parametrize("size", range(1, 11))
+def test_css_pixel_rounding(session, size):
+    session.url = square(size)
+    element = session.find.css("#target", all=False)
+    expected_click_point = center_point(element)
+
+    response = element_click(session, element)
+    assert_success(response)
+
+    actual_click_point = assert_one_click(session)
+    assert actual_click_point == expected_click_point