WIP on test recorder click offsets

This commit is contained in:
Isaiah Odhner 2023-09-09 15:46:35 -04:00
parent 24b9b9986c
commit 8838250e94

View File

@ -2,6 +2,7 @@ import os
from textual.css.query import NoMatches, TooManyMatches from textual.css.query import NoMatches, TooManyMatches
from textual.dom import DOMNode from textual.dom import DOMNode
from textual.events import Event, Key, MouseDown, MouseMove, MouseUp from textual.events import Event, Key, MouseDown, MouseMove, MouseUp
from textual.geometry import Offset
from textual.screen import Screen from textual.screen import Screen
from textual_paint.paint import PaintApp from textual_paint.paint import PaintApp
@ -18,7 +19,7 @@ def unique_file(path: str) -> str:
OUTPUT_FILE = unique_file("tests/test_paint_something.py") OUTPUT_FILE = unique_file("tests/test_paint_something.py")
steps: list[tuple[Event, str, int|None]] = [] steps: list[tuple[Event, Offset, str, int|None]] = []
def get_selector(target: DOMNode) -> tuple[str, int|None]: def get_selector(target: DOMNode) -> tuple[str, int|None]:
"""Return a selector that can be used to find the widget.""" """Return a selector that can be used to find the widget."""
@ -52,8 +53,13 @@ original_on_event = PaintApp.on_event
async def on_event(self: PaintApp, event: Event) -> None: async def on_event(self: PaintApp, event: Event) -> None:
await original_on_event(self, event) await original_on_event(self, event)
if isinstance(event, (MouseDown, MouseMove, MouseUp)): if isinstance(event, (MouseDown, MouseMove, MouseUp)):
widget, _ = self.get_widget_at(event.x, event.y) widget, _ = self.get_widget_at(*event.screen_offset)
steps.append((event, *get_selector(widget))) offset = event.screen_offset - widget.region.offset
steps.append((event, offset, *get_selector(widget)))
# This doesn't hold:
# assert event.x == event.screen_x - widget.region.x, f"event.x ({event.x}) should be event.screen_x ({event.screen_x}) - widget ({widget!r}).region.x ({widget.region.x})"
# assert event.y == event.screen_y - widget.region.y, f"event.y ({event.y}) should be event.screen_y ({event.screen_y}) - widget ({widget!r}).region.y ({widget.region.y})"
# I think the offset == screen_offset once it's bubbled up to the app?
elif isinstance(event, Key): elif isinstance(event, Key):
if event.key == "ctrl+z": if event.key == "ctrl+z":
steps.pop() steps.pop()
@ -71,7 +77,7 @@ def replay() -> None:
app.on_event = on_event.__get__(app) app.on_event = on_event.__get__(app)
async def replay_steps() -> None: async def replay_steps() -> None:
assert app is not None, "app should be set by now" assert app is not None, "app should be set by now"
for event, selector, index in steps: for event, offset, selector, index in steps:
await app.on_event(event) await app.on_event(event)
app.call_later(replay_steps) app.call_later(replay_steps)
app.run() # blocking app.run() # blocking
@ -83,14 +89,14 @@ def save_replay() -> None:
assert app is not None, "app should be set by now" assert app is not None, "app should be set by now"
helpers_code = "" helpers_code = ""
steps_code = "" steps_code = ""
for event, selector, index in steps: for event, offset, selector, index in steps:
if isinstance(event, MouseDown): if isinstance(event, MouseDown):
if index is None: if index is None:
steps_code += f"await pilot.click({selector!r}, offset=Offset({event.x}, {event.y}))\n" steps_code += f"await pilot.click({selector!r}, offset=Offset({offset.x}, {offset.y}))\n"
else: else:
steps_code += f"widget = pilot.app.query({selector!r})[{index!r}]\n" steps_code += f"widget = pilot.app.query({selector!r})[{index!r}]\n"
# steps_code += f"await pilot.click(widget, offset=Offset({event.x}, {event.y}))\n" # would be nice # can't pass a widget to pilot.click, only a selector, or None
steps_code += f"await pilot.click(offset=Offset({event.x}, {event.y}) + widget.region.offset)\n" steps_code += f"await pilot.click(offset=Offset({offset.x}, {offset.y}) + widget.region.offset)\n"
script = f"""\ script = f"""\