drive
Observe, drive, and verify live running UI: read a surface's elements, inject real input, and assert on-screen conditions.
What it’s for
This is the live-UI surface: your assistant looks at the running interface the way a player
would, then acts on it. drive.observe returns the elements on screen with stable
handles and an annotated screenshot; the action verbs (drive.click,
drive.type, drive.key, drive.drag, drive.hover,
drive.scroll) send real input; drive.expect and
drive.wait_for turn what is on screen into checkable conditions.
Use it to verify work end to end: build something, press the buttons a player would press, and
assert the result. It complements widget.* (which authors the widget asset on disk)
and ui.* (which mutates live widget properties directly): drive interacts through
input and reads back what actually rendered.
It also reaches editor chrome (surface:"editor_chrome", plus
drive.list_windows to target a window), and drive.events_since reads
the gameplay journal delta between actions.
Examples
Observe, then click what you saw
Ask for interactable elements only, then click a button by its returned handle.
You: Start a match from the main menu.
call("drive.observe", {interactables_only: true})
→ {elements:[{handle:"e3", label:"Play", ...}, {handle:"e4", label:"Settings", ...}]}
call("drive.click", {handle:"e3"})
→ {ok:true}
Done. Clicked Play; the match is loading.
Press a key and assert the outcome
Run the game, send input, and check the HUD text instead of eyeballing a screenshot.
You: Verify that scoring works.
call("editor.play", {})
call("drive.key", {key:"SpaceBar"})
call("drive.expect", {condition:{type:"text_contains",
target:"ScoreText", expected_text:"Score: 10"}})
→ {met:true, actual:"Score: 10"}
call("editor.stop", {})
Done. The HUD shows Score: 10 after the input; scoring works.
Wait for a screen to appear
Poll a condition each frame instead of sleeping and hoping.
You: After the last checkpoint, the results screen should come up.
call("drive.wait_for", {condition:{type:"widget_present", target:"ResultsScreen"},
timeout_ms: 8000})
→ {met:true}
Done. ResultsScreen appeared within the timeout.