Bug 1385476 - Test double-click, starting a new session for each test; r?ato draft
authorMaja Frydrychowicz <mjzffr@gmail.com>
Tue, 28 Nov 2017 11:41:28 -0500
changeset 705212 bb08fd1d94faf2e48bf53d153b06ac219ead8302
parent 705211 76b2e3fbd3cbb86f062227c779e88e61fefc1d8d
child 742297 15f22ba0633a1860fce072edd38cdacea17514d5
push id91400
push userbmo:mjzffr@gmail.com
push dateWed, 29 Nov 2017 16:45:18 +0000
reviewersato
bugs1385476, 1421323
milestone59.0a1
Bug 1385476 - Test double-click, starting a new session for each test; r?ato This is a modification of the tests proposed by our contributor, muthuraj90ec. The changes that allow Marionette to synthesize dblclick events cause consecutive modifier click tests to interfere with each other by generating extra dblclick events, so the need a new session per test as well I have removed some incorrect tests for ctrl+click, but I will add them back in Bug 1421323. MozReview-Commit-ID: 8t3wpF3CFUK
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webdriver/tests/actions/modifier_click.py
testing/web-platform/tests/webdriver/tests/actions/mouse.py
testing/web-platform/tests/webdriver/tests/actions/mouse_dblclick.py
testing/web-platform/tests/webdriver/tests/actions/sequence.py
testing/web-platform/tests/webdriver/tests/actions/support/mouse.py
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -283639,16 +283639,21 @@
      {}
     ]
    ],
    "webdriver/tests/actions/support/keys.py": [
     [
      {}
     ]
    ],
+   "webdriver/tests/actions/support/mouse.py": [
+    [
+     {}
+    ]
+   ],
    "webdriver/tests/actions/support/refine.py": [
     [
      {}
     ]
    ],
    "webdriver/tests/actions/support/test_actions_wdspec.html": [
     [
      {}
@@ -373648,16 +373653,22 @@
     ]
    ],
    "webdriver/tests/actions/mouse.py": [
     [
      "/webdriver/tests/actions/mouse.py",
      {}
     ]
    ],
+   "webdriver/tests/actions/mouse_dblclick.py": [
+    [
+     "/webdriver/tests/actions/mouse_dblclick.py",
+     {}
+    ]
+   ],
    "webdriver/tests/actions/sequence.py": [
     [
      "/webdriver/tests/actions/sequence.py",
      {
       "timeout": "long"
      }
     ]
    ],
@@ -576426,39 +576437,47 @@
    "d589b53f0096893600e696b43ec19ca84e5ee2ab",
    "wdspec"
   ],
   "webdriver/tests/actions/key_shortcuts.py": [
    "dbe27dd0b1625169fc8cc2055f8fb49d5a4a78d2",
    "wdspec"
   ],
   "webdriver/tests/actions/modifier_click.py": [
-   "2ec22f44973e6da3b9506ad7cc9fd0949f3ef8b5",
+   "be31579cae0cb3dd26a913ce0d966be72fd79495",
    "wdspec"
   ],
   "webdriver/tests/actions/mouse.py": [
-   "c3cf09eaad1f24b2946c0ef865b10c5ac2e52700",
+   "0af689cee458ed260b2b9cc6f3231c314a3a6638",
+   "wdspec"
+  ],
+  "webdriver/tests/actions/mouse_dblclick.py": [
+   "61bab159bf1ccc7d44e4034a3e67d60b13fc1607",
    "wdspec"
   ],
   "webdriver/tests/actions/sequence.py": [
-   "8c948c12cea1e2e8f2de845555817910904f757a",
+   "d43caf0f8607a76c3baed7806664b686bde21fda",
    "wdspec"
   ],
   "webdriver/tests/actions/special_keys.py": [
    "64eb2401664b71d68f7b53e236a947eec6d651cc",
    "wdspec"
   ],
   "webdriver/tests/actions/support/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/actions/support/keys.py": [
    "528ab8473914c14f9671d89b8a888d30162714ec",
    "support"
   ],
