Skip to content

feat(e2e): scripted touch input + the first touch goldens#167

Draft
doodlewind wants to merge 1 commit into
feat/osk-touch-modelfrom
feat/touch-goldens
Draft

feat(e2e): scripted touch input + the first touch goldens#167
doodlewind wants to merge 1 commit into
feat/osk-touch-modelfrom
feat/touch-goldens

Conversation

@doodlewind

Copy link
Copy Markdown
Collaborator

Part 6/6 of the touch-input series (stacked on #166).

What

Scripted touch through every capture layer, closing the loop opened in #161#166:

  • GoldenSpec.touch?(frame) + app field (multiple specs per bundle); encodeTouchInput() emits the level-triggered compact script (frame:id,x,y[+…];frame:-), "" for touch-free specs — button-only capture builds stay byte-identical.
  • hosts/vita: POCKETJS_CAPTURE_TOUCH baked by build.rs; scripted_touches() (threshold convention of scripted_buttons) feeds TouchSnapshot::from_logical, replacing the hard-coded EMPTY at the frame loop.
  • tests/golden.ts: the wasm oracle passes packed contacts as the third frame argument — web and Vita goldens replay the same touch tape.
  • tools/vita.ts env pass-through; tests/e2e/vita3k.ts encodes per spec.

The first touch golden

im-touch (bundle im-main): finger lands on h and holds — f124 pins the pressed-key active: variant, a state no button tape could ever capture — release commits (the #166 press model), tap types i, START sends.

capture shows
124 OSK with 'h' held-highlighted
180 live "hi" draft, 2/140
300 delivered "hi" bubble

Results: Vita3K e2e 3/3 on first capture (960×544 native density, real QuickJS + input loop, CPU-oracle pixels); wasm oracle wrote the web goldens and all 49 pre-existing web goldens pass unchanged — zero regression across the whole 6-PR touch stack.

🤖 Generated with Claude Code

Golden capture was button-only: the Vita capture host hard-coded
TouchSnapshot::EMPTY, so nothing touch-driven could ever be pinned by a
golden. This adds a scripted touch channel through every capture layer:

- GoldenSpec grows touch(frame) -> contacts and an `app` field (several
  specs can exercise one bundle; golden files keep the spec's own name).
  encodeTouchInput() emits the level-triggered compact script
  ("frame:id,x,y[+id,x,y];frame:-"), "" for touch-free specs so button-only
  builds stay byte-identical.
- hosts/vita: POCKETJS_CAPTURE_TOUCH baked via build.rs like the button
  script; scripted_touches() parses it with the scripted_buttons threshold
  convention and feeds TouchSnapshot::from_logical — replacing the
  hard-coded EMPTY.
- tests/golden.ts (wasm oracle) passes the packed contacts as the third
  frame argument, so web and Vita goldens run the same touch tape.
- tools/vita.ts passes the env through; tests/e2e/vita3k.ts encodes and
  builds per spec.

First touch spec: "im-touch" (bundle im-main) — a finger lands on 'h' and
HOLDS (f124 captures the pressed-key active: variant, a state no button
tape can show), release commits, a tap types 'i', START sends. Goldens:
web (480x272 oracle) and Vita3K (960x544 native density, real QuickJS +
frame loop) — 3/3 passed on first capture; all 49 existing web goldens
pass unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind
doodlewind force-pushed the feat/touch-goldens branch from 247d666 to ab36340 Compare July 23, 2026 13:04
@doodlewind
doodlewind force-pushed the feat/osk-touch-model branch from 095d242 to 0025104 Compare July 23, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant