Builtin Library
README.md
test
Test-input helpers that simulate keyboard / mouse / scroll events and
yield one engine frame so the queued events drain into the next
snapshot. Backs Zin.test. Helpers do NOT call Zin.tick() —
explicit dispatch control is left to the caller.
Exports
M.runFrame()— yield one engine frame so simulated events drain.M.pressKey(code: string)— hold the key DOWN and leave it held. A secondpressKeyon a held key produces no new press edge — pair everypressKeywith areleaseKey, or usetapKeyfor a full press.M.releaseKey(code: string)— simulate a key release.M.tapKey(code: string, duration: number?)— press + optional hold + release. The helper for "the player taps a key".M.pressMouse(button: (number | string)?)— simulate a mouse button press (default 0 = left). The index and the name ("left"/"right"/"middle") reach the same button.M.releaseMouse(button: (number | string)?)— simulate a mouse button release.M.dragFiles(x: number, y: number, count: number)— stand a drag of files from outside the engine at a window point;M.endFileDrag()carries it off.M.dropFiles(x: number, y: number, files: { any })— drop files on a window point, each{ name, bytes, type? }.M.pasteFiles(files: { any })— paste files through the path a clipboard image takes.M.setClipboard(content: { text: string?, image: string? }?): state what the clipboard a Ctrl+V reads holds (imagea PNG's bytes), in place of the host clipboard;nilhands it back. Raises on a browser engine.M.clickMouse(button: (number | string)?, x: number?, y: number?, duration: number?)— full click, optionally moving the cursor to(x, y)first and holding fordurationseconds.M.moveMouse(x: number, y: number)— set absolute cursor position.M.moveMouseBy(dx: number, dy: number, steps: number?)— move the pointer by a relative motion. The motion lands in this frame'smouse_deltaand the position advances by the same amount, so the same(dx, dy)repeated keeps producing look movement.stepsspreads it over that many frames, each carrying its share; 1 when omitted.M.scroll(dy: number)— simulate a wheel scroll.
Usage
local Test = require("@builtin::modules.zinput.test")
Test.tapKey("KeyM") -- press + release
Zin.tick(1 / 60) -- explicit dispatch
assert(#Zin.scheme.fired() > 0)
Test.pressKey("Space") -- key goes DOWN and stays held...
Zin.tick(1 / 60)
Test.releaseKey("Space") -- ...until released
Test.clickMouse(0, 100, 200)
Notes
- Each helper queues the simulated event and yields one frame
(
task.wait(0)) so the snapshot reflects the input on return. - Simulated key state persists like real key state: after
pressKeythe key stays held untilreleaseKey, and only the release re-arms the next press edge.tapKeyis the edge-per-call helper. - Helpers do NOT call
Zin.tick()— a test that relies on a control's handlers, or onZin.input.on*/Zin.actions.bind, must run a tick itself.Zin.scheme.fired()is what turns a simulated input into an assertion: it reports which controls fired since it last read, and from which device class. - Mouse button index is 0-based (0=left, 1=right, 2=middle) following the
InputResource.mouse_buttonsconvention. - All helpers are no-ops when the
__zero_input.simulate*FFI is missing (off-host execution).