+  "webdriver/tests/actions/support/mouse.py": [
+   "0a6fca5e3fe20db114dbee1dd9d290ec343f6f9c",
+   "support"
+  ],
   "webdriver/tests/actions/support/refine.py": [
    "0d244bffe67ef57be68aad99f1cbc7440ff80e27",
    "support"
   ],
   "webdriver/tests/actions/support/test_actions_wdspec.html": [
    "95203777fcc012ab64465287737a89a4ba2c31dc",
    "support"
   ],
@@ -576474,25 +576493,25 @@
    "7912e2f7ebdffe2598eb3b9a20f4fc7fce22447e",
    "wdspec"
   ],
   "webdriver/tests/contexts/resizing_and_positioning.py": [
    "479379109115668183643e8a050396219332887d",
    "wdspec"
   ],
   "webdriver/tests/cookies/add_cookie.py": [
-   "7cf4fecd0e9a10bbdbbc120c94e7a298efef943a",
+   "c58e50480aa3189bd4f1c52050cff6fcfcdf8d8b",
    "wdspec"
   ],
   "webdriver/tests/cookies/delete_cookie.py": [
    "451cef1c071f67bc2bc1666a906b4c289b700d22",
    "wdspec"
   ],
   "webdriver/tests/cookies/get_named_cookie.py": [
-   "9455d1504590154ad2a540f102455baff602aefb",
+   "12e1f83275fbfe6926380b267689fbfa55d6b93a",
    "wdspec"
   ],
   "webdriver/tests/document_handling/page_source.py": [
    "5dddfce0a5e43f02b8a050afda8c9a07c43cf797",
    "wdspec"
   ],
   "webdriver/tests/element_click/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
--- a/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py
+++ b/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py
@@ -1,74 +1,118 @@
 # META: timeout=long
 
 import pytest
 
 from tests.actions.support.refine import filter_dict, get_events
 from tests.actions.support.keys import Keys
 
 
+# Using local fixtures because we want to start a new session between
+# each test, otherwise the clicks in each test interfere with each other.
+@pytest.fixture(autouse=True)
+def release_actions(mod_click_session, request):
+    request.addfinalizer(mod_click_session.actions.release)
+
+
+@pytest.fixture
+def mod_click_session(new_session, url, add_browser_capabilites):
+    _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({})}})
+    session.url = url("/webdriver/tests/actions/support/test_actions_wdspec.html")
+
+    return session
+
+
+@pytest.fixture
+def key_chain(mod_click_session):
+    return mod_click_session.actions.sequence("key", "keyboard_id")
+
+
+@pytest.fixture
+def mouse_chain(mod_click_session):
+    return mod_click_session.actions.sequence(
+        "pointer",
+        "pointer_id",
+        {"pointerType": "mouse"})
+
+
 @pytest.mark.parametrize("modifier, prop", [
-    (Keys.CONTROL, "ctrlKey"),
-    (Keys.ALT, "altKey"),
-    (Keys.META, "metaKey"),
-    (Keys.SHIFT, "shiftKey"),
-    (Keys.R_CONTROL, "ctrlKey"),
-    (Keys.R_ALT, "altKey"),
-    (Keys.R_META, "metaKey"),
-    (Keys.R_SHIFT, "shiftKey"),
+   (Keys.ALT, "altKey"),
+   (Keys.R_ALT, "altKey"),
+   (Keys.META, "metaKey"),
+   (Keys.R_META, "metaKey"),
+   (Keys.SHIFT, "shiftKey"),
+   (Keys.R_SHIFT, "shiftKey"),
 ])
