Skip to main content

terminal-capture

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.

Jump to install

Source facts

Repository
QwenLM/qwen-code
Last source activity
July 30, 2026 at 05:37
Detected SKILL.md language
English
Stars
28,175
Forks
3,119

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
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: ```bash npm install # Install project dependencies. npx playwright install chromium # Install Playwright browser (skip in CI: see note below) ``` > **CI / verify context:** when `QWEN_VERIFY_CHROMIUM=1` is set, the browser > is already installed and `PLAYWRIGHT_BROWSERS_PATH` points at it. Do **not** > run `playwright install` — it downloads ~170 MB and fails on system deps > the agent user cannot install. ## 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/`: ```typescript import type { ScenarioConfig } from '../scenario-runner.js'; export default { name: '/about', spawn: ['node', 'dist/cli.js', '--yolo'], // cwd is relative to this config file's location. terminal: { title: 'qwen-code', cwd: '../../..' }, flow: [ { type: 'Hi, can you help me understand this codebase?' }, { type: '/about' }, ], } satisfies ScenarioConfig; ``` ### 2. Run ```bash # Single scenario npx tsx integration-tests/terminal-capture/run.ts \ integration-tests/terminal-capture/scenarios/about.ts # Batch (entire directory) 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). ```typescript { type: 'Hello'; } // Plain text { type: '/about'; } // Slash command (auto-completion handled automatically) ``` **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` ```typescript { key: 'ArrowDown'; } // Single key { key: ['ArrowDown', 'ArrowDown', 'Enter']; } // Multiple keys ``` 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. ```typescript { type: 'Run this command: bash progress.sh', streaming: { delayMs: 7000, // Wait before first capture (skip initial waiting phase) intervalMs: 500, // Interval between captures count: 20, // Maximum number of captures gif: true, // Generate animated GIF (default: true, requires ffmpeg) }, } ``` - `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: ```bash # Check which ffmpeg # Install (macOS) 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: ```typescript { capture: 'initial.png'; } // Screenshot current viewport only { captureFull: 'all-output.png'; } // Screenshot full scrollback buffer ``` ## Scenario Examples ### Basic: Input + Command ```typescript flow: [{ type: 'explain this project' }, { type: '/about' }]; ``` ### Secondary Menu Selection (/auth) ```typescript flow: [ { type: '/auth' }, { key: 'ArrowDown' }, // Select API Key option { key: 'Enter' }, // Confirm { type: 'sk-xxx' }, // Input API key ]; ``` ### Tab Completion Selection (/export) ```typescript flow: [ { type: 'Tell me about yourself' }, { type: '/export' }, // No auto-Enter (next step is key) { key: 'Tab' }, // Pop format selection { key: 'ArrowDown' }, // Select format { key: 'Enter' }, // Confirm → auto-screenshot ]; ``` ### Array Batch (Multiple Scenarios in One File) ```typescript 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` (local dev only — in CI verify runs, this means the pre-install step failed; report it, do not install). - 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 ```typescript interface FlowStep { type?: string; // Input text key?: string | string[]; // Key press(es) capture?: string; // Viewport screenshot filename captureFull?: string; // Full scrollback screenshot filename streaming?: { delayMs?: number; // Delay before first capture (default: 0) intervalMs: number; // Interval between captures in ms count: number; // Maximum number of captures gif?: boolean; // Generate animated GIF (default: true) }; } interface ScenarioConfig { name: string; // Scenario name (also used as screenshot subdirectory name) spawn: string[]; // Launch command ["node", "dist/cli.js", "--yolo"] flow: FlowStep[]; // Interaction steps terminal?: { cols?: number; // Number of columns, default 100 rows?: number; // Number of rows, default 28 theme?: string; // Theme: dracula|one-dark|github-dark|monokai|night-owl chrome?: boolean; // macOS window decorations, default true title?: string; // Window title, default "Terminal" fontSize?: number; // Font size cwd?: string; // Working directory (relative to config file) }; outputDir?: string; // Screenshot output directory (relative to config file) } ```
View on GitHub