Files
pleno-vue/tests/unit/playwright-full-workflow.spec.js
T
Jeppe BandJeppe Bundgaard d2682da3cc [codex] Improve admin notifications page UI (#145)
* Improve admin notifications page UI

* Stabilize notifications page E2E bootstrap wait

* Fix PR Playwright diff head ref

* Guard MyWashStart timers after test teardown

* Stabilize self-serve wash E2E timing

* Refresh edge gateway fixture runtime state

* Run Playwright E2E on GitHub-hosted runners

* Run all frontend CI on GitHub-hosted runners

* Increase hosted full E2E parallelism

* Stabilize full E2E validation

* Preserve superuser gateway navigation label

* Add targeted Playwright dispatch workflow

* Integrate targeted Playwright dispatch into tests workflow

---------

Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
2026-07-06 22:33:40 +02:00

120 lines
5.5 KiB
JavaScript

import { readFileSync } from "node:fs";
import { join } from "node:path";
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", () => {
const source = workflowSource();
expect(source).toContain("name: E2E-full-${{ matrix.browser_label }}-${{ matrix.device }}-${{ matrix.role }}");
expect(source).toContain("browser: [chromium, webkit, firefox]");
expect(source).toContain("device: [mobile, desktop, tablet]");
expect(source).toContain("role: [superuser, admin, customer, subuser]");
});
it("uses browser-device-role artifact namespaces and generated test lists", () => {
const source = workflowSource();
expect(source).toContain(
"PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-full-${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}"
);
expect(source).toContain(
"name: playwright-report-full-${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}"
);
expect(source).toContain(
"output/playwright/test-lists/${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}.txt"
);
});
it("keeps full-suite runner pressure bounded and diagnosable", () => {
const source = workflowSource();
expect(source).toMatch(
/e2e-full:[\s\S]*?max-parallel: \$\{\{ fromJSON\(github\.event_name == 'workflow_dispatch' && github\.event\.inputs\.runner == 'github-hosted' && '12' \|\| '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");
});
it("diffs pull request changed-area tests against the PR head instead of the merge commit", () => {
const source = workflowSource();
expect(source).toContain("PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}");
expect(source).toMatch(
/if \[\[ "\$EVENT_NAME" == "pull_request" && -n "\$PR_BASE_SHA" \]\]; then[\s\S]*?head_ref="\$PR_HEAD_SHA"/u
);
expect(source).toContain('echo "head=$head_ref" >> "$GITHUB_OUTPUT"');
});
it("keeps PR E2E runner pressure bounded and diagnosable", () => {
const source = workflowSource();
expect(source).toMatch(/e2e-pr:[\s\S]*?runs-on: ubuntu-24\.04/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?max-parallel: 4/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?PLAYWRIGHT_WORKERS: 1/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?PLAYWRIGHT_VIDEO_MODE: on-first-retry/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?--env PLAYWRIGHT_WORKERS="\$PLAYWRIGHT_WORKERS"/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?--env PLAYWRIGHT_VIDEO_MODE="\$PLAYWRIGHT_VIDEO_MODE"/u);
});
it("supports GitHub-hosted manual runners while keeping PR E2E on Ubuntu", () => {
const source = workflowSource();
expect(source).toContain("github.event.inputs.runner == 'github-hosted'");
expect(source).toContain('["ubuntu-latest"]');
expect(source).toContain('["self-hosted","Linux","X64","pleno","frontend"]');
expect(source).toMatch(/e2e-targeted:[\s\S]*?runs-on: ubuntu-24\.04/u);
expect(source).toMatch(/e2e-pr:[\s\S]*?runs-on: ubuntu-24\.04/u);
expect(source).toMatch(/e2e-full:[\s\S]*?frontend","docker"\]/u);
});
it("supports targeted manual Playwright reruns on GitHub-hosted runners", () => {
const source = workflowSource();
expect(source).toContain("workflow_dispatch:");
expect(source).toContain("targeted-then-full");
expect(source).toContain("target_specs:");
expect(source).toContain("target_projects:");
expect(source).toContain("e2e-targeted:");
expect(source).toContain("matrix:");
expect(source).toContain("project: ${{ fromJSON(inputs.target_projects || '[\"chromium-desktop\"]') }}");
expect(source).toMatch(/e2e-targeted:[\s\S]*?runs-on: ubuntu-24\.04/u);
expect(source).toContain('npx playwright test "${args[@]}"');
expect(source).toContain('"$spec_path" != tests/e2e/*');
expect(source).toMatch(/e2e-pr:[\s\S]*?needs: \[build-and-unit, e2e-targeted\]/u);
});
it("uses a machine-wide Playwright port lock across self-hosted runner processes", () => {
const source = workflowSource();
expect(source.match(/PLAYWRIGHT_PORT_LOCK_ROOT:-\/tmp\/pleno-playwright-port-locks/gu)).toHaveLength(3);
expect(source.match(/chmod 1777 "\$lock_root"/gu)).toHaveLength(3);
expect(source).not.toContain("${RUNNER_TEMP:-/tmp}/pleno-playwright-port-locks");
});
it("allows CI to reduce Playwright video artifact pressure", () => {
const source = readFileSync(join(root, "playwright.config.ts"), "utf8");
expect(source).toContain("PLAYWRIGHT_VIDEO_MODE");
expect(source).toContain('"retain-on-failure"');
expect(source).toContain('"on-first-retry"');
});
it("serves Font Awesome from local fixtures so external stylesheets cannot block page load", () => {
const source = networkFixtureSource();
expect(source).toContain("fixtures/fontawesome/6.7.1");
expect(source).toContain("FONT_AWESOME_CSS");
expect(source).toContain("FONT_AWESOME_WEBFONTS");
expect(source).toContain('contentType: "text/css"');
expect(source).toContain('contentType: "font/woff2"');
expect(source).toContain("body: FONT_AWESOME_CSS");
});
});