ScreenshotNeo

BlogHow-to

Cypress Screenshot Not Working in GitLab CI: Fix

Fix missing Cypress screenshots in GitLab CI by checking file creation, Cypress settings, and GitLab artifact paths in the right order.

By the ScreenshotNeo team4 October 20266 min read

Fix: configure the GitLab test job to collect Cypress’s nested screenshot files even when the job fails. Add when: always and cypress/screenshots/**/*.png under artifacts. If GitLab still shows no screenshots, check that Cypress created files during cypress run, that automatic failure screenshots are enabled, and that the artifact path matches the effective screenshotsFolder.

Cypress creating a screenshot and GitLab retaining it are separate steps. First check the job workspace; then configure GitLab to upload the files. Artifact settings cannot recover a file Cypress never wrote.

1. Collect screenshots as GitLab artifacts

In the GitLab CI job that runs Cypress, add this artifact configuration:

test:e2e:
  script:
    - npx cypress run
  artifacts:
    when: always
    paths:
      - cypress/screenshots/**/*.png

The glob includes PNGs in nested directories. when: always asks GitLab to collect the artifacts even if the test command fails, which is a common case when you need a failure screenshot. Cypress’s documented GitLab example uses this pattern and also collects videos with cypress/videos/**/*.mp4. See the Cypress GitLab CI example.

After the job finishes, open its artifacts in GitLab and browse or download the collected files. Artifact UI labels can vary with the GitLab version and job view, but the key check is whether the artifact archive contains the expected PNGs.

2. Confirm Cypress generated a screenshot

Failure screenshots are captured automatically during cypress run, including in CI. They are not automatic during cypress open. Automatic failure capture can be disabled with screenshotOnRunFailure: false. Check the Cypress command in the job and the effective configuration, including configuration files and command-line overrides. Cypress screenshots and videos documentation.

Temporarily list the files immediately after the Cypress command to distinguish a generation problem from an artifact collection problem:

test:e2e:
  script:
    - npx cypress run
    - find cypress/screenshots -type f -name '*.png' -print
  artifacts:
    when: always
    paths:
      - cypress/screenshots/**/*.png

GitLab runs later script commands after a failing command in many configurations only when the script handles that failure; a plain failed command may stop the script before find. For an inspection-only run where you need the listing regardless of Cypress’s exit status, capture the status explicitly:

test:e2e:
  script:
    - |
      npx cypress run
      cypress_status=$?
      find cypress/screenshots -type f -name '*.png' -print || true
      exit "$cypress_status"
  artifacts:
    when: always
    paths:
      - cypress/screenshots/**/*.png

This preserves Cypress’s exit code while printing the file list. Remove the diagnostic wrapper once the issue is understood if you prefer the simpler job script.

3. Check the screenshot folder and nested paths

Cypress’s default screenshotsFolder is cypress/screenshots. You can change it in Cypress configuration, so the GitLab artifact path must follow the configured value. For example:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  screenshotsFolder: 'artifacts/cypress-shots',
  e2e: {
    setupNodeEvents(on, config) {},
  },
})

For that configuration, use artifacts/cypress-shots/**/*.png in GitLab instead of the default path. Keep the glob recursive: screenshots are nested under spec-related directories rather than necessarily sitting directly in the screenshots folder. Cypress derives these directories from spec paths and the common ancestor among the selected specs, so a screenshot’s subfolder can change when the selected spec set changes. Avoid scripts that assume a fixed spec-derived path. Cypress documents callbacks that expose the resolved screenshot path when a workflow needs the exact path. Cypress after:screenshot event.

4. Check cleanup and job ordering

trashAssetsBeforeRuns defaults to true. Before a run, Cypress clears the contents of its screenshots folder (and other run asset folders). If an earlier job step copies or generates files there, Cypress may remove them before the tests execute.

Prefer generating the files after Cypress starts or storing unrelated files elsewhere. You can disable cleanup deliberately:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  trashAssetsBeforeRuns: false,
})

With cleanup disabled, old screenshots can be mistaken for output from the current run. Use a clean workspace or remove stale files in a controlled step when that matters.

5. Optional: inspect screenshots in Cypress Cloud

GitLab job artifacts are enough when the goal is to retain and download PNG files. Cypress Cloud is an optional route when you want screenshots attached to recorded test results alongside run context such as videos and CI logs. It requires setting up the project to record runs to Cloud and reliably providing the commit SHA for the GitLab integration. It is not required for ordinary GitLab artifact collection. See Cypress’s GitLab CI guidance and Cypress Cloud GitLab integration.

Quick diagnosis by symptom

Symptom Likely cause Check or fix
Tests fail, but there is no PNG in the job workspace The job did not run cypress run, failure screenshots are disabled, or the configured folder is different. Check the command, effective screenshotOnRunFailure, and screenshotsFolder; list files after the run.
PNG exists in the workspace, but GitLab shows no artifact The artifact path is missing, too narrow, or collected only on success. Use the configured folder with a recursive /**/*.png glob and when: always.
The artifact entry exists but its archive is empty The path does not match the real folder, or the glob omits nested files. Compare the job’s file listing with the configured screenshots folder and broaden the glob.
Files copied into the screenshots folder disappear Cypress cleared the folder before the run. Generate them after the run begins, store them elsewhere, or configure cleanup with stale-file handling in mind.
Screenshot appears under a surprising directory Cypress builds nested paths from spec locations and the selected specs’ common ancestor. Use a recursive artifact glob; do not hard-code a spec subfolder.

Or skip the browser setup

If you need a screenshot of a page rather than a Cypress test failure capture, ScreenshotNeo provides a website screenshot API and MCP server. A GET request returns an image or PDF. Here is a runnable cURL example; replace the key and target URL. See the ScreenshotNeo API documentation for options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Cookie and consent banners are accepted like a visitor, and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and whether it was billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Performance, reliability, and cost notes

  • Performance: GitLab artifact collection happens after the job’s commands, so it does not make Cypress capture faster. Keep artifact paths focused on the files you need; collecting videos as well increases the stored artifact size.
  • Reliability: when: always helps retain evidence from failing jobs, but the file must exist and match a path under the job workspace. A screenshot generated in another job is not automatically present in this job; pass it between jobs using artifacts if needed.
  • Cost and retention: PNG artifacts consume the GitLab project’s artifact storage and are subject to the project’s artifact expiration and retention settings. Set retention according to how long your team needs failure evidence; Cypress Cloud recording is a separate optional workflow.

FAQ

Does Cypress take a screenshot for every passing test?

No. Automatic screenshots are taken on test failure during cypress run. Use Cypress’s screenshot command in a test when you need a deliberate capture.

Can GitLab artifacts include videos too?

Yes. Add cypress/videos/**/*.mp4 to the artifact paths if video recording is enabled and those files are useful to your debugging workflow.

Do I need Cypress Cloud to download failure screenshots?

No. GitLab job artifacts can retain the PNG files directly. Cloud is optional for teams that want recorded-run results and related context in its interface.

Why does a screenshot path change when I run a different subset of specs?

Cypress builds spec-related nested paths using the common ancestor of the selected specs. Use a recursive folder glob or inspect the resolved path through Cypress’s screenshot event callback.