.qwen/skills/terminal-capture/SKILL.md
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.
npx skillsauth add qwenlm/qwen-code terminal-captureInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Drive terminal interactions and screenshots via TypeScript configuration, used for visual verification during PR reviews.
Ensure the following dependencies are installed before running:
npm install # Install project dependencies (including node-pty, xterm, playwright, etc.)
npx playwright install chromium # Install Playwright browser
node-pty (pseudo-terminal) → ANSI byte stream → xterm.js (Playwright headless) → Screenshot
Core files:
| File | Purpose |
| -------------------------------------------------------- | ------------------------------------------------------------------------ |
| integration-tests/terminal-capture/terminal-capture.ts | Low-level engine (PTY + xterm.js + Playwright) |
| integration-tests/terminal-capture/scenario-runner.ts | Scenario executor (parses config, drives interactions, auto-screenshots) |
| integration-tests/terminal-capture/run.ts | CLI entry point (batch run scenarios) |
| integration-tests/terminal-capture/scenarios/*.ts | Scenario configuration files |
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: 'qwen-code', cwd: '../../..' }, // Relative to this config file's location
flow: [
{ type: 'Hi, can you help me understand this codebase?' },
{ type: '/about' },
],
} satisfies ScenarioConfig;
# 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/
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 |
Each flow step can contain the following fields:
type: string — Input TextAutomatic behavior: Input text → Screenshot (01) → Press Enter → Wait for output to stabilize → Screenshot (02).
{
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 PressUsed 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';
} // 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 ExecutionCapture 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, // 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.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:
# 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 ScreenshotUse as a standalone step, or override automatic naming:
{
capture: 'initial.png';
} // Screenshot current viewport only
{
captureFull: 'all-output.png';
} // Screenshot full scrollback buffer
flow: [{ type: 'explain this project' }, { type: '/about' }];
flow: [
{ type: '/auth' },
{ key: 'ArrowDown' }, // Select API Key option
{ key: 'Enter' }, // Confirm
{ type: 'sk-xxx' }, // Input API key
];
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
];
export default [
{ name: '/about', spawn: [...], flow: [...] },
{ name: '/context', spawn: [...], flow: [...] },
] satisfies ScenarioConfig[];
This tool is commonly used for visual verification during PR reviews.
| Issue | Cause | Solution |
| ------------------------------------ | ------------------------------------- | ---------------------------------------------------- |
| Playwright error browser not found | Browser not installed | npx playwright install chromium |
| Blank screenshot | Process starts slowly or build failed | Ensure npm run build succeeds, check spawn command |
| PTY-related errors | node-pty native module not compiled | npm rebuild node-pty |
| Unstable screenshot output | Terminal output not fully rendered | Check if the scenario needs additional wait time |
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)
}
development
Review changed code for correctness, security, code quality, and performance. Use when the user asks to review code changes, a PR, or specific files. Invoke with `/review`, `/review <pr-number>`, `/review <file-path>`, or `/review <pr-number> --comment` to post inline comments on the PR.
tools
Answer any question about Qwen Code usage, features, configuration, and troubleshooting by referencing the official user documentation. Also helps users view or modify their settings.json. Invoke with `/qc-helper` followed by a question, e.g. `/qc-helper how do I configure MCP servers?` or `/qc-helper change approval mode to yolo`.
development
Create a recurring loop that runs a prompt on a schedule. Usage - /loop 5m check the build, /loop check the PR every 30m, /loop run tests (defaults to 10m). /loop list to show jobs, /loop clear to cancel all.
tools
Generate synonyms for words or phrases. Use this skill when the user needs alternative words with similar meanings, wants to expand vocabulary, or seeks varied expressions for writing.