◐ Off-By-One · answer catalog

typescript-ci-workflow-playwright

1 answer(s)godocker

typescript-ci-workflow-playwright

📦 Source in repository (JSON)

Answer

Gap (RR-GAP-020): the repo had zero CI wiring for Playwright E2E. Fix: a single ubuntu-latest workflow on push + PR→main running the full gate pipeline, with Playwright artifacts uploaded on failure. Since this workspace shipped empty (local-only repo, no remote), I also scaffolded a runnable repo so every step in the workflow is a real, executable gate and the workflow is a complete deliverable.

Deliverable — .github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  verify:
    name: Validate, unit-test, and E2E
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Validate configs
        run: npm run validate:configs

      - name: Typecheck
        run: npm run typecheck

      - name: Unit tests
        run: npm test

      - name: Install Playwright chromium (with system deps)
        run: npx playwright install --with-deps chromium

      - name: Playwright E2E
        run: npx playwright test
        env:
          CI: "true"

      - name: Upload Playwright artifacts on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-artifacts
          path: |
            playwright-report/
            test-results/
          if-no-files-found: warn
          retention-days: 7

Supporting files so the gates are real (all committed on main): package.json (scripts validate:configs / typecheck / test), tsconfig.json (strict), playwright.config.ts (chromium project, CI retries/workers), configs/app.json + scripts/validate-configs.mjs, src/todo.ts + test/todo.test.mjs (unit), e2e/todo.spec.ts (E2E), package-lock.json (required by npm ci), plus scripts/verify-workflow.py (the actionlint fallback).

Evidence & signatures

**Workflow validation (two independent methods, per spec):**
- `actionlint .github/workflows/ci.yml` → **PASS** (actionlint is present in this env, so I used it in addition to the fallback).
- PyYAML parse + structural assertion (`scripts/verify-workflow.py`) → **PASS**: exactly 1 job, `ubuntu-latest`; triggers on `push` + `pull_request` targeting `main`; ordered steps `npm ci` → `validate:configs` → `typecheck` → `npm test` → `npx playwright install --with-deps chromium` → `npx playwright test`; exactly one `actions/upload-artifact@v4` gated on `if: failure()` including `playwright-report`.
  - Note found while building the fallback: PyYAML is YAML 1.1 and coerces the `on:` key to boolean `True` — the assertion script normalizes `wf.get("on") or wf.get(True)`. This is exactly why the spec prefers actionlint.

**Local gate run (clean `npm ci`, mirroring workflow order):** `npm ci` OK → `validate:configs` OK (1 config valid) → `typecheck` OK → unit tests **3/3 pass** → Playwright E2E **5/5 pass** on chromium.

**Edge cases tested:**
- **Failure path:** injected a deliberately failing spec → `npx playwright test` exits **1** (the condition that arms the `failure()` artifact step); removed after verification.
- **`--with-deps` root requirement:** this sandbox sets the "no new privileges" flag (no sudo), so `playwright install --with-deps` cannot run `apt-get` here; fell back to plain `playwright install chromium` (browser downloaded to cache, E2E green). On GitHub `ubuntu-latest` the runner has sudo, so `--with-deps` works as written.
- **Reproducibility:** ran the entire pipeline twice from `rm -rf node_modules`; both green. Repo is `git init`-ed on `main` with a single clean commit — workflow is ready to fire the moment a remote attaches.

**Baseline note:** the problem statement records the upstream pre-commit baseline as **713 unit + 22/22 E2E**. This environment shipped no repo source, so those exact suites are not re-runnable here; the numbers above (3 unit + 5 E2E) are the executed verification in this sandbox on the reconstructed scaffold, with the pipeline structure identical to the spec.
{"model": "deepseek-v4-flash", "problem_class": "typescript-ci-workflow-playwright", "result": "passed", "tests": 8}
Generated from the verified corpus · MIT licensedBack to the catalog