HTML Test Reports: Host and Share with Your Team

Playwright generates a stunning HTML report with screenshots, traces, and video. pytest-html creates a clean, interactive summary. But then what? The report sits on your machine or gets buried in CI artifacts. Your beautiful reports deserve to be seen.

Why Teams Use HTML Test Reports

HTML reports are popular because they’re genuinely useful:

  • Rich visualization - Screenshots, video recordings, trace viewers (Playwright)
  • Interactive - Click to expand failures, filter by status, search tests
  • Self-contained - Single file or folder, opens in any browser
  • Human-readable - PMs and QA can understand them without developer help

Unlike JSON or JUnit XML, HTML reports are designed for humans. They tell the story of what happened during the test run.

The Sharing Problem

HTML reports are local files. There’s no built-in way to share them.

Common Workarounds

Email the zip file

You zip up the report folder, email it, and hope the recipient knows how to extract and open index.html. Works, but feels like 2005.

Upload to S3 manually

You could upload to S3 and share the URL. But that’s manual work every time, and someone has to manage the bucket, permissions, and cleanup.

Rely on CI artifacts

GitHub Actions and GitLab CI can store artifacts, but:

  • Finding the right artifact in 50 workflow runs is tedious
  • Viewing requires CI access (QA might not have it)
  • You have to download and extract to view
  • Artifacts eventually expire

Share your screen

Works for live debugging, but you can’t reference it later. Not async-friendly.

Frameworks That Generate HTML Reports

Playwright

Playwright’s HTML reporter is one of the best in the industry.

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

export default defineConfig({
  reporter: [
    ['html', { open: 'never' }],
    ['list']
  ],
});

Generates playwright-report/ with:

  • Interactive test list with filtering
  • Screenshots at each step
  • Video recordings of failures
  • Trace viewer for debugging timing issues
Playwright HTML test report with screenshots and trace viewer hosted in Gaffer

pytest (pytest-html)

pip install pytest-html
pytest --html=report.html --self-contained-html

Generates a single report.html with:

  • Test results grouped by outcome
  • Captured logs and stdout
  • Environment metadata
  • Duration breakdown

Cypress

// cypress.config.js
module.exports = {
  reporter: 'mochawesome',
  reporterOptions: {
    reportDir: 'cypress/results',
    html: true,
  },
};

Other Frameworks

  • Allure - Cross-framework HTML reports with history
  • ExtentReports - Popular for Java/C#
  • jest-html-reporter - HTML output for Jest
  • HTMLTestRunner - Python unittest HTML reports

A Better Approach: Hosted HTML Reports

The solution is simple: upload your HTML reports somewhere accessible and get a shareable link.

What You Need

  1. Automatic upload - No manual steps after the test run
  2. Shareable links - Anyone with the link can view
  3. Organized history - Find reports by project, branch, date
  4. No infrastructure - Don’t manage S3 buckets or CloudFront

How Gaffer Handles HTML Reports

Step 1: Generate your report (unchanged)

npx playwright test
# or
pytest --html=report.html

Step 2: Upload in CI

# GitHub Actions
- name: Run Playwright tests
  run: npx playwright test

- name: Upload report to Gaffer
  if: always()
  uses: gaffer-sh/gaffer-uploader@v2
  with:
    api-key: ${{ secrets.GAFFER_UPLOAD_TOKEN }}
    report-path: ./playwright-report

Step 3: Share the link

After upload, you get a URL like:

https://app.gaffer.sh/reports/abc123

Share it in Slack, add it to a GitHub PR comment, attach it to a Jira ticket. Anyone with the link can view the full interactive report in their browser.

HTML Reports + Structured Data

HTML reports are great for humans, but you also want structured data for:

  • Pass/fail counts in dashboards
  • Duration tracking over time
  • Flaky test detection from historical patterns

Best Practice: Generate Both

Most frameworks can output multiple formats simultaneously:

// playwright.config.ts
export default defineConfig({
  reporter: [
    ['html', { open: 'never' }],           // For humans
    ['json', { outputFile: 'results.json' }] // For analytics
  ],
});
# pytest
pytest --html=report.html --junitxml=results.xml

Gaffer accepts both formats. Upload the HTML for viewing and the JSON/XML for analytics. You get beautiful reports AND trend data.

Comparing Your Options

SolutionHTML ViewingShareableSetup EffortAnalytics
Local open report.htmlNativeNoNoneNo
Email zip fileAfter extractionAwkwardManual each timeNo
CI artifactsDownload requiredWith CI accessBuilt-inNo
S3 + CloudFrontNativeYesSignificantNo
GafferNativeYes (simple link)5 minutesYes

Slack Integration

Tired of checking CI manually? Gaffer can notify your team in Slack when tests complete:

  • Pass/fail summary at a glance
  • Direct link to the HTML report
  • Filter by branch (only notify on main, skip feature branches)

No more wondering if tests passed or sending messages around.

Getting Started

Gaffers free tier includes 500 MB storage with 7-day retention. Paid plans offer up to 90-day retention for teams that need longer access to historical reports.

Start Free