-def test_modifier_click(session,
-                       test_actions_page,
+def test_modifier_click(mod_click_session,
                        key_chain,
                        mouse_chain,
                        modifier,
                        prop):
     key_chain \
-        .pause(0) \
+        .pause(200) \
         .key_down(modifier) \
         .pause(200) \
         .key_up(modifier)
-    outer = session.find.css("#outer", all=False)
+    outer = mod_click_session.find.css("#outer", all=False)
     mouse_chain.click(element=outer)
-    session.actions.perform([key_chain.dict, mouse_chain.dict])
+    mod_click_session.actions.perform([key_chain.dict, mouse_chain.dict])
     expected = [
         {"type": "mousemove"},
         {"type": "mousedown"},
         {"type": "mouseup"},
         {"type": "click"},
     ]
     defaults = {
         "altKey": False,
         "metaKey": False,
         "shiftKey": False,
         "ctrlKey": False
     }
     for e in expected:
         e.update(defaults)
         if e["type"] != "mousemove":
             e[prop] = True
-    filtered_events = [filter_dict(e, expected[0]) for e in get_events(session)]
+    print get_events(mod_click_session)
+    filtered_events = [filter_dict(e, expected[0]) for e in get_events(mod_click_session)]
     assert expected == filtered_events
 
 
-def test_release_control_click(session, key_reporter, key_chain, mouse_chain):
+def test_many_modifiers_click(mod_click_session, key_chain, mouse_chain):
+    outer = mod_click_session.find.css("#outer", all=False)
     key_chain \
         .pause(0) \
-        .key_down(Keys.CONTROL)
+        .key_down(Keys.CONTROL) \
+        .key_down(Keys.SHIFT) \
+        .pause(0) \
+        .key_up(Keys.CONTROL) \
+        .key_up(Keys.SHIFT)
     mouse_chain \
-        .pointer_move(0, 0, origin=key_reporter) \
+        .pointer_move(0, 0, origin=outer) \
+        .pause(0) \
+        .pointer_down() \
+        .pointer_up() \
+        .pause(0) \
+        .pause(0) \
         .pointer_down()
-    session.actions.perform([key_chain.dict, mouse_chain.dict])
-    session.execute_script("""
-        var keyReporter = document.getElementById("keys");
-        ["mousedown", "mouseup"].forEach((e) => {
-            keyReporter.addEventListener(e, recordPointerEvent);
-          });
-        resetEvents();
-    """)
-    session.actions.release()
+    mod_click_session.actions.perform([key_chain.dict, mouse_chain.dict])
     expected = [
+        {"type": "mousemove"},
+        # shift and ctrl presses
+        {"type": "mousedown"},
         {"type": "mouseup"},
-        {"type": "keyup"},
+        {"type": "click"},
+        # no modifiers pressed
+        {"type": "mousedown"},
     ]
-    events = [filter_dict(e, expected[0]) for e in get_events(session)]
+    defaults = {
+        "altKey": False,
+        "metaKey": False,
+        "shiftKey": False,
+        "ctrlKey": False
+    }
+    for e in expected:
+        e.update(defaults)
+    for e in expected[1:4]:
+        e["shiftKey"] = True
+        e["ctrlKey"] = True
+    events = [filter_dict(e, expected[0]) for e in get_events(mod_click_session)]
     assert events == expected
--- a/testing/web-platform/tests/webdriver/tests/actions/mouse.py
+++ b/testing/web-platform/tests/webdriver/tests/actions/mouse.py
@@ -1,48 +1,39 @@
 import pytest
 
+from tests.actions.support.mouse import assert_move_to_coordinates, get_center
+from tests.actions.support.refine import get_events, filter_dict
 from tests.support.inline import inline
-from tests.actions.support.refine import get_events, filter_dict
 from tests.support.wait import wait
 
 
 def link_doc(dest):
     content = "<a href=\"{}\" id=\"link\">destination</a>".format(dest)
     return inline(content)
 
 
-def get_center(rect):
-    return {
-        "x": rect["width"] / 2 + rect["x"],
-        "y": rect["height"] / 2 + rect["y"],
-    }
-
-
 # TODO use pytest.approx once we upgrade to pytest > 3.0
 def approx(n, m, tolerance=1):
     return abs(n - m) <= tolerance
 
 
 def test_click_at_coordinates(session, test_actions_page, mouse_chain):
     div_point = {
         "x": 82,
         "y": 187,
     }
     mouse_chain \
         .pointer_move(div_point["x"], div_point["y"], duration=1000) \
         .click() \
         .perform()
     events = get_events(session)
     assert len(events) == 4
+    assert_move_to_coordinates(div_point, "outer", events)
     for e in events:
-        if e["type"] != "mousemove":
-            assert e["pageX"] == div_point["x"]
-            assert e["pageY"] == div_point["y"]
-            assert e["target"] == "outer"
         if e["type"] != "mousedown":
             assert e["buttons"] == 0
         assert e["button"] == 0
     expected = [
         {"type": "mousedown", "buttons": 1},
         {"type": "mouseup",  "buttons": 0},
         {"type": "click", "buttons": 0},
     ]
@@ -84,17 +75,17 @@ def test_click_element_center(session, t
     assert ["mousemove", "mousedown", "mouseup", "click"] == event_types
     for e in events:
         if e["type"] != "mousemove":
             assert approx(e["pageX"], center["x"])
             assert approx(e["pageY"], center["y"])
             assert e["target"] == "outer"
 
 
-def test_click_navigation(session, url):
+def test_click_navigation(session, url, release_actions):
     destination = url("/webdriver/tests/actions/support/test_actions_wdspec.html")
     start = link_doc(destination)
 
     def click(link):
         mouse_chain = session.actions.sequence(
             "pointer", "pointer_id", {"pointerType": "mouse"})
         mouse_chain.click(element=link).perform()
 
@@ -107,17 +98,22 @@ def test_click_navigation(session, url):
     session.url = start
     click(session.find.css("#link", all=False))
     wait(session, lambda s: s.url == destination, error_message)
 
 
 @pytest.mark.parametrize("drag_duration", [0, 300, 800])
 @pytest.mark.parametrize("dx, dy",
     [(20, 0), (0, 15), (10, 15), (-20, 0), (10, -15), (-10, -15)])
-def test_drag_and_drop(session, test_actions_page, mouse_chain, dx, dy, drag_duration):
+def test_drag_and_drop(session,
+                       test_actions_page,
+                       mouse_chain,
+                       dx,
+                       dy,
+                       drag_duration):
     drag_target = session.find.css("#dragTarget", all=False)
     initial_rect = drag_target.rect
     initial_center = get_center(initial_rect)
     # Conclude chain with extra move to allow time for last queued
     # coordinate-update of drag_target and to test that drag_target is "dropped".
     mouse_chain \
         .pointer_move(0, 0, origin=drag_target) \
         .pointer_down() \
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/actions/mouse_dblclick.py
@@ -0,0 +1,108 @@
+import pytest
+
+from tests.actions.support.mouse import assert_move_to_coordinates, get_center
+from tests.actions.support.refine import get_events, filter_dict
+
+
+_DBLCLICK_INTERVAL = 640
+
+
+# Using local fixtures because we want to start a new session between
+# each test, otherwise the clicks in each test interfere with each other.
+@pytest.fixture(autouse=True)
+def release_actions(dblclick_session, request):
+    # release all actions after each test
+    # equivalent to a teardown_function, but with access to session fixture
+    request.addfinalizer(dblclick_session.actions.release)
+
+
+@pytest.fixture
+def dblclick_session(new_session, url, add_browser_capabilites):
+    _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({})}})
+    session.url = url("/webdriver/tests/actions/support/test_actions_wdspec.html")
+
+    return session
+
+
+@pytest.fixture
+def mouse_chain(dblclick_session):
+    return dblclick_session.actions.sequence(
+        "pointer",
+        "pointer_id",
+        {"pointerType": "mouse"})
+
+
+@pytest.mark.parametrize("click_pause", [0, 200])
+def test_dblclick_at_coordinates(dblclick_session, mouse_chain, click_pause):
+    div_point = {
+        "x": 82,
+        "y": 187,
+    }
+    mouse_chain \
+        .pointer_move(div_point["x"], div_point["y"]) \
+        .click() \
+        .pause(click_pause) \
+        .click() \
+        .perform()
+    events = get_events(dblclick_session)
+    assert_move_to_coordinates(div_point, "outer", events)
+    expected = [
+        {"type": "mousedown", "button": 0},
+        {"type": "mouseup", "button": 0},
+        {"type": "click", "button": 0},
+        {"type": "mousedown", "button": 0},
+        {"type": "mouseup", "button": 0},
+        {"type": "click", "button": 0},
+        {"type": "dblclick", "button": 0},
+    ]
+    assert len(events) == 8
+    filtered_events = [filter_dict(e, expected[0]) for e in events]
+    assert expected == filtered_events[1:]
+
+
+def test_dblclick_with_pause_after_second_pointerdown(dblclick_session, mouse_chain):
+        outer = dblclick_session.find.css("#outer", all=False)
+        center = get_center(outer.rect)
+        mouse_chain \
+            .pointer_move(int(center["x"]), int(center["y"])) \
+            .click() \
+            .pointer_down() \
+            .pause(_DBLCLICK_INTERVAL + 10) \
+            .pointer_up() \
+            .perform()
+        events = get_events(dblclick_session)
+        expected = [
+            {"type": "mousedown", "button": 0},
+            {"type": "mouseup", "button": 0},
+            {"type": "click", "button": 0},
+            {"type": "mousedown", "button": 0},
+            {"type": "mouseup", "button": 0},
+            {"type": "click", "button": 0},
+            {"type": "dblclick", "button": 0},
+        ]
+        assert len(events) == 8
+        filtered_events = [filter_dict(e, expected[0]) for e in events]
+        assert expected == filtered_events[1:]
+
+
+def test_no_dblclick(dblclick_session, mouse_chain):
+        outer = dblclick_session.find.css("#outer", all=False)
+        center = get_center(outer.rect)
+        mouse_chain \
+            .pointer_move(int(center["x"]), int(center["y"])) \
+            .click() \
+            .pause(_DBLCLICK_INTERVAL + 10) \
+            .click() \
+            .perform()
+        events = get_events(dblclick_session)
+        expected = [
+            {"type": "mousedown", "button": 0},
+            {"type": "mouseup", "button": 0},
+            {"type": "click", "button": 0},
+            {"type": "mousedown", "button": 0},
+            {"type": "mouseup", "button": 0},
+            {"type": "click", "button": 0},
+        ]
+        assert len(events) == 7
+        filtered_events = [filter_dict(e, expected[0]) for e in events]
+        assert expected == filtered_events[1:]
--- a/testing/web-platform/tests/webdriver/tests/actions/sequence.py
+++ b/testing/web-platform/tests/webdriver/tests/actions/sequence.py
@@ -32,50 +32,8 @@ def test_release_char_sequence_sends_key
         events = [filter_dict(e, expected[0]) for e in events]
     assert events == expected
 
 
 def test_release_no_actions_sends_no_events(session, key_reporter):
     session.actions.release()
     assert len(get_keys(key_reporter)) == 0
     assert len(get_events(session)) == 0
