---
id: app/guides/screenshots-and-videos
title: Capture screenshots and videos in Cypress
description: >-
  Capture screenshots and videos of your tests with Cypress and configure
  settings for them.
section: app
source_path: docs/app/guides/screenshots-and-videos.mdx
version: 3163d68b20e695f2c76d40c85c3f3b956dd19a3b
updated_at: '2026-08-21T20:59:04.402Z'
---
# Screenshots and Videos

What you'll learn

*   How to capture screenshots and videos
*   How to configure screenshot and video settings
*   How to delete videos for specs without failing or retried tests

**Debugging Cypress Cloud Test Runs?**

Don't rely on artifact representations or reproducing failing conditions locally. Replay the test as it executed during the recorded run with full debug capability using [Test Replay](/llm/markdown/cloud/features/test-replay.md).

## Screenshots

Cypress comes with the ability to take screenshots, whether you are running via `cypress open` or `cypress run`, even in CI.

To take a manual screenshot you can use the [`cy.screenshot()`](/llm/markdown/api/commands/screenshot.md) command.

Additionally, Cypress will automatically capture screenshots when a failure happens during `cypress run`. Screenshots on failure are _not_ automatically taken during `cypress open`.

Capturing of screenshots when a test fails can be turned off entirely by setting [`screenshotOnRunFailure`](/llm/markdown/app/references/configuration.md#Screenshots) to `false` from within the [Cypress configuration](/llm/markdown/app/references/configuration.md) or by setting `screenshotOnRunFailure` to `false` in the [Cypress.Screenshot.defaults()](/llm/markdown/api/cypress-api/screenshot-api.md).

Screenshots are stored in the [`screenshotsFolder`](/llm/markdown/app/references/configuration.md#Screenshots) which is set to `cypress/screenshots` by default.

Before `cypress run`, Cypress clears the **entire contents** of the `screenshotsFolder`—every file and nested subfolder, not just images. If you do not want to clear your screenshots folder before a run, you can set [`trashAssetsBeforeRuns`](/llm/markdown/app/references/configuration.md#Screenshots) to `false`. See the [`trashAssetsBeforeRuns` notes](/llm/markdown/app/references/configuration.md#trashAssetsBeforeRuns) for more details.

## Videos

Video recording is disabled by default, but can be turned on by setting [`video`](/llm/markdown/app/references/configuration.md#Videos) to `true` from within your configuration.

If enabled, Cypress records a video for each spec file when running tests during `cypress run`. Videos are _not_ recorded during `cypress open`.

*   cypress.config.js
*   cypress.config.ts

```
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  video: true,
})
```

```
import { defineConfig } from 'cypress'

export default defineConfig({
  video: true,
})
```

Videos are stored in the [`videosFolder`](/llm/markdown/app/references/configuration.md#Videos) which is set to `cypress/videos` by default.

When using the `--record` flag while running your tests, videos are processed, compressed, and uploaded to [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md) after every spec file runs, successful or not. To change this behavior to only process videos in the case that tests fail, see how to [delete videos for specs without failing or retried tests](/llm/markdown/app/guides/screenshots-and-videos.md#Delete-videos-for-specs-without-failing-or-retried-tests). Deleting the video will cause the video to not be uploaded to Cypress Cloud.

Before `cypress run`, Cypress clears the **entire contents** of the `videosFolder`—every file and nested subfolder, not just videos. If you do not want to clear your videos folder before a run, you can set [`trashAssetsBeforeRuns`](/llm/markdown/app/references/configuration.md#Videos) to `false`. See the [`trashAssetsBeforeRuns` notes](/llm/markdown/app/references/configuration.md#trashAssetsBeforeRuns) for more details.

### Video encoding

After a video is recorded, Cypress encodes the video to a commonly digestable format. Part of this encoding process includes video compression.

Compression is disabled by default, meaning this step will be skipped completely, so the file size of the video will be larger, but the encoding process is faster. Setting [`videoCompression`](/llm/markdown/app/references/configuration.md#Videos) to `true` will coerce the video compression value to 32 Constant Rate Factor (CRF), which takes longer to process, but results in a smaller video.

**Enabling compression**

*   cypress.config.js
*   cypress.config.ts

```
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  videoCompression: true,
})
```

```
import { defineConfig } from 'cypress'

export default defineConfig({
  videoCompression: true,
})
```

If your spec files have a long run duration and [`videoCompression`](/llm/markdown/app/references/configuration.md#Videos) is enabled, you might notice a time gap between a finished spec and a new spec starting during `cypress run`. During this time, Cypress is encoding the captured video and possibly uploading it to Cypress Cloud.

**Change compression value from 32**

*   cypress.config.js
*   cypress.config.ts

```
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  videoCompression: 15,
})
```

```
import { defineConfig } from 'cypress'

export default defineConfig({
  videoCompression: 15,
})
```

In addition to enabling or disabling video compress, you can specify the CRF value used to compress the video. Here are some common scenarios:

*   If the machine is encoding the video slowly (which is often the case for virtual machines that use less CPU cores), try increasing the CRF value.
    
*   If your videos are extremely low quality, try decreasing the CRF value.
    

A lower `videoCompression` value will spend less time compressing and result in a bigger video file size and higher quality video.

If you are an FFmpeg pro and want to see all the settings and debug messages during the encoding, run Cypress with the following system environment variable:

```
DEBUG=cypress:server:video
```

### Video chapters

While encoding a video, Cypress embeds chapter markers into the resulting `.mp4` file, one for each test attempt in the spec. Video players that support chapters, such as VLC, QuickTime, and IINA, use these markers to let you jump to a specific test instead of scrubbing through the whole recording. Each chapter is titled with the full title of the test, including the titles of the suites it is nested in. When a test runs more than once because of [test retries](/llm/markdown/app/guides/test-retries.md), each attempt gets its own chapter.

Chapters are only written during video compression, and [`videoCompression`](/llm/markdown/app/references/configuration.md#Videos) is disabled by default. To get chapters, enable both `video` and `videoCompression`.

*   cypress.config.js
*   cypress.config.ts

```
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  video: true,
  videoCompression: true,
})
```

```
import { defineConfig } from 'cypress'

export default defineConfig({
  video: true,
  videoCompression: true,
})
```

Setting `videoCompression` to a CRF value such as `15` also produces chapters. Setting it to `false` or `0` skips encoding entirely, so the video contains no chapters.

Chapters only help when you open the video file yourself. Record your runs to [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md) and you get this for free: every test in the run is listed alongside its video, and selecting one takes you straight to that moment, with no chapters to configure and no scrubbing.

Skip the video and debug the run with [Test Replay](/llm/markdown/cloud/features/test-replay.md). Rather than watching a recording, you replay the test exactly as it executed in CI, so you can time travel to the point of failure and inspect the DOM, network requests, console logs, JavaScript errors, and element rendering, giving you the same debugging experience you have locally without reproducing the failure on your machine.

### Control which videos to keep and upload to Cypress Cloud

You may want to have more control over which videos you want to keep and upload to Cypress Cloud. Deleting videos after the run can save resource space on the machine as well as skip the time used to process, compress, and upload the video to [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md).

To only process videos in the case that a test fails, you can [delete videos for specs without failing or retried tests](/llm/markdown/app/guides/screenshots-and-videos.md#Delete-videos-for-specs-without-failing-or-retried-tests), which will not upload the video of passed runs to Cypress Cloud.

For more fine grained control, you can use Cypress's [`after:spec`](/llm/markdown/api/node-events/after-spec-api.md) event listener that fires after each spec file is run and delete the video when certain conditions are met.

### Delete videos for specs without failing or retried tests

The example below shows how to delete the recorded video for specs that had no retry attempts or failures when using Cypress [test retries](/llm/markdown/app/guides/test-retries.md).

*   cypress.config.js
*   cypress.config.ts

```
const { defineConfig } = require('cypress')
const fs = require('fs')

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    setupNodeEvents(on, config) {
      on('after:spec', (spec, results) => {
        if (results && results.video) {
          // Do we have failures for any retry attempts?
          const failures = results.tests.some((test) =>
            test.attempts.some((attempt) => attempt.state === 'failed')
          )
          if (!failures) {
            // delete the video if the spec passed and no tests retried
            fs.unlinkSync(results.video)
          }
        }
      })
    },
  },
})
```

```
import { defineConfig } from 'cypress'
import fs from 'fs'

export default defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    setupNodeEvents(on, config) {
      on(
        'after:spec',
        (spec: Cypress.Spec, results: CypressCommandLine.RunResult) => {
          if (results && results.video) {
            // Do we have failures for any retry attempts?
            const failures = results.tests.some((test) =>
              test.attempts.some((attempt) => attempt.state === 'failed')
            )
            if (!failures) {
              // delete the video if the spec passed and no tests retried
              fs.unlinkSync(results.video)
            }
          }
        }
      )
    },
  },
})
```

## Now What?

So you are capturing screenshots and recording videos of your test runs, now what?

### Share Them With Your Team

Something you can take advantage of today is [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md): our companion enterprise service that stores your artifacts for you and lets you view them from any web browser, as well as share them with your team.

### Visual Regression Test / Screenshot Diffing

Another possibility is visual regression testing: comparing screenshots of past runs with the current run to ensure that nothing changed. [Read about how to implement visual testing.](/llm/markdown/app/tooling/visual-testing.md)

## See also

*   [After Screenshot API](/llm/markdown/api/node-events/after-screenshot-api.md)
*   [Cypress.Screenshot](/llm/markdown/api/cypress-api/screenshot-api.md)
*   [`cy.screenshot()`](/llm/markdown/api/commands/screenshot.md)
*   [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md)
*   [Test Replay](/llm/markdown/cloud/features/test-replay.md)
*   [Visual Testing](/llm/markdown/app/tooling/visual-testing.md)
