---
title: "Screenshots"
sidebarTitle: "Screenshots"
description: "Capture and manage screenshots during test execution"
icon: "camera"
mode: "wide"
---

## 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:

```javascript
const path = await testdriver.screenshot();
console.log('Saved to:', path);
// .testdriver/screenshots/my-test/screenshot-1719849312345.png
```

### Options

```javascript
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.

```javascript
// 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:

```javascript
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>

### Filename Format

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:

```javascript
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

```javascript
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
├── ...
```
