This module covers the tricky cases. Some already work in the capture.mjs; others still require manually driving agent-browser and are in the backlog. Each topic clearly marks its status.
📜 Scroll before the screenshot roadmap
Long pages require scrollIntoView in the section before capturing. Today, done manually.
O capture.mjs doesn't scroll the page. On inemaVOX screens, it was necessary to drive agent-browser manually, making scrollIntoView per section before each screenshot.
That’s why it’s backlog priority #1. Until it arrives, scrolling manually before measuring/capturing works—it just takes more effort.
⚛️ React/Vue-controlled inputs partial
Set .value shows the text but doesn’t trigger the state—buttons stay disabled.
- ✗
el.value = "768"via plain eval - ✗ React doesn't notice → button remains disabled
- ✗ The screenshot shows the control inactive
- ✓
setValuetriggersinput+change - ✓ Ideal (roadmap):
fillnative to Playwright - ✓ Check that the button is enabled in the shot
The ideal is the capture.mjs call agent-browser fill @ref (Playwright’s native fill) instead of setting .value — simulates real typing and reliably triggers the state.
⏱️ Wait for a CONDITION, not a fixed amount of time roadmap
Today, capture uses wait (ms). Ideally, a waitFor text/selector.
| Approach | wait (ms) — today | waitFor — roadmap |
|---|---|---|
| Criterion | fixed timing | real condition |
| Slow generation | guess the margin | waits for the <img> |
| Risk | too early / slow | happens at the right time |
flux2-klein took ~2.5 min in the POC. Before the result screenshot, poll for a <img> actually loaded in the panel — don’t rely on the clock alone. Changing wait by waitFor is backlog item #3.
🔄 Multi-state asynchronous flows handmade
Analyze → approve → dub → complete: captured as named sub-steps, with completion polling.
Start processing; the status changes. Capture the "analyzing" state.
The flow pauses for approval. It captures the waiting state and the approval action.
Long process; poll for completion between captures.
Final result, zoomed in. Ends the walkthrough before the CTA.
In the POC, the completion poll (poll-job*.sh) was built outside capture.mjs. Embedding it as named substeps with polling is backlog item #4.
⏸️ States like waiting_approval
Event-triggered states (not time-triggered) need a status poll — not a wait fixed.
One waiting_approval changes when someone approves—not when the clock strikes. Waiting X ms may capture too early (or too late).
O waiting_approval is the use case that justifies the waitFor of topic 3: wait for a condition (status changed) instead of a duration.
⚠️ Capture pitfalls
The mistakes that cost the most time—address them before rendering. Details in gotchas.md.
- ✗ Inconsistent viewport → cursor misses the target
- ✗ @eN refs shift after DOM changes
- ✗
eval --jsonnested: data URL indata.result - ✗ Screenshot exceeding the canvas boundaries
- ✓ Same viewport for bbox and shot; recapture everything
- ✓ CSS selectors / {tag,text} + re-snapshot
- ✓ Read
data.result; decode base64 if saving - ✓ Viewport 1280×800 → screenshot x320..1600, y148..948
If the app generates a file (e.g., an image), get the src (data: URL) via eval—which comes in data.result — and decode base64 to PNG, or click the download button.
🗺️ What already works vs. what's on the roadmap
The skill's honest boundary: what capture.mjs does today and what still requires manual work.
- ✓ actions.json: fill, click, clickText, setValue, wait
- ✓ Bounding boxes via getBoundingClientRect → steps.json
- ✓ 1 shot per state + frame + cursor + zoom + CTA
- ✓ Long, multi-state pages, driven manually
- 1. Scroll/scrollIntoView in capture.mjs
- 2. Playwright's native fill for React inputs
- 3. waitFor (condition) instead of a fixed wait
- 4. Embedded multi-state polling · 5. 9:16 · 6. v3 recording
Dynamic state becomes a static screenshot (for real motion, use v3 and record the screen). Apps with login require test credentials. The natural format is 16:9 — 9:16 would require reframing.
🎯 Module summary
- ✓ Long pages: manual scrollIntoView for now (scroll = backlog item #1)
- ✓ React inputs: use setValue (triggers input/change); native fill is #2
- ✓ Wait for a condition (waitFor) > fixed time; poll for the actual <img> (no. 3)
- ✓ Multi-state (analyze→approve→dub→done) with polling (no. 4)
- ✓ Apply the gotchas before rendering; always mark what’s on the roadmap