diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5567a0d8..33fd7c8b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -303,7 +303,7 @@ jobs: env: PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-full-${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }} PLAYWRIGHT_REPORTER_MODE: line-html - PLAYWRIGHT_WORKERS: ${{ matrix.browser == 'firefox' && '1' || '2' }} + PLAYWRIGHT_WORKERS: 1 PLAYWRIGHT_VIDEO_MODE: off steps: - name: Repair self-hosted workspace permissions diff --git a/README.md b/README.md index b6149820..d2aa18b4 100644 --- a/README.md +++ b/README.md @@ -138,9 +138,11 @@ PLAYWRIGHT_PARALLEL_WORKERS_WEBKIT=1 The runner fails fast if the combined worker count exceeds 5. GitHub Actions keeps the full browser/device/role matrix stable by capping full-suite -matrix parallelism at 2 jobs, wrapping Docker Playwright runs with `systemd-inhibit` -when available, and setting `PLAYWRIGHT_VIDEO_MODE=off` for the full matrix. Traces -and screenshots are still retained on failure. +matrix parallelism at 2 jobs, running each full slice with `PLAYWRIGHT_WORKERS=1`, +wrapping Docker Playwright runs with `systemd-inhibit` when available, and setting +`PLAYWRIGHT_VIDEO_MODE=off` for the full matrix. The E2E network harness stubs the +external Font Awesome stylesheet so WebKit page loads do not depend on CDN/TLS +availability. Traces and screenshots are still retained on failure. Artifacts and summaries: diff --git a/tests/e2e/support/network.js b/tests/e2e/support/network.js index bbff3ca2..293ea4ba 100644 --- a/tests/e2e/support/network.js +++ b/tests/e2e/support/network.js @@ -5831,6 +5831,17 @@ export async function mockApi(page, options = {}) { ...(options.sessionData?.notifications || {}), }; + await page.route( + /https:\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/font-awesome\/.*\/css\/all\.min\.css(?:[?#].*)?$/i, + async (route) => { + await route.fulfill({ + status: 200, + contentType: "text/css", + body: "", + }); + } + ); + await page.route(/https:\/\/cdn\.example\.test\/.*$/i, async (route) => { const request = route.request(); if (request.method() !== "GET") { diff --git a/tests/unit/playwright-full-workflow.spec.js b/tests/unit/playwright-full-workflow.spec.js index f594530e..883946f1 100644 --- a/tests/unit/playwright-full-workflow.spec.js +++ b/tests/unit/playwright-full-workflow.spec.js @@ -4,6 +4,7 @@ import { describe, expect, it } from "vitest"; const root = process.cwd(); const workflowSource = () => readFileSync(join(root, ".github/workflows/tests.yml"), "utf8"); +const networkFixtureSource = () => readFileSync(join(root, "tests/e2e/support/network.js"), "utf8"); describe("Playwright full E2E workflow grouping", () => { it("orders full-suite matrix dimensions by browser, device, then role", () => { @@ -33,6 +34,7 @@ describe("Playwright full E2E workflow grouping", () => { const source = workflowSource(); expect(source).toMatch(/e2e-full:[\s\S]*?max-parallel: 2/u); + expect(source).toMatch(/e2e-full:[\s\S]*?PLAYWRIGHT_WORKERS: 1/u); expect(source).toMatch(/e2e-full:[\s\S]*?PLAYWRIGHT_VIDEO_MODE: off/u); expect(source).toContain("scripts/ci/with-systemd-inhibit.sh"); expect(source).toContain("scripts/ci/runner-diagnostics.sh"); @@ -45,4 +47,11 @@ describe("Playwright full E2E workflow grouping", () => { expect(source).toContain('"retain-on-failure"'); expect(source).toContain('"on-first-retry"'); }); + + it("stubs external stylesheets that can block WebKit page load", () => { + const source = networkFixtureSource(); + + expect(source).toContain("cdnjs\\.cloudflare\\.com"); + expect(source).toContain('contentType: "text/css"'); + }); });