diff --git a/AGENTS.md b/AGENTS.md index cb6755ab..29748416 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -291,6 +291,16 @@ pnpm build 예: `pnpm --filter @sammo-ts/game-engine test monthlyCoreEventHandler.test.ts` - frontend package의 `test` placeholder를 실제 UI 검증으로 오해하지 말아 주세요. 해당 Playwright script 또는 legacy parity suite를 사용해 주세요. +- 새 worktree에서 direct Playwright를 실행하기 전에 현재 호스트의 `fnm use` + (nvm 환경은 `nvm use`) 후 + `pnpm test:bootstrap`을 실행해 install, Prisma client와 + common → logic → infra → game-engine → API 산출물을 준비해 주세요. 이미 + install된 checkout은 `pnpm test:prepare`를 사용합니다. Playwright + `webServer` 실패를 이 준비가 끝나기 전 제품 회귀로 분류하지 말아 주세요. +- E2E port가 다른 worktree와 겹치면 설정 파일을 임시 수정하지 말고 + `PLAYWRIGHT_FRONTEND_PORT`, `PLAYWRIGHT_GATEWAY_FRONTEND_PORT` 또는 + `FRONTEND_PARITY_*_PORT`를 지정합니다. 같은 game frontend `dist`를 쓰는 + profile production run은 직렬로 실행합니다. - 전체 lint/test의 기존 실패가 있으면 targeted 결과와 baseline 재현 결과를 구분하고, 관련 없는 기대값을 완화해 숨기지 말아 주세요. diff --git a/README.md b/README.md index 991a14b8..43b5ad73 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,21 @@ full Git commit으로 고정하고, 실험 릴리스 같은 milestone은 annotat ## 개발 환경 ```sh -pnpm install --frozen-lockfile +fnm use +pnpm test:bootstrap cp .env.example .env -pnpm --filter @sammo-ts/infra prisma:generate CI=1 pnpm typecheck ``` +현재 호스트의 `fnm use`는 `.nvmrc`의 Node 24를 적용합니다. nvm을 사용하는 다른 +환경에서는 같은 위치에서 `nvm use`를 사용합니다. + +`test:bootstrap`은 새 worktree에서 offline frozen install, game/Gateway Prisma +client 생성과 내부 package build를 순서대로 수행합니다. 이미 install이 끝난 +worktree에서 schema 또는 내부 package가 바뀌었으면 `pnpm test:prepare`만 다시 +실행합니다. Playwright를 직접 실행하기 전의 표준 절차와 오류별 복구 방법은 +[테스트 정책](docs/testing-policy.md#새-worktree-준비)에 있습니다. + `.env`는 Git에서 제외됩니다. 비밀값은 명령행, 로그, screenshot, report, `VITE_*` 변수에 넣지 말아 주세요. 상위 작업공간에서는 `../docker_compose_files/development/README.md`의 PostgreSQL·Redis stack을 diff --git a/docs/testing-policy.md b/docs/testing-policy.md index b04755a2..4b236200 100644 --- a/docs/testing-policy.md +++ b/docs/testing-policy.md @@ -23,6 +23,97 @@ pnpm build `pnpm docs:build`를 확인합니다. 제품 코드 동작을 바꾸지 않은 문서 작업은 typecheck·unit·Chromium 검증을 실행한 것으로 설명하지 않습니다. +## 새 worktree 준비 + +Playwright 설정의 `webServer`는 frontend package의 `dev` 또는 +`vue-tsc && vite build`를 직접 실행합니다. 이 경로는 root Turbo task가 +보장하는 Prisma 생성과 upstream package build를 거치지 않으므로, 새 worktree에서 +브라우저 test를 먼저 실행하면 제품 코드와 무관한 module/type 오류가 발생할 수 +있습니다. + +Node 24 환경을 활성화한 뒤 저장소 root에서 다음 한 명령으로 준비합니다. + +```sh +fnm use +pnpm test:bootstrap +``` + +현재 호스트는 `fnm use`가 `.nvmrc`를 읽습니다. nvm 환경에서는 `nvm use`로 같은 +Node 24 계약을 적용합니다. + +`test:bootstrap`은 다음 순서를 고정합니다. + +1. `pnpm install --offline --frozen-lockfile` +2. game/Gateway Prisma client 생성 +3. `common → logic → infra → game-engine → game-api → gateway-api` build + +로컬 pnpm store에 필요한 package가 없는 호스트에서만 network 사용 가능 여부를 +확인한 뒤 `pnpm install --frozen-lockfile`과 `pnpm test:prepare`를 +나누어 실행합니다. 이미 install된 worktree에서는 schema, package source 또는 +branch가 바뀐 뒤 다음 준비 명령만 다시 실행합니다. + +```sh +pnpm test:prepare +``` + +Chromium executable이 없다는 Playwright 안내가 나온 경우에만 다음을 실행합니다. +이는 package/Prisma 준비와 별도이며 browser cache를 변경합니다. + +```sh +pnpm exec playwright install chromium +``` + +### Browser test 실행 + +Game frontend fixture의 예시는 다음과 같습니다. Ref 룩앤필 근거가 필요한 UI +변경은 `PLAYWRIGHT_FRONTEND_MODE=production`을 사용해 production bundle을 +검증합니다. + +```sh +PLAYWRIGHT_FRONTEND_PORT=15241 \ +PLAYWRIGHT_FRONTEND_MODE=production \ +pnpm --filter @sammo-ts/game-frontend exec playwright test \ + inGameMenus.spec.ts --config e2e/playwright.config.mjs --grep '대상 이름' +``` + +Gateway fixture는 별도의 port 환경 변수를 사용합니다. + +```sh +PLAYWRIGHT_GATEWAY_FRONTEND_PORT=15242 \ +pnpm --filter @sammo-ts/gateway-frontend exec playwright test \ + public-map-tabs.spec.ts --config e2e/playwright.config.mjs --grep '대상 이름' +``` + +Ref/Core 공통 fixture는 root script를 사용하며, 다른 worktree와 port가 겹치면 +설정을 편집하지 않고 환경 변수로 격리합니다. + +```sh +FRONTEND_PARITY_GATEWAY_PORT=15243 \ +FRONTEND_PARITY_GAME_PORT=15244 \ +pnpm test:e2e:frontend-legacy +``` + +같은 game frontend `dist`를 쓰는 CHE/HWE production build와 Playwright run은 +동시에 실행하지 않습니다. 각 profile을 직렬로 실행하고 해당 run의 base path, +profile, viewport와 fixture를 결과에 기록합니다. + +### 준비 실패와 제품 실패 구분 + +| 증상 | 먼저 확인할 항목 | 처리 | +| ------------------------------------------------------------------------------ | ------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `pnpm: command not found` | `.nvmrc`의 Node 24가 활성화됐는지 | 현재 호스트는 `fnm use`; nvm 환경은 `nvm use`; shim이 없으면 `corepack enable` 후 재실행 | +| Corepack 하위 실행에서 pnpm version mismatch | package script 안에서 다른 Corepack pnpm이 재호출됐는지 | Node 24 적용 후 직접 `pnpm test:bootstrap` 실행; `corepack pnpm test:bootstrap` 중첩 금지 | +| `Cannot find module '../prisma/generated/...'` 또는 새 Prisma field 부재 | generated client가 현재 checkout schema와 같은지 | `pnpm test:prepare` | +| `Failed to resolve import '@sammo-ts/common'`, `@sammo-ts/logic` 또는 `TS6305` | upstream `dist`가 현재 checkout source로 build됐는지 | `pnpm test:prepare`; 계속되면 실패 package의 `build`를 단독 실행해 실제 오류 확인 | +| `Process from config.webServer was not able to start` | 위 준비 오류와 frontend build의 숨겨진 stderr | 준비 후 `pnpm --filter build`를 단독 실행 | +| `EADDRINUSE` 또는 server timeout | 다른 worktree의 151xx listener | 해당 Playwright port 환경 변수로 고유 port 지정; config 임시 수정 금지 | +| browser executable 부재 | Playwright가 표시한 cache path | `pnpm exec playwright install chromium` | +| `node_modules/.modules.yaml` `EACCES` | 기존 checkout의 소유권이 다른 작업에서 바뀌었는지 | 소유권을 임의 변경하지 말고 같은 commit의 깨끗한 worktree에서 준비·검증 | + +준비 명령이 성공한 뒤 발생한 assertion, browser console, request 또는 geometry +차이만 제품/fixture 분석 대상으로 올립니다. 넓은 suite 실패는 변경 없는 동일 +commit에서도 재현하여 baseline과 회귀를 구분하고, skip은 pass로 세지 않습니다. + ## 테스트 계층 ### Unit diff --git a/package.json b/package.json index f118a9fa..b43bb606 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "lint:fix": "turbo lint:fix", "format": "prettier --write .", "test": "turbo test", + "test:bootstrap": "pnpm install --offline --frozen-lockfile && pnpm test:prepare", + "test:prepare": "pnpm --filter @sammo-ts/infra prisma:generate && pnpm --filter @sammo-ts/common build && pnpm --filter @sammo-ts/logic build && pnpm --filter @sammo-ts/infra build && pnpm --filter @sammo-ts/game-engine build && pnpm --filter @sammo-ts/game-api build && pnpm --filter @sammo-ts/gateway-api build", "test:integration": "pnpm --filter @sammo-ts/integration-tests test:integration", "test:integration:conditional": "./tools/run-conditional-integration.sh", "build": "turbo build",