The default Playwright GitHub Actions workflow uploads HTML reports as workflow artifacts. This is trivial to set up, but viewing them is inconvenient1. A solution is to upload the report to an Object Storage service for direct browser access with clickable URLs that work immediately.

Implementation

Here's the GitHub Actions workflow addition:

- name: Publish test results to object storage
  continue-on-error: true
  run: |
    # Install Rclone
    curl https://rclone.org/install.sh | sudo bash

    # Upload playwright report
    rclone copy playwright-report/ publish:$PUBLISH_BUCKET/$PUBLISH_KEY/playwright-report/ --progress

    # Print report URL for CI logs
    REPORT_URL="$REPORT_URL_PREFIX/$PUBLISH_KEY/playwright-report/index.html"
    echo "📊 Test report published: $REPORT_URL"

    # Generate preview URL and add to step summary
    echo "## 📊 Test Results Published" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY
    echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
    echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
    echo "**Run:** ${{ github.run_id }}-${{ github.run_attempt }}" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY
    echo "🔗 **[View Test Report]($REPORT_URL)**" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY
    echo "📦 Fallback: Download artifacts below if S3 link is unavailable" >> $GITHUB_STEP_SUMMARY
  env:
    PUBLISH_BUCKET: ghartifacts
    PUBLISH_KEY: ${{ github.repository }}/${{ github.run_id }}-${{ github.run_attempt }}
    REPORT_URL_PREFIX: https://ghartifacts.t3.storage.dev
    RCLONE_CONFIG_PUBLISH_TYPE: s3
    RCLONE_CONFIG_PUBLISH_PROVIDER: Other
    RCLONE_CONFIG_PUBLISH_REGION: auto
    RCLONE_CONFIG_PUBLISH_ACL: public-read
    RCLONE_CONFIG_PUBLISH_ENDPOINT: https://t3.storage.dev
    RCLONE_CONFIG_PUBLISH_ACCESS_KEY_ID: your_access_key_id
    RCLONE_CONFIG_PUBLISH_SECRET_ACCESS_KEY: ${{ secrets.RCLONE_CONFIG_PUBLISH_SECRET_ACCESS_KEY }}
  if: always() && hashFiles('playwright-report/**/*') != ''

This generates a job summary like this:

Screenshot of a GitHub Actions job summary displaying test results published for the master branch. There is a prominent heading Test Results Published with a bar chart icon. Below, a blue link labeled View Test Report is shown, followed by a fallback message to download artifacts if the S3 link is unavailable. The overall tone is informative and professional, set against a dark-themed interface.

Object storage options

As of August 2025, here are some S3-compatible storage providers I use:

International:

Thailand region:

  • NIPA Cloud - prepaid, has 2 regions (Bangkok and Nonthaburi)
  • Inspace Cloud - prepaid, unmetered bandwidth, but access keys can access all buckets

In this example, I use Tigris for open source project reports.

Lifecycle management

To avoid accumulating storage usage indefinitely, set up lifecycle policies or lifecycle rules in your object storage provider to automatically delete old reports after a certain period.

Footnotes

  1. I had to download a zip file, extract it, and view locally, which works fine until I want to view traces, because Playwright’s Trace Viewer doesn’t work with the file:// protocol and require running npx playwright show-report to launch a local web server. ↩