name: E2E Tests on: push: branches: - dev - master pull_request: branches: - dev - master # BrowserStack runs are gated by the `e2e-browserstack` label or manual # dispatch — see the e2e-browserstack job below. Local Chromium always runs. workflow_dispatch: inputs: run-browserstack: description: "Run BrowserStack suite" type: boolean default: true env: NODE_OPTIONS: --max_old_space_size=6144 concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true permissions: contents: read jobs: # ── Build the demo once and share it across test jobs via artifact ────────── build-demo: name: Build demo runs-on: ubuntu-latest steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable - name: Build demo run: ./node_modules/.bin/gulp build-demo env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload demo build uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: demo-dist path: demo/dist/ if-no-files-found: error retention-days: 3 # ── Build the e2e test app and share it via artifact ──────────────────────── build-e2e-test-app: name: Build e2e test app runs-on: ubuntu-latest steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable - name: Build e2e test app run: ./node_modules/.bin/gulp build-e2e-test-app env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload e2e test app build uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: e2e-test-app-dist path: test/e2e/app/dist/ if-no-files-found: error retention-days: 3 # ── Build the gallery and share it via artifact ───────────────────────────── build-gallery: name: Build gallery runs-on: ubuntu-latest steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable - name: Build gallery run: ./node_modules/.bin/gulp build-gallery env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload gallery build uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: gallery-dist path: gallery/dist/ if-no-files-found: error retention-days: 3 # ── Run Playwright tests locally against Chromium ────────────────────────── e2e-local: name: E2E (local Chromium) needs: [build-demo, build-e2e-test-app, build-gallery] runs-on: ubuntu-latest # Fail fast if anything hangs. The whole suite should take < 15 minutes on # Chromium; anything longer is almost certainly an install or webServer # hang. timeout-minutes: 30 steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable # Cache the downloaded browser build keyed on the pinned Playwright # version (yarn.lock), so re-runs skip the ~170 MB download. - name: Cache Playwright browsers uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }} - name: Install Playwright browsers run: yarn playwright install --with-deps chromium timeout-minutes: 10 - name: Download demo build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: demo-dist path: demo/dist/ - name: Download e2e test app build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: e2e-test-app-dist path: test/e2e/app/dist/ - name: Download gallery build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: gallery-dist path: gallery/dist/ - name: Run Playwright tests (local) run: yarn test:e2e timeout-minutes: 15 - name: Upload blob report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: blob-report-local path: test/e2e/reports/ retention-days: 3 # ── Run Playwright tests on BrowserStack (real devices + browsers) ───────── # The BrowserStack SDK manages the Local tunnel and uploads results to the # BrowserStack Automate dashboard automatically — no tunnel action needed. # # Gated on: # - manual dispatch with the run-browserstack input enabled, OR # - a PR with the `e2e-browserstack` label applied. # This keeps CI fast on normal PRs while still allowing on-demand runs. e2e-browserstack: name: E2E (BrowserStack) needs: [build-demo, build-e2e-test-app, build-gallery] runs-on: ubuntu-latest if: | (github.event_name == 'workflow_dispatch' && inputs.run-browserstack) || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'e2e-browserstack')) environment: browserstack env: BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable - name: Download demo build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: demo-dist path: demo/dist/ - name: Download e2e test app build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: e2e-test-app-dist path: test/e2e/app/dist/ - name: Download gallery build uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: gallery-dist path: gallery/dist/ - name: Run Playwright tests (BrowserStack) run: yarn test:e2e:browserstack # ── Merge local blob reports and post PR comment ─────────────────────────── # Only depends on the local job — BrowserStack reports live on the # BrowserStack Automate dashboard and don't feed into the local blob report. report: name: Report needs: [e2e-local] runs-on: ubuntu-latest if: always() permissions: contents: read pull-requests: write steps: - name: Check out files from GitHub uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: ".nvmrc" cache: yarn - name: Install dependencies run: yarn install --immutable - name: Download blob report (local) uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 continue-on-error: true with: name: blob-report-local path: test/e2e/reports/ - name: Stage blobs for merge run: node test/e2e/collect-blob-reports.mjs - name: Merge blob reports run: npx playwright merge-reports -c test/e2e/playwright.merge.config.ts test/e2e/reports/blob - name: Upload merged HTML report id: upload-report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: playwright-report path: test/e2e/reports/combined/ retention-days: 14 - name: Post report link to PR if: github.event_name == 'pull_request' uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: script: | const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; const body = `## Playwright E2E test report\n\nThe combined HTML report is available as a workflow artifact.\n\n[View workflow run](${runUrl})`; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body, });