Files
recordingtest/tests/Recordingtest.Recorder.Tests/WindowPointResolverTests.cs
minsung b139f2b169 Fix smoke 2차 gaps: hotkey tests, focus filter, viewport picking (#13)
Gap E — Hotkey named key
- UiaPlayerHost: extract ParsedHotkey record + ParseHotkey static
- HotkeyParseTests: 8 tests (enter/tab/a/ctrl+c/ctrl+shift+s/f5/alt+f4/empty)

Gap F — recorder focus_change SUT filter
- FocusEventFilter.ShouldAccept static rule (same/zero/unknown/unknown-sut)
- Program.cs wires it inside RegisterFocusChangedEvent callback
- FocusEventFilterTests: 4 tests

Gap G — viewport picking foreign-process fallback
- IWindowPointSource + WindowPointResolver pure resolver
- FlaUiPointSource wired in Program.cs (best-effort hit test, honest partial for live SUT)
- WindowPointResolverTests: 5 tests

Tests: 77 → 94, build 0/0 (TreatWarningsAsErrors preserved).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 18:21:36 +09:00

77 lines
2.8 KiB
C#

using Xunit;
namespace Recordingtest.Recorder.Tests;
public class WindowPointResolverTests
{
private sealed class FakeSnapshot : IElementSnapshot
{
public string Tag { get; init; } = "";
public string ClassName => Tag;
public string? AutomationId => null;
public string? Name => Tag;
public bool IsPassword => false;
public (double Left, double Top, double Width, double Height) BoundingRectangle => (0, 0, 0, 0);
public IElementSnapshot? Parent => null;
}
private sealed class FakeSource : IWindowPointSource
{
public int? Pid { get; set; }
public IElementSnapshot? Primary { get; set; }
public IElementSnapshot? SutScope { get; set; }
public int? GetProcessIdAt(int x, int y) => Pid;
public IElementSnapshot? GetElementAt(int x, int y) => Primary;
public IElementSnapshot? GetElementFromSutScope(int x, int y) => SutScope;
}
[Fact]
public void Resolve_SamePid_ReturnsPrimary()
{
var primary = new FakeSnapshot { Tag = "primary" };
var sut = new FakeSnapshot { Tag = "sut" };
var src = new FakeSource { Pid = 100, Primary = primary, SutScope = sut };
var r = WindowPointResolver.Resolve(src, 10, 20, sutPid: 100);
Assert.Same(primary, r);
}
[Fact]
public void Resolve_DifferentPid_FallsBackToSutScope()
{
var primary = new FakeSnapshot { Tag = "primary" };
var sut = new FakeSnapshot { Tag = "sut" };
var src = new FakeSource { Pid = 999, Primary = primary, SutScope = sut };
var r = WindowPointResolver.Resolve(src, 10, 20, sutPid: 100);
Assert.Same(sut, r);
}
[Fact]
public void Resolve_UnknownPid_ReturnsPrimary()
{
var primary = new FakeSnapshot { Tag = "primary" };
var src = new FakeSource { Pid = null, Primary = primary, SutScope = null };
var r = WindowPointResolver.Resolve(src, 10, 20, sutPid: 100);
Assert.Same(primary, r);
}
[Fact]
public void Resolve_ZeroPid_ReturnsPrimary()
{
var primary = new FakeSnapshot { Tag = "primary" };
var src = new FakeSource { Pid = 0, Primary = primary, SutScope = null };
var r = WindowPointResolver.Resolve(src, 10, 20, sutPid: 100);
Assert.Same(primary, r);
}
[Fact]
public void Resolve_DifferentPid_FallbackNull_ReturnsPrimary()
{
// Documented semantic: if SUT-scope fallback can't find anything,
// keep the primary as a last resort rather than dropping the event.
var primary = new FakeSnapshot { Tag = "primary" };
var src = new FakeSource { Pid = 999, Primary = primary, SutScope = null };
var r = WindowPointResolver.Resolve(src, 10, 20, sutPid: 100);
Assert.Same(primary, r);
}
}