Skip to content

johnsta/playwright-static-report-sample

Repository files navigation

Sample: Reporting with Azure Static Website, GitHub CI, and Playwright Workspaces

This repository demonstrates running Playwright tests in GitHub Actions using Playwright Workspaces, publishing HTML reports to an Azure Storage static website, and maintaining a small JSON feed that the lightweight index.html viewer consumes.

At a high level:

  • GitHub Actions (see .github/workflows/playwright-workspaces.yml) runs Playwright tests (configured in playwright.service.config.ts).
  • The workflow assembles an HTML report (Playwright report), creates a meta.json describing the run, uploads the report to an Azure Storage static website ($web), and merges a new feed entry into feed.json.
  • index.html in this repo is a viewer that reads feed.json and displays available test run reports (it expects meta.json and related report content to be present under the run folder on the static website).

This README documents how the pieces fit together and how to configure Azure and GitHub Secrets to run the sample.


Files of interest

  • .github/workflows/playwright-workspaces.yml — the GitHub Actions pipeline that runs tests and uploads the HTML report and meta.json to Azure. It also updates feed.json.
  • playwright.service.config.ts — Playwright configuration used by the sample tests (the repo includes a Playwright test in tests/).
  • index.html — static viewer that loads feed.json and renders the list of reports (and pulls data/report.json from each report URL to show stats when available).

How the workflow works (high level)

  1. On push / pull_request, the workflow checks out the repo and installs dependencies.

  2. It runs Playwright tests (the workflow uses npx playwright test -c playwright.service.config.ts and expects the Playwright Service environment variables if required).

    Note: the workflow uses the Playwright blob reporter and merges it into an HTML report in CI so an HTML report is produced and uploaded.

  3. The job ensures a minimal HTML exists for playwright-report/index.html and then builds meta.json containing metadata about the run (title, subtitle, dates, commitSha, runId, reportUrl, outcome).

  4. It uploads the contents of ./playwright-report to Azure Storage static website under a run directory (e.g. $web/run-<id>-<attempt>/...).

  5. The workflow writes meta.json and then merges a new feed entry into the global feed.json (also stored in the $web static website container) — index.html pulls this feed.

index.html then fetches feed.json at runtime, lists entries, and loads data/report.json from each report URL to show test stats (if present).


Azure setup (short guide)

The workflow uploads generated reports and metadata into the storage account's $web container (static website hosting). There are two primary setup tasks:

  1. Create an Azure Storage account and enable static website hosting
  2. Create a service principal for azcopy to authenticate from GitHub Actions

Below are example az commands to provision resources (replace placeholders):

# create resource group
az group create --name my-playwright-rg --location eastus

# create a StorageV2 account
az storage account create \
  --resource-group my-playwright-rg \
  --name <STORAGE_ACCOUNT_NAME> \
  --location eastus \
  --sku Standard_LRS \
  --kind StorageV2

# enable static website and set index / error docs
az storage blob service-properties update \
  --account-name <STORAGE_ACCOUNT_NAME> \
  --static-website --index-document index.html --404-document 404.html

# get the static website endpoint (use this to preview uploads)
az storage account show -n <STORAGE_ACCOUNT_NAME> -g my-playwright-rg --query primaryEndpoints.web -o tsv

Create a service principal used by azcopy in the Actions runner. Grant it at least the Storage Blob Data Contributor role on the storage account (scoping more narrowly is recommended):

az ad sp create-for-rbac \
  --name "azcopy-playwright-ci" \
  --role "Storage Blob Data Contributor" \
  --scopes "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/my-playwright-rg/providers/Microsoft.Storage/storageAccounts/<STORAGE_ACCOUNT_NAME>"

The above command prints JSON with appId, password, tenant. Save those and add to GitHub secrets.


Playwright Workspaces resource

Create your Playwright Workspaces resource by following the Azure quickstart:

https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-automate-end-to-end-testing

After the workspace is created, open the workspace in the Azure portal and copy the region-specific service endpoint from the Get Started page — this is the PLAYWRIGHT_SERVICE_URL you will store in GitHub Secrets.


Secrets and where to get them

Below is a quick mapping of the GitHub secrets used by the workflow and how to obtain each value.

This sample uses Playwright Workspaces access token authentication. You only need the PLAYWRIGHT_SERVICE_URL and PLAYWRIGHT_SERVICE_ACCESS_TOKEN for the test runs. The azcopy-related secrets are required for uploading reports to the static website (see below).

  • PLAYWRIGHT_SERVICE_URL — workspace service endpoint (Get Started page in the workspace)

    • Portal: workspace → Get Started → copy the endpoint URL (region-specific)
  • PLAYWRIGHT_SERVICE_ACCESS_TOKEN — Playwright Workspaces access token (used in this sample)

    • Portal: workspace → Access / API tokens → Create a token, copy the generated token value and add it to GitHub secrets as PLAYWRIGHT_SERVICE_ACCESS_TOKEN.
    • Treat this token like a password: do not check it into source control.
  • STORAGE_ACCOUNT_NAME — Azure Storage account name used for hosting static website

    • Portal: Storage account → Overview → Account name
    • CLI: output from az storage account create or az storage account list
  • AZCOPY_SPA_APPLICATION_ID, AZCOPY_SPA_CLIENT_SECRET, AZCOPY_TENANT_ID — credentials for azcopy (if you are using a service principal to upload)

    • Create a service principal scoped to your storage account and save the appId and password values:
      az ad sp create-for-rbac --name "azcopy-playwright-ci" \
        --role "Storage Blob Data Contributor" \
        --scopes "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RG>/providers/Microsoft.Storage/storageAccounts/<STORAGE_ACCOUNT_NAME>"
      • Use the returned appId as AZCOPY_SPA_APPLICATION_ID
      • Use the returned password as AZCOPY_SPA_CLIENT_SECRET
      • Use the returned tenant as AZCOPY_TENANT_ID

Notes:

  • For best security, use Microsoft Entra ID + GitHub OIDC (configure a federated identity credential on the App Registration or create a user-assigned managed identity) instead of long-lived client secrets where possible. The workflow supports Entra ID authentication via the azure/login action (see the quickstart link).
  • The Playwright workspace service endpoint (the PLAYWRIGHT_SERVICE_URL) is region-specific and must match the workspace you created.

GitHub secrets and repository variables

Add the following repository secrets (Repository settings → Secrets → Actions). These are referenced by the workflow:

  • STORAGE_ACCOUNT_NAME — the storage account name used for static website uploads
  • AZCOPY_SPA_APPLICATION_ID — the service principal app id (value appId)
  • AZCOPY_SPA_CLIENT_SECRET — the service principal password (value password)
  • AZCOPY_TENANT_ID — the tenant id (value tenant)
  • PLAYWRIGHT_SERVICE_URL — (optional) Playwright Service URL if you run tests against a Playwright test service
  • PLAYWRIGHT_SERVICE_ACCESS_TOKEN — (optional) Playwright Service token

The workflow uses azcopy with service principal env vars (set as above). It also uses jq in the runner to build meta.json and to merge feed.json entries.


Feed format and index.html

  • The workflow writes a meta.json per run (contains title, date, updated, branch, commitSha, reportUrl, outcome, runId etc.).
  • The workflow merges a feed entry into feed.json at the repository static site root. index.html fetches feed.json and renders entries; it will fetch data/report.json from each report URL to show stats in the viewer when available.

If you are adapting this example, keep meta.json fields the same (title, updated, generatedAt, reportUrl, outcome) so index.html can show the run properly.


Troubleshooting / tips

  • Ensure the service principal has Storage Blob Data Contributor role on the storage account resource (otherwise azcopy will get 403).
  • The workflow ensures meta.json is uploaded with --cache-control "no-cache, no-store, must-revalidate" to reduce stale content issues.
  • If index.html shows "No matching reports", check that feed.json is present at the static website root ($web/feed.json) and that entries have reportUrl pointing to the correct run folder.
  • Use az storage account show -n <ACCOUNT> -g <RG> --query primaryEndpoints.web -o tsv to find the static website endpoint.

License

This repository is a small sample. Use the code as you see fit.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published