How to Host HTML Test Reports for Your Team

HTML test reports exist because developers want more than console output. Playwright gives you screenshots, traces, and video. pytest-html gives you an interactive summary. But these reports are local files — and there’s no built-in way to host them where your team can access them.

The Hosting Problem

HTML reports are designed for browsers, but they’re generated on CI runners or local machines. Your team can’t view them without extra steps:

Common (Bad) Solutions

Email the zip file

Zip up the report folder, email it, hope the recipient extracts it and opens index.html. Works, but feels like 2005.

Upload to S3 manually

Set up a bucket, configure permissions, upload after each run, manage cleanup. That’s infrastructure work just to share a test report.

Rely on CI artifacts

GitHub Actions and GitLab CI store artifacts, but:

  • Viewing requires downloading and extracting a zip
  • Finding the right artifact in dozens of workflow runs is tedious
  • QA might not have CI access
  • Artifacts expire (30-90 days depending on the CI system)

Share your screen

Works for live debugging. Can’t reference it later. Not async-friendly.

Upload your HTML reports after every CI run. Every report gets a permanent URL that opens directly in the browser — no downloads, no extraction, no CI access required.

HTML test reports hosted in Gaffer with shareable links

What This Looks Like

  1. CI runs your tests and generates the HTML report (unchanged)
  2. One upload step sends the report to Gaffer
  3. You get a URL like https://app.gaffer.sh/reports/abc123
  4. Share it in Slack, GitHub PRs, Jira — anywhere
  5. Anyone with access sees the full interactive report in their browser

Setting Up HTML Report Hosting with Gaffer

Step 1: Generate Your Report (Unchanged)

Use whatever reporter your framework provides:

# Playwright
npx playwright test

# pytest
pytest --html=report.html --self-contained-html

# Cypress (with mochawesome)
npx cypress run --reporter mochawesome

Step 2: Upload in CI

GitHub Actions:

- name: Run 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

Share the URL in Slack, add it to a GitHub PR comment, attach it to a Jira ticket. Recipients see the full interactive report in their browser.

HTML Reports + Structured Data

HTML reports are great for humans, but you also want structured data for analytics — pass/fail trends, duration tracking, flaky test detection. Most frameworks can output both:

// 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

Upload both formats. Gaffer serves the HTML for viewing and parses the structured data for trend analytics.

Slack and Webhook Notifications

Get notified when tests finish instead of checking CI manually:

  • Pass/fail summary posted to your Slack channel
  • Direct link to the hosted HTML report
  • Filter by branch — only notify on main, skip feature branches
  • Webhooks for custom integrations

Comparing Your Options

SolutionHTML ViewingShareable LinkAutomatedAnalytics
Local open report.htmlNativeNoNoNo
Email zip fileAfter extractionAwkwardManualNo
CI artifactsDownload requiredWith CI accessBuilt-inNo
S3 + CloudFrontNativeYesDIYNo
GafferNativeYesYesYes

Get Started

Gaffer’s free tier includes 500 MB of storage with 7-day retention. Paid plans offer up to 90-day retention.

Start Free