diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index b737eadc8666..5e95d3a8245a 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -283644,6 +283644,11 @@ {} ] ], + "webdriver/tests/actions/support/mouse.py": [ + [ + {} + ] + ], "webdriver/tests/actions/support/refine.py": [ [ {} @@ -373653,6 +373658,12 @@ {} ] ], + "webdriver/tests/actions/mouse_dblclick.py": [ + [ + "/webdriver/tests/actions/mouse_dblclick.py", + {} + ] + ], "webdriver/tests/actions/sequence.py": [ [ "/webdriver/tests/actions/sequence.py", @@ -576431,15 +576442,19 @@ "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": [ @@ -576454,6 +576469,10 @@ "528ab8473914c14f9671d89b8a888d30162714ec", "support" ], + "webdriver/tests/actions/support/mouse.py": [ + "0a6fca5e3fe20db114dbee1dd9d290ec343f6f9c", + "support" + ], "webdriver/tests/actions/support/refine.py": [ "0d244bffe67ef57be68aad99f1cbc7440ff80e27", "support" @@ -576479,7 +576498,7 @@ "wdspec" ], "webdriver/tests/cookies/add_cookie.py": [ - "7cf4fecd0e9a10bbdbbc120c94e7a298efef943a", + "c58e50480aa3189bd4f1c52050cff6fcfcdf8d8b", "wdspec" ], "webdriver/tests/cookies/delete_cookie.py": [ @@ -576487,7 +576506,7 @@ "wdspec" ], "webdriver/tests/cookies/get_named_cookie.py": [ - "9455d1504590154ad2a540f102455baff602aefb", + "12e1f83275fbfe6926380b267689fbfa55d6b93a", "wdspec" ], "webdriver/tests/document_handling/page_source.py": [ diff --git a/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py b/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py index 73de161119d8..2b7eb64fa54a 100644 --- a/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py +++ b/testing/web-platform/tests/webdriver/tests/actions/modifier_click.py @@ -6,30 +6,55 @@ 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"}, @@ -46,29 +71,48 @@ def test_modifier_click(session, 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 diff --git a/testing/web-platform/tests/webdriver/tests/actions/mouse.py b/testing/web-platform/tests/webdriver/tests/actions/mouse.py index 07f7809e918f..95d284c4b72b 100644 --- a/testing/web-platform/tests/webdriver/tests/actions/mouse.py +++ b/testing/web-platform/tests/webdriver/tests/actions/mouse.py @@ -1,7 +1,8 @@ import pytest -from tests.support.inline import inline +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.support.wait import wait @@ -10,13 +11,6 @@ def link_doc(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 @@ -33,11 +27,8 @@ def test_click_at_coordinates(session, test_actions_page, mouse_chain): .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 @@ -89,7 +80,7 @@ def test_click_element_center(session, test_actions_page, mouse_chain): 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) @@ -112,7 +103,12 @@ def test_click_navigation(session, url): @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) diff --git a/testing/web-platform/tests/webdriver/tests/actions/mouse_dblclick.py b/testing/web-platform/tests/webdriver/tests/actions/mouse_dblclick.py new file mode 100644 index 000000000000..f73f780a7a7e --- /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:] diff --git a/testing/web-platform/tests/webdriver/tests/actions/sequence.py b/testing/web-platform/tests/webdriver/tests/actions/sequence.py index 3092034c46fd..426dbe82f48e 100644 --- a/testing/web-platform/tests/webdriver/tests/actions/sequence.py +++ b/testing/web-platform/tests/webdriver/tests/actions/sequence.py @@ -37,45 +37,3 @@ 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 diff --git a/testing/web-platform/tests/webdriver/tests/actions/support/mouse.py b/testing/web-platform/tests/webdriver/tests/actions/support/mouse.py new file mode 100644 index 000000000000..63a771d9487a --- /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"], + }