diff --git a/.pi/skills/test-e32r40t-firmware/SKILL.md b/.pi/skills/test-e32r40t-firmware/SKILL.md index 1b72222..ab25a86 100644 --- a/.pi/skills/test-e32r40t-firmware/SKILL.md +++ b/.pi/skills/test-e32r40t-firmware/SKILL.md @@ -32,11 +32,12 @@ Use an executable `.e32r40t` script. Assert on the app path the firmware logs ra #!/usr/bin/env -S esp-emu --board e32r40t boot .pio/build/esp32-32e/firmware.bin --sdcard sdcard/ --fresh-sd -wait-log "launcher ready" --timeout 120 +wait-log "\[lua\] info: home ready" --timeout 180 +wait-idle 3 -tap 60 55 +tap 85 127 wait-log "running Hello" -wait-log "\[lua\] .* started" +wait-idle 3 capture _scratch/emulator-app.png ``` @@ -50,27 +51,28 @@ Blank lines and `#` comments are allowed. Scripts also run explicitly or through ```sh esp-emu --board e32r40t --state /tmp/my-test run flow.e32r40t -printf '%s\n' 'boot .pio/build/esp32-32e/firmware.bin' 'wait-log "launcher ready"' | esp-emu --board e32r40t run +printf '%s\n' 'boot .pio/build/esp32-32e/firmware.bin' 'wait-log "info: home ready"' | esp-emu --board e32r40t run ``` ## Synchronization -Lua logs carry a level in the prefix (`[lua:info] home ready`), so match `\[lua:info\]` and -not `\[lua\]`. +`LogProvider` prints the level after the tag -- `[lua] info: home ready` -- so match +`\[lua\] info:` and never `\[lua:info\]`, which matches nothing and burns the whole timeout. -Firmware sync points, in order: `running ` (printed by the host for every app, -including the launcher itself), `[lua:info] home ready` (menu -drawn, touch accepted), then whatever the app logs through `log.info(...)`. Exiting an -app relaunches the launcher, so both lines repeat. +Firmware sync points, in order: an app's own `log.info(...)`, then `running ` printed +by the host for every app including the launcher. The app line comes **first**, because +`init()` runs inside `startApp()` and the host logs the route after it returns. Wait for +`[lua] info: home ready` and then `running Home`. Exiting an app relaunches the launcher, so +both lines repeat. A scripted tap must land after the app is idle: `setup()` can block for seconds on a full-screen clear under TCG, and a 250 ms press that lands during it is missed -entirely. Wait for the app's own ready log, then `sleep` a few seconds. +entirely. Wait for the app's own ready log, then `wait-idle 3`. - Use `wait-log REGEX` as the default synchronization and assertion mechanism. - Assert on the `running ...` line rather than on tap coordinates: menu rows follow SD directory order, which the image build decides. -- Use `wait-frame [COUNT]` only when a panel redraw is itself the behavior under test. -- Use `wait-idle SECONDS` only when silence is the actual readiness signal. +- Use `wait-idle SECONDS` between a ready log and the first tap, and between a tap and a capture. +- `wait-frame` is an e-ink command and hangs on this board; `sleep` is not a command at all. A script using either stops silently. - Capture and inspect the final screen after semantic log assertions. ## Touch @@ -78,12 +80,16 @@ entirely. Wait for the app's own ready log, then `sleep` a few seconds. `tap` always takes physical panel pixels (320x480 portrait), because the glass never rotates. Screens are laid out by `/.lua/lib/ui.lua`, so read tap targets off a `capture` rather than -computing them. The status bar takes the top 44 rows; card grids use three portrait columns -and four landscape columns. With the current apps, portrait Home card centres are near -`(109,102)` and `(210,102)`, while Settings' first row is near x=59/160/261 at y=102. +computing them. The status bar takes the top 44 rows and card grids are two columns wide in +portrait. With the current apps, portrait Home card centres are near `(85,127)` / `(235,127)` +and `(85,275)` / `(235,275)`, and Settings' rows sit at x=85/235 with y=115/240/375. Taps that land within the first few seconds after a ready log are missed, so `wait-idle 3` before the first one. +A grid reflows when the frame does, so the rotated launcher is not the portrait one turned +sideways -- its cards move and change count per row. After any rotation, capture and read the +new targets instead of converting the old ones. + Use `touch-hold` plus `capture` plus `touch-release` to photograph a pressed button: `on_press` fires on release, and the pressed style is only visible mid-gesture. @@ -127,7 +133,7 @@ the submodule and are not committed here. Directory contents overwrite matching ## Lua-only Logic -Pure Lua helpers run far faster on the host than in the emulator. Stub the `gui`, `input`, `sys` and `log` tables and load the app directly, as `test/settings_calibration.lua` does: +Pure Lua helpers run far faster on the host than in the emulator. Stub the `screen`, `tree`, `touch`, `sys` and `log` tables and load the app directly, as `test/settings_calibration.lua` does -- or use `test/fake_device.lua`, which is the single definition of that binding surface: ```sh nix run nixpkgs#lua -- test/settings_calibration.lua