| name | terminal-capture |
| description | Automates terminal UI screenshot testing for CLI commands. Applies when reviewing PRs that affect CLI output, testing slash commands (/about, /context, /auth, /export), generating visual documentation, or when 'terminal screenshot', 'CLI test', 'visual test', or 'terminal-capture' is mentioned. |
Terminal Capture — CLI Terminal Screenshot Automation
Drive terminal interactions and screenshots via TypeScript configuration, used
for visual verification during PR reviews.
Prerequisites
Ensure the following dependencies are installed before running:
npm install
npx playwright install chromium
Architecture
node-pty (pseudo-terminal)
→ ANSI byte stream
→ xterm.js (Playwright headless)
→ Screenshot
Core files:
integration-tests/terminal-capture/terminal-capture.ts
Low-level PTY, xterm.js, and Playwright engine.
integration-tests/terminal-capture/scenario-runner.ts
Scenario executor for config, interactions, and screenshots.
integration-tests/terminal-capture/run.ts
CLI entry point for batch scenario runs.
integration-tests/terminal-capture/scenarios/*.ts
Scenario configuration files.
Quick Start
1. Write Scenario Configuration
Create a .ts file under integration-tests/terminal-capture/scenarios/:
import type { ScenarioConfig } from '../scenario-runner.js';
export default {
name: '/about',
spawn: ['node', 'dist/cli.js', '--yolo'],
terminal: { title: 'glm-code', cwd: '../../..' },
flow: [
{ type: 'Hi, can you help me understand this codebase?' },
{ type: '/about' },
],
} satisfies ScenarioConfig;
2. Run
npx tsx integration-tests/terminal-capture/run.ts \
integration-tests/terminal-capture/scenarios/about.ts
npx tsx integration-tests/terminal-capture/run.ts \
integration-tests/terminal-capture/scenarios/
3. Output
Screenshots are saved to
integration-tests/terminal-capture/scenarios/screenshots/{name}/:
| File | Description |
|---|
01-01.png | Step 1 input state |
01-02.png | Step 1 execution result |
02-01.png | Step 2 input state |
02-02.png | Step 2 execution result |
full-flow.png | Final state full-length screenshot |
FlowStep API
Each flow step can contain the following fields:
type: string — Input Text
Automatic behavior:
Input text → Screenshot (01) → Enter → stable output → Screenshot (02).
{
type: 'Hello';
}
{
type: '/about';
}
Special rule: If the next step is key, do not auto-press Enter (hand over
control to the key sequence).
key: string | string[] — Send Key Press
Used for menu selection, Tab completion, and other interactions. Does not
auto-press Enter or auto-screenshot.
Supported key names: ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Enter,
Tab, Escape, Backspace, Space, Home, End, PageUp, PageDown,
Delete
{
key: 'ArrowDown';
}
{
key: ['ArrowDown', 'ArrowDown', 'Enter'];
}
Auto-screenshot is triggered after the key sequence ends (when the next step is
not a key).
streaming — Capture During Execution
Capture multiple screenshots at intervals during long-running output (e.g.,
progress bars). Optionally generates an animated GIF.
{
type: 'Run this command: bash progress.sh',
streaming: {
delayMs: 7000,
intervalMs: 500,
count: 20,
gif: true,
},
}
delayMs (optional): Milliseconds to wait after pressing Enter before
starting captures. Useful for skipping model thinking/approval time.
- Captures stop early if terminal output is unchanged for 3 consecutive
intervals.
- Duplicate frames (no output change) are automatically skipped.
GIF prerequisite: If the scenario uses streaming with GIF enabled
(default), check if ffmpeg is installed before running. If not, ask the user
whether they'd like to install it:
which ffmpeg
brew install ffmpeg
If the user declines, the scenario still runs. GIF generation is skipped with a
warning.
capture / captureFull — Explicit Screenshot
Use as a standalone step, or override automatic naming:
{
capture: 'initial.png';
}
{
captureFull: 'all-output.png';
}
Scenario Examples
Basic: Input + Command
flow: [{ type: 'explain this project' }, { type: '/about' }];
Secondary Menu Selection (/auth)
flow: [
{ type: '/auth' },
{ key: 'ArrowDown' },
{ key: 'Enter' },
{ type: 'sk-xxx' },
];
Tab Completion Selection (/export)
flow: [
{ type: 'Tell me about yourself' },
{ type: '/export' },
{ key: 'Tab' },
{ key: 'ArrowDown' },
{ key: 'Enter' },
];
Array Batch (Multiple Scenarios in One File)
export default [
{ name: '/about', spawn: [...], flow: [...] },
{ name: '/context', spawn: [...], flow: [...] },
] satisfies ScenarioConfig[];
Integration with PR Review
This tool is commonly used for visual verification during PR reviews.
Troubleshooting
- Playwright error
browser not found
Cause: browser not installed.
Solution: npx playwright install chromium.
- Blank screenshot
Cause: process starts slowly or build failed.
Solution: check build success and the spawn command.
- PTY-related errors
Cause: node-pty native module not compiled.
Solution:
npm rebuild node-pty.
- Unstable screenshot output
Cause: terminal output not fully rendered.
Solution: add scenario wait time.
Full ScenarioConfig Type
interface FlowStep {
type?: string;
key?: string | string[];
capture?: string;
captureFull?: string;
streaming?: {
delayMs?: number;
intervalMs: number;
count: number;
gif?: boolean;
};
}
interface ScenarioConfig {
name: string;
spawn: string[];
flow: FlowStep[];
terminal?: {
cols?: number;
rows?: number;
theme?: string;
chrome?: boolean;
title?: string;
fontSize?: number;
cwd?: string;
};
outputDir?: string;
}