test: screenshot harness for the interactive UI - #122
Conversation
There was a problem hiding this comment.
Caution
Changes requested ❌ — 1 issue
Reviewed 7171890 in 11 minutes, 19 seconds.
- Reviewed
1commit with545lines of code in6files - Ran
1review agent producing1comment where1was posted - This pipeline runs no gatekeeper, so findings are posted as written.
- View full details on ellipsis.dev
This review was created by . You can tag
@ellipsis in this pull request.
| // interactive pinned on: ink treats CI as non-interactive and would buffer | ||
| // one final frame — no repaints, no alt-screen hop, nothing this harness is | ||
| // for (same reason connect-render.test.ts pins it). | ||
| const app = render(element, { stdout, stdin, patchConsole: false, interactive: true }) |
There was a problem hiding this comment.
The harness renders with every style stripped, so the PNGs are monochrome and the whole colour path is dead code: chalk sizes itself from the real process.stdout, which is never a TTY inside a vitest worker, so ink emits no SGR bytes at all. Pin the level in the harness.
Measured in this repo: under npx vitest run (piped and under a pty) chalk.level === 0, and ink's output for <Text color="#ff8800" bold> is literally HELLO with no escape. So renderPng's fg/bg, isInverse, bold/dim/italic/underline branches and the entire 256-colour palette never fire — the four committed screenshots are default-fg-on-default-bg, and a human reviewing one cannot see a colour, emphasis or surface regression. With chalk.level = 3 the same run renders the brand cursor, the bold header and the composer's inputSurface fill; note it also changes 2 of the 3 text snapshots (painted cells stop being trimmed as trailing whitespace), so those need regenerating with the fix.
| // interactive pinned on: ink treats CI as non-interactive and would buffer | |
| // one final frame — no repaints, no alt-screen hop, nothing this harness is | |
| // for (same reason connect-render.test.ts pins it). | |
| const app = render(element, { stdout, stdin, patchConsole: false, interactive: true }) | |
| // interactive pinned on: ink treats CI as non-interactive and would buffer | |
| // one final frame — no repaints, no alt-screen hop, nothing this harness is | |
| // for (same reason connect-render.test.ts pins it). | |
| // Colour pinned on for the same class of reason: chalk sizes itself from the | |
| // REAL process.stdout, which is never a TTY under vitest, so without this ink | |
| // emits no SGR bytes and every screenshot comes out monochrome. | |
| ;(await import('chalk')).default.level = 3 | |
| const app = render(element, { stdout, stdin, patchConsole: false, interactive: true }) |
Important
Adds a screenshot harness for end-to-end testing of the interactive terminal UI.
test/screenshot.tssets up a fake terminal emulator using@xterm/headless, feeds rendered ink output through it, and exposespage.text()(plain text for CI snapshots) andpage.png(name)(PNG for visual review). Network and timers are stubbed. Window resize and key presses (named keys and literals) are supported.test/screenshot.test.tscovers three flows — new-session composer startup, session picker navigation with keyboard, and opening a session chat. Tests save both text snapshots (for assertion) and PNG images totest/__screenshots__/.@resvg/resvg-js, capturing text content, colors, and style (bold, italic, underline) faithfully.@resvg/resvg-js@^2.6.2and@xterm/headless@^6.0.0.This description was created by
for 7171890. It will automatically update as commits are pushed.