using CloakBrowser.Human; using CloakBrowser.Wrappers; using Microsoft.Playwright; using Xunit; namespace CloakBrowser.Tests.Wrappers; /// /// Tests for the transparent decorator: nested objects /// (Mouse/Keyboard/Locator/Frame) are returned wrapped, selector actions run through /// the humanize engine, non-interaction members delegate, and the escape hatch works. /// public class PageWrapperTests { private static HumanConfig FastConfig() => new() { IdleBetweenActions = false, MouseMinSteps = 2, MouseMaxSteps = 3, MouseBurstPause = (0, 0), MouseOvershootChance = 0, ClickAimDelayButton = (0, 0), ClickHoldButton = (0, 0), ClickAimDelayInput = (0, 0), ClickHoldInput = (0, 0), TypingDelay = 0, TypingDelaySpread = 0, TypingPauseChance = 0, MistypeChance = 0, ShiftDownDelay = (0, 0), ShiftUpDelay = (0, 0), KeyHold = (0, 0), InitialCursorX = (100, 100), InitialCursorY = (100, 100), }; /// Build a fake page whose Locator(...) returns an actionable fake locator. private static (HumanizedPage human, FakeProxy pageRec, FakeProxy mouseRec) BuildHumanizedPage() { var (mouse, mouseRec) = Fake.Of(); var (keyboard, _) = Fake.Of(); var (page, pageRec) = Fake.Of(); var (locator, locRec) = Fake.Of(); locRec.On("First", locator); locRec.On("BoundingBoxAsync", Task.FromResult( new LocatorBoundingBoxResult { X = 100, Y = 200, Width = 80, Height = 30 })); locRec.On("IsVisibleAsync", Task.FromResult(true)); locRec.On("IsEnabledAsync", Task.FromResult(true)); locRec.On("IsEditableAsync", Task.FromResult(true)); locRec.On("WaitForAsync", Task.CompletedTask); locRec.On("EvaluateAsync", Task.FromResult( System.Text.Json.JsonSerializer.SerializeToElement(new { hit = true }))); pageRec.On("Mouse", mouse); pageRec.On("Keyboard", keyboard); pageRec.On("ViewportSize", new PageViewportSizeResult { Width = 1280, Height = 720 }); pageRec.On("Locator", locator); pageRec.On("EvaluateAsync", Task.FromResult( System.Text.Json.JsonSerializer.SerializeToElement(false))); var cursor = new HumanCursor(page); var human = new HumanizedPage(page, cursor, FastConfig()); return (human, pageRec, mouseRec); } // ----------------------------------------------------------------------- // Nested objects are wrapped // ----------------------------------------------------------------------- [Fact] public void Mouse_and_Keyboard_are_humanized_wrappers() { var (human, _, _) = BuildHumanizedPage(); Assert.IsType(human.Mouse); Assert.IsType(human.Keyboard); } [Fact] public void Locator_and_GetBy_return_humanized_locators() { var (human, _, _) = BuildHumanizedPage(); Assert.IsType(human.Locator("#a")); Assert.IsType(human.GetByTestId("t")); Assert.IsType(human.GetByText("x")); Assert.IsType(human.GetByRole(AriaRole.Button)); } [Fact] public void MainFrame_and_Frames_return_humanized_frames() { var (mouse, _) = Fake.Of(); var (keyboard, _) = Fake.Of(); var (frame, _) = Fake.Of