# 라이브 SUT Smoke Test 가이드 이 문서는 recordingtest의 5개 PoC 모듈을 **실제 EG-BIM Modeler** 위에서 E2E로 검증하는 수동 절차다. 샌드박스 환경에서는 실행 불가 — 실제 Windows 워크스테이션에서 사용자가 직접 수행한다. ## 목적 다음 PoC의 DoD 중 "라이브 SUT 필수" 항목을 확인한다: - recorder #1: console attach + Win32 hook capture - recorder #7: 60 FPS 성능 - player #2: `wait_for` UIA 이벤트 동작 - player #7: 동일 시나리오 10회 중 9회 성공 - test-runner: 실 시나리오 → normalize → diff 파이프라인 - engine-bridge v2: HttpListener 플러그인 로드 + `/health` 응답 ## 사전 준비 ### 1. 환경 - Windows 10/11 대화형 세션 (세션 0 불가) - .NET SDK 8 또는 9 (`dotnet --info` 확인) - `EG-BIM Modeler/` 폴더가 repo root 하위에 존재 (git 제외 대상) - 고정 DPI 권장 (100% 또는 150% 일관) - 관리자 권한은 `HttpListener` urlacl 이슈 시에만 필요 ### 2. 빌드 ```powershell cd d:\MYCLAUDE_PROJECT\recordingtest dotnet build recordingtest.sln dotnet test ``` **기대**: 전체 green, 42+ 테스트 통과. ### 3. 시나리오/베이스라인 디렉터리 준비 ```powershell mkdir scenarios baselines artifacts ``` --- ## Step 1 — recorder 수동 캡처 ### 1a. SUT 실행 `EG-BIM Modeler\EG-BIM Modeler.exe` 를 더블클릭하거나: ```powershell & ".\EG-BIM Modeler\EG-BIM Modeler.exe" ``` 메인 창이 뜰 때까지 대기. ### 1b. recorder attach 새 터미널에서: ```powershell dotnet run --project src\Recordingtest.Recorder -- ` --output scenarios\box-create.yaml ` --attach "EG-BIM Modeler" ``` 콘솔에 "attached" 메시지 확인. ### 1c. 수동 테스트 동작 메인 창에서 다음 수행: 1. `Box` 명령 실행 (리본/툴바/커맨드 라인) 2. 첫 번째 코너 클릭 3. 두 번째 코너 클릭 4. 높이 입력 후 Enter 5. 파일 → 저장 → `artifacts\manual-box.hme` ### 1d. recorder 종료 터미널에서 `Ctrl+C`. 요약 출력 확인: - 캡처된 이벤트 수 - 미해결 uia_path 수 - 소요 시간 ### 1e. 산출물 확인 ```powershell Get-Content scenarios\box-create.yaml ``` - 클릭·드래그·키 이벤트가 기록됐는지 - `uia_path` 가 유의미한 값인지 (3D 뷰포트 클릭은 호스팅 WPF 컨트롤 경로) - `offset_norm` 이 `[0..1]` 범위 - `PasswordBox` 있으면 `` 처리 **Smoke 체크리스트**: - [ ] recorder가 attach 성공 - [ ] Ctrl+C 후 yaml 파일 생성 - [ ] 이벤트 수 ≥ 5 - [ ] SUT 정상 종료 --- ## Step 2 — player 재생 ### 2a. baseline 저장 첫 성공 수행 시 저장된 `manual-box.hme` 를 베이스라인으로 승격: ```powershell Copy-Item artifacts\manual-box.hme baselines\box-create.approved.hme ``` ### 2b. SUT 재시작 (깨끗한 상태) EG-BIM Modeler 를 완전히 종료 후 다시 실행. ### 2c. player 실행 ```powershell dotnet run --project src\Recordingtest.Player -- ` --scenario scenarios\box-create.yaml ` --output-dir artifacts\replay ` --no-launch ``` **Smoke 체크리스트**: - [ ] player가 SUT에 attach - [ ] Box 명령이 실제로 실행되는 것이 화면에 보임 - [ ] exit code 0 - [ ] `artifacts\replay\` 에 결과 파일 존재 - [ ] 고정 sleep 없이 동작 (UIA 대기 기반) ### 2d. 10회 reliability (player DoD #7) ```powershell for ($i=1; $i -le 10; $i++) { dotnet run --project src\Recordingtest.Player -- ` --scenario scenarios\box-create.yaml ` --output-dir "artifacts\replay-$i" ` --no-launch if ($LASTEXITCODE -ne 0) { "Run $i FAILED" } } ``` **기대**: 9회 이상 exit 0. 실패 케이스는 `artifacts\replay-N\error.log` 확인. --- ## Step 3 — test-runner E2E 파이프라인 ### 3a. 여러 시나리오 등록 Step 1을 반복해 최소 2~3개 yaml 생성 (예: `box-create.yaml`, `circle-draw.yaml`). ### 3b. 러너 실행 ```powershell dotnet run --project src\Recordingtest.Runner -- ` --scenarios scenarios ` --baselines baselines ` --out artifacts\regression-run ` --profile default ``` ### 3c. 리포트 확인 ```powershell Get-Content artifacts\regression-run\report.md Get-Content artifacts\regression-run\report.json | ConvertFrom-Json ``` **Smoke 체크리스트**: - [ ] 모든 시나리오 `pass` - [ ] `report.json` 스키마 정상 (`runAt`, `total`, `passed`, `failed`, `errored`, `scenarios[]`) - [ ] `report.md` 표 렌더링 정상 - [ ] 고의로 baseline 1바이트 바꿔 재실행 → `fail` + hunk 리포트 확인 --- ## Step 4 — engine-bridge v2 플러그인 배포 ### 4a. 플러그인 빌드 ```powershell dotnet publish src\Recordingtest.EgPlugin -c Release -o publish\EgPlugin ``` ### 4b. SUT Plugins 폴더에 복사 (사용자 수동) ⚠ `EG-BIM Modeler/` 는 `guard-sut-folder.sh` hook이 Claude의 자동 쓰기를 차단한다. **사용자가 직접** PowerShell로 복사: ```powershell $dest = ".\EG-BIM Modeler\Plugins\Recordingtest.EgPlugin" mkdir $dest -Force Copy-Item publish\EgPlugin\Recordingtest.EgPlugin.dll $dest ``` `Editor03.PluginInterface.dll` 과 `HmEG.dll` 은 복사하지 않는다 (SUT 정본 사용). ### 4c. 환경변수 (선택) ```powershell $env:RECORDINGTEST_BRIDGE_PORT = "38080" ``` ### 4d. SUT 실행 `EG-BIM Modeler.exe` 시작. 플러그인 로더가 `Recordingtest.EgPlugin.dll` 을 자동 발견. ### 4e. `/health` 확인 ```powershell curl http://localhost:38080/health ``` **기대**: `{"status":"ok","port":38080}` ### 4f. 상태 엔드포인트 ```powershell curl http://localhost:38080/selection curl http://localhost:38080/camera curl http://localhost:38080/scene curl http://localhost:38080/render ``` v2는 ReflectionEngineStateProvider가 skeleton이라 기본값 또는 `{"error": ...}` 반환 가능. 이후 **v3에서 실매핑** 예정. ### 4g. 언인스톨 ```powershell Remove-Item .\EG-BIM Modeler\Plugins\Recordingtest.EgPlugin -Recurse ``` **Smoke 체크리스트**: - [ ] 플러그인 dll이 SUT에 로드 (로그 확인: `EG-BIM Modeler\hmlogs\` 또는 `Log\`) - [ ] `/health` 200 OK - [ ] 포트 충돌 없음 - [ ] SUT 정상 종료 시 listener 해제 --- ## 실패 시 트러블슈팅 | 증상 | 원인 후보 | 조치 | |------|-----------|------| | recorder attach 실패 | 창 제목 mismatch | `--attach` 값을 정확한 제목 또는 PID로 | | player uia_path 탐색 실패 | 해상도/DPI 변경 | baseline 당시와 동일 DPI 고정 | | 10회 중 실패 다수 | plugin 로드 지연 | scenario 첫 step에 `wait_for` 추가 | | report 바이너리 diff 많음 | normalizer 규칙 미흡 | `docs/contracts/normalizer.md` follow-up 반영 | | 플러그인 미로드 | dll 경로/버전 mismatch | `hmlogs`에서 로더 메시지 확인 | | `/health` 연결 거부 | HttpListener urlacl | 관리자 권한 실행 or `netsh http add urlacl` | ## 결과 보고 Smoke test 완료 후: 1. 각 체크리스트 결과 수집 2. 실패 항목은 `docs/history/YYYY-MM-DD_smoke-test.md` 에 기록 (소요 시간, Context 사용량 포함) 3. 10회 재생 reliability 수치 → player DoD #7 update 4. 이슈 #2 또는 새 이슈에 리포트 코멘트 ## 한글 yaml 확인 팁 (issue #12 Gap D) `ScenarioWriter`는 UTF-8 (BOM 없음)으로 저장한다. PowerShell `Get-Content`는 시스템 코드페이지로 디코딩해서 한글이 깨져 보일 수 있다. 파일 자체의 정합성을 확인하려면 다음 중 하나를 사용한다: ```powershell # 권장: 명시적 UTF-8 디코딩 Get-Content -Encoding UTF8 scenarios/box-v4.yaml # 또는 출력 시 BOM 없이 다시 저장해 비교 Get-Content -Encoding UTF8 scenarios/box-v4.yaml | Out-File -Encoding UTF8 tmp.yaml ``` `UiaPathResolverTests.UiaPathParser_ParsesNameAttribute` 와 `ScenarioWriter_RoundTrip_PreservesKorean` 가 한글 path/속성 round-trip을 회귀로 잡는다. ## v3 이후 과제 - recorder IME 조합 키 처리 - player full ancestor chain uia_path resolver - engine-bridge ReflectionEngineStateProvider 실매핑 (HmEG 내부 타입 접근) - normalizer `mask_volatile_settings` JSON-path 스코핑