Goal
Why this matters
Prerequisites
PlatformFactAttribute and PlatformTheoryAttribute skip tests on unsupported OSes (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/PlatformFactAttribute.cs:7). Use them to branch behavior cleanly:
[PlatformFact(TestPlatforms.MacOS)]
public void ThickTitleBar_Drag_Reports_Moves() { ... }
Group tests into collections bound to fixtures that configure capabilities. For example, DefaultAppFixture launches the stock ControlCatalog, while OverlayPopupsAppFixture adds --overlayPopups arguments to highlight overlay behavior (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/OverlayPopupsAppFixture.cs:4).
WindowTests (see external/Avalonia/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs) verifies state transitions (Normal, Maximized, FullScreen), docked windows, and mode toggles. It uses SendClick on combo entries because native Click() is unreliable on certain automation peers (ElementExtensions.SendClick, external/Avalonia/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs:235).
WindowTests_MacOS covers thick title bars, system chrome toggles, and fullscreen animations (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs:19). Tests depend on applying window decoration parameters via checkboxes exposed in the demo app.
Tips
PointerTests_MacOS.Dispose resets window parameters before exiting (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/PointerTests_MacOS.cs:119).WebDriverWait polling before grabbing the next snapshot.Use ElementExtensions.OpenWindowWithClick to encapsulate the logic of detecting new windows. It differentiates between top-level handles (Windows) and child windows (macOS) and returns an IDisposable that closes the window on teardown (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs:86).
using (Control("OpenModal").OpenWindowWithClick())
{
// Assert modal state
}
PointerTests.Pointer_Capture_Is_Released_When_Showing_Dialog relies on this helper to ensure capture is cleared when a dialog opens (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/PointerTests.cs:13).
System integration differs dramatically:
TrayIconTests locates the shell tray window, handles overflow flyouts, and accounts for whitespace-prefixed icon names (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/TrayIconTests.cs:62). It also opens a secondary “Root” session that targets the desktop to access the taskbar.XCUIElementTypeStatusItem elements and menus are retrieved via //XCUIElementTypeStatusItem/XCUIElementTypeMenu.Wrap this logic in helper methods and hide it behind PageObjects so tests merely call TrayIcon().ShowMenu() and assert resulting automation flags.
GestureTests demonstrates how to script taps, double-taps, drags, and right-clicks using Actions API (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/GestureTests.cs:16). Examples:
new Actions(Session).DoubleClick(element).Perform();PointerInputDevice for macOS-specific right-tap semantics (GestureTests.RightTapped_Is_Raised_2, line 139).PointerTests_MacOS.OSXThickTitleBar_Pointer_Events_Continue_Outside_Window_During_Drag verifies pointer capture beyond window bounds while dragging the title bar (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/PointerTests_MacOS.cs:17). It uses DragAndDropToOffset and reads automation counters from the secondary window.
Practice
new Actions(Session).MoveToElement(titleAreaControl).Perform();GestureTests.DoubleTapped_Is_Raised_2, line 70).ListBoxTests executes Shift-range selection and marks Ctrl-click tests as skipped due to driver limitations (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/ListBoxTests.cs:36). Document such constraints in your suite and apply [Fact(Skip=...)] with explanations for future debugging.
ComboBoxTests rely on keyboard shortcuts (Keys.LeftAlt + Keys.ArrowDown) and ensure wrapping behavior toggles via checkboxes before assertion (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs:41). Keep these interactions in PageObjects so tests remain expressive (ComboBoxPage.OpenDropdown() vs. inline key sequences).
ScreenTests pulls current monitor data and asserts invariants around bounds, work area, and scaling (external/Avalonia/tests/Avalonia.IntegrationTests.Appium/ScreenTests.cs:12). Use similar verifications when you need to assert window placement on multi-monitor setups.
For drag-to-monitor flows, record starting and ending positions via text fields surfaced in the app, then compare after applying pointer moves. Ensure tests reset state (move window back) when done to avoid cascading failures.
PointerInputDevice sequences end with PointerUp. If a test fails mid-action, add try/finally to release buttons.PointerTests_MacOS.OSXThickTitleBar_Single_Click_Does_Not_Generate_DoubleTapped_Event, add counters to your app to observe actual events and assert on them instead of stateful UI side effects.ShowMenu() and ClickMenuItem(string text) methods that handle Windows overflow and macOS status items automatically. Use it to verify a menu command toggles a checkbox in the main window.PointerSequence builder). Use it to test tap, double-tap, drag, and right-tap on the same control, asserting the logged gesture text each time.[PlatformTheory]. Capture driver logs on failure and assert the test records which platform executed for easier triage.What's next