-
-
-def test_many_modifiers_click(session, test_actions_page, key_chain, mouse_chain):
-    outer = session.find.css("#outer", all=False)
-    key_chain \
-        .pause(0) \
-        .key_down(Keys.CONTROL) \
-        .key_down(Keys.SHIFT) \
-        .pause(0) \
-        .key_up(Keys.CONTROL) \
-        .key_up(Keys.SHIFT)
-    mouse_chain \
-        .pointer_move(0, 0, origin=outer) \
-        .pause(0) \
-        .pointer_down() \
-        .pointer_up() \
-        .pause(0) \
-        .pause(0) \
-        .pointer_down()
-    session.actions.perform([key_chain.dict, mouse_chain.dict])
-    expected = [
-        {"type": "mousemove"},
-        # shift and ctrl presses
-        {"type": "mousedown"},
-        {"type": "mouseup"},
-        {"type": "click"},
-        # no modifiers pressed
-        {"type": "mousedown"},
-    ]
-    defaults = {
-        "altKey": False,
-        "metaKey": False,
-        "shiftKey": False,
-        "ctrlKey": False
-    }
-    for e in expected:
-        e.update(defaults)
-    for e in expected[1:4]:
-        e["shiftKey"] = True
-        e["ctrlKey"] = True
-    events = [filter_dict(e, expected[0]) for e in get_events(session)]
-    assert events == expected
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/actions/support/mouse.py
@@ -0,0 +1,13 @@
+def assert_move_to_coordinates(point, target, events):
+    for e in events:
+        if e["type"] != "mousemove":
+            assert e["pageX"] == point["x"]
+            assert e["pageY"] == point["y"]
+            assert e["target"] == target
+
+
+def get_center(rect):
+    return {
+        "x": rect["width"] / 2 + rect["x"],
+        "y": rect["height"] / 2 + rect["y"],
+    }