# npx playwright show-report: open, share and host the HTML report from CI

> How npx playwright show-report works: where the report is written, opening a report zip downloaded from CI, host and port, and hosting it for your team.

Published 2026-10-06, updated 2026-10-06. Canonical: https://turnsignal.ai/blog/playwright-show-report-ci

## In short

- `npx playwright show-report` serves the last HTML report from `playwright-report/`. Pass a folder or, in Playwright 1.63, the `.zip` you downloaded from CI.
- Don't open `index.html` straight from disk: Playwright's CI guide says the report needs a web server, and `show-report` is that server.
- Use `--host` and `--port` (default `localhost:9323`) to change where it listens; in CI set `open: 'never'` so nothing waits for a browser.
- The report describes one run. For which failures are new, which tests are flaky over weeks and which never reported, you need results kept across runs.

## What show-report does

The HTML reporter writes a self-contained folder at the end of a run. `npx playwright show-report` starts a small local web server for that folder and opens it in your browser. With no argument it opens the last report from the default folder, `playwright-report/` in the current directory:

```bash
npx playwright show-report
```

If your config writes the report somewhere else (the `outputFolder` option of the `html` reporter, or the `PLAYWRIGHT_HTML_OUTPUT_DIR` environment variable), pass that folder:

```ts
// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  reporter: [['html', { outputFolder: 'my-report', open: 'never' }]],
});
```

```bash
npx playwright show-report my-report
```

> By default the HTML reporter opens the report automatically when some tests failed (`open: 'on-failure'`). In CI, set `open: 'never'` or `PLAYWRIGHT_HTML_OPEN=never` so the run never tries to start a browser.

## Opening a report downloaded from CI

In CI you usually upload `playwright-report/` as a build artifact. On GitHub Actions the workflow Playwright generates already does this with `actions/upload-artifact`, and you download the artifact as a zip from the run summary page.

Playwright 1.63's `show-report` accepts that zip directly, as long as `index.html` is at the top level of the archive. Playwright extracts it to a temporary folder and serves it:

```bash
npx playwright show-report playwright-report.zip
```

On older versions, extract the zip first and pass the folder. Run the command in a project that already has `@playwright/test` installed, so `npx` uses that version instead of downloading one.

### Why double-clicking index.html is not enough

Playwright's own CI guide says that opening the report locally does not work as expected without a web server. Parts of the report, traces in particular, are loaded by the page after it opens, and browsers restrict what a page opened from `file://` may load. `show-report` serves the folder over `http://localhost`, so everything works, including the trace viewer behind each test.

## Host and port

`show-report` listens on `localhost` port `9323` by default. Both can be changed:

```bash
npx playwright show-report --host 0.0.0.0 --port 8080
```

`--host 0.0.0.0` makes the report reachable from other machines on your network, for example from a dev container or a VM. Anyone who can reach that port can read the report, including errors, screenshots and traces, so only do this on a network you trust. The `host` and `port` reporter options (or `PLAYWRIGHT_HTML_HOST` and `PLAYWRIGHT_HTML_PORT`) set the same values for the report that opens at the end of a local run.

## Viewing traces from the report

When a test recorded a trace, the report shows a trace icon next to it. Click it to step through every action with the DOM snapshot, console and network requests at that moment. To get traces only when they help, record them on the first retry or keep them on failure:

```ts
use: {
  trace: 'on-first-retry', // or 'retain-on-failure'
},
```

You can also open a single `trace.zip` without the report: `npx playwright show-trace trace.zip`, or drag it into trace.playwright.dev. Playwright documents that trace.playwright.dev loads the trace entirely in your browser and does not send it anywhere.

## One report from sharded runs

When you shard (`--shard=1/4` … `--shard=4/4`), each machine writes its own report. Opening four reports is slow and easy to get wrong. Make each shard write a **blob** report, download them into one folder, and merge them into a single HTML report that `show-report` can open:

```bash
# on each shard (playwright.config.ts: reporter: process.env.CI ? 'blob' : 'html')
npx playwright test --shard=1/4

# in a final job, with every shard's blob-report downloaded into ./all-blob-reports
npx playwright merge-reports --reporter html ./all-blob-reports
npx playwright show-report
```

Playwright's sharding guide has the full GitHub Actions workflow. The [GitHub Actions setup guide](https://turnsignal.ai/blog/playwright-github-actions-setup-guide) on this blog walks through it step by step.

## Sharing the report with your team

Downloading a zip and running a command is fine for the person debugging. It is a lot to ask of everyone else on a pull request. Teams usually do one of three things:

- **Keep it as an artifact** and link the run in the pull request. Simple, private to people with access to the CI, and limited by your artifact retention.
- **Publish it as a static site.** The report folder is plain files, so any static host works; Playwright's CI intro shows an example with Azure Storage static websites. Put access control in front of it: reports can contain error messages, screenshots and traces of your app.
- **Send results to a service** that keeps them across runs, so people get a link and a short verdict instead of a zip.

If you host the report under a strict Content Security Policy that blocks inline scripts, set `doNotInlineAssets: true` (or `PLAYWRIGHT_HTML_DO_NOT_INLINE_ASSETS=1`) so the JavaScript and CSS are written as separate files. If you upload the `data` folder with attachments to a different place than the report, `attachmentsBaseURL` tells the report where to find them.

## What one report can't tell you

The HTML report is excellent at one thing: everything about a single run. The questions after a red pull request are usually about many runs:

- **Did my change break this, or was it already failing on main?** The report of your branch knows nothing about main.
- **Is this test flaky, or is this the first time?** The report sees the retries in this run, not the last hundred runs.
- **Where did the missing tests go?** If a shard was killed, for example out of memory, its part of the report may never be written, and those tests are simply not there.

[TurnSignal](https://turnsignal.ai/) answers those with one more reporter next to the HTML report: `reporter: [['html', { open: 'never' }], ['turnsignal']]`. Every run opens with a verdict, each failure is labelled **new**, **also failing on main** or **known flaky**, tests from a crashed runner are listed as **Missing**, and on GitHub the verdict is posted as a pull request comment. Traces open in the browser from the run page, without downloading a zip. The reporter never changes your exit code. The [docs](https://turnsignal.ai/docs) have the setup.

## FAQ

**Where does Playwright save the HTML report?**

In `playwright-report/` in the current working directory, unless you set `outputFolder` on the `html` reporter or the `PLAYWRIGHT_HTML_OUTPUT_DIR` environment variable.

**Can I open a Playwright report zip without extracting it?**

Yes, in Playwright 1.63: `npx playwright show-report playwright-report.zip` works when the archive has `index.html` at its top level. On older versions, extract it and pass the folder.

**Why does the trace not open when I open index.html directly?**

The report needs to be served by a web server. `npx playwright show-report <folder>` serves it on localhost, and traces open from there.

**How do I stop the report from opening after every run?**

Set `open: 'never'` on the `html` reporter, or `PLAYWRIGHT_HTML_OPEN=never`. The default is `'on-failure'`.

## Sources

- [Playwright docs: Reporters (HTML reporter, show-report, options)](https://playwright.dev/docs/test-reporters#html-reporter)
- [Playwright docs: CI intro (downloading, viewing and hosting the HTML report)](https://playwright.dev/docs/ci-intro)
- [Playwright docs: Sharding and merging reports](https://playwright.dev/docs/test-sharding)
- [Playwright docs: Trace viewer](https://playwright.dev/docs/trace-viewer)
