Closes P1 #10 step 2 / launch sequence step 10. PR #17 already
plumbed VERCEL_AUTOMATION_BYPASS_SECRET into both workflows' env;
this brief wires the actual @playwright/test dep, the
playwright.config.js that bridges env -> use.extraHTTPHeaders,
and a single visual spec so the screenshot workflow has something
to discover.
Per architect Decision 1 - tests/smoke/app.smoke.spec.ts stays as
.ts (npx eslint exits 0 against the current config); new visual
spec also .ts.
Per Decision 2 - playwright.config.js fail-loud in CI when
VERCEL_AUTOMATION_BYPASS_SECRET is missing (throw at config load
with actionable message naming the env var, rotation command,
AGENTS.md reference); warn-and-no-op in dev. Mirrors lib/rate-limit.js
fail-closed pattern (AGENTS.md Gotcha #12).
Per Decision 3 - two projects partitioned by testMatch:
- smoke -> tests/smoke/**/*.spec.{ts,js}
- visual -> tests/visual/**/*.spec.{ts,js}
Shared use: block. Matches the workflows' --project=smoke|visual
invocations.
Per Decision 4 - NO baselines committed. The Mac-vs-Linux platform-
suffix issue (architect Boot-the-brief Finding 7: Playwright's custom
snapshotPathTemplate has no {platform} token) means a Mac-generated
baseline would silently overwrite a Linux CI baseline. Queued as
seed-visual-baselines-on-linux follow-up convoy. First CI run of
Screenshot diff will fail at the test step; existing
continue-on-error: true swallows it and the comment-on-PR step
posts the run link.
Per Decision 5 - no eslint.config.mjs change.
Per Decision 6 - three simple scripts (test:smoke, test:visual,
test:visual:update). No auto-boot wrapper.
Verification:
- npm ci --dry-run exits 0 (lockfile in sync)
- npm run lint: 128 problems (baseline match - 81 errors, 47 warnings)
- npm run test:run: 21/21 vitest pass (no regression)
- npm run test:smoke (no BASE_URL): dev-path warn-and-continue
fires "[playwright.config] VERCEL_AUTOMATION_BYPASS_SECRET unset"
warning, enumerates 3 smoke tests, attempts to run (fails on
missing local chromium binary - workflows install browsers via
npx playwright install --with-deps chromium)
- CI=true npm run test:smoke: CI-path throws at config load with
"VERCEL_AUTOMATION_BYPASS_SECRET is required in CI to reach
Vercel-Protection-protected preview deployments. Reseed via:
gh secret set VERCEL_AUTOMATION_BYPASS_SECRET --body \"<value>\".
See AGENTS.md \xc2\xa7 7 for the full plumbing context."
- npx playwright --version: Version 1.60.0
Implementation note: removed the architect's defensive eslint-disable-
next-line no-console directive in the dev-warn branch because the
active eslint config does not enable no-console for repo-root config
files; ESLint reported the directive as unused, which would have
regressed the lint baseline by +1. Behavior unchanged; comment-only
edit per the brief's explicit "comment wording can be tightened"
allowance. Replaced with an explanatory comment noting why the
directive is intentionally absent.
Implementation note 2: alphabetized @playwright/test as the FIRST
entry in devDependencies (before @testing-library/dom) because
"@p" < "@t". The brief's prose said "between @testing-library/react
and autoprefixer" which would have broken alphabetization; followed
the brief's overarching principle ("alphabetical position") instead.
No code paths in pages/** or lib/** touched. No workflow YAML
edited. No AGENTS.md edits (doc-writer pass at convoy close handles
the seed-on-Linux runbook).
Co-authored-by: Cursor <cursoragent@cursor.com>
Convoy file:
- status: queued -> in-progress
- New § Decisions (post-IA round): 6 decisions investigated.
Architect-self-ratifiable: D2 (CI fail-loud predicate mirrors
rate-limit.js convention), D3 (two projects is a structural
workflow requirement), D5 (no eslint change — verified `npx
eslint tests/smoke/app.smoke.spec.ts` exits 0). Operator-
ratifiable at gate 1: D1 (recommend keep .ts; convention call),
D4 (recommend defer baseline commit to Linux-Docker follow-up;
process call), D6 (recommend simple test:smoke/test:visual
scripts, no auto-boot wrapper; DX call).
- New § Architecture: file plan (5 files), API surface (n/a),
schema diff (n/a), test plan (3 smoke + 1 visual; vitest 21/21
+ lint baseline 128 held), risk list R1-R9 (request fixture
header propagation, snapshotPathTemplate alignment, cross-
platform mismatch, --update-snapshots=none semantics, CI
predicate variants, bypass trace leak, npm ci lockfile sync,
eslint future drift, Playwright 1.60.0 freshness).
- New § Decomposition: 1 brief, ~120 LOC, slice_dependencies
YAML block. Justified single brief because total LOC is
small and all files are semantically coupled (visual spec
depends on visual project in config which depends on the
installed dep).
Brief file (.convoys/adopt-playwright-smoke/brief-1-*.md):
- Goal/Files/Conventions/Acceptance/Manual-verification/
Boot-the-brief findings/Out-of-scope sections matching the
fix-vercel-deployment-protection-in-ci/brief-1 shape.
- 8 Boot-the-brief findings: dep resolution clean, .ts lints
clean, baselines dir MUST NOT be gitignored, extraHTTPHeaders
propagates to request fixture per docs, /api/health is
anonymous, ESM shape required, snapshotPathTemplate token set
has no {platform}, --update-snapshots=none never auto-creates.
- Verbatim playwright.config.js shape with CI fail-loud / dev
warn predicate, snapshotPathTemplate aligned with workflow's
artifact upload path, two projects with testMatch partitioning.
No code changes (read-only architect pass). No push.
Co-authored-by: Cursor <cursoragent@cursor.com>
Scaffolds the convoy file for the next sequential convoy in
.convoys/ship-readiness.md's launch sequence (step 10). The
infra prerequisites have already shipped:
- bump-next-js (e57ea17) — Vercel previews actually deploy
- fix-vercel-deployment-protection-in-ci (9a3e077) — wait-action
healthcheck reaches 200; BASE_URL and VERCEL_AUTOMATION_BYPASS_SECRET
already exported to the test step's env: in both workflows
What remains is small and well-bounded: add @playwright/test to
devDependencies, scaffold playwright.config.js with two projects
(smoke + visual), decide what to do with the existing
tests/smoke/app.smoke.spec.ts (which is .ts in a JS-only repo —
Decision A queued for architect), and put a trivial visual baseline
in place so the screenshot workflow has something to do on first run.
6 decisions queued for architect ratification (TS vs JS spec,
fail-loud vs warn-and-continue on missing secret, project shape,
visual baseline strategy, lint coverage for tests/, local-test
script ergonomics). No operator action required — all secrets
and env vars are already wired.
Co-authored-by: Cursor <cursoragent@cursor.com>