зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1824230 - [wdspec] Add WebDriver BiDi tests for actions on elements in ShadowRoot r=webdriver-reviewers,whimboo
Depends on D182474 Differential Revision: https://phabricator.services.mozilla.com/D182498
This commit is contained in:
Родитель
ecb0e3716e
Коммит
d14b62e23e
|
@ -1,4 +1,16 @@
|
|||
[pointer_pen.py]
|
||||
[test_pen_pointer_in_shadow_tree[outer-open\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_pen_pointer_in_shadow_tree[outer-closed\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_pen_pointer_in_shadow_tree[inner-open\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_pen_pointer_in_shadow_tree[inner-closed\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_pen_pointer_properties]
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1658880
|
||||
expected: FAIL
|
||||
|
|
|
@ -2,15 +2,19 @@ import json
|
|||
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
|
||||
async def get_events(bidi_session, context):
|
||||
"""Return list of key events recorded on the test_actions.html page."""
|
||||
async def get_object_from_context(bidi_session, context, object_path):
|
||||
"""Return a plain JS object from a given context, accessible at the given object_path"""
|
||||
events_str = await bidi_session.script.evaluate(
|
||||
expression="JSON.stringify(allEvents.events)",
|
||||
expression=f"JSON.stringify({object_path})",
|
||||
target=ContextTarget(context),
|
||||
await_promise=False,
|
||||
)
|
||||
events = json.loads(events_str["value"])
|
||||
return json.loads(events_str["value"])
|
||||
|
||||
|
||||
async def get_events(bidi_session, context):
|
||||
"""Return list of key events recorded on the test_actions.html page."""
|
||||
events = await get_object_from_context(bidi_session, context, "allEvents.events")
|
||||
|
||||
# `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in
|
||||
# test_actions.html), so this converts them back into unicode literals.
|
||||
|
|
|
@ -1,10 +1,35 @@
|
|||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from ... import get_viewport_dimensions, remote_mapping_to_dict
|
||||
from .. import get_object_from_context
|
||||
|
||||
|
||||
def remote_mapping_to_dict(js_object):
|
||||
obj = {}
|
||||
for key, value in js_object:
|
||||
obj[key] = value["value"]
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
async def assert_pointer_events(
|
||||
bidi_session, context, expected_events, target, pointer_type
|
||||
):
|
||||
events = await get_object_from_context(
|
||||
bidi_session, context["context"], "window.recordedEvents"
|
||||
)
|
||||
|
||||
assert len(events) == len(expected_events)
|
||||
event_types = [e["type"] for e in events]
|
||||
assert expected_events == event_types
|
||||
|
||||
for e in events:
|
||||
assert e["target"] == target
|
||||
assert e["pointerType"] == pointer_type
|
||||
|
||||
|
||||
async def get_inview_center_bidi(bidi_session, context, element):
|
||||
elem_rect = await get_element_rect(bidi_session, context=context, element=element)
|
||||
viewport_rect = await get_viewport_dimensions(bidi_session, context=context)
|
||||
viewport_rect = await get_viewport_rect(bidi_session, context=context)
|
||||
|
||||
x = {
|
||||
"left": max(0, min(elem_rect["x"], elem_rect["x"] + elem_rect["width"])),
|
||||
|
@ -39,3 +64,68 @@ el => el.getBoundingClientRect().toJSON()
|
|||
)
|
||||
|
||||
return remote_mapping_to_dict(result["value"])
|
||||
|
||||
|
||||
async def get_shadow_root_from_test_page(bidi_session, context, nested=False):
|
||||
custom_element = await bidi_session.script.call_function(
|
||||
function_declaration="""() => document.querySelector("custom-element")""",
|
||||
target=ContextTarget(context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
shadow_root = custom_element["value"]["shadowRoot"]
|
||||
|
||||
if nested:
|
||||
custom_element = await bidi_session.script.call_function(
|
||||
function_declaration="""shadowRoot => shadowRoot.querySelector("inner-custom-element")""",
|
||||
target=ContextTarget(context["context"]),
|
||||
arguments=[shadow_root],
|
||||
await_promise=False,
|
||||
)
|
||||
shadow_root = custom_element["value"]["shadowRoot"]
|
||||
|
||||
return shadow_root
|
||||
|
||||
|
||||
async def get_viewport_rect(bidi_session, context):
|
||||
expression = """
|
||||
({
|
||||
height: window.innerHeight || document.documentElement.clientHeight,
|
||||
width: window.innerWidth || document.documentElement.clientWidth,
|
||||
});
|
||||
"""
|
||||
result = await bidi_session.script.evaluate(
|
||||
expression=expression,
|
||||
target=ContextTarget(context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
return remote_mapping_to_dict(result["value"])
|
||||
|
||||
|
||||
async def record_pointer_events(bidi_session, context, container, selector):
|
||||
# Record basic mouse / pointer events on the element matching the given
|
||||
# selector in the container.
|
||||
# The serialized element will be returned
|
||||
target = await bidi_session.script.call_function(
|
||||
function_declaration=f"""container => {{
|
||||
const target = container.querySelector("{selector}");
|
||||
window.recordedEvents = [];
|
||||
function onPointerEvent(event) {{
|
||||
window.recordedEvents.push({{
|
||||
"type": event.type,
|
||||
"pointerType": event.pointerType,
|
||||
"target": event.target.id
|
||||
}});
|
||||
}}
|
||||
target.addEventListener("pointerdown", onPointerEvent);
|
||||
target.addEventListener("pointerup", onPointerEvent);
|
||||
return target;
|
||||
}}
|
||||
""",
|
||||
arguments=[container],
|
||||
target=ContextTarget(context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
return target
|
|
@ -1,9 +1,11 @@
|
|||
import pytest
|
||||
|
||||
from webdriver.bidi.modules.input import Actions
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from tests.support.keys import Keys
|
||||
from .. import get_keys_value
|
||||
from . import get_shadow_root_from_test_page
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
@ -45,6 +47,48 @@ async def test_key_codepoint(
|
|||
assert keys_value == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["open", "closed"])
|
||||
@pytest.mark.parametrize("nested", [False, True], ids=["outer", "inner"])
|
||||
async def test_key_shadow_tree(bidi_session, top_context, get_test_page, mode, nested):
|
||||
await bidi_session.browsing_context.navigate(
|
||||
context=top_context["context"],
|
||||
url=get_test_page(
|
||||
shadow_doc="<div><input type=text></div>",
|
||||
shadow_root_mode=mode,
|
||||
nested_shadow_dom=nested,
|
||||
),
|
||||
wait="complete",
|
||||
)
|
||||
|
||||
shadow_root = await get_shadow_root_from_test_page(bidi_session, top_context, nested)
|
||||
input_el = await bidi_session.script.call_function(
|
||||
function_declaration=f"""shadowRoot => {{
|
||||
const input = shadowRoot.querySelector('input');
|
||||
input.focus();
|
||||
return input;
|
||||
}}
|
||||
""",
|
||||
arguments=[shadow_root],
|
||||
target=ContextTarget(top_context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
actions = Actions()
|
||||
(actions.add_key().key_down("a").key_up("a"))
|
||||
await bidi_session.input.perform_actions(
|
||||
actions=actions, context=top_context["context"]
|
||||
)
|
||||
|
||||
input_value = await bidi_session.script.call_function(
|
||||
function_declaration="input => input.value",
|
||||
arguments=[input_el],
|
||||
target=ContextTarget(top_context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
assert input_value["value"] == "a"
|
||||
|
||||
|
||||
async def test_null_response_value(bidi_session, top_context):
|
||||
actions = Actions()
|
||||
actions.add_key().key_down("a").key_up("a")
|
||||
|
|
|
@ -75,9 +75,7 @@ async def test_non_printable_key_sends_events(
|
|||
(Keys.R_SHIFT, "R_SHIFT"),
|
||||
],
|
||||
)
|
||||
async def test_key_modifier_key(
|
||||
bidi_session, top_context, setup_key_test, key, event
|
||||
):
|
||||
async def test_key_modifier_key(bidi_session, top_context, setup_key_test, key, event):
|
||||
code = ALL_EVENTS[event]["code"]
|
||||
value = ALL_EVENTS[event]["key"]
|
||||
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
import pytest
|
||||
|
||||
from webdriver.bidi.modules.input import Actions, get_element_origin
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from tests.support.asserts import assert_move_to_coordinates
|
||||
from tests.support.helpers import filter_dict
|
||||
|
||||
from .. import get_events
|
||||
from . import get_element_rect, get_inview_center_bidi
|
||||
from . import (
|
||||
assert_pointer_events,
|
||||
get_element_rect,
|
||||
get_inview_center_bidi,
|
||||
get_shadow_root_from_test_page,
|
||||
record_pointer_events,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
@ -117,6 +124,53 @@ async def test_click_element_center(
|
|||
assert e["target"] == "outer"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["open", "closed"])
|
||||
@pytest.mark.parametrize("nested", [False, True], ids=["outer", "inner"])
|
||||
async def test_click_element_in_shadow_tree(
|
||||
bidi_session, top_context, get_test_page, mode, nested
|
||||
):
|
||||
await bidi_session.browsing_context.navigate(
|
||||
context=top_context["context"],
|
||||
url=get_test_page(
|
||||
shadow_doc="""
|
||||
<div id="pointer-target"
|
||||
style="width: 10px; height: 10px; background-color:blue;">
|
||||
</div>""",
|
||||
shadow_root_mode=mode,
|
||||
nested_shadow_dom=nested,
|
||||
),
|
||||
wait="complete",
|
||||
)
|
||||
|
||||
shadow_root = await get_shadow_root_from_test_page(
|
||||
bidi_session, top_context, nested
|
||||
)
|
||||
|
||||
target = await record_pointer_events(
|
||||
bidi_session, top_context, shadow_root, "#pointer-target"
|
||||
)
|
||||
|
||||
actions = Actions()
|
||||
(
|
||||
actions.add_pointer()
|
||||
.pointer_move(x=0, y=0, origin=get_element_origin(target))
|
||||
.pointer_down(button=0)
|
||||
.pointer_up(button=0)
|
||||
)
|
||||
|
||||
await bidi_session.input.perform_actions(
|
||||
actions=actions, context=top_context["context"]
|
||||
)
|
||||
|
||||
await assert_pointer_events(
|
||||
bidi_session,
|
||||
top_context,
|
||||
expected_events=["pointerdown", "pointerup"],
|
||||
target="pointer-target",
|
||||
pointer_type="mouse",
|
||||
)
|
||||
|
||||
|
||||
async def test_click_navigation(
|
||||
bidi_session,
|
||||
top_context,
|
||||
|
|
|
@ -1,13 +1,67 @@
|
|||
import pytest
|
||||
|
||||
from webdriver.bidi.modules.input import Actions, get_element_origin
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from .. import get_events
|
||||
from . import get_inview_center_bidi
|
||||
from . import (
|
||||
assert_pointer_events,
|
||||
get_inview_center_bidi,
|
||||
get_shadow_root_from_test_page,
|
||||
record_pointer_events,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["open", "closed"])
|
||||
@pytest.mark.parametrize("nested", [False, True], ids=["outer", "inner"])
|
||||
async def test_pen_pointer_in_shadow_tree(
|
||||
bidi_session, top_context, get_test_page, mode, nested
|
||||
):
|
||||
await bidi_session.browsing_context.navigate(
|
||||
context=top_context["context"],
|
||||
url=get_test_page(
|
||||
shadow_doc="""
|
||||
<div id="pointer-target"
|
||||
style="width: 10px; height: 10px; background-color:blue;">
|
||||
</div>""",
|
||||
shadow_root_mode=mode,
|
||||
nested_shadow_dom=nested,
|
||||
),
|
||||
wait="complete",
|
||||
)
|
||||
|
||||
shadow_root = await get_shadow_root_from_test_page(
|
||||
bidi_session, top_context, nested
|
||||
)
|
||||
|
||||
# Add a simplified event recorder to track events in the test ShadowRoot.
|
||||
target = await record_pointer_events(
|
||||
bidi_session, top_context, shadow_root, "#pointer-target"
|
||||
)
|
||||
|
||||
actions = Actions()
|
||||
(
|
||||
actions.add_pointer(pointer_type="pen")
|
||||
.pointer_move(x=0, y=0, origin=get_element_origin(target))
|
||||
.pointer_down(button=0)
|
||||
.pointer_up(button=0)
|
||||
)
|
||||
|
||||
await bidi_session.input.perform_actions(
|
||||
actions=actions, context=top_context["context"]
|
||||
)
|
||||
|
||||
await assert_pointer_events(
|
||||
bidi_session,
|
||||
top_context,
|
||||
expected_events=["pointerdown", "pointerup"],
|
||||
target="pointer-target",
|
||||
pointer_type="pen",
|
||||
)
|
||||
|
||||
|
||||
async def test_pen_pointer_properties(
|
||||
bidi_session, top_context, get_element, load_static_test_page
|
||||
):
|
||||
|
|
|
@ -1,13 +1,67 @@
|
|||
import pytest
|
||||
|
||||
from webdriver.bidi.modules.input import Actions, get_element_origin
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from .. import get_events
|
||||
from . import get_inview_center_bidi
|
||||
from . import (
|
||||
assert_pointer_events,
|
||||
get_inview_center_bidi,
|
||||
get_shadow_root_from_test_page,
|
||||
record_pointer_events,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["open", "closed"])
|
||||
@pytest.mark.parametrize("nested", [False, True], ids=["outer", "inner"])
|
||||
async def test_touch_pointer_in_shadow_tree(
|
||||
bidi_session, top_context, get_test_page, mode, nested
|
||||
):
|
||||
await bidi_session.browsing_context.navigate(
|
||||
context=top_context["context"],
|
||||
url=get_test_page(
|
||||
shadow_doc="""
|
||||
<div id="pointer-target"
|
||||
style="width: 10px; height: 10px; background-color:blue;">
|
||||
</div>""",
|
||||
shadow_root_mode=mode,
|
||||
nested_shadow_dom=nested,
|
||||
),
|
||||
wait="complete",
|
||||
)
|
||||
|
||||
shadow_root = await get_shadow_root_from_test_page(
|
||||
bidi_session, top_context, nested
|
||||
)
|
||||
|
||||
# Add a simplified event recorder to track events in the test ShadowRoot.
|
||||
target = await record_pointer_events(
|
||||
bidi_session, top_context, shadow_root, "#pointer-target"
|
||||
)
|
||||
|
||||
actions = Actions()
|
||||
(
|
||||
actions.add_pointer(pointer_type="touch")
|
||||
.pointer_move(x=0, y=0, origin=get_element_origin(target))
|
||||
.pointer_down(button=0)
|
||||
.pointer_up(button=0)
|
||||
)
|
||||
|
||||
await bidi_session.input.perform_actions(
|
||||
actions=actions, context=top_context["context"]
|
||||
)
|
||||
|
||||
await assert_pointer_events(
|
||||
bidi_session,
|
||||
top_context,
|
||||
expected_events=["pointerdown", "pointerup"],
|
||||
target="pointer-target",
|
||||
pointer_type="touch",
|
||||
)
|
||||
|
||||
|
||||
async def test_touch_pointer_properties(
|
||||
bidi_session, top_context, get_element, load_static_test_page
|
||||
):
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import pytest
|
||||
|
||||
from webdriver.bidi.modules.input import Actions, get_element_origin
|
||||
from .. import get_events
|
||||
from webdriver.bidi.modules.script import ContextTarget
|
||||
|
||||
from .. import get_events, get_object_from_context
|
||||
from . import get_shadow_root_from_test_page
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
@ -79,3 +82,71 @@ async def test_wheel_scroll_overflow(
|
|||
assert events[0]["deltaY"] >= delta_y
|
||||
assert events[0]["deltaZ"] == 0
|
||||
assert events[0]["target"] == "scrollContent"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["open", "closed"])
|
||||
@pytest.mark.parametrize("nested", [False, True], ids=["outer", "inner"])
|
||||
async def test_wheel_scroll_shadow_tree(
|
||||
bidi_session, top_context, get_test_page, mode, nested
|
||||
):
|
||||
await bidi_session.browsing_context.navigate(
|
||||
context=top_context["context"],
|
||||
url=get_test_page(
|
||||
shadow_doc="""
|
||||
<div id="scrollableShadowTree"
|
||||
style="width: 100px; height: 100px; overflow: auto;">
|
||||
<div
|
||||
id="scrollableShadowTreeContent"
|
||||
style="width: 600px; height: 1000px; background-color:blue"></div>
|
||||
</div>""",
|
||||
shadow_root_mode=mode,
|
||||
nested_shadow_dom=nested,
|
||||
),
|
||||
wait="complete",
|
||||
)
|
||||
|
||||
shadow_root = await get_shadow_root_from_test_page(bidi_session, top_context, nested)
|
||||
|
||||
# Add a simplified event recorder to track events in the test ShadowRoot.
|
||||
scrollable = await bidi_session.script.call_function(
|
||||
function_declaration=f"""shadowRoot => {{
|
||||
window.wheelEvents = [];
|
||||
const scrollable = shadowRoot.querySelector("#scrollableShadowTree");
|
||||
scrollable.addEventListener("wheel",
|
||||
function(event) {{
|
||||
window.wheelEvents.push({{
|
||||
"deltaX": event.deltaX,
|
||||
"deltaY": event.deltaY,
|
||||
"target": event.target.id
|
||||
}});
|
||||
}}
|
||||
);
|
||||
return scrollable;
|
||||
}}
|
||||
""",
|
||||
arguments=[shadow_root],
|
||||
target=ContextTarget(top_context["context"]),
|
||||
await_promise=False,
|
||||
)
|
||||
|
||||
actions = Actions()
|
||||
actions.add_wheel().scroll(
|
||||
x=0,
|
||||
y=0,
|
||||
delta_x=5,
|
||||
delta_y=10,
|
||||
origin=get_element_origin(scrollable),
|
||||
)
|
||||
|
||||
await bidi_session.input.perform_actions(
|
||||
actions=actions, context=top_context["context"]
|
||||
)
|
||||
|
||||
events = await get_object_from_context(
|
||||
bidi_session, top_context["context"], "window.wheelEvents"
|
||||
)
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0]["deltaX"] >= 5
|
||||
assert events[0]["deltaY"] >= 10
|
||||
assert events[0]["target"] == "scrollableShadowTreeContent"
|
||||
|
|
Загрузка…
Ссылка в новой задаче