diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1322ff1..0ba9fd1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,6 +108,11 @@ jobs: e2e-ui-test: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + shardIndex: [1, 2, 3, 4] + shardTotal: [4] steps: - name: Checkout @@ -128,21 +133,62 @@ jobs: - name: Install dependencies run: just deps - - name: Run E2E tests - run: just test e2e-ui + - name: Run E2E tests (shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) + run: just test e2e-ui "" "${{ matrix.shardIndex }}/${{ matrix.shardTotal }}" - - name: Upload test results + - name: Upload blob report if: always() uses: actions/upload-artifact@v5 with: - name: playwright-report - path: src/view/playwright-report/ - retention-days: 30 + name: blob-report-${{ matrix.shardIndex }} + path: src/view/blob-report/ + retention-days: 1 - name: Upload test traces if: failure() uses: actions/upload-artifact@v5 with: - name: playwright-traces + name: playwright-traces-${{ matrix.shardIndex }} path: src/view/test-results/ retention-days: 30 + + e2e-report-merge: + runs-on: ubuntu-latest + needs: e2e-ui-test + if: always() + + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Setup Node 22 + uses: actions/setup-node@v6 + with: + node-version: "22.18.0" + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9.15.0 + + - name: Install Playwright + run: cd src/view && pnpm install + + - name: Download all blob reports + uses: actions/download-artifact@v4 + with: + pattern: blob-report-* + path: all-blob-reports/ + merge-multiple: true + + - name: Merge reports + run: | + cd src/view + pnpm exec playwright merge-reports --reporter=html ../../all-blob-reports + + - name: Upload merged HTML report + uses: actions/upload-artifact@v5 + with: + name: playwright-report + path: src/view/playwright-report/ + retention-days: 30 diff --git a/justfile b/justfile index b6cd0ff..937ef07 100644 --- a/justfile +++ b/justfile @@ -153,7 +153,11 @@ test target="" mode="" shard="": fi pnpm test:e2e-ui:report else - pnpm test:e2e-ui + if [ -n "{{ shard }}" ]; then + pnpm exec playwright test --shard="{{ shard }}" + else + pnpm test:e2e-ui + fi fi ;; *) diff --git a/src/view/playwright.config.ts b/src/view/playwright.config.ts index 1cc1740..93a0a65 100644 --- a/src/view/playwright.config.ts +++ b/src/view/playwright.config.ts @@ -1,19 +1,20 @@ import { defineConfig, devices } from "@playwright/test"; const BASE_URL = "http://localhost:5173"; +const isCI = !!process.env.CI; export default defineConfig({ testDir: "./e2e", - fullyParallel: false, - forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: 1, - reporter: [["html", { open: "never" }]], + fullyParallel: true, + forbidOnly: isCI, + retries: isCI ? 2 : 0, + workers: isCI ? 2 : 1, + reporter: isCI ? [["blob"], ["html", { open: "never" }]] : [["html", { open: "never" }]], use: { baseURL: BASE_URL, - trace: process.env.CI ? "on-first-retry" : "on", - screenshot: process.env.CI ? "only-on-failure" : "on", - video: process.env.CI ? "retain-on-failure" : "on", + trace: isCI ? "on-first-retry" : "on", + screenshot: isCI ? "only-on-failure" : "on", + video: isCI ? "retain-on-failure" : "on", }, projects: [ { @@ -24,7 +25,7 @@ export default defineConfig({ webServer: { command: "pnpm dev", url: BASE_URL, - reuseExistingServer: !process.env.CI, + reuseExistingServer: !isCI, timeout: 120 * 1000, }, });