testdriver-agent
How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Capture and manage screenshots during test execution
$ npx -y skills add testdriverai/testdriverai --skill testdriver-screenshots --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/testdriver-screenshotsContext preview
The summary Claude sees to decide when to auto-load this skill.
Capture and manage screenshots during test execution
name: testdriver:screenshots description: Capture and manage screenshots during test execution
<!-- 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.pngawait 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.pngEnable 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('testuser@example.com');
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 ├── ...
Repo: testdriverai/testdriverai
How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Deploy TestDriver on your AWS infrastructure using CloudFormation
How TestDriver learns your app and caches what it discovers for instant, deterministic replays