From 5cc46338d47b1d3345346c585037b04dff195e57 Mon Sep 17 00:00:00 2001 From: SyniRon <66834451+SyniRon@users.noreply.github.com> Date: Fri, 22 May 2026 14:19:24 -0400 Subject: [PATCH] chore(ci): add baseline test workflow (build + vitest + playwright) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The repo had no test workflow before — only Dependabot Updates was configured, so PRs merged on local-pnpm-test trust (e.g. PR #7). Adds `.github/workflows/ci.yml`: - pnpm 11 + Node 22 (matches the local dev pin) - caches the ~50MB CCP SDE zip between runs (the build:sde script already self-invalidates after 7 days, so the static key is safe) - runs `pnpm build` (which chains build:sde + build:services + tsc -b + vite build — also our typecheck gate), then `pnpm test` (vitest), then the Playwright smoke against `pnpm preview` - uploads the Playwright report as an artifact on failure Also patches `e2e/playwright.config.ts` to fall back to Playwright's bundled Chromium when `/snap/bin/chromium` isn't present. The hardcoded snap path was synicloud-specific; GitHub Actions runners don't have it. --- .github/workflows/ci.yml | 76 ++++++++++++++++++++++++++++++++++++++++ e2e/playwright.config.ts | 14 +++++--- 2 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e49df83 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: build + vitest + playwright smoke + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 11 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: | + web/pnpm-lock.yaml + e2e/pnpm-lock.yaml + + # Cache the ~50MB CCP SDE zip across runs. scripts/build-sde.ts + # already self-invalidates after 7 days, so the same key is safe to + # keep — a stale entry will just trigger one re-download. + - name: Cache SDE zip + uses: actions/cache@v4 + with: + path: web/scripts/cache + key: freightdesk-sde-zip-v1 + + - name: Install web deps + working-directory: web + run: pnpm install --frozen-lockfile + + - name: Install e2e deps + working-directory: e2e + run: pnpm install --frozen-lockfile + + # `pnpm build` chains: build:sde → build:services → tsc -b → vite build. + # This is also our typecheck gate. + - name: Build web (SDE + services + tsc + vite) + working-directory: web + run: pnpm build + + - name: Run vitest + working-directory: web + run: pnpm test + + - name: Install Playwright Chromium + working-directory: e2e + run: pnpm exec playwright install --with-deps chromium + + - name: Run Playwright smoke + working-directory: e2e + run: pnpm exec playwright test + + - name: Upload Playwright report on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: | + e2e/playwright-report + e2e/test-results + retention-days: 7 diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 3803b84..9daf9f7 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -1,16 +1,20 @@ +import { existsSync } from "node:fs"; import { defineConfig, devices } from "@playwright/test"; +// On synicloud's Ubuntu host we use the snap-packaged Chromium; on macOS dev +// boxes and GitHub Actions runners we let Playwright's bundled Chromium win. +const SNAP_CHROMIUM = "/snap/bin/chromium"; +const useSnapChromium = process.platform === "linux" && existsSync(SNAP_CHROMIUM); + export default defineConfig({ testDir: ".", fullyParallel: false, retries: 0, use: { baseURL: process.env.E2E_BASE_URL ?? "http://localhost:4173", - launchOptions: { - ...(process.platform === "linux" - ? { executablePath: "/snap/bin/chromium", args: ["--no-sandbox", "--disable-setuid-sandbox"] } - : {}), - }, + launchOptions: useSnapChromium + ? { executablePath: SNAP_CHROMIUM, args: ["--no-sandbox", "--disable-setuid-sandbox"] } + : {}, }, projects: [{ name: "chromium", use: devices["Desktop Chrome"] }], webServer: process.env.E2E_BASE_URL