How to Share a Playwright HTML Report With Your Team

Playwright's report is a folder, which is why nobody can just open the one you ran. Turn the run into a single self-contained HTML file, then publish it behind your company login so the team clicks a link instead of unzi

TL;DR
The default Playwright HTML reporter writes a `playwright-report/` directory, not a file, so you can't attach it to a message or upload it anywhere useful. Produce a single self-contained report (a one-file reporter like `monocart-reporter` does this), then `dsp publish report.html` returns a permanent URL gated to your company email. No GitHub Pages, no zip-and-pray, no per-report hosting bill.

Playwright's report is a folder, which is why nobody can just open the one you ran. Turn the run into a single self-contained HTML file, then publish it behind your company login so the team clicks a link instead of unzipping a CI artifact.


Why sharing a Playwright report is annoying

Run the tests and Playwright writes playwright-report/index.html plus a data/ folder of traces, screenshots, and attachments. Locally, npx playwright show-report spins up a server and it all works.

The trouble starts the moment someone else needs to see it. The report is a directory, so:

  • Attaching it means zipping the folder. The recipient downloads the zip, unzips it, finds index.html, and opens it from disk, where the trace viewer and some attachments break because the browser blocks local file access.
  • CI artifacts keep the folder intact, but only people with access to the CI run can download it, and they still have to unzip and open it themselves.
  • GitHub Pages can host the folder, but a public Pages site exposes your test names, selectors, and screenshots to anyone, and a private one needs every viewer to have repo access.
  • A dedicated report host solves the folder problem, but it's another tool to wire in and pay for per run.

The failing test happened an hour ago. The engineer who can fix it still hasn't seen the report.


Step 1: Produce one self-contained report file

display.dev publishes a single HTML file, and the default Playwright reporter doesn't give you one. The fix is a reporter that emits a single self-contained report.html with the trace data inlined.

monocart-reporter is the common choice. Add it as a reporter in your Playwright config:

// playwright.config.ts
import { defineConfig } from '@playwright/test';
 
export default defineConfig({
  reporter: [
    ['monocart-reporter', {
      name: 'E2E Report',
      outputFile: './report/index.html',
    }],
  ],
});

Run the suite as usual:

npx playwright test

The output is a single HTML file with the test tree, timings, error diffs, and trace data embedded. Move it to another folder, open it, and confirm the failures and attachments still load. If they do, it's ready to publish.

If you'd rather keep the stock Playwright reporter, you can still get one file by merging the run into a single blob and rendering it, but a single-file reporter is the shortest path from "tests ran" to "one file to share."


Step 2: Publish it behind company auth

display.dev puts that file at a permanent URL behind your identity provider. Viewers authenticate with the Google Workspace or Microsoft 365 account they already use.

npm install -g @displaydev/cli
 
dsp login
 
dsp publish ./report/index.html --name "e2e-report"

Paste the URL in the failing build's Slack thread or the bug ticket. Anyone with a company email opens it and reads the full report (failures, retries, traces) with nothing to download or unzip. People outside your domain hit a login wall, so your selectors and screenshots stay internal.

That's gated publishing: one action to publish, company identity to gate, a stable link. Readers aren't charged per seat, so the whole team can open the report without a hosting bill that scales with how many people look.


How the options compare

MethodOne link to openPrivate to your companyViewer needs an accountExtra tooling
Zip the folderNo (download + unzip)YesNoNo
CI artifactNo (download + unzip)YesYes (CI access)No
GitHub PagesYesOnly on private reposYes (GitHub) for privatePages setup
Dedicated report hostYesVariesVariesPer-run hosting
Single-file report + display.devYesYes (SSO)Company email onlyA one-file reporter

Publishing it straight from CI

The natural place to publish is the same job that runs the tests. After the suite produces report/index.html, publish it with an API key instead of an interactive login:

- name: Publish Playwright report
  if: always()
  env:
    DISPLAYDEV_API_KEY: ${{ secrets.DISPLAYDEV_API_KEY }}
  run: |
    npm install -g @displaydev/cli
    dsp publish ./report/index.html --name "e2e-${{ github.run_number }}"

The if: always() is the important part: you most want the report when the suite fails. Each run can publish to a fresh URL, or re-publish to a stable one with --id <shortId> --base-version <currentVersion> so a single "latest E2E report" link always shows the most recent run. The full pattern, including how to store the API key, is in publishing HTML from GitHub Actions.


Where this fits

A test report is one case of a recurring problem: a tool produces rich HTML and the people who need to read it live somewhere else. The same one-command flow publishes Jupyter notebooks, Quarto and R Markdown reports, and data dashboards behind the same company login.


FAQ

Why can't I just publish the default `playwright-report/` folder?+

The default reporter writes a directory of files, and gated publishing takes a single file. Generate a single self-contained report (a one-file reporter like monocart-reporter produces one report.html) and publish that.

Does the trace viewer still work in a published report?+

It works when the trace data is inlined into the single HTML file, which is what a self-contained report does. The fragile path is opening an unzipped default report from your local disk, where the browser blocks the file access the trace viewer needs. A published, served file doesn't have that problem.

Will the report be public?+

No. On the Pro plan, access is gated by your Google Workspace or Microsoft 365 domain, so your test names, selectors, and screenshots stay internal. Someone without a company email hits a login wall.

How is this different from a report-hosting service like Gaffer?+

A dedicated report host uploads and serves the report folder, billed around test runs. Gated publishing serves a single report file behind your company SSO at a flat price, alongside every other HTML artifact your team publishes (dashboards, notebooks, proposals), rather than as a test-only tool.

Can I keep one stable "latest report" URL?+

Yes. Re-publish each run with --id <shortId> and the current --base-version. The URL stays the same and always shows the most recent run, which is handy to pin in a CI channel.

Publish your first artifact in 15 seconds.

Free tier. No credit card. One-time password auth for viewers on free, Google + Microsoft SSO on Pro (€49/month flat).

Get started free →See pricing