Skip to content

Your Playwright HTML report, online before the run finishes

The HTML report Playwright writes on every run is a full interactive website — traces, screenshots, videos, network logs. GitHub's answer is to zip it and hide it in the artifacts tab. Here's the two-line fix that puts a clickable link on every run instead.

Drop your Playwright report here — get a live link

free, no account, live for 30 days.

Shipping…

The artifact dead-end

The default flow punishes anyone who wants to look at results: find the workflow run, scroll to artifacts, download a zip, extract it, open index.html — and then watch half the assets 404, because browsers sandbox file:// pages and Playwright's report wasn't built for them.

So reviewers don't look. A red PR gets approved on vibes because opening the report costs two minutes of faff. The information existed; it just wasn't reachable.

Two lines to a live link

Build your output like you already do, then hand the folder to the action:

Generate the report

npx playwright test

.github/workflows/ci.yml

- uses: bitgate/ship-page-action@v1
  if: always()
  with:
    engine: playwright

Or with plain curl — no account needed

cd playwright-report && zip -qr - . | curl -fsS -X POST https://ship.page/deploy   -H "Content-Type: application/zip"   --data-binary @- | jq -r .url

engine: playwright makes the action find playwright-report/ on its own — prefer explicit? path: playwright-report/ does the same thing. Omit both and every known report gets probed; two or more matches land behind one URL with a built-in switcher. The link goes in the job summary — add comment: true and it lands on the pull request too.

What you get

  • Traces, screenshots and videos all resolve — every drop mounts at the root of its own subdomain, exactly like localhost did
  • if: always() publishes the report even when tests fail, which is precisely the run you want to inspect
  • Add name: pr-${{ github.event.number }} and an API key for a stable per-PR URL that every push redeploys in place
  • The URL is the access control — viewers need no GitHub account or repo access, slugs are unguessable, and there's no public index
  • Anonymous links live for 30 days; deploy with an API key to control the TTL, or drop expiry entirely on a paid plan

Questions

Does the trace viewer actually work from the link?

Yes — verified against a real report: open the test, click the trace, and the full timeline with DOM snapshots and network log loads straight from the deployed folder. No server-side anything. Capture with trace: 'on' (or 'retain-on-failure') in playwright.config.

Does the link work without an account?

Yes. Anonymous deploys need zero config and stay live for 30 days. Viewers never log in — the URL is the access control.

What about sharded or merged reports?

Point path at whatever directory holds your final report — after npx playwright merge-reports, or each shard's own folder deployed as separate drops. Omit path entirely and the action auto-detects playwright-report/ on its own.

How is this different from GitHub Pages?

No gh-pages branch, no commit churn, no per-repo site limit, no waiting on a Pages build. The report folder is served as-is, seconds after the test step ends.

How do I share a Playwright report from CI?

Add the action step after your test step with if: always() — the report URL lands in the job summary, and comment: true posts it on the pull request. Anyone with the link can open it, no GitHub login or repo access required.

Does the report expire?

Anonymous drops expire after 30 days. An sp_ API key lets you set the TTL per deploy, and paid plans can keep reports live indefinitely.

Related recipes

Try it on your next run

Anonymous deploys need no account and no key — paste the step, get a link. When you want stable URLs that redeploy in place, an API key and a name are all it takes.

Need to share the report with someone outside GitHub? How to share a GitHub Actions artifact without a login.