Skip to content

Commit 8715f81

Browse files
committed
Drop the UI half of the mouse coverage
mouse-ui could not fail for the right reason. Instrumenting the callins showed why: RmlUi is fed mouse input by the engine, so a press over the panel or an open console never reaches the native callin, and the ownership checks that do run are gated on a pointer-capture state that a scripted click cannot steer. The scenario passed with the panel's hit test deliberately broken, and its field assertions only repeated what the gallery scenario already covers. mouse-coordinates stays: it was verified to catch the inversion it is written for, reporting both positions it compared.
1 parent c972eea commit 8715f81

1 file changed

Lines changed: 17 additions & 71 deletions

File tree

tools/e2e/scenarios/mouse.py

Lines changed: 17 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
1-
"""Physical-mouse coverage for the panel and for the screen-to-world contract.
1+
"""Physical-mouse coverage for the screen-to-world contract.
22
33
Most scenarios reach the editors through the typed control channel, which never
4-
touches the engine's mouse callins. These two do the opposite: every input here
5-
is a real X11 event, and the assertions read the resulting state back through
6-
the control channel. They carry no goldens, so they stay cheap enough to run on
7-
every suite.
4+
touches the engine's mouse callins at all. This one does the opposite: the input
5+
is real X11, and the result is read back through the control channel. It carries
6+
no golden, so a vertical flip is reported as two coordinates rather than as a
7+
picture full of moved trees.
88
"""
99

1010
from typing import TYPE_CHECKING
1111

1212
from e2e.driver.timing import Delay
1313
from e2e.scenarios.helpers.camera import zoom_map
14-
from e2e.scenarios.helpers.geometry import (
15-
MAP,
16-
OBJECTS,
17-
TAB_X,
18-
TAB_Y,
19-
editor_point,
20-
panel_left,
21-
panel_point,
22-
window_size,
23-
)
14+
from e2e.scenarios.helpers.geometry import OBJECTS, panel_point, window_size
2415
from e2e.scenarios.helpers.objects import arm_tree as _arm_tree
2516
from e2e.scenarios.helpers.objects import open_object_editor as _open
2617
from e2e.scenarios.helpers.registry import scenario
@@ -30,71 +21,26 @@
3021
from e2e.driver.state import RunState
3122

3223
# A click and the ray query for the same pixel describe the same spot. The
33-
# budget covers the brush's own rounding, not a different point on the map: a
34-
# mirrored y lands hundreds of units away even near the middle of the view.
24+
# budget covers the placement's own rounding, not a different point on the map:
25+
# a mirrored y lands hundreds of units away even near the middle of the view.
3526
TRACE_TOLERANCE = 40.0
3627

3728

38-
@scenario()
39-
def mouse_ui(run_state: "RunState") -> None:
40-
"""The panel, driven only by the pointer.
41-
42-
Tab, editor button, field click, typed commit and a numeric drag are all
43-
real X11 input, and the editor model is read back to prove each one landed
44-
on the control it aimed at. Without this, every editor is reachable in tests
45-
only through the control channel, which no user has.
46-
47-
Note what this cannot cover: RmlUi consumes a press over the panel document
48-
inside the engine, so those clicks never reach the native mouse callin at
49-
all. The panel's own hit test therefore sees map presses only, and this
50-
scenario proves the user-facing path rather than that hit test.
51-
"""
52-
run_state.focus()
53-
left = panel_left(run_state)
54-
run_state.click(left + TAB_X["map"], TAB_Y, delay=Delay.FRAME)
55-
run_state.click(*editor_point(left, "map", "terrain"), delay=Delay.READY)
56-
57-
terrain = run_state.control.editor("heightmapEditor")
58-
run_state.fill_text(
59-
*panel_point(left, MAP["terrain_size"]),
60-
"140",
61-
click_delay=Delay.FRAME,
62-
commit_delay=Delay.SETTLE,
63-
)
64-
typed = terrain.get("size")
65-
assert typed == 140.0, f"typing into the Size field gave {typed!r}, want 140.0"
66-
67-
# A numeric drag pins the pointer and warps it back, so the motion has to be
68-
# relative. The direction is what matters: the exact value depends on which
69-
# tick the release meets.
70-
run_state.press(*panel_point(left, MAP["terrain_size"]))
71-
run_state.move_relative(60)
72-
run_state.release(*panel_point(left, MAP["terrain_size"]), delay=Delay.SETTLE)
73-
dragged = terrain.get("size")
74-
assert isinstance(dragged, float), f"Size is {dragged!r}, want a number"
75-
assert dragged > typed, f"dragging right did not raise Size: {typed} -> {dragged}"
76-
77-
# A press beside the panel belongs to the map, not to the control that was
78-
# last touched. This is the ownership half of the hit test.
79-
run_state.fill_text(
80-
*panel_point(left, MAP["terrain_rotation"]),
81-
"15",
82-
click_delay=Delay.FRAME,
83-
commit_delay=Delay.SETTLE,
84-
)
85-
rotation = terrain.get("rotation")
86-
assert rotation == 15.0, f"the second field took {rotation!r}, want 15.0"
87-
assert terrain.get("size") == dragged, "editing Rotation moved Size"
88-
89-
9029
@scenario()
9130
def mouse_coordinates(run_state: "RunState") -> None:
9231
"""A click places an object where that pixel points.
9332
9433
The engine reports mouse callbacks in its own bottom-origin screen space,
9534
while control clients address the window top-origin like a screenshot. Both
96-
paths are asked about the same two pixels here, so a future flip on either
97-
side fails immediately -- and says so, rather than moving a golden's trees.
35+
paths are asked about the same two pixels here, so a flip on either side
36+
fails immediately and names the two positions it compared.
37+
38+
This is deliberately the only mouse scenario. The panel and the consoles do
39+
their hit testing inside RmlUi, which the engine feeds directly: a press
40+
over either never reaches the native callin, and their ownership checks are
41+
reached through a pointer-capture state that a scripted click cannot steer.
42+
A UI-side mouse test therefore passes whatever the coordinate space is,
43+
while this one cannot.
9844
"""
9945
run_state.focus()
10046
left = _open(run_state, "features")

0 commit comments

Comments
 (0)