player: raw scenario replay without manual cleanup (#14)

First time box-v6.yaml (raw recorder output, 676 lines) replays end-to-end
and actually creates a Box in the SUT — no AI post-editing of target paths
or offsets required. This is the counterpart to #13's recorder-side fixes:
the player now absorbs the remaining record→replay gaps instead of demanding
a hand-cleaned scenario.

Changes (all in Recordingtest.Player):

- PlayerEngine: null-target fallbacks
  - Type with null target → host.Type() against current focus
  - Click with null target + raw_coord → click at screen-absolute raw_coord
  - Other null targets still skipped
- PlayerEngine: strip leading alt+tab hotkey steps (recording-startup noise
  that fights the player's own foreground switch)
- PlayerEngine: preserve recorded inter-step timing, clamped 150ms–3s,
  routed through new IPlayerHost.Delay so the engine itself stays Sleep-free
  (keeps the existing "no fixed sleep" DoD test passing)
- PlayerEngine: per-step console log for live debugging
- UiaPlayerHost: BringSutToForeground() — SetForeground + Focus + 600ms
  settle, called from Program.cs before engine.Run
- Step model: add RawCoord (int[]) and Ts (long?) fields, auto-mapped from
  YAML raw_coord / ts keys

Tests updated:
- PlayerEngine_NullTarget_SkipsWithoutCalling → _Fallback_Issue14
  (verifies the new Click-with-raw_coord and Type behavior)
- FakePlayerHost (both player.tests and runner.tests) implement Delay

Live smoke: box-v6.yaml raw replay produced the expected Box geometry on
the 2nd attempt; 1st attempt dropped the initial "BOX" keystrokes, tracked
as a follow-up (foreground settle is still threshold-sensitive at 600ms).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-08 19:26:41 +09:00
parent 4ba5b3d74b
commit 70bf5703b3
12 changed files with 237 additions and 18 deletions

View File

@@ -10,8 +10,9 @@
## P1 — 라이브 검증 (사용자 환경 필요)
4. **라이브 SUT smoke test 실행**`docs/guides/smoke-test.md` 따라 수동 수행
5. **engine-bridge v3** — ReflectionEngineStateProvider 실매핑 (smoke test 이후)
4. **이슈 #14 재생 안정화** — 첫 시도 BOX 타이핑 누락 문제. foreground settle 600ms→능동 대기 전환 또는 첫 type 이전 `Keyboard.Type` warm-up. `/contract player-foreground-stabilize`.
5. **recorder Gap I-1** — type 스텝 target을 `Automation.FocusedElement`로 직접 채워 null_target_steps=0 달성. `/contract recorder-focused-element-target`.
6. **engine-bridge v3** — ReflectionEngineStateProvider 실매핑 (smoke test 이후)
## Follow-ups (non-blocking)