Overview
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.
Manual Screenshots
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
Options
await testdriver.screenshot(filename?)
Custom filename for the screenshot. .png is appended automatically if missing. If omitted, defaults to screenshot-<timestamp>.png.
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
Auto Screenshots
Enable automatic screenshots before and after every command:
const testdriver = new TestDriver({
autoScreenshots: true,
});
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.
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
Phases
| 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) |
Screenshot Directory
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/.
Directory Cleanup
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.
Debug Screenshots
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.
Complete Example
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
├── ...