using XFEExtension.NetCore.InputSimulator;
using XFEExtension.NetCore.XUnit.Assertions;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEWorkflow.Test;
[TestFixture]
public class DesktopInputTests
{
[Test]
public async Task UnicodeAndSurrogatePairsAreReleased()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend);
await controller.TypeTextAsync("中文😀");
Assert.Equal(8, backend.Unicode.Count); Assert.Equal(4, backend.Unicode.Count(x => x.Up)); Assert.Equal("中文😀", new string(backend.Unicode.Where(x => !x.Up).Select(x => x.Value).ToArray()));
}
[Test]
public async Task CancelledCombinationReleasesAllPressedKeys()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend); using var cancel = new CancellationTokenSource(50);
Func<Task> press = () => controller.PressCombinationAsync([ScanCode.LeftControl, ScanCode.A], 10_000, cancel.Token);
await Assert.ThrowsAsync<OperationCanceledException>(press); Assert.Equal(4, backend.Keys.Count); Assert.Equal(2, backend.Keys.Count(x => x.Up));
}
[Test]
public void UnsupportedUnicodeBackendFailsBeforeSendingInput()
{
var backend = new RecordingBackend { SupportsUnicodeText = false }; using var controller = new InputController(backend);
Assert.Throws<NotSupportedException>(() => controller.TypeText("中文")); Assert.Empty(backend.Unicode);
}
[Test]
public async Task DragCancellationReleasesTheHeldMouseButton()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend); using var cancel = new CancellationTokenSource(80);
await Assert.ThrowsAsync<OperationCanceledException>(() => controller.MouseDragAsync(new(10, 10), new(200, 200), 5000, MouseButton.Left, cancel.Token));
Assert.True(backend.MouseButtons.Any(x => !x.Up)); Assert.True(backend.MouseButtons.Last().Up);
}
private sealed class RecordingBackend : IInputBackend
{
public string Name => "recording"; public bool SupportsUnicodeText { get; set; } = true;
public List<(ScanCode Key, bool Up)> Keys { get; } = [];
public List<(char Value, bool Up)> Unicode { get; } = [];
public void SendKey(ScanCode key, bool isKeyUp) => Keys.Add((key, isKeyUp));
public void SendUnicode(char codeUnit, bool isKeyUp) => Unicode.Add((codeUnit, isKeyUp));
public void MoveMouse(int x, int y, bool absolute, bool virtualDesktop) { }
public List<(MouseButton Button, bool Up)> MouseButtons { get; } = [];
public void SendMouseButton(MouseButton button, bool isKeyUp) => MouseButtons.Add((button, isKeyUp));
public void ScrollMouse(int delta, bool horizontal) { }
public void Dispose() { }
}
}
using XFEExtension.NetCore.InputSimulator;
using XFEExtension.NetCore.XUnit.Assertions;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEWorkflow.Test;
[TestFixture]
public class DesktopInputTests
{
[Test]
public async Task UnicodeAndSurrogatePairsAreReleased()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend);
await controller.TypeTextAsync("中文😀");
Assert.Equal(8, backend.Unicode.Count); Assert.Equal(4, backend.Unicode.Count(x => x.Up)); Assert.Equal("中文😀", new string(backend.Unicode.Where(x => !x.Up).Select(x => x.Value).ToArray()));
}
[Test]
public async Task CancelledCombinationReleasesAllPressedKeys()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend); using var cancel = new CancellationTokenSource(50);
Func<Task> press = () => controller.PressCombinationAsync([ScanCode.LeftControl, ScanCode.A], 10_000, cancel.Token);
await Assert.ThrowsAsync<OperationCanceledException>(press); Assert.Equal(4, backend.Keys.Count); Assert.Equal(2, backend.Keys.Count(x => x.Up));
}
[Test]
public void UnsupportedUnicodeBackendFailsBeforeSendingInput()
{
var backend = new RecordingBackend { SupportsUnicodeText = false }; using var controller = new InputController(backend);
Assert.Throws<NotSupportedException>(() => controller.TypeText("中文")); Assert.Empty(backend.Unicode);
}
[Test]
public async Task DragCancellationReleasesTheHeldMouseButton()
{
var backend = new RecordingBackend(); using var controller = new InputController(backend); using var cancel = new CancellationTokenSource(80);
await Assert.ThrowsAsync<OperationCanceledException>(() => controller.MouseDragAsync(new(10, 10), new(200, 200), 5000, MouseButton.Left, cancel.Token));
Assert.True(backend.MouseButtons.Any(x => !x.Up)); Assert.True(backend.MouseButtons.Last().Up);
}
private sealed class RecordingBackend : IInputBackend
{
public string Name => "recording"; public bool SupportsUnicodeText { get; set; } = true;
public List<(ScanCode Key, bool Up)> Keys { get; } = [];
public List<(char Value, bool Up)> Unicode { get; } = [];
public void SendKey(ScanCode key, bool isKeyUp) => Keys.Add((key, isKeyUp));
public void SendUnicode(char codeUnit, bool isKeyUp) => Unicode.Add((codeUnit, isKeyUp));
public void MoveMouse(int x, int y, bool absolute, bool virtualDesktop) { }
public List<(MouseButton Button, bool Up)> MouseButtons { get; } = [];
public void SendMouseButton(MouseButton button, bool isKeyUp) => MouseButtons.Add((button, isKeyUp));
public void ScrollMouse(int delta, bool horizontal) { }
public void Dispose() { }
}
}