The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: configure Playwright Test to capture screenshots on failures, then upload the directory controlled by outputDir as a GitHub Actions artifact. A screenshot saved on the runner is not downloadable until the workflow uploads it. The two most common causes are a disabled or overridden use.screenshot setting and an artifact step that points at the wrong directory or never runs after the test command fails.
1. Enable failure screenshots in Playwright
Put the screenshot policy in the Playwright configuration that your CI command actually loads. The documented values are 'off', 'on', and 'only-on-failure'. For CI diagnostics, failure-only capture usually provides the useful evidence without creating an image for every passing test.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure',
},
});
only-on-failure does not mean “save a screenshot for every test.” A passing test should not be expected to leave a screenshot under this mode. If you need visual output for every test, use 'on'; use 'off' to disable screenshots.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Check for configuration overrides
Playwright projects can override a shared use block, and the command line can replace the output location. Inspect the effective project configuration, the config file selected by the invocation, and any project-specific settings. A correct setting in an unused configuration file has no effect.
#1 Best Overall
2. Upload the directory after the test step
GitHub Actions does not automatically publish files created by Playwright. Add an artifact step whose path matches Playwright’s output directory and allow that step to run when tests fail.
- 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
The cancellation-aware condition is important. Without a condition, a later step can be skipped when npx playwright test exits non-zero. The sample keeps the upload step eligible after a test failure while still respecting workflow cancellation. Confirm that the action version matches your repository’s current conventions before copying it into a long-lived workflow.
Upload the right kind of output
Playwright’s HTML report directory and its test output directory are not necessarily the same. Screenshots, videos, and traces are written under outputDir; an HTML report is commonly generated elsewhere. If developers need both, upload both paths in separate artifact steps or use a parent directory that contains both.
3. Find the directory Playwright actually used
The default testConfig.outputDir is test-results under the package directory. Your configuration can change it, and --output <dir> can override it for a particular run.
import { defineConfig } from '@playwright/test';
export default defineConfig({
outputDir: 'artifacts/pw',
use: {
screenshot: 'only-on-failure',
},
});
With that configuration, the upload step must use artifacts/pw/, not test-results/:
- name: Upload Playwright output
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v5
with:
name: playwright-output
path: artifacts/pw/
if-no-files-found: warn
Relative paths are resolved from the job’s workspace and its configured working directory. If tests run inside a subdirectory, make the upload path relative to that same workspace or use the appropriate subdirectory explicitly.
4. A practical diagnostic sequence
Confirm capture is enabled
Search the effective playwright.config.* for use.screenshot. Set it to 'only-on-failure' when failure evidence is the goal. Check project-level use blocks and command-line options for overrides.
Free tools Windows power users keep installed
One-click scans. No signup required.
Confirm the test really failed
Failure-only capture is tied to a failed test. Do not use a passing test as proof that screenshot capture is broken when the policy is only-on-failure.
Rank #3
Confirm the loaded configuration
Monorepos and package-based workflows often contain several Playwright configurations. Verify the file loaded by the exact CI command and the package directory from which the command runs.
Confirm outputDir and --output
Look for a configured outputDir and inspect the workflow command for --output. The command-line value wins for that invocation, so the upload path must follow it.
Match the artifact path
If files exist on the runner but the downloaded artifact is empty, compare the configured output path, the job’s working-directory, and the upload step’s path. Keep if-no-files-found: warn while diagnosing so a missing directory is visible without hiding the earlier test failure.
Verify that the upload step ran
Open the workflow log and inspect skipped-step details. A normal later step may be skipped after a failing test command; use if: ${{ !cancelled() }} or another condition appropriate for your workflow.
Download and inspect the artifact
After the run, open the Actions run’s artifact list and download the artifact. Check its directory layout and filenames. If it contains a report but no screenshots, the workflow may be uploading only the report directory rather than the test output directory.
5. Use traces when a screenshot is not enough
A screenshot shows the final rendered state, but it does not show the sequence of actions, locator resolutions, network activity, or console details. Playwright recommends its Trace Viewer for CI failures instead of relying only on videos and screenshots.
With one retry enabled, a practical CI configuration is:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsimport { 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',
},
});
on-first-retry records a trace for a test that is retried. If you do not use retries, retain-on-failure can retain traces for failed tests. Other documented retention choices include retain-on-first-failure. Choose the mode that preserves the failed attempt you need to diagnose; tracing every test can add substantial runtime and storage overhead.
To inspect a downloaded trace locally, run:
npx playwright show-trace path/to/trace.zip
The trace can also be opened through the HTML report when the attachment is present. Trace files and reports can contain page content, URLs, headers, and other diagnostic data, so apply your repository’s security and retention policy before publishing them as artifacts.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.6. Match the fix to the symptom
| Symptom | Likely check | Fix |
|---|---|---|
| No screenshot exists on the runner | Capture mode, test result, loaded config, and output directory | Set screenshot: 'only-on-failure', verify the test failed, and inspect the effective outputDir. |
| Screenshot exists on the runner but no artifact is downloadable | Upload step condition or path | Use a cancellation-aware condition and point path at the actual output directory. |
| HTML report downloads but screenshots or traces are absent | Report directory differs from test output directory | Upload the directory controlled by outputDir as well as the report directory. |
| A retry passes and the original failure evidence is needed | Screenshot and trace retention policy | Select a trace mode and retry policy that retain the failed attempt, such as on-first-retry with one retry or a failure-retaining mode without retries. |
| Artifact is empty | Working directory, path spelling, or no failed tests | Compare the job workspace with the configured path and keep if-no-files-found: warn while troubleshooting. |
7. Sharding and parallel jobs
When a workflow shards tests, each shard produces its own report data and attachments. Give each shard a distinct artifact name so later jobs do not overwrite one another. Playwright’s sharding guidance uses per-shard blob-report artifacts and a later merge job; blob reports can include attachments such as traces and screenshot diffs. The same principle applies to failure screenshots: upload every shard’s output, then merge or inspect the artifacts deliberately.
8. Capture volume, runtime, and retention choices
| Setting | What it captures | Typical use |
|---|---|---|
screenshot: 'off' |
No screenshots | Fast runs where traces or logs are sufficient |
screenshot: 'only-on-failure' |
Failure screenshots | Default diagnostic evidence for CI |
screenshot: 'on' |
Every test | Visual archives or investigations that require passing-state images |
trace: 'on-first-retry' |
Traces for retried tests | CI with retries enabled |
trace: 'retain-on-failure' |
Retained traces for failures | Failure evidence when retries are disabled |
More screenshots and traces increase artifact size and upload time. Keep failure-only screenshots for routine runs, use traces for interaction history, and set an artifact retention period that matches your debugging and compliance needs.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall9. Or skip the browser setup
If your goal is a clean image of a URL rather than Playwright interaction debugging, ScreenshotNeo provides a single-request screenshot API. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; 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.
See the ScreenshotNeo API documentation for the complete parameter reference. This cURL request saves a WebP image:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python equivalent:
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 request:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF output with paper size, margins, landscape mode and page ranges, HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors, delays or network idle, ad/tracker/request/resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed links for public images, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Plans include a free allowance of 1,000 screenshots per month with no card, Starter at $5 for 3,000, Growth at $15 for 15,000, Pro at $39 for 60,000, Scale at $99 for 250,000, and Business at $249 for 1,000,000. Yearly billing provides two months free, and every feature is included on every plan.
Create a free ScreenshotNeo account to get 1,000 screenshots a month without adding a card.
Quick Recap
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.

