Visual HTML report
The visual report is a single offline HTML file that lets you replay a Tales run action by action, screenshot by screenshot. It is designed for mobile runs today; the data model is shaped so a future web/browser provider can slot in without changes.
Quick start
Section titled “Quick start”tales test ./e2e/ios/pass \ --seed 1234 \ --report-html build/reports/visual.html \ --capture-screenshots actionsOpen build/reports/visual.html in any modern browser. The file is fully offline, no CDN, no network requests, no npm.
CLI flags
Section titled “CLI flags”| Flag | Description |
|---|---|
--report-html <path> | Write the visual HTML report to <path>. The parent directory is created if missing. |
--capture-screenshots <mode> | Pick the screenshot capture mode. One of none, failures, steps, actions. |
Default capture mode
Section titled “Default capture mode”| Flags passed | Effective mode |
|---|---|
| neither | failures (legacy) |
--report-html only | actions |
explicit --capture-screenshots | always wins |
Invalid values exit with code 2 and a message listing the four supported modes.
Layout
Section titled “Layout”The HTML follows a macOS-Setup aesthetic:
- dark gradient backdrop, centered light card with soft shadow
- screenshot pane on the left
- vertical action timeline on the right, grouped by step: each step contributes a header (name + status pill + duration) followed by its actions in execution order; the active action is centered and highlighted, previous actions above, future actions below
- playback controls below: previous / play-pause / next, speed selector (0.5×, 0.75×, 1×, 1.5×, 2×), progress bar
- header has a scenario selector plus an overall status pill
Keyboard shortcuts:
| Key | Action |
|---|---|
Space | Play / pause |
→ | Next action |
← | Previous action |
Home | First action |
End | Last action |
Playback timing is derived from each action’s measured duration, clamped to [500ms, 3000ms] and divided by the current speed factor. Long real waits (wait_visible with a 10s timeout) therefore show their real duration in the action label but are scrubbed quickly during playback.
Artifact layout
Section titled “Artifact layout”When a capture mode writes artifacts, they are nested under the existing mobile artifacts tree so screenshots stay grouped with the failure artifacts they belong to:
build/artifacts/mobile/ <scenario>-<hash>/ <step>/ <phase>/ attempt-<n>/ actions/ 0000-tap-welcome.register/ screenshot.png hierarchy.json 0001-input_text-register.email/ screenshot.png hierarchy.json step/ screenshot.png # CaptureSteps mode only hierarchy.json screenshot.png # legacy step-level failure hierarchy.jsonNo screenshot or hierarchy is ever written. Step-level failure artifacts that previously appeared on failure are also suppressed. The only artifact still surfaced is the driver_log produced when the embedded driver fails to start, because it is the only way to debug a non-starting driver.
failures (default without --report-html)
Section titled “failures (default without --report-html)”Matches the pre-visual-report behavior: one screenshot and one hierarchy written at the step level on failure. Per-action results are still recorded in the data model (with no screenshot paths) so JSONL action events and the HTML timeline can still list what was queued.
One screenshot and one hierarchy captured at the end of each step. Internally a synthetic step_end ActionResult is appended after the real actions; the visual timeline renders one extra tile per step.
actions
Section titled “actions”One screenshot and one hierarchy captured after each UI action succeeds, plus a best-effort capture on the failing action. This is the mode that makes the replay feel like a video. Used automatically when --report-html is provided.
Secure values
Section titled “Secure values”scripts/verify-ios-visual.sh greps the rendered HTML for a list of known-demo secrets (hunter2, Secret123) and fails the build if any leaks. Add new canaries to that list when introducing new demo secrets.
Performance notes
Section titled “Performance notes”Per-action capture in actions mode adds a Screenshot() and a Hierarchy() call to every UI action. On a slow simulator this can add several seconds per scenario. Recommendations:
- CI, stick to
failuresunless you specifically want the visual replay. - Local debugging, run
--capture-screenshots actionsonly when needed. - Capture errors never mask the underlying action error. They are silently dropped: the action’s status, duration, and error reflect the real operation, while the missing screenshot / hierarchy fields on that action signal that the capture itself failed.
Known limitations (V1)
Section titled “Known limitations (V1)”- Screenshot-based, not real video. No MP4 generation.
- No visual diff between runs.
- Mobile provider only. HTTP and keyword steps appear as plain entries with no screenshots. A web/browser provider is planned.
- Assets are external files by default (no base64 embedding). Moving the HTML file without moving
build/artifacts/breaks image references, copy the artifacts tree alongside. - Relative-path conversion falls back to the absolute path if
filepath.Relfails (cross-volume on Windows). The report still works locally but loses portability.
Integration with other reporters
Section titled “Integration with other reporters”- Console, prints
HTML report: <path>after writing. - JSONL (
--report-jsonl), emits one"type":"action"event per action after the step event whenstep.Actionsis populated. Empty action slices produce byte-identical JSONL to the pre-visual-report format. - JUnit (
--report-junit), unchanged. Action-level data is intentionally not flattened into JUnit XML.