Capture and manage screenshots during test execution
npx skills add https://github.com/testdriverai/testdriverai --skill testdriver:screenshots
<!-- Generated from screenshots.mdx. DO NOT EDIT. -->
TestDriver can capture screenshots manually at any point during a test, or automatically before and after every command. Screenshots are saved to a structured directory for easy debugging.
Use testdriver.screenshot() to capture the current screen:
const path = await testdriver.screenshot();
console.log('Saved to:', path);
// .testdriver/screenshots/my-test/screenshot-1719849312345.png
await testdriver.screenshot(filename?)
<ParamField path="filename" type="string">
Custom filename for the screenshot. .png is appended automatically if missing. If omitted, defaults to screenshot-<timestamp>.png.
</ParamField>
Returns: Promise<string> — the absolute file path of the saved screenshot.
// Default filename
await testdriver.screenshot();
// → .testdriver/screenshots/my-test/screenshot-1719849312345.png
// Custom filename
await testdriver.screenshot('login-page');
// → .testdriver/screenshots/my-test/login-page.png
// With .png extension
await testdriver.screenshot('dashboard-loaded.png');
// → .testdriver/screenshots/my-test/dashboard-loaded.png
Enable automatic screenshots before and after every command:
const testdriver = new TestDriver({
autoScreenshots: true,
});
<ParamField path="autoScreenshots" type="boolean" default={false}>
When true, captures a screenshot before and after every SDK command (click, type, find, scroll, hover, pressKeys, assert, exec, etc.). On error, an error-phase screenshot replaces the after-phase screenshot.
</ParamField>
Auto-screenshots follow this naming convention:
<seq>-<action>-<phase>-L<line>-<description>.png
| Part | Description | Example |
|---|---|---|
| seq | 3-digit zero-padded sequence number | 001 |
| action | Command name | click, type, find |
| phase | before, after, or error | before |
| L<line> | Source line number from your test file | L42 |
| description | Sanitized from command arguments (max 30 chars) | submit-button |
Examples:
001-find-before-L15-login-button.png
002-find-after-L15-login-button.png
003-click-before-L16-login-button.png
004-click-after-L16-login-button.png
005-type-before-L18-username-field.png
006-type-error-L18-username-field.png
| Phase | When | Description |
|---|---|---|
| before | Before command executes | Captures the screen state before the action |
| after | After successful command | Captures the result of the action |
| error | After failed command | Captures the screen at the point of failure (replaces after) |
Screenshots are saved to:
<cwd>/.testdriver/screenshots/<testFileName>/
Where <testFileName> is the test file name without its extension. For example, a test at tests/login.test.mjs saves screenshots to .testdriver/screenshots/login.test/.
The screenshot directory for each test file is automatically cleaned at the start of a test run. This happens once per process per test file to prevent concurrent tests from the same file from interfering with each other.
Elements have a saveDebugScreenshot() method for debugging element detection:
const el = await testdriver.find('submit button');
// Save the screenshot that was used to detect this element
const debugPath = await el.saveDebugScreenshot();
console.log('Debug screenshot:', debugPath);
// → ./debug-screenshot-1719849312345.png
// Custom path
await el.saveDebugScreenshot('./my-debug.png');
This saves the screenshot that was captured during the find() call, which can be useful for understanding what the AI "saw" when locating the element.
import { describe, it, beforeAll, afterAll } from 'vitest';
import TestDriver from 'testdriverai';
describe('Screenshot Example', () => {
let testdriver;
beforeAll(async () => {
testdriver = new TestDriver({
autoScreenshots: true, // capture every step
});
await testdriver.ready();
await testdriver.provision.chrome({ url: 'https://example.com' });
});
afterAll(async () => {
await testdriver.disconnect();
});
it('captures the login flow', async () => {
// Auto-screenshots capture before/after each command
// Manual screenshot for a specific moment
await testdriver.screenshot('initial-page-load');
const username = await testdriver.find('username input');
await username.click();
await testdriver.type('[email protected]');
await testdriver.screenshot('after-username-entry');
const password = await testdriver.find('password input');
await password.click();
await testdriver.type('password123');
await testdriver.find('login button').click();
await testdriver.screenshot('after-login-click');
});
});
After running, your screenshot directory will contain:
.testdriver/screenshots/login-flow.test/
├── initial-page-load.png
├── 001-find-before-L18-username-input.png
├── 002-find-after-L18-username-input.png
├── 003-click-before-L19-username-input.png
├── 004-click-after-L19-username-input.png
├── 005-type-before-L20-testuser-example-com.png
├── 006-type-after-L20-testuser-example-com.png
├── after-username-entry.png
├── 007-find-before-L24-password-input.png
├── ...
Use when the user explicitly asks for a desktop or system screenshot (full screen, specific app or window, or a pixel region), or when tool-specific capture capabilities are unavailable and an OS-level capture is needed.
Mirror an iOS Simulator into the Codex in-app browser and render SwiftUI previews from importable Swift packages in that simulator with hot reload. Use when a user wants to watch or interact with an iOS app in the browser, see a SwiftUI preview outside Xcode Canvas, iterate live on a preview, or capture browser-visible simulator proof.
Annotate UI screenshots with documentation callouts in Fellyph's established visual style — uniform-width orange arrows with white halos, double-stroke target outlines, numbered callout cards, dim overlays and a framed canvas. Use this whenever the user asks to annotate a screenshot, add arrows or callouts to a screenshot, create documentation images, highlight UI controls in a capture, or produce docs/tutorial visuals for Playground, Studio or any web UI — even if they just say "add arrows to this" or "make a docs screenshot".
Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.
> End-to-end skill that turns a single reference image into a published Gooseworks style — analyzes the image, drafts the slim style spec, renders a hero example plus 2-3 additional formats via Playwright, writes the `gooseworks-style.json` manifest, and publishes via `npx gooseworks styles publish` so other agents can discover it. Mirrors goose-graphics-create-format but for styles.
Resize and validate App Store screenshots with current asc screenshot-size data and macOS sips. Use when preparing or fixing screenshots for App Store Connect submission.
Generates an automated App Store screenshot pipeline with UI tests for screenshot capture, device framing, localized caption overlays, and multi-size batch export. Use when user wants automated screenshots, App Store screenshot generation, or a fastlane snapshot replacement.
Dependency checker and installer for agent-canvas, agent-eyes, and canvas-edit skills. Use BEFORE running any canvas skill for the first time, or when canvas skills fail with import/browser errors. Triggers on "setup agent canvas", "install canvas dependencies", "canvas not working", "playwright not found", or any setup/installation request for canvas skills.
Take testdriverai/testdriver:screenshots from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.