diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 046ce7d..d8c2cda 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,31 +1,11 @@ -# Dev container for mifi Ventures static site -# Lightweight: Node for static server (npx serve), no app dependencies +# Dev container: same image as CI e2e (Playwright Noble) so visual snapshots match. +# Snapshots generated in the devcontainer will match CI; no need to run update-snapshots in CI. +FROM mcr.microsoft.com/playwright:v1.58.0-noble -FROM mcr.microsoft.com/devcontainers/javascript-node:1-22-bookworm +# pnpm for this project (CI uses the same) +RUN corepack enable && corepack prepare pnpm@10.28.2 --activate -# Install system deps for static site tooling + Playwright (e2e tests) -RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - # Playwright browser dependencies (so e2e tests run inside devcontainer) - libnspr4 \ - libnss3 \ - libatk1.0-0 \ - libdbus-1-3 \ - libatspi2.0-0 \ - libxcomposite1 \ - libxdamage1 \ - libxfixes3 \ - libxrandr2 \ - libgbm1 \ - libxkbcommon0 \ - libasound2 \ - && rm -rf /var/lib/apt/lists/* - -# Ensure workspace dir exists (mount point) RUN mkdir -p /workspaces/mifi-ventures-landing - -# Default working directory WORKDIR /workspaces/mifi-ventures-landing -# npx serve is used at runtime via postStartCommand -# No npm install needed — static site, no package.json +# Default user is root (Playwright image); devcontainer runs as root for e2e. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cf2882d..9a3f96c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,9 @@ "dockerFile": "Dockerfile", "workspaceFolder": "/workspaces/mifi-ventures-landing", "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/mifi-ventures-landing,type=bind", - "postCreateCommand": "pnpm install && pnpm exec playwright install chromium", + "runArgs": ["-u", "root"], + "remoteUser": "root", + "postCreateCommand": "pnpm install", "forwardPorts": [5173, 4173], "portsAttributes": { "5173": { @@ -38,6 +40,5 @@ } } } - }, - "remoteUser": "node" + } } diff --git a/.woodpecker/update-e2e-snapshots.yaml b/.woodpecker/update-e2e-snapshots.yaml new file mode 100644 index 0000000..37c7a24 --- /dev/null +++ b/.woodpecker/update-e2e-snapshots.yaml @@ -0,0 +1,41 @@ +# Manual workflow: regenerate e2e Linux snapshot in CI and push it (fallback when not using the devcontainer). +# Prefer updating snapshots in the devcontainer (same image as CI); use this workflow if you don't use the +# devcontainer (e.g. macOS-only) or can't run the update locally. Trigger manually; choose the branch to update. +# +# Required secret: git_push_token — repo push token (e.g. Gitea/Forgejo personal access token). +# Add in Woodpecker → Repo → Settings → Secrets. +when: + event: manual + +steps: + - name: update e2e snapshots + image: mcr.microsoft.com/playwright:v1.58.0-noble + commands: + - corepack enable && corepack prepare pnpm@10.28.2 --activate + - pnpm install --frozen-lockfile || pnpm install + - pnpm run build + - npx serve dist -p 4173 & + - sleep 2 + - CI=1 pnpm exec playwright test --update-snapshots + + - name: commit and push snapshot + image: alpine/git + environment: + GIT_PUSH_TOKEN: + from_secret: git_push_token + commands: + - set -e + - 'git config user.email "ci@woodpecker"' + - 'git config user.name "Woodpecker CI"' + # Push URL with token for write access (Gitea/Forgejo: token as username) + - 'PUSH_URL="https://$${GIT_PUSH_TOKEN}@$${CI_REPO_CLONE_URL#https://}"' + - git remote set-url origin "$PUSH_URL" + - git add tests/visual.spec.ts-snapshots/ + - | + if git diff --staged --quiet; then + echo "No snapshot changes to commit." + else + git commit -m "chore: update e2e snapshot from CI [skip ci]" + git push origin "$CI_COMMIT_BRANCH" + echo "Snapshot pushed to $CI_COMMIT_BRANCH" + fi diff --git a/README.md b/README.md index 7f2f4e1..25a1001 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ This project uses **pnpm** as the package manager. After cloning, run `pnpm inst | `pnpm run preview` | Serve `dist/` (Critters-processed) at http://localhost:4173 — same as deployed | | `pnpm test` | Run unit tests (Vitest) | | `pnpm run test:e2e` | Run Playwright visual regression (e2e) | -| `pnpm run test:e2e:update-snapshots` | Regenerate e2e snapshots in CI Docker image (see below) | +| `pnpm run test:e2e:update-snapshots` | Regenerate e2e snapshots (in devcontainer = CI; see Visual regression) | | `pnpm run lint` | ESLint (JS/TS/Svelte) | | `pnpm run lint:css` | Stylelint (global CSS + Svelte styles) | | `pnpm run format` | Prettier (JS/TS/Svelte/CSS/JSON) | @@ -61,11 +61,11 @@ Preview uses `serve dist` so you see the same HTML/CSS as in production (includi ### Option 3: Dev Container -Open the project in a dev container for a consistent local environment: +Open the project in a dev container for a consistent local environment. The devcontainer uses the **same image as CI** (`mcr.microsoft.com/playwright:v1.58.0-noble`), so e2e snapshots generated inside it match CI. 1. **Open in Cursor or VS Code** with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension installed. 2. **Reopen in Container**: Command Palette (`Cmd/Ctrl+Shift+P`) → **Dev Containers: Reopen in Container**. -3. Wait for the container to build and start. +3. Wait for the container to build and start. (If you already had a devcontainer open, use **Rebuild Container** once to pick up the Playwright Noble image.) **Inside the container**, run: @@ -74,21 +74,21 @@ pnpm install pnpm run dev ``` -The site is served at **http://localhost:5173** (or the port shown) with live reload (port forwarded automatically). +The site is served at **http://localhost:5173** (or the port shown) with live reload (port forwarded automatically). Run `pnpm run test:e2e:update-snapshots` here to regenerate the Linux snapshot when the layout changes. ### Visual regression (e2e) -E2e tests use Playwright and compare full-page screenshots to committed snapshots. CI runs in `mcr.microsoft.com/playwright:v1.58.0-noble`; the **Linux** snapshot (`home-chromium-linux.png`) must be generated in that same environment or CI will fail (e.g. different height due to font/layout rendering). +E2e tests use Playwright and compare full-page screenshots to committed snapshots. CI and the **devcontainer** both use `mcr.microsoft.com/playwright:v1.58.0-noble`, so snapshots generated in the devcontainer match CI. -If CI fails with a snapshot mismatch (e.g. "Expected 1280×5985px, received 1280×5782px"): +**To update the Linux snapshot locally (devcontainer):** -1. Regenerate the Linux snapshot in the CI Docker image: - ```bash - pnpm run test:e2e:update-snapshots - ``` -2. Commit the updated file(s) under `tests/visual.spec.ts-snapshots/`. +1. Rebuild the devcontainer once (so it uses the Playwright Noble image; see Option 3 below). +2. Run `pnpm run test:e2e:update-snapshots` (no Docker needed — same environment as CI). +3. Commit the updated file(s) under `tests/visual.spec.ts-snapshots/`. -Local `pnpm run test:e2e` uses the **Darwin** snapshot on macOS; the Linux snapshot is only used in CI. +**If you’re not using the devcontainer:** run the **update-e2e-snapshots** workflow manually in Woodpecker (requires a `git_push_token` secret), or run `pnpm run test:e2e:update-snapshots` on a host with Docker. + +Local `pnpm run test:e2e` on **macOS** uses the Darwin snapshot; the Linux snapshot is used in CI and in the devcontainer. ### Option 4: Docker (Production-like Test) @@ -178,6 +178,7 @@ Navigate to your repository → Settings → Secrets and add: | `deploy_username` | SSH username | `deploy` or `root` | | `deploy_ssh_key` | Private SSH key (multi-line) | `-----BEGIN OPENSSH PRIVATE KEY-----...` | | `deploy_port` | SSH port | `22` (default) | +| `git_push_token` | *(Optional)* Repo push token for manual **update-e2e-snapshots** workflow (fallback when not using devcontainer) | Gitea/Forgejo personal access token | **Generate SSH key for deployment:** diff --git a/scripts/update-e2e-snapshots.sh b/scripts/update-e2e-snapshots.sh index 3ef34a8..c065948 100755 --- a/scripts/update-e2e-snapshots.sh +++ b/scripts/update-e2e-snapshots.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash # Regenerate Playwright visual regression snapshots. -# - When Docker is available: runs in the same image as CI (Playwright Noble) for a CI-accurate baseline. -# - When Docker is not available (e.g. devcontainer): runs Playwright in the current environment; -# the Linux snapshot may still differ slightly from CI — if CI fails, run this script on the host with Docker. +# - In the devcontainer (Playwright Noble): same image as CI, snapshot matches CI. +# - When Docker is available on host: runs in the same image as CI for a CI-accurate baseline. +# - Otherwise: run the update-e2e-snapshots workflow in Woodpecker (manual pipeline). set -e SCRIPT_DIR="${BASH_SOURCE%/*}" @@ -28,8 +28,7 @@ if command -v docker >/dev/null 2>&1; then pnpm exec playwright test --update-snapshots ' else - echo "Docker not found — updating snapshots in the current environment." - echo "If CI later fails with a snapshot mismatch, run this script on a host with Docker for a CI-accurate baseline." + echo "Updating snapshots in the current environment (matches CI when using the devcontainer)." echo "" # Unset CI so Playwright config starts the preview server diff --git a/tests/visual.spec.ts-snapshots/home-chromium-linux.png b/tests/visual.spec.ts-snapshots/home-chromium-linux.png index 3b7f9bd..3f42193 100644 Binary files a/tests/visual.spec.ts-snapshots/home-chromium-linux.png and b/tests/visual.spec.ts-snapshots/home-chromium-linux.png differ