Skip to content

E2E

E2E #141

Workflow file for this run

name: E2E
# Playwright-BDD suites for each SPA. The Playwright config boots the app's own dev
# server (webServer), so each job installs both the web app and the e2e harness, then
# runs the browser tests. Heavier/flakier than unit tests, so it lives in its own
# workflow (keep it non-required) and also runs nightly.
on:
pull_request:
paths:
- 'src/web/**'
- 'tests/e2e/**'
- '.github/workflows/e2e.yml'
schedule:
- cron: '0 3 * * *' # nightly 03:00 UTC
workflow_dispatch:
concurrency:
group: e2e-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
e2e:
name: ${{ matrix.app }}
runs-on: ubuntu-latest
timeout-minutes: 30 # browser suites can hang; fail fast instead of burning the 6h default
permissions:
contents: read
checks: write # let the test reporter publish a per-test Check run.
strategy:
fail-fast: false
matrix:
include:
- app: admin
web: src/web/admin
e2e: tests/e2e/admin
- app: terminal
web: src/web/terminal
e2e: tests/e2e/terminal
env:
CI: '1'
steps:
- uses: actions/checkout@v7
- name: Setup Node 20
uses: actions/setup-node@v6
with:
node-version: 20
cache: npm
cache-dependency-path: |
${{ matrix.web }}/package-lock.json
${{ matrix.e2e }}/package-lock.json
# The webServer in playwright.config boots `npm run dev`/`web` from the web app dir,
# so the app needs its deps installed.
- name: Install web app
working-directory: ${{ matrix.web }}
run: npm ci
# Admin still boots MSW for its e2e; the terminal drives the real api seam (Playwright
# route mocks) and has no `mock:init` script.
- name: Generate MSW worker (admin)
if: matrix.app == 'admin'
working-directory: ${{ matrix.web }}
run: npm run mock:init
- name: Install e2e harness
working-directory: ${{ matrix.e2e }}
run: npm ci
- name: Install Playwright browsers
working-directory: ${{ matrix.e2e }}
run: npx playwright install --with-deps chromium
- name: Run e2e
working-directory: ${{ matrix.e2e }}
run: npm test
# Per-test pass/fail Check from Playwright's JUnit output (the `github` reporter also
# annotates failures inline on the PR). Runs even when the suite fails.
- name: Publish test report
if: ${{ !cancelled() }}
uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 # v3
with:
name: E2E tests (${{ matrix.app }})
path: ${{ matrix.e2e }}/test-results/junit.xml
reporter: java-junit
fail-on-error: false
- name: Upload Playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
with:
name: playwright-report-${{ matrix.app }}
path: |
${{ matrix.e2e }}/playwright-report
${{ matrix.e2e }}/test-results
if-no-files-found: ignore