Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If Playwright is not leaving failure screenshots in a GitHub Actions run, fix both halves of the pipeline: enable screenshot capture in the effective Playwright Test configuration, then upload the directory Playwright actually used as a workflow artifact. A file that exists on the runner is not automatically downloadable from GitHub Actions.

The two-step fix

Put failure-only screenshots in playwright.config.ts:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    screenshot: 'only-on-failure',
  },
});

Then upload the configured output directory after the test step. The condition below allows the upload to run when tests fail, but not after the workflow is cancelled:

- name: Run Playwright tests
  run: npx playwright test

- name: Upload Playwright test results
  if: ${{ !cancelled() }}
  uses: actions/upload-artifact@v5
  with:
    name: playwright-test-results
    path: test-results/
    if-no-files-found: warn
    retention-days: 14

Use the same directory in both places. Playwright’s default outputDir is test-results under the package directory, but your configuration, working directory, or command line can change it.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What “not working” can mean

There are two separate failure points:

  • No file on the runner: capture was disabled, the test did not fail, the wrong configuration was loaded, or you inspected the wrong output directory.
  • File on the runner but no download in Actions: the upload step was skipped or its path does not match the directory containing the file.

screenshot: 'only-on-failure' intentionally does not retain screenshots for passing tests. If a retry passes, decide whether you need evidence from the original failed attempt and select trace and retry settings accordingly.

Check the effective Playwright configuration

  1. Find the configuration used by the command. Confirm that npx playwright test is running the expected playwright.config.* from the workflow’s working-directory. A monorepo can contain more than one package and configuration file.
  2. Inspect project-specific overrides. A project-level use block, a separate project definition, or command-line options can override shared settings. Verify the project that actually runs the failing test.
  3. Confirm the test failed. Failure-only mode is not a general capture mode. A passing test should not be expected to produce a retained screenshot.
  4. Check the output location. testConfig.outputDir controls screenshots, videos, and traces. The command-line option --output <dir> overrides it for that invocation.
  5. Match the upload path. If the effective output directory is artifacts/pw, uploading test-results/ cannot find those files.

Choose the right screenshot mode

Mode Behavior When to use it
off No screenshots are captured. When screenshots are unnecessary and you want the least artifact work.
only-on-failure Captures screenshots for failed tests. The usual CI choice for focused failure evidence.
on Captures screenshots for every test. When every test needs visual output; expect more files and upload time.

The setting belongs under use in Playwright Test configuration. It is independent of whether GitHub later uploads the resulting files.

A practical CI configuration with traces

Screenshots show the final rendered state, but a trace can reveal actions, network activity, console output, and timing. A common starting point is one retry in CI, a trace on the first retry, and failure screenshots:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  retries: process.env.CI ? 1 : 0,
  outputDir: 'test-results',
  use: {
    screenshot: 'only-on-failure',
    trace: process.env.CI ? 'on-first-retry' : 'off',
  },
});

This is a starting point, not a requirement. With retries enabled, trace: 'on-first-retry' records a trace for the retry path. If you do not use retries, trace: 'retain-on-failure' can retain traces for failed tests. Playwright advises using Trace Viewer for CI failures rather than recording videos and screenshots for every test; tracing every test has a significant runtime and storage cost.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Upload the directories you actually need

The test output directory and the HTML report directory are separate concerns. A workflow that uploads only an HTML report can omit screenshots, traces, or videos stored under outputDir. Upload both when investigators need both views:

- name: Run Playwright tests
  run: npx playwright test

- name: Upload test output
  if: ${{ !cancelled() }}
  uses: actions/upload-artifact@v5
  with:
    name: playwright-test-output
    path: test-results/
    if-no-files-found: warn
    retention-days: 14

- name: Upload HTML report
  if: ${{ !cancelled() }}
  uses: actions/upload-artifact@v5
  with:
    name: playwright-html-report
    path: playwright-report/
    if-no-files-found: warn
    retention-days: 14

Replace either path with the directory configured by your project. The if-no-files-found: warn setting makes a path mistake visible without hiding the test result; use a stricter policy if your team requires artifacts on every failed run.

Diagnostic sequence for a failing run

  1. Read the job log and confirm the Playwright command reached the tests rather than failing during installation or configuration loading.
  2. Confirm at least one test failed if using only-on-failure.
  3. Print or otherwise inspect the working directory and package location used by the job, especially in a monorepo.
  4. Check for --output in the command, scripts, or wrapper tooling.
  5. Inspect the configured outputDir and list that directory immediately after the test command.
  6. Verify the upload step appears in the run and was not marked skipped. if: ${{ !cancelled() }} is important because a normal later step can be skipped after a failed test command.
  7. Open the run’s artifact list, download the named artifact, and compare its directory layout with the runner’s listing.
  8. If a report is present but screenshots are absent, compare the report path with the test-output path; they may be different directories.

Common symptoms and targeted fixes

No screenshot file exists on the runner

  • Set use.screenshot to 'only-on-failure' or 'on', depending on the desired volume.
  • Confirm the test really failed and that the intended project configuration was loaded.
  • Inspect the effective output directory instead of assuming test-results/.

A screenshot exists, but no artifact is downloadable

  • Add a cancellation-aware condition to the upload step.
  • Point path to the exact output directory, relative to the job’s working directory.
  • Check the step details for a skipped condition or an “no files found” warning.

The HTML report downloads, but screenshots or traces do not

Upload the test output directory as a separate artifact. A report artifact does not automatically include files written elsewhere.

A retry passes and the original failure evidence is missing

Choose retention deliberately. Failure screenshots and traces have different policies. Use a trace mode such as retain-on-failure when retries are disabled, or configure first-retry tracing when a retry is part of the CI strategy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The workflow is sharded

Each shard should publish its own report data and attachments. Playwright’s blob-report workflow pattern uses per-shard artifacts followed by a merge job; attachments such as traces and screenshot diffs can be included in that data. Do not make every shard write to a single shared directory unless your workflow explicitly prevents collisions.

Inspecting traces and reports

After downloading a trace, open it locally with:

npx playwright show-trace path/to/trace.zip

You can also open traces through the HTML report when they are attached. Trace Viewer can run locally or in a browser. Treat reports, screenshots, and traces as potentially sensitive: they may contain page content, test data, tokens shown in the UI, or diagnostic details. Apply your repository’s access and retention policy before publishing them as artifacts.

Reliability, runtime, and retention choices

  • Capture volume: only-on-failure limits files during healthy runs; on produces an artifact for every test and can increase storage and upload time.
  • Retries: retries can make transient failures easier to classify, but they also change which attempt remains visible. Pair retries with an explicit trace policy.
  • Artifact retention: set retention-days to the period your team needs for diagnosis. The sample uses 14 days; it is a workflow choice, not a Playwright requirement.
  • Path determinism: use an explicit outputDir and a consistent job working directory when possible. This reduces surprises across packages and matrix jobs.
  • Cancellation behavior: an upload cannot run after a cancelled workflow, but it should still run after a test failure. The cancellation-aware condition expresses that distinction.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a clean screenshot of a URL rather than Playwright’s test-failure evidence, ScreenshotNeo provides a single screenshot API request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.

For API details, see the ScreenshotNeo documentation. A cURL request is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

It also supports full-page and element captures, device and viewport settings, dark mode, retina scale, PDF output, custom CSS and JavaScript, waits, request blocking, headers, cookies, user agents, geolocation, caching, signed links, asynchronous webhooks, bulk capture, and a usage API. Every plan includes every feature. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account to try it.

Frequently Asked Questions

Why does a passing test have no screenshot with `only-on-failure`?

That mode is intentionally failure-only. Use `on` when every test needs a screenshot.

Can I upload screenshots without uploading the HTML report?

Yes. Upload the configured Playwright `outputDir` as its own artifact; the report directory is independent.

What should I retain when a failure is intermittent?

Use a CI retry and `trace: ‘on-first-retry’`, or use `retain-on-failure` when retries are disabled, according to which attempt you need to inspect.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Are Playwright artifacts safe to make public?

Not automatically. Screenshots, reports, and traces can contain page content and diagnostic data, so restrict artifact access and retention to your project’s security policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.