using XFESystem.Core; using XFESystem.Desktop; using Xunit; namespace XFESystem.Core.Tests; public sealed class DesktopTests { private sealed class Canvas(int width = 1280, int height = 800, bool cached = false) : IDesktopIconCanvas { public int Width => width; public int Height => height; public bool SupportsSceneCache => cached; public int Frames { get; private set; } public int SavedScenes { get; private set; } public List RestoredRegions { get; } = []; public List PresentedRegions { get; } = []; public List SceneRegions { get; } = []; public List SavedRegions { get; } = []; public List Icons { get; } = []; public List<(uint Color, int X, int Y, int Width, int Height)> Fills { get; } = []; public List TextRuns { get; } = []; public List<(string Text, int X, int Y)> DrawnTexts { get; } = []; public int TextWidth(string text) => text.Sum(c => c < 128 ? 8 : 16); public void Fill(uint rgb, int x, int y, int width, int height) => Fills.Add((rgb, x, y, width, height)); public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) { TextRuns.Add(text); DrawnTexts.Add((text, x, y)); } public void Present() => Frames++; public void DrawIcon(DesktopIcon icon, int x, int y, int size) => Icons.Add(icon); public void SaveScene() => SavedScenes++; public void SaveScene(DesktopBounds damage) { SavedRegions.Add(damage); SavedScenes++; } public void BeginScene(DesktopBounds damage) => SceneRegions.Add(damage); public void RestoreSceneRegion(DesktopBounds bounds) => RestoredRegions.Add(bounds); public void Present(DesktopBounds damage) { PresentedRegions.Add(damage); Frames++; } } private sealed class Browser : IBrowserService { public BrowserPage Navigate(string address) => new(address, "Test", ""); public string ExecuteJavaScript(string source) => ""; public string PreviewMarkdown(string markdown) => markdown; } [Fact] public void StartupIsDesktopAndIdleDoesNotRenderRepeatedly() { var canvas = new Canvas(); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); Assert.Empty(desktop.Windows); desktop.Render(); desktop.Render(); Assert.Equal(1, canvas.Frames); Assert.Contains("XFESystem", canvas.TextRuns); } [Fact] public void MouseOpensFilesAndFileEntryOpensActualEditor() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); desktop.Pointer(50, 108, true); desktop.Pointer(50, 108, false); Assert.Equal(DesktopApplication.Files, desktop.ActiveWindow!.Application); var b = desktop.ActiveWindow.Bounds; desktop.Pointer(b.X + 90, b.Y + 106, true); desktop.Pointer(b.X + 90, b.Y + 106, false); Assert.Equal(DesktopApplication.Editor, desktop.ActiveWindow!.Application); Assert.EndsWith("Hello.cs", desktop.ActiveWindow.Location); Assert.Contains("Console.ForegroundColor", desktop.ActiveWindow.Content); } [Fact] public void EditingMiddleAndSavingAffectsOnlyGuestMemory() { var storage = new MemoryWorkspace(false); var path = SystemPaths.Combine(SystemPaths.Documents, "Test.txt"); storage.WriteText(path, "ab\ncd"); var desktop = new DesktopSession(new Canvas(), storage); var window = desktop.Open(DesktopApplication.Editor, path); desktop.Key(DesktopKey.Right); desktop.Key(DesktopKey.Character, 'X'); Assert.Equal("aXb\ncd", window.Content); desktop.Key(DesktopKey.Down); desktop.Key(DesktopKey.Home); desktop.Key(DesktopKey.Delete); desktop.Key(DesktopKey.Save); Assert.Equal("aXb\nd", storage.ReadText(path)); Assert.False(window.IsDirty); Assert.Contains("RAM live", window.Status); } [Fact] public void UnsavedCloseIsPreventedUntilExplicitDiscard() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Editor); desktop.Key(DesktopKey.Character, 'x'); desktop.Close(window.Id); Assert.Single(desktop.Windows); Assert.Contains("Unsaved", window.Status); desktop.Key(DesktopKey.Escape); Assert.Empty(desktop.Windows); } [Fact] public void DraggingKeepsWindowWithinScreenAndScrollIsBounded() { var storage = new MemoryWorkspace(); var path = SystemPaths.Combine(SystemPaths.Documents, "Long.txt"); storage.WriteText(path, string.Join('\n', Enumerable.Range(0, 100))); var desktop = new DesktopSession(new Canvas(), storage); var window = desktop.Open(DesktopApplication.Editor, path); var b = window.Bounds; desktop.Pointer(b.X + 20, b.Y + 15, true); desktop.Pointer(1279, 799, true); desktop.Pointer(1279, 799, false); Assert.InRange(window.Bounds.X, 0, 1280 - b.Width); Assert.InRange(window.Bounds.Y, 0, 800 - b.Height - 48); desktop.Pointer(0, 0, false, -1000); Assert.InRange(window.ScrollLine, 1, 100); desktop.Pointer(0, 0, false, 1000); Assert.Equal(0, window.ScrollLine); } [Fact] public void UnconnectedBrowserDoesNotClaimNavigationWorks() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var browser = desktop.Open(DesktopApplication.Browser); Assert.Contains("unavailable", browser.Status); Assert.Contains("does not claim", browser.Content); } [Fact] public void ManagedFileUsesOnlyExplicitGuestApplicationCallback() { string? invoked = null; var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(), managedApplication: path => invoked = path); desktop.OpenFile("X:\\Programs\\Hello.dll"); Assert.Equal("X:\\Programs\\Hello.dll", invoked); Assert.Empty(desktop.Windows); } [Fact] public void WindowLimitDoesNotEscapePointerOrPreviewEvent() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(), new Browser()); for (int i = 0; i < 12; i++) desktop.Open(DesktopApplication.Editor); desktop.Pointer(50, 108, true); Assert.Equal(12, desktop.Windows.Count); desktop.Key(DesktopKey.Run); Assert.Equal(12, desktop.Windows.Count); Assert.Contains("Close a window", desktop.ActiveWindow!.Status); } [Fact] public void FilesStatusBarCannotOpenAnInvisibleEntry() { var storage = new MemoryWorkspace(false); for (int i = 0; i < 16; i++) storage.WriteText(SystemPaths.Combine(SystemPaths.Documents, $"File{i:D2}.txt"), ""); var desktop = new DesktopSession(new Canvas(), storage); var files = desktop.Open(DesktopApplication.Files); desktop.Pointer(files.Bounds.X + 50, files.Bounds.Y + files.Bounds.Height - 20, true); Assert.Same(files, desktop.ActiveWindow); Assert.Single(desktop.Windows); } [Fact] public void BrowserAddressFocusReplacesExistingAddress() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(), new Browser()); var window = desktop.Open(DesktopApplication.Browser); foreach (char c in "http://example.test/") desktop.Key(DesktopKey.Character, c); Assert.Equal("http://example.test/", window.Location); desktop.Key(DesktopKey.Enter); desktop.Key(DesktopKey.FocusAddress); foreach (char c in "about:Start") desktop.Key(DesktopKey.Character, c); Assert.Equal("about:Start", window.Location); } [Fact] public void RunningAnotherProgramShowsItsOutputInExistingTerminal() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var terminal = desktop.Open(DesktopApplication.Terminal); var shell = Assert.IsType(terminal.Shell); Assert.True(desktop.PasteTerminalInput("echo Previous shell output")); desktop.Key(DesktopKey.Enter); Assert.True(desktop.PasteTerminalInput("draft command")); desktop.Key(DesktopKey.Left); int caret = shell.Caret; string directory = shell.CurrentDirectory; desktop.Open(DesktopApplication.Files); var output = new XFESystem.Console.TerminalBuffer(40, 10); output.Write("\u001b[1;38;2;23;45;67;48;2;7;8;9mProgram output\u001b[0m"); var snapshot = output.Snapshot(); desktop.SetTerminalSnapshot(snapshot); Assert.Same(terminal, desktop.ActiveWindow); Assert.Equal(2, desktop.Windows.Count); Assert.Same(terminal, Assert.Single(desktop.Windows, window => window.Application == DesktopApplication.Terminal)); Assert.Same(shell, terminal.Shell); Assert.Equal(directory, shell.CurrentDirectory); Assert.Equal("draft command", shell.Input); Assert.Equal(caret, shell.Caret); Assert.Equal(new[] { "echo Previous shell output" }, shell.History); var combined = Assert.IsType(terminal.Terminal); string transcript = string.Concat(combined.Cells.Select(cell => cell.Text)); Assert.Contains("XFESystem|XFEstudio", transcript); Assert.Contains(desktop.TerminalVersion, transcript); Assert.Contains("Type help for commands.", transcript); Assert.Contains("Previous shell output", transcript); Assert.Contains("Program output", transcript); int programRow = Assert.Single(Enumerable.Range(0, combined.Rows), row => string.Concat(Enumerable.Range(0, combined.Columns).Select(column => combined.GetCell(column, row).Text)) .StartsWith("Program output", StringComparison.Ordinal)); for (int index = 0; index < "Program output".Length; index++) Assert.Equal(snapshot.GetCell(index, 0).Style, combined.GetCell(index, programRow).Style); desktop.Key(DesktopKey.Up); Assert.Equal("echo Previous shell output", shell.Input); desktop.Key(DesktopKey.Down); Assert.Equal("draft command", shell.Input); } [Fact] public void ChineseTextUsesActualGlyphWidthForClippingAndCaretPlacement() { var canvas = new Canvas(); var storage = new MemoryWorkspace(); var path = SystemPaths.Combine(SystemPaths.Documents, "Wide.txt"); storage.WriteText(path, new string('δΈ­', 100)); var desktop = new DesktopSession(canvas, storage); var window = desktop.Open(DesktopApplication.Editor, path); desktop.Pointer(window.Bounds.X + 20 + 32, window.Bounds.Y + 76, true); desktop.Pointer(window.Bounds.X + 20 + 32, window.Bounds.Y + 76, false); Assert.Equal(2, window.Caret); desktop.Render(); var body = Assert.Single(canvas.DrawnTexts, t => t.Y == window.Bounds.Y + 76); Assert.True(canvas.TextWidth(body.Text) <= window.Bounds.Width - 48); Assert.EndsWith("...", body.Text); desktop.Key(DesktopKey.End); desktop.Render(); Assert.Equal(100, window.Caret); } private static void Click(DesktopSession desktop, int x, int y, long timestamp = -1) { desktop.Pointer(x, y, true, timestampMs: timestamp); desktop.Pointer(x, y, false, timestampMs: timestamp); } [Fact] public void TitleDoubleClickMaximizesToWorkAreaAndRestoresExactBounds() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; Click(desktop, original.X + 100, original.Y + 16, 100); Click(desktop, original.X + 100, original.Y + 16, 220); Assert.True(window.IsMaximized); Assert.Equal(desktop.WorkArea, window.Bounds); Click(desktop, 100, desktop.WorkArea.Y + 16, 500); Click(desktop, 100, desktop.WorkArea.Y + 16, 640); Assert.False(window.IsMaximized); Assert.Equal(original, window.Bounds); } [Fact] public void SlowOrDistantTitleClicksDoNotMaximize() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var b = window.Bounds; Click(desktop, b.X + 80, b.Y + 16, 100); Click(desktop, b.X + 80, b.Y + 16, 800); Click(desktop, b.X + 100, b.Y + 16, 900); Assert.False(window.IsMaximized); } [Fact] public void DraggingMaximizedTitleRestoresWindowUnderPointer() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Editor); var original = window.Bounds; desktop.ToggleMaximize(window.Id); desktop.Pointer(320, 15, true, timestampMs: 1000); desktop.Pointer(350, 38, true, timestampMs: 1050); desktop.Pointer(350, 38, false, timestampMs: 1050); Assert.False(window.IsMaximized); Assert.Equal(original.Width, window.Bounds.Width); Assert.Equal(original.Height, window.Bounds.Height); Assert.Equal(150, window.Bounds.X); Assert.Equal(23, window.Bounds.Y); } [Fact] public void ResizeGripClampsMinimumAndWorkAreaWithoutMovingOrigin() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; desktop.Pointer(original.X + original.Width - 2, original.Y + original.Height - 2, true); desktop.Pointer(1279, 799, true); desktop.Pointer(1279, 799, false); Assert.Equal(original.X, window.Bounds.X); Assert.Equal(original.Y, window.Bounds.Y); Assert.True(window.Bounds.X + window.Bounds.Width <= desktop.WorkArea.Width); Assert.True(window.Bounds.Y + window.Bounds.Height <= desktop.WorkArea.Y + desktop.WorkArea.Height); var b = window.Bounds; desktop.Pointer(b.X + b.Width - 2, b.Y + b.Height - 2, true); desktop.Pointer(0, 0, true); desktop.Pointer(0, 0, false); Assert.Equal(320, window.Bounds.Width); Assert.Equal(200, window.Bounds.Height); Assert.Equal(original.X, window.Bounds.X); Assert.Equal(original.Y, window.Bounds.Y); } [Fact] public void TitleHasOnlyMinimizeAndCloseWhileDoubleClickMaximizes() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var b = window.Bounds; Click(desktop, b.X + b.Width - 80, b.Y + 16); Assert.False(window.IsMinimized); Assert.False(window.IsMaximized); Click(desktop, b.X + b.Width - 48, b.Y + 16); Assert.True(window.IsMinimized); Assert.Null(desktop.ActiveWindow); desktop.Activate(window.Id); b = window.Bounds; Click(desktop, b.X + 150, b.Y + 16, 1000); Click(desktop, b.X + 150, b.Y + 16, 1100); Assert.True(window.IsMaximized); b = window.Bounds; Click(desktop, b.X + b.Width - 16, b.Y + 16); Assert.Empty(desktop.Windows); } [Fact] public void TaskbarButtonsKeepCreationOrderAndRestoreOrMinimizeWindows() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var first = desktop.Open(DesktopApplication.Files); var second = desktop.Open(DesktopApplication.Terminal); Click(desktop, 90, 776); Assert.Same(first, desktop.ActiveWindow); Click(desktop, 90, 776); Assert.True(first.IsMinimized); Assert.Same(second, desktop.ActiveWindow); Click(desktop, 90, 776); Assert.False(first.IsMinimized); Assert.Same(first, desktop.ActiveWindow); } [Fact] public void StartMenuCanOpenApplicationsWithMouseOrKeyboard() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); desktop.Key(DesktopKey.StartMenu); Assert.True(desktop.IsStartMenuOpen); desktop.Key(DesktopKey.Down); desktop.Key(DesktopKey.Enter); Assert.Equal(DesktopApplication.Editor, desktop.ActiveWindow!.Application); Assert.False(desktop.IsStartMenuOpen); Click(desktop, 30, 776); Assert.True(desktop.IsStartMenuOpen); Click(desktop, 80, 644); Assert.Equal(DesktopApplication.Browser, desktop.ActiveWindow!.Application); desktop.Key(DesktopKey.StartMenu); desktop.Key(DesktopKey.Escape); Assert.False(desktop.IsStartMenuOpen); Assert.Equal(2, desktop.Windows.Count); } [Fact] public void AltTabCyclesStableMruAndCommitsOnlyOnRelease() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var first = desktop.Open(DesktopApplication.Files); var second = desktop.Open(DesktopApplication.Editor); var third = desktop.Open(DesktopApplication.Terminal); desktop.Key(DesktopKey.SwitchWindow); Assert.Same(second, desktop.ActiveWindow); desktop.Key(DesktopKey.SwitchWindow); Assert.Same(first, desktop.ActiveWindow); desktop.Key(DesktopKey.SwitchWindow); Assert.Same(third, desktop.ActiveWindow); desktop.Key(DesktopKey.SwitchWindowBack); Assert.Same(first, desktop.ActiveWindow); desktop.Key(DesktopKey.EndWindowSwitch); Assert.False(desktop.IsWindowSwitching); desktop.Key(DesktopKey.SwitchWindow); Assert.Same(third, desktop.ActiveWindow); desktop.Key(DesktopKey.EndWindowSwitch); } [Fact] public void ShowDesktopPreservesPreviouslyMinimizedWindows() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var first = desktop.Open(DesktopApplication.Files); var second = desktop.Open(DesktopApplication.Editor); desktop.Minimize(first.Id); desktop.Key(DesktopKey.ShowDesktop); Assert.Null(desktop.ActiveWindow); desktop.Key(DesktopKey.ShowDesktop); Assert.Same(second, desktop.ActiveWindow); Assert.True(first.IsMinimized); desktop.Key(DesktopKey.OpenFiles); Assert.Equal(DesktopApplication.Files, desktop.ActiveWindow!.Application); } [Fact] public void SnapAndMaximizeRestoreOriginalGeometryAndRespectTaskbar() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; desktop.Key(DesktopKey.SnapRight); Assert.True(window.IsSnapped); Assert.Equal(640, window.Bounds.X); Assert.Equal(640, window.Bounds.Width); Assert.Equal(desktop.WorkArea.Height, window.Bounds.Height); desktop.Key(DesktopKey.Maximize); Assert.Equal(desktop.WorkArea, window.Bounds); desktop.Key(DesktopKey.Restore); Assert.Equal(original, window.Bounds); desktop.Key(DesktopKey.Restore); Assert.True(window.IsMinimized); } [Fact] public void SmallScreenStillContainsWindowsAndTaskbar() { var desktop = new DesktopSession(new Canvas(480, 360), new MemoryWorkspace()); for (int i = 0; i < 6; i++) { var window = desktop.Open(DesktopApplication.Editor); Assert.True(window.Bounds.X >= 0 && window.Bounds.Y >= desktop.WorkArea.Y); Assert.True(window.Bounds.X + window.Bounds.Width <= 480); Assert.True(window.Bounds.Y + window.Bounds.Height <= 312); } desktop.Render(); } [Fact] public void PointerOnlyFrameRestoresCachedRegionsWithoutRedrawingScene() { var canvas = new Canvas(cached: true); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); desktop.Render(); Assert.Equal(1, canvas.SavedScenes); canvas.RestoredRegions.Clear(); int textCount = canvas.TextRuns.Count; desktop.Pointer(600, 500, false); desktop.Render(); Assert.Equal(textCount, canvas.TextRuns.Count); Assert.Equal(1, canvas.SavedScenes); Assert.Equal(2, canvas.RestoredRegions.Count); Assert.Single(canvas.PresentedRegions); desktop.Open(DesktopApplication.Files); desktop.Render(); Assert.Equal(2, canvas.SavedScenes); } [Fact] public void FilesAndApplicationEntrancesRequestTheirSpecificThemeIcons() { var canvas = new Canvas(); var storage = new MemoryWorkspace(); storage.WriteText(SystemPaths.Combine(SystemPaths.Documents, "Readme.md"), ""); storage.WriteText(SystemPaths.Combine(SystemPaths.Documents, "Program.dll"), ""); storage.CreateDirectory(SystemPaths.Combine(SystemPaths.Documents, "Folder")); var desktop = new DesktopSession(canvas, storage); desktop.Open(DesktopApplication.Files); desktop.Render(); Assert.Contains(DesktopIcon.Files, canvas.Icons); Assert.Contains(DesktopIcon.Editor, canvas.Icons); Assert.Contains(DesktopIcon.Browser, canvas.Icons); Assert.Contains(DesktopIcon.Terminal, canvas.Icons); Assert.Contains(DesktopIcon.Folder, canvas.Icons); Assert.Contains(DesktopIcon.CodeFile, canvas.Icons); Assert.Contains(DesktopIcon.MarkdownFile, canvas.Icons); Assert.Contains(DesktopIcon.TextFile, canvas.Icons); Assert.Contains(DesktopIcon.ApplicationFile, canvas.Icons); } [Fact] public void DragResizeScrollAndTypingUseBoundedSceneDamage() { var canvas = new Canvas(cached: true); var storage = new MemoryWorkspace(); var path = SystemPaths.Combine(SystemPaths.Documents, "Long.txt"); storage.WriteText(path, string.Join('\n', Enumerable.Range(0, 100))); var desktop = new DesktopSession(canvas, storage); var window = desktop.Open(DesktopApplication.Editor, path); desktop.Render(); var b = window.Bounds; desktop.Pointer(b.X + 100, b.Y + 15, true); desktop.Render(); desktop.Pointer(b.X + 130, b.Y + 35, true); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width < canvas.Width); Assert.True(canvas.SavedRegions[^1].Height < canvas.Height); desktop.Pointer(b.X + 130, b.Y + 35, false); desktop.Pointer(window.Bounds.X + 60, window.Bounds.Y + 100, false, -1); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width < canvas.Width); desktop.Key(DesktopKey.Character, 'X'); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width < canvas.Width); Assert.Equal(new DesktopBounds(0, 0, canvas.Width, canvas.Height), canvas.SceneRegions[^1]); b = window.Bounds; desktop.Pointer(b.X + b.Width - 2, b.Y + b.Height - 2, true); desktop.Render(); desktop.Pointer(b.X + b.Width + 20, b.Y + b.Height + 20, true); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width < canvas.Width); } [Fact] public void LegacyCanvasPointerUsesOnlyTheNarrowThemeCoreWithoutAnOpaqueHalo() { var canvas = new Canvas(cached: true); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); desktop.Render(); canvas.Fills.Clear(); desktop.Pointer(600, 500, false); desktop.Render(); Assert.NotEmpty(canvas.Fills); Assert.All(canvas.Fills, fill => Assert.Equal(desktop.Theme.AccentStroke, fill.Color)); Assert.True(canvas.Fills.Sum(fill => fill.Width * fill.Height) < 60); Assert.Contains(canvas.Fills, fill => fill.Width == 1); } [Fact] public void ScrollingShortLinesDamagesOnlyInkColumnsAndKeepsUnchangedPointer() { var canvas = new Canvas(cached: true); var storage = new MemoryWorkspace(); var path = SystemPaths.Combine(SystemPaths.Documents, "Narrow.txt"); storage.WriteText(path, string.Join('\n', Enumerable.Range(0, 100).Select(i => $"row{i:D2}"))); var desktop = new DesktopSession(canvas, storage); var window = desktop.Open(DesktopApplication.Editor, path); desktop.Pointer(window.Bounds.X + 180, window.Bounds.Y + 150, false); desktop.Render(); canvas.RestoredRegions.Clear(); desktop.Pointer(window.Bounds.X + 180, window.Bounds.Y + 150, false, -1); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width < 80); Assert.True(canvas.PresentedRegions[^1].Width < 80); Assert.Empty(canvas.RestoredRegions); desktop.Key(DesktopKey.End); desktop.Key(DesktopKey.Character, 'X'); desktop.Render(); Assert.True(canvas.SavedRegions[^1].Width > 80); // Edits still include dirty status/title and full window bounds. } [Fact] public void DesktopAndWindowSwitchCancelExistingMouseCapture() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); desktop.Open(DesktopApplication.Files); var editor = desktop.Open(DesktopApplication.Editor); var b = editor.Bounds; desktop.Pointer(b.X + 100, b.Y + 16, true, timestampMs: 100); desktop.Key(DesktopKey.ShowDesktop); desktop.Pointer(b.X + 150, b.Y + 66, true, timestampMs: 200); Assert.Equal(b, editor.Bounds); Assert.True(editor.IsMinimized); desktop.Pointer(b.X + 150, b.Y + 66, false); desktop.Key(DesktopKey.ShowDesktop); desktop.Pointer(b.X + 100, b.Y + 16, true, timestampMs: 400); desktop.Key(DesktopKey.SwitchWindow); desktop.Pointer(b.X + 170, b.Y + 86, true, timestampMs: 450); Assert.Equal(b, editor.Bounds); desktop.Pointer(b.X + 170, b.Y + 86, false); desktop.Key(DesktopKey.EndWindowSwitch); desktop.Activate(editor.Id); desktop.Pointer(b.X + 100, b.Y + 16, true, timestampMs: 700); desktop.Key(DesktopKey.SnapRight); var snapped = editor.Bounds; desktop.Pointer(b.X + 170, b.Y + 86, true, timestampMs: 750); Assert.Equal(snapped, editor.Bounds); Assert.True(editor.IsSnapped); desktop.Pointer(b.X + 170, b.Y + 86, false); } [Fact] public void TitleButtonsAndTaskbarBreakPreviousDoubleClickSequence() { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); desktop.Key(DesktopKey.SnapLeft); var b = window.Bounds; Click(desktop, b.X + 100, b.Y + 16, 100); Click(desktop, b.X + b.Width - 48, b.Y + 16, 200); Assert.True(window.IsMinimized); Click(desktop, 90, 776, 210); Click(desktop, b.X + 100, b.Y + 16, 220); Assert.False(window.IsMaximized); desktop.ToggleMaximize(window.Id); Assert.True(window.IsMaximized); Click(desktop, 100, desktop.WorkArea.Y + 16, 250); Assert.True(window.IsMaximized); Click(desktop, 90, 776, 280); Assert.True(window.IsMinimized); Click(desktop, 90, 776, 300); Assert.False(window.IsMinimized); Click(desktop, 100, desktop.WorkArea.Y + 16, 320); Assert.True(window.IsMaximized); } }