Skip to content

Early Adopter Offer:Get 40% off Core & Scale for your first year with code EARLYQFView pricing

Playwright test reporting

Keep Playwright’s HTML report for debugging individual runs. Upload local and CI results to Qualflare so your team can review failures, retries and case history in one place. This guide explains the reporters, the upload setup and the two paths for sharded runs.

Qualflare launch Overview with passed, failed and skipped counts, case retries and slowest cases.
Illustrative launch overview from the Qualflare docs, not a verified Playwright run. Open your uploaded launch to check results and retries, then inspect failed cases for details and available attachments. Select the image to view it at full size.

Playwright’s built-in reporters, explained

Playwright test reporting is the process of turning raw run results — passes, failures, retries, traces — into something a team can read and act on. Playwright ships several built-in reporters, and they compose: you can run a console reporter for humans and a machine-readable one for tools in the same run.

  • list / line / dot. Console output at three verbosity levels. list prints a line per test (the local default); dot prints one character per test, which keeps CI logs short and is the default on CI.
  • html. A self-contained interactive report in playwright-report/ — filterable, with attached traces, screenshots, and videos. The best way to debug a single run locally.
  • json. The full structured result — every test, attempt, retry, error, and attachment — written to a file you point tools at. This is the richest machine-readable output Playwright produces.
  • junit. JUnit-style XML. Less detailed than JSON, but the lingua franca of CI platforms: GitLab, Jenkins, and Azure DevOps all render it natively as a test report tab.
  • blob. A raw intermediate report whose only job is to be merged later — the building block for sharded runs (more below).
  • github. GitHub Actions annotations: failures show up inline on the PR diff. Zero value outside GitHub, cheap to add inside it.

Keep the HTML report, add history across runs

The HTML report is useful for inspecting one run. By default, the next run replaces the playwright-report folder. You can archive reports and merge shards, but the report itself does not maintain case history across separate runs.

Upload results from a local debugging session or a CI job to keep them available for team review. In Qualflare, open a case’s Run History to inspect earlier results. Local reporting remains useful alongside CI; you can keep both reporters in the same configuration.

Send Playwright results to Qualflare

First, create your account and project, install qf and save your project-token login with qf login my-project. Paste the token at the hidden prompt. The token chooses the project; my-project is a local alias.

Install the native reporter and add it alongside your current reporters:

npm install --save-dev @qualflare/playwright
// playwright.config.ts
import { defineConfig } from '@playwright/test';
import { qualflareReporter } from '@qualflare/playwright';

export default defineConfig({
  // Keep the reporters you already use and add this one:
  reporter: [
    [process.env.CI ? 'dot' : 'list'],
    ['html', { open: 'never' }],
    qualflareReporter({ environment: 'staging' }),
  ],
});

Use your environment’s Identifier for staging. The reporter requires Playwright Test 1.40+ and qf 0.1.24+; see the reporter guide for runtime requirements and configuration. It writes ./qualflare-results locally with no network calls.

npx playwright test                    # writes ./qualflare-results

Then upload separately, including when tests fail. Don’t join these commands with &&:

qf my-project collect ./qualflare-results

Open the new launch and match its test names and passed, failed and skipped counts to your run. Referenced screenshots upload by default. Add --upload-artifacts video,trace for recorded videos and traces; qf reports skipped artifacts. Uploaded screenshots, videos and traces are deleted after 30 days. See artifact uploads and retention.

CI patterns: GitHub Actions, GitLab, Jenkins

GitHub Actions. With the native reporter configured above, store your project access token as the QF_TOKEN secret. After dependency and browser setup, these steps upload ./qualflare-results even when tests fail, unless the workflow is cancelled:

# Steps after checkout, Node, dependencies and browsers are installed.
# Configure @qualflare/playwright as shown above.
- name: Run Playwright tests
  run: npx playwright test

- name: Upload results to Qualflare
  if: ${{ !cancelled() }} # upload even when tests fail
  env:
    QF_TOKEN: ${{ secrets.QF_TOKEN }}
    QF_BRANCH: ${{ github.head_ref || github.ref_name }}
    QF_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
  run: |
    npm install -g @qualflare/cli
    qf login ci --force
    qf ci collect ./qualflare-results

GitLab CI. GitLab renders JUnit XML natively in the pipeline’s Tests tab, so emit JUnit alongside whatever else you run:

// playwright.config.ts — JUnit XML for CI test-report integrations
import { defineConfig } from '@playwright/test';
import { qualflareReporter } from '@qualflare/playwright';

export default defineConfig({
  reporter: [
    ['dot'],
    ['html', { open: 'never' }],
    ['junit', { outputFile: 'results.xml' }],
    qualflareReporter({ environment: 'staging' }),
  ],
});
# .gitlab-ci.yml — JUnit output doubles as GitLab's native test report
e2e:
  script:
    - npx playwright test
  artifacts:
    when: always
    reports:
      junit: results.xml
    paths:
      - playwright-report/

Jenkins. Same idea: produce results.xml with the JUnit reporter and hand it to the classic junit 'results.xml' pipeline step. Jenkins tracks pass/fail counts per build — useful, though it knows nothing about retries or flakiness semantics.

The GitLab example archives reports for GitLab’s own test view; add a separate authenticated qf upload for hosted Qualflare results. For complete provider-specific setup, including uploads after failed tests, see the CI integration guides.

Sharded runs: one report from parallel jobs

Native reporter: gather result directories

Keep the native reporter enabled in each shard. A final job downloads the result directories and uploads them as one launch. Install qf and authenticate with qf login ci --force using the QF_TOKEN secret, as in the CI example above.

# Run each shard with the native reporter configured above.
npx playwright test --shard=1/4
# Repeat with 2/4, 3/4 and 4/4 in separate jobs.
# Save each job's qualflare-results directory as a CI artifact.

# In a final job, gather all directories into ./qualflare-results,
# preserving report and attachment files, then upload once:
qf ci collect ./qualflare-results

The native reporter does not support blob or merge-reports mode. Use the complete directory-gathering workflow, including artifact saving and the final upload when tests fail. Collect only this pipeline’s files; add --upload-artifacts video,trace if you also want its recorded videos and traces.

Built-in reporters: merge blobs into JSON

If you choose the results-only JSON route instead, Playwright’s blob reporter plus merge-reports combines the shards. The --reporter=blob flag replaces the configured reporter list:

# Run a 4-way shard — each job writes a blob report
npx playwright test --shard=1/4 --reporter=blob
# (repeat with 2/4, 3/4, 4/4 in parallel CI jobs;
#  upload each job's blob-report/ directory as a CI artifact)
# In a final CI job: download all blob reports, merge to one JSON, upload once
PLAYWRIGHT_JSON_OUTPUT_NAME=playwright-results.json \
  npx playwright merge-reports --reporter json ./all-blob-reports

qf my-project collect playwright-results.json

Authenticate the my-project alias before collecting the merged JSON. This route uploads results, not the native reporter’s artifact directory. One collection of all shards creates one launch.

Common Playwright reporting problems (and fixes)

  • The results file is missing after a crashed run. Reporters write their output when the run finishes — if the process is killed (CI timeout, OOM), the JSON file may never be written. Set a job-level timeout above Playwright’s own globalTimeout so Playwright ends the run and reports, instead of the CI runner killing it mid-flight.
  • CLI reporter config silently replaces yours. Passing --reporter on the command line overrides the config file’s reporter array rather than adding to it — a classic cause of “the JSON stopped appearing in CI.” Keep the full reporter list in playwright.config.ts and avoid the flag in CI scripts, or repeat every reporter in the flag.
  • Mismatched shard reports won’t merge. merge-reports requires all blob reports to come from the same Playwright version. If shards install dependencies independently, a lockfile update landing mid-pipeline can split versions across shards — pin the version and install from the lockfile (npm ci).
  • The HTML report self-opens and hangs CI. The HTML reporter’s default open: 'on-failure' tries to serve the report after a failed local run; on CI that can stall a job. Set open: 'never' when process.env.CI is set.
  • Artifacts balloon to gigabytes. Traces and videos for every test add up fast. Record them only when they’re useful: trace: 'on-first-retry' and video: 'retain-on-failure' keep failure debugging intact while shrinking artifact uploads by an order of magnitude.
  • Pass rates look fine but the suite is rotting. Retries hide instability: a test that passes on attempt two counts as a pass. Track the flaky status (Playwright marks retried-then-passed tests as flaky in JSON output) — if you only watch the red/green summary, flakiness compounds until the suite stops being trusted. This is the metric to alert on, not the pass rate.

Without the native reporter: upload JSON

If you would rather not add a dependency, Playwright’s own JSON reporter still works — you lose the step traces, screenshots, videos and traces the reporter collects, but the results land:

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

export default defineConfig({
  // Keep your existing reporters and add JSON for upload:
  reporter: [
    ['html'],
    ['json', { outputFile: 'playwright-results.json' }],
  ],
});

After running your tests, upload that file with your saved login. The CLI auto-detects the Playwright format:

# Upload the results — the CLI auto-detects the Playwright format
qf my-project collect playwright-results.json

In the GitHub Actions example, replace qf ci collect ./qualflare-results with qf ci collect playwright-results.json when using this JSON configuration. Keep authentication, branch/commit metadata and the failure-safe upload condition. For other providers, follow the CI guides.

What you get on top of Playwright

  • AI failure clustering. When a deploy breaks 40 Playwright specs, Qualflare groups them by root cause so you triage a handful of clusters instead of 40 stack traces.
  • Flaky-test scoring from your retry data. The CLI reads Playwright’s native retry counts and flaky status, and Qualflare scores each test’s flakiness across runs — so you can quarantine or fix the genuinely unstable ones.
  • Launch review. Each local or CI upload creates a launch with test results. When AI analysis is available, its summary and risk assessment can support investigation; they are not a release verdict.
  • History & trends. Pass rate, slowest specs, and flakiness over time across branches and shards — the aggregation the HTML report can’t do.
  • Context & defects. Inspect failure details and uploaded attachments, then track the issue as a defect. Artifact availability depends on recording, upload settings and the 30-day retention period.

Built-in HTML reporter vs Qualflare

  Playwright HTML report Qualflare
History across local and CI uploads—Yes
Aggregates sharded / parallel runsVia merge-reportsYes
AI failure clustering (root cause)—Yes
Flaky-test scoring over time—Yes
Local, zero-setup, offlineYes—
Traces & screenshots per failureYesYes

They’re complementary: keep the HTML reporter for individual-run debugging and add Qualflare for team review and history across local and CI uploads. Attachment support requires recorded, referenced files and the appropriate upload settings.

Open your own Playwright results in Qualflare

Add the native reporter, run your tests locally or in CI, and upload the result directory. Open the launch to review your test names, outcomes and available evidence.

Set up Playwright reporting

New to Qualflare? Create your account and project. Report uploads and AI analyses have separate allowances; see plans and limits.

Qualflare works the same with pytest, Cypress, Jest, JUnit and 20+ more frameworks. Testing a mobile app too? See our Android (Espresso), iOS (XCTest), and Maestro guides. Weighing tools? See how it compares to other test management platforms, or browse all framework reporting guides. Fighting flaky specs? Read our guide to fixing flaky Playwright tests in CI.

Frequently asked questions

Which Playwright reporter should I use in CI?

Use a quiet console reporter (dot) plus the output your tools need. For Qualflare, add @qualflare/playwright to write ./qualflare-results. Add JUnit XML for your CI test-report tab and the github reporter for GitHub Actions annotations if needed. Reporters compose: keep HTML too, with open: never for unattended runs.

How do I merge reports from sharded Playwright runs?

With @qualflare/playwright, save each shard’s qualflare-results directory, gather the report and attachment files in a final job, authenticate qf and collect the directory once. The native reporter does not support blob or merge-reports mode. As a separate results-only route, use Playwright’s blob reporter, merge to JSON with merge-reports and upload that JSON with qf.

Does Qualflare replace the Playwright HTML reporter?

No — it complements it. Keep Playwright’s HTML report for debugging individual runs. Upload local and CI results to Qualflare so your team can review failures, retries and case history in one place. Local uploads remain useful even when you already have CI. AI analyses have a separate allowance from report uploads.

How do I send Playwright results to Qualflare?

Create a Qualflare project, install qf and save a project-token login with qf login my-project. Install @qualflare/playwright and add qualflareReporter({ environment: 'staging' }) alongside your existing reporters, using your environment’s Identifier. Run npx playwright test, then separately run qf my-project collect ./qualflare-results, including when tests fail. The reporter writes files without network calls; qf uploads them. Open the launch and check its test names and counts. Requires @playwright/test 1.40+ and qf 0.1.24+.

Do I need the reporter, or is the JSON file enough?

Both work. The native reporter records nested steps, retries, metadata and available attachments in ./qualflare-results. qf uploads that directory separately. Playwright’s JSON reporter is a results-only alternative without the native reporter’s artifact path. Referenced screenshots upload by default; add --upload-artifacts video,trace for recorded videos and traces. Uploaded screenshots, videos and traces are deleted after 30 days.

Does Qualflare detect flaky Playwright tests?

Yes. The CLI reads Playwright’s native retry counts and flaky status directly from the results — no extra configuration — and Qualflare scores each test’s flakiness from history across runs. You can see which Playwright tests are intermittently failing and whether that’s trending up or down.

Does it work in GitHub Actions, GitLab CI, and Jenkins?

Yes. After tests, authenticate qf with a project access token stored as a CI secret and collect the native results directory or your chosen result file. Configure the upload to run when tests fail. Set branch and commit metadata using the provider-specific docs; GitHub pull requests need the head branch and SHA. Each upload creates a launch; AI analysis availability and allowance are separate.

Recent updates

All updates on the Qualflare changelog

Setup reflects the Qualflare CLI (docs.qualflare.com) and Playwright’s reporters. Setup and evaluation guidance updated 5 November 2026. Published 11 June 2026. Written by İbrahim Süren, Qualflare.