fix: strip trailing recorder-stop noise in PlayerEngine (#14)

box-v7 패턴: alt+tab → click(PowerShell) → ctrl+c ctrl+c 가 재생 시
SUT 외부 창(브라우저 등)에 입력을 보내는 버그.

- PlayerEngine.Run: trailing (alt+tab → optional click → ctrl+c+) 감지 시 제거
- leading alt+tab 제거와 대칭적으로 동작
- ctrl+c 단독으로는 제거하지 않음 (SUT 내 복사 액션과 구분)
- 테스트 2건 추가 (138 total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-10 08:59:22 +09:00
parent 612cc8ac51
commit a310ca2ce4
5 changed files with 95 additions and 2 deletions

View File

@@ -221,6 +221,58 @@ steps:
Assert.Equal(StepKind.Focus, s.Steps[1].Kind);
}
// ---- trailing recorder-stop noise stripping --------------------------------
[Fact]
public void TrailingRecorderStop_AltTabClickCtrlC_Stripped()
{
// box-v7 pattern: real work → alt+tab → click → ctrl+c ctrl+c
var host = new FakePlayerHost();
var engine = new PlayerEngine(new PlayerEngineOptions { PreserveTiming = false });
var scenario = new Scenario
{
Steps =
{
new Step { Kind = StepKind.Type, Value = "BOX" }, // real work
new Step { Kind = StepKind.Hotkey, Value = "enter" }, // real work
new Step { Kind = StepKind.Hotkey, Value = "alt+tab" }, // recorder stop →
new Step { Kind = StepKind.Click, RawCoord = [771, 833] }, // click terminal
new Step { Kind = StepKind.Hotkey, Value = "ctrl+c" }, // stop recorder
new Step { Kind = StepKind.Hotkey, Value = "ctrl+c" }, // stop recorder
},
};
engine.Run(scenario, host);
// Only the two real-work steps should have fired — no Clicks, hotkey only "enter"
Assert.Empty(host.Clicks); // click (771,833) stripped
Assert.Single(host.Types); // only "BOX"
Assert.Equal("BOX", host.Types[0]);
Assert.Single(host.Hotkeys); // only "enter", not ctrl+c
Assert.Equal("enter", host.Hotkeys[0]);
}
[Fact]
public void TrailingCtrlCAlone_NotStripped_RequiresAltTab()
{
// ctrl+c without preceding alt+tab is a legitimate SUT action (copy)
var host = new FakePlayerHost();
var engine = new PlayerEngine(new PlayerEngineOptions { PreserveTiming = false });
var scenario = new Scenario
{
Steps =
{
new Step { Kind = StepKind.Type, Value = "BOX" },
new Step { Kind = StepKind.Hotkey, Value = "ctrl+c" },
},
};
engine.Run(scenario, host);
// ctrl+c alone at the end must NOT be stripped (it's a copy action)
Assert.Single(host.Hotkeys);
Assert.Equal("ctrl+c", host.Hotkeys[0]);
}
private static string LocateEngineSource([CallerFilePath] string here = "")
{
// here = .../tests/Recordingtest.Player.Tests/PlayerEngineTests.cs