diff --git a/remote/shared/webdriver/Actions.sys.mjs b/remote/shared/webdriver/Actions.sys.mjs index 85177c8fe360..4d8568c58808 100644 --- a/remote/shared/webdriver/Actions.sys.mjs +++ b/remote/shared/webdriver/Actions.sys.mjs @@ -1984,7 +1984,26 @@ class PointerEventData extends InputEventData { this.shiftKey = otherInputSource.shift || this.shiftKey; } const allButtons = Array.from(inputSource.pressed); - this.buttons = allButtons.reduce((a, i) => a + Math.pow(2, i), 0); + this.buttons = allButtons.reduce( + (a, i) => a + PointerEventData.getButtonFlag(i), + 0 + ); + } + + /** + * Return a flag for buttons which indicates a button is pressed. + * + * @param {integer} button - Mouse button number. + */ + static getButtonFlag(button) { + switch (button) { + case 1: + return 4; + case 2: + return 2; + default: + return Math.pow(2, button); + } } } @@ -2093,7 +2112,8 @@ class MultiTouchEventData extends PointerEventData { // anyway. const allButtons = Array.from(inputSource.pressed); this.buttons = - this.buttons | allButtons.reduce((a, i) => a + Math.pow(2, i), 0); + this.buttons | + allButtons.reduce((a, i) => a + PointerEventData.getButtonFlag(i), 0); } } diff --git a/testing/web-platform/meta/pointerevents/pointerevent_attributes_hoverable_rightbutton.html.ini b/testing/web-platform/meta/pointerevents/pointerevent_attributes_hoverable_rightbutton.html.ini index a2bf764cf7e7..d2b894d68eed 100644 --- a/testing/web-platform/meta/pointerevents/pointerevent_attributes_hoverable_rightbutton.html.ini +++ b/testing/web-platform/meta/pointerevents/pointerevent_attributes_hoverable_rightbutton.html.ini @@ -9,47 +9,86 @@ [mouse pointerevent attributes] expected: NOTRUN - [mouse pointerdown's type should be pointerdown] - expected: FAIL - - [mouse pointerup's type should be pointerup] - expected: FAIL - - [mouse pointerout's type should be pointerout] - expected: FAIL - - [mouse pointerenter.toElement value is null] - expected: PRECONDITION_FAILED - - [mouse pointerout.toElement value is null] - expected: PRECONDITION_FAILED - - [mouse pointermove.fromElement value is null] - expected: PRECONDITION_FAILED - - [mouse pointerout.fromElement value is null] - expected: PRECONDITION_FAILED - [mouse pointerover.fromElement value is null] expected: PRECONDITION_FAILED - [mouse pointerenter.fromElement value is null] - expected: PRECONDITION_FAILED - [mouse pointerover.toElement value is null] expected: PRECONDITION_FAILED - [mouse pointerup.toElement value is null] + [mouse pointerenter.fromElement value is null] expected: PRECONDITION_FAILED - [mouse pointerleave.toElement value is null] + [mouse pointerenter.toElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointermove.fromElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointermove.toElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointerdown.fromElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointerdown.toElement value is null] expected: PRECONDITION_FAILED [mouse pointerup.fromElement value is null] expected: PRECONDITION_FAILED + [mouse pointerup.toElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointerout.fromElement value is null] + expected: PRECONDITION_FAILED + + [mouse pointerout.toElement value is null] + expected: PRECONDITION_FAILED + [mouse pointerleave.fromElement value is null] expected: PRECONDITION_FAILED - [mouse pointermove.toElement value is null] + [mouse pointerleave.toElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerover's button is -1 when mouse buttons are in released state.] + expected: FAIL + + [Inner frame mouse pointerover's buttons is 0 when mouse buttons are in released state.] + expected: FAIL + + [Inner frame mouse pointerover.fromElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerover.toElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerenter's button is -1 when mouse buttons are in released state.] + expected: FAIL + + [Inner frame mouse pointerenter's buttons is 0 when mouse buttons are in released state.] + expected: FAIL + + [Inner frame mouse pointerenter.fromElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerenter.toElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointermove's type should be pointermove] + expected: FAIL + + [Inner frame mouse pointerdown.fromElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerdown.toElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerdown's type should be pointerdown] + expected: FAIL + + [Inner frame mouse pointerup.fromElement value is null] + expected: PRECONDITION_FAILED + + [Inner frame mouse pointerup.toElement value is null] expected: PRECONDITION_FAILED diff --git a/testing/web-platform/meta/pointerevents/pointerevent_auxclick_is_a_pointerevent.html.ini b/testing/web-platform/meta/pointerevents/pointerevent_auxclick_is_a_pointerevent.html.ini index b0ddd40a3c57..da0e43e380eb 100644 --- a/testing/web-platform/meta/pointerevents/pointerevent_auxclick_is_a_pointerevent.html.ini +++ b/testing/web-platform/meta/pointerevents/pointerevent_auxclick_is_a_pointerevent.html.ini @@ -7,9 +7,8 @@ [pointerevent_auxclick_is_a_pointerevent.html?mouse] - expected: TIMEOUT [auxclick using mouse is a PointerEvent with correct properties] - expected: TIMEOUT + expected: FAIL [auxclick using mouse is a PointerEvent with correct properties when no other PointerEvent listeners are present] - expected: NOTRUN + expected: FAIL diff --git a/testing/web-platform/meta/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html.ini b/testing/web-platform/meta/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html.ini index 9de934c98e18..16fb6fb6c237 100644 --- a/testing/web-platform/meta/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html.ini +++ b/testing/web-platform/meta/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html.ini @@ -13,9 +13,8 @@ [pointerevent_contextmenu_is_a_pointerevent.html?mouse] - expected: TIMEOUT [contextmenu using mouse is a PointerEvent with correct properties] - expected: TIMEOUT + expected: FAIL [contextmenu using mouse is a PointerEvent with correct properties when no other PointerEvent listeners are present] - expected: NOTRUN + expected: FAIL diff --git a/testing/web-platform/meta/selection/contenteditable/modifying-selection-with-middle-mouse-button.tentative.html.ini b/testing/web-platform/meta/selection/contenteditable/modifying-selection-with-middle-mouse-button.tentative.html.ini index df6ec1fa298d..662eb5d66be8 100644 --- a/testing/web-platform/meta/selection/contenteditable/modifying-selection-with-middle-mouse-button.tentative.html.ini +++ b/testing/web-platform/meta/selection/contenteditable/modifying-selection-with-middle-mouse-button.tentative.html.ini @@ -1,5 +1,3 @@ [modifying-selection-with-middle-mouse-button.tentative.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [Middle click shouldn't move caret in an editable element if the default of pointerdown event is prevented] - expected: FAIL diff --git a/testing/web-platform/tests/webdriver/tests/bidi/input/perform_actions/pointer_mouse.py b/testing/web-platform/tests/webdriver/tests/bidi/input/perform_actions/pointer_mouse.py index 15e0eb798408..f4a4e52dcbf1 100644 --- a/testing/web-platform/tests/webdriver/tests/bidi/input/perform_actions/pointer_mouse.py +++ b/testing/web-platform/tests/webdriver/tests/bidi/input/perform_actions/pointer_mouse.py @@ -80,14 +80,55 @@ async def test_context_menu_at_coordinates( assert len(events) == 4 expected = [ - {"type": "mousedown", "button": 2}, - {"type": "contextmenu", "button": 2}, + {"type": "mousedown", "button": 2, "buttons": 2}, + {"type": "contextmenu", "button": 2, "buttons": 2}, + ] + # Some browsers in some platforms may dispatch `contextmenu` event as a + # a default action of `mouseup`. In the case, `.buttons` of the event + # should be 0. + anotherExpected = [ + {"type": "mousedown", "button": 2, "buttons": 2}, + {"type": "contextmenu", "button": 2, "buttons": 0}, ] filtered_events = [filter_dict(e, expected[0]) for e in events] mousedown_contextmenu_events = [ x for x in filtered_events if x["type"] in ["mousedown", "contextmenu"] ] - assert expected == mousedown_contextmenu_events + assert mousedown_contextmenu_events in [expected, anotherExpected] + + +async def test_middle_click(bidi_session, top_context, load_static_test_page): + await load_static_test_page(page="test_actions.html") + + div_point = { + "x": 82, + "y": 187, + } + + actions = Actions() + ( + actions.add_pointer() + .pointer_move(x=div_point["x"], y=div_point["y"]) + .pointer_down(button=1) + .pointer_up(button=1) + ) + await bidi_session.input.perform_actions( + actions=actions, context=top_context["context"] + ) + + + events = await get_events(bidi_session, top_context["context"]) + assert len(events) == 3 + + expected = [ + {"type": "mousedown", "button": 1, "buttons": 4}, + {"type": "mouseup", "button": 1, "buttons": 0}, + ] + filtered_events = [filter_dict(e, expected[0]) for e in events] + mousedown_mouseup_events = [ + x for x in filtered_events if x["type"] in ["mousedown", "mouseup"] + ] + assert expected == mousedown_mouseup_events async def test_click_element_center( diff --git a/testing/web-platform/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py b/testing/web-platform/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py index 152447aeefdf..97295f56f413 100644 --- a/testing/web-platform/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py +++ b/testing/web-platform/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py @@ -74,18 +74,53 @@ def test_context_menu_at_coordinates(session, test_actions_page, mouse_chain): .pointer_down(button=2) \ .pointer_up(button=2) \ .perform() + events = get_events(session) - expected = [ - {"type": "mousedown", "button": 2}, - {"type": "contextmenu", "button": 2}, - ] assert len(events) == 4 + + expected = [ + {"type": "mousedown", "button": 2, "buttons": 2}, + {"type": "contextmenu", "button": 2, "buttons": 2}, + ] + # Some browsers in some platforms may dispatch `contextmenu` event as a + # a default action of `mouseup`. In the case, `.buttons` of the event + # should be 0. + anotherExpected = [ + {"type": "mousedown", "button": 2, "buttons": 2}, + {"type": "contextmenu", "button": 2, "buttons": 0}, + ] filtered_events = [filter_dict(e, expected[0]) for e in events] mousedown_contextmenu_events = [ x for x in filtered_events if x["type"] in ["mousedown", "contextmenu"] ] - assert expected == mousedown_contextmenu_events + assert mousedown_contextmenu_events in [expected, anotherExpected] + + +def test_middle_click(session, test_actions_page, mouse_chain): + div_point = { + "x": 82, + "y": 187, + } + mouse_chain \ + .pointer_move(div_point["x"], div_point["y"]) \ + .pointer_down(button=1) \ + .pointer_up(button=1) \ + .perform() + + events = get_events(session) + assert len(events) == 3 + + expected = [ + {"type": "mousedown", "button": 1, "buttons": 4}, + {"type": "mouseup", "button": 1, "buttons": 0}, + ] + filtered_events = [filter_dict(e, expected[0]) for e in events] + mousedown_mouseup_events = [ + x for x in filtered_events + if x["type"] in ["mousedown", "mouseup"] + ] + assert expected == mousedown_mouseup_events def test_click_element_center(session, test_actions_page, mouse_chain):