> ## Documentation Index
> Fetch the complete documentation index at: https://docs.testdriver.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# screenshot()

> Capture and save screenshots during test execution

## Overview

Capture a screenshot of the current screen and automatically save it to a local file. Screenshots are organized by test file for easy debugging and review.

<Note>
  **Automatic Screenshots**: TestDriver can automatically capture screenshots before and after every command (click, type, find, etc.). These are saved with descriptive filenames like `001-click-before-L42-submit-button.png` that include the line number from your test file. Enable this with `autoScreenshots: true` in your TestDriver options.
</Note>

## Syntax

```javascript theme={null}
const filePath = await testdriver.screenshot(filename)
```

## Parameters

<ParamField path="filename" type="string" optional>
  Custom filename for the screenshot (without .png extension). If not provided, a timestamp-based filename is generated automatically.
</ParamField>

## Returns

`Promise<string>` - The absolute file path where the screenshot was saved

## File Organization

Screenshots are automatically saved to `.testdriver/screenshots/<test-file-name>/` in your project root:

```
.testdriver/
  screenshots/
    login.test/
      001-find-before-L15-email-input.png     # Auto: before find()
      002-find-after-L15-email-input.png      # Auto: after find()
      003-click-before-L16-email-input.png    # Auto: before click()
      004-click-after-L16-email-input.png     # Auto: after click()
      005-type-before-L17-userexamplecom.png  # Auto: before type()
      006-type-after-L17-userexamplecom.png   # Auto: after type()
      custom-screenshot.png                    # Manual: screenshot("custom-screenshot")
    checkout.test/
      001-find-before-L12-checkout-button.png
      ...
```

### Automatic Screenshot Naming

When `autoScreenshots` is enabled, filenames follow this format:

`<seq>-<action>-<phase>-L<line>-<description>.png`

| Component     | Description                          | Example                 |
| ------------- | ------------------------------------ | ----------------------- |
| `seq`         | Sequential number (001, 002, ...)    | `001`                   |
| `action`      | Command name                         | `click`, `type`, `find` |
| `phase`       | Before, after, or error              | `before`, `after`       |
| `L<line>`     | Line number from test file           | `L42`                   |
| `description` | Element description or action target | `submit-button`         |

<Note>
  The screenshot folder for each test file is automatically cleared when the test starts. This ensures you only see screenshots from the most recent test run.
</Note>

## Examples

### Basic Screenshot

```javascript theme={null}
// Capture a screenshot with auto-generated filename
const screenshotPath = await testdriver.screenshot();
console.log('Screenshot saved to:', screenshotPath);
```

### Custom Filename

```javascript theme={null}
// Save with a descriptive filename
await testdriver.screenshot("login-page");
// Saves to: .testdriver/screenshots/<test>/login-page.png

await testdriver.screenshot("after-click");
// Saves to: .testdriver/screenshots/<test>/after-click.png
```

### Debugging with Screenshots

```javascript theme={null}
import { describe, expect, it } from "vitest";
import { TestDriver } from "testdriverai/vitest/hooks";

describe("Login Flow", () => {
  it("should log in successfully", async (context) => {
    const testdriver = TestDriver(context);
    
    await testdriver.provision.chrome({
      url: 'https://myapp.com/login',
    });

    // Capture initial state
    await testdriver.screenshot();

    // Fill in login form
    const emailInput = await testdriver.find("email input");
    await emailInput.click();
    await testdriver.type("user@example.com");

    // Capture state after typing
    await testdriver.screenshot();

    const passwordInput = await testdriver.find("password input");
    await passwordInput.click();
    await testdriver.type("password123");

    // Capture before clicking login
    await testdriver.screenshot();

    const loginButton = await testdriver.find("Login button");
    await loginButton.click();

    // Capture after login attempt
    await testdriver.screenshot();

    const result = await testdriver.assert("dashboard is visible");
    expect(result).toBeTruthy();
  });
});
```

## Automatic Screenshots

By default, TestDriver captures screenshots **automatically** before and after every command. This creates a complete visual timeline of your test execution without any additional code.

### Enabling/Disabling

```javascript theme={null}
// Auto-screenshots enabled by default
const testdriver = TestDriver(context);

// Explicitly disable if needed (not recommended)
const testdriver = TestDriver(context, {
  autoScreenshots: false
});
```

### What Gets Captured

Automatic screenshots are taken around these commands:

* `find()` / `findAll()`
* `click()` / `hover()` / `doubleClick()` / `rightClick()`
* `type()` / `pressKeys()`
* `scroll()`
* `waitForText()` / `waitForImage()`
* `focusApplication()`
* `assert()` / `extract()` / `exec()`

### Example Output

For this test code:

```javascript theme={null}
// Line 15: Find email input
const emailInput = await testdriver.find("email input");
// Line 16: Click it
await emailInput.click();
// Line 17: Type email
await testdriver.type("user@example.com");
```

TestDriver automatically saves:

```
001-find-before-L15-email-input.png
002-find-after-L15-email-input.png
003-click-before-L16-email-input.png
004-click-after-L16-email-input.png
005-type-before-L17-userexamplecom.png
006-type-after-L17-userexamplecom.png
```

If an error occurs, the phase will be `error` instead of `after`.

## Best Practices

<AccordionGroup>
  <Accordion title="Let automatic screenshots do the work">
    With `autoScreenshots: true`, you get comprehensive coverage without adding manual `screenshot()` calls. Only add manual screenshots for specific named checkpoints.
  </Accordion>

  <Accordion title="Use screenshots for debugging flaky tests">
    When a test fails intermittently, add screenshots at key steps to capture the actual screen state. This helps identify timing issues or unexpected UI states.
  </Accordion>

  <Accordion title="Capture before assertions">
    Take a screenshot before making assertions. If the assertion fails, you'll have a visual record of what the screen looked like.

    ```javascript theme={null}
    await testdriver.screenshot();
    const result = await testdriver.assert("checkout button is visible");
    ```
  </Accordion>

  <Accordion title="Add to .gitignore">
    Add `.testdriver/screenshots/` to your `.gitignore` to avoid committing screenshots to version control:

    ```
    # .gitignore
    .testdriver/screenshots/
    ```
  </Accordion>
</AccordionGroup>

## Viewing Saved Screenshots

After saving screenshots during test execution, you can view them using TestDriver MCP commands. This is especially useful for debugging failed tests or verifying test behavior.

### MCP Commands for Screenshot Viewing

**List all saved screenshots:**

```
list_local_screenshots()
```

**View a specific screenshot:**

```
view_local_screenshot({ path: "/full/path/to/screenshot.png" })
```

These commands allow you to:

* View screenshots from failed tests to understand what went wrong
* Review test execution flow by examining screenshots in chronological order
* Compare screenshots across test runs to identify flaky behavior

<Note>
  For detailed workflows and examples of using these MCP commands for debugging, see the [Debugging with Screenshots](/v7/debugging-with-screenshots) guide.
</Note>

## Related

* [Debugging with Screenshots](/v7/debugging-with-screenshots) - View and analyze saved screenshots using MCP
* [assert()](/v7/assert) - Make AI-powered assertions
* [find()](/v7/find) - Locate elements on screen
