Repository navigation
Web e2e smoke (Playwright) + pending branch work - #14
Merged
Merged
Conversation
Single-source the 7 hand-duplicated tool versions (typescript, eslint, vitest, @types/node, tsx, tsup, drizzle-orm) via a pnpm workspace catalog in pnpm-workspace.yaml; drizzle-orm had already drifted across three manifests (^0.45.2 vs a bare pin). Also remove the no-op "build": "tsc --noEmit" script from the four internal packages (bots, engine, fairness, shared) so `turbo run build` only runs the apps' real builds and stops double type-checking every package in CI.
Add loadLocalEnv() (packages/shared/src/server/env/local.ts) which hydrates process.env from the repo-root .env at boot: dev-only (no-op when NODE_ENV is production/test) and never overrides an already-set variable. api, match, and bots each call it before loading their own validated env, so a plain root `pnpm dev` boots the whole stack with no exported shell vars. Since one .env now feeds all three long-lived services at once, PORT must stay unset there or every service would bind the same port. The PORT schema treats an empty string as unset, falling through to each service's own default (api 3001, match 2567, bots 2568); a real PORT env var still overrides for a single process.
Records the direct commits (no OpenSpec change) for the turbo build/typecheck split, the pnpm catalog, and root .env auto-loading for local dev; also drops the stale "P1 complete except item 9" note from item 14 now that item 9 (bot-service integration) is archived.
Adds vitest + testing-library harness to apps/web (jsdom env, fake Colyseus client injected through ColyseusProvider's new `client` prop) and covers the use-table-connection reconnect machine plus table-store derivation logic with unit tests. table-store exports buildRenderModel and deriveAvailableAction so tests can exercise them directly. Archives the add-web-test-foundation OpenSpec change and marks item 15 in the hardening audit as half done, with the Playwright e2e smoke left as a follow-up.
Audit item 15's second half (change add-web-e2e-smoke): a Playwright suite in apps/web/e2e/ proving the signed-in happy path end to end — hall → Quick Play → live table → shuffle handshake → a full hand played to its conclusion — against the real web+api+match+bots stack. - Clerk auth via @clerk/testing: each run creates an ephemeral test user (Backend API), signs it in server-side in global setup, persists storage state, and deletes the user in a teardown project; stale orphans are swept at the next run's setup. Per-run identities avoid the leftover live-match contention a shared user hits (bots play an abandoned match out for ~8 minutes). - webServer boots/attaches to the four services; new unauthenticated GET /healthz liveness routes on match and bots (api reuses its tRPC health query; web probes /sign-in, the one unprotected route). - The hand loop is strategy-free: pass every auction turn, declare an accepted suit if dealer-forced in (all-pass rule), click cards until accepted on trick-play turns (reject+resync makes wrong clicks harmless). - New non-blocking e2e.yml workflow on PRs (E2E_* repository secrets → root .env, the contract the services already read); not in the main ruleset's required checks — promotion is a later ruleset edit. - vitest excludes e2e/** so the unit gate is untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
`next dev` rejects an empty PORT env var (the root .env deliberately ships `PORT=` empty for the Node services, whose schema treats empty as unset) — the Playwright config inherited it via loadLocalEnv and every CI boot died instantly. Also pipe webServer stdout so boot failures are diagnosable in CI logs, and exempt the Node-only Playwright harness from the web browser-bundle import guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add an end-to-end Playwright test in `apps/web/e2e/` to validate the signed-in happy path: hall → Quick Play → live table → shuffle handshake → full hand completion. Includes: - Ephemeral Clerk test user setup via `@clerk/testing`, with session persistence and teardown. - Playwright `webServer` boots/attaches to the local stack, probing health endpoints. - Strategy-free hand completion logic (pass auction turns, declare trump if forced in, play any legal card). - Separate non-blocking CI workflow (`e2e.yml`) with Playwright artifacts uploaded on failure. Workflow runs on PRs and uses `E2E_*` secrets for dev-resource provisioning. Unit testing remains unaffected (`vitest` excludes `e2e/**`). The smoke test is not a required check yet, awaiting stability observations.
…ions Resolve the polish-engine-correctness change: royal-marriage melds now record the physical card copies a run did not consume (copyIndex-based), so identity-based bury exclusions no longer miss or double-count cards. Add reduceWithVerdict alongside reduce, projecting a typed RejectionCode (wrong-phase, out-of-turn, illegal-bid, unknown-suit, card-not-held, illegal-card, illegal-bury, no-forced-move, config-fault) instead of silently returning the unchanged state, while reduce stays its exact .state projection so replay behavior is unchanged. Prove timeout escape completeness end-to-end with a 32-seed x 2-variant match-fold property test, and bump ENGINE_VERSION to 0.1.0 as the replay-compatibility stamp for the meld attribution change.
Extract the four-suit tuple into variant/suits.ts and reuse it from schema.ts, canonical.ts, and meld-table.ts instead of three copies. Remove exports with no remaining callers: pingRedis, widowEnabled/ buryEnabled/passingEnabled, TRACE_ID_FIELD, and PACKAGE_NAME. Un-barrel canonicalJson from the variant surface, and update stale doc comments (errors.ts, db/client.ts, trace.ts) to match current behavior.
…it scan Export applyDealWithRng and startNextHandBase from the reducer so the match room's deal.ts becomes a thin adapter over the engine's own orchestration instead of re-implementing phase-advance and hand-boundary logic locally. Reuse the shared SUITS tuple in meld.ts instead of a local copy. Update the hand-lifecycle-state-machine and match-shuffle-handshake specs to describe the engine-owned seam, and add dealOrchestration.test.ts covering it.
…lyph Introduce PageShell/CenteredMessage to replace the duplicated <main> shell markup across the landing, sign-in/up, table, and waiting-room pages. Add a createStoreContext factory and rebuild SessionStore/ TableStore on top of it, removing duplicated Provider/useContext boilerplate. Add useTableHandoff to dedupe the handoff-to-table logic shared by casual-hall and use-waiting-room. Extract SUIT_GLYPH into suit-glyph.ts so card.tsx and table-view.tsx share one copy, and use cardIdentityKey for the card list key instead of a hand-rolled string. Also fixes a stale doc comment in env.ts now that the Clerk publishable key is required.
…ckerfile Replace the three near-identical apps/*/Dockerfile files with a single parameterized root Dockerfile that selects the service via PKG/APP_DIR build args. Each fly.toml's [build] section now points at the root Dockerfile and supplies its own args, so deploy.yml no longer passes --dockerfile and a base-image or build-pipeline change is made exactly once. Update infra/README.md and the deployment-config spec to match.
Archive the completed prune-and-dedupe-hygiene change and mark item 19 of the hardening audit done, closing out the last remaining audit item.
JasonPaff
added a commit
that referenced
this pull request
Jul 3, 2026
…res (#15) The PR #14 merge exposed two resource-exhaustion failures that never hit PR runs: - Deploy: all three Fly apps built concurrently on the shared remote builder and api/match were OOM-killed (exit 137) in pnpm deploy. Serialize the matrix with max-parallel: 1. - CI: the lockfile change invalidated every turbo hash, so main ran all 25 tasks cold at default concurrency 10 and a vitest worker was killed. Cap the quality gate at --concurrency=4 to match runner cores. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands
add-web-e2e-smoke(audit item 15, second half): the repo's first e2e layer — a Playwright smoke inapps/web/e2e/that signs in through real Clerk, hits Quick Play, reaches the live table, completes the shuffle handshake, and plays a full hand to its conclusion against the real four-service stack.@clerk/testingwith an ephemeral per-run test user (created via the Backend API in global setup, deleted in a teardown project, stale orphans swept). Per-run identities eliminate leftover-live-match contention between runs — a shared user blocked consecutive runs for ~8 minutes while bots played out its abandoned match.webServerattaches to a running local stack, boots it in CI. New unauthenticatedGET /healthzroutes on match + bots serve as readiness URLs (api reuses its tRPChealthquery; web probes/sign-in).E2Eworkflow on PRs (E2E_*repo secrets → root.env). Deliberately NOT in themainruleset's required checks; promote via a one-line ruleset edit after a stable stretch (~2 weeks).e2e/**;turbo run testcollects zero Playwright specs.This branch also carries the previously unmerged work: web vitest foundation (
add-web-test-foundation), root.envauto-load, pnpm catalog, audit doc updates.Test plan
pnpm lint/typecheck/testgreen; unit runner collects no e2e specs🤖 Generated with Claude Code