Pure-reference catalog of desktop GUI test strategies across Windows, macOS, and Linux. Defines the three accessibility-tree backends (Microsoft UI Automation on Windows, Apple Accessibility / XCTest on macOS, AT-SPI on Linux), the wrapper-tools that drive each backend (WinAppDriver, Appium-Windows, XCUIApplication, AT-SPI clients), the cross-toolkit Electron + Qt paths, and a per-OS decision matrix with accessibility-first locator strategy. Deep operational detail (per-OS asynchronous-wait hierarchies, parallel-test policy, foreground-lock / UAC / TCC / AT-SPI elevation hazards, and the high-DPI / per-monitor test matrix) lives in references/. Use as the strategic reference before picking a desktop test stack, ahead of the per-tool implementation skills.
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Deep reference for desktop-test-strategy-reference SKILL.md. Consult
after picking the OS backend, when wiring the actual waits and the
parallel-run policy.
Every reliable desktop test routes UI polls through the driver's
retry primitive, never raw Thread.Sleep / Task.Delay. The three
backends ship distinct mechanisms.
macOS - three-tier XCTest hierarchy (XCUIElement.waitForExistence, Asynchronous Tests and Expectations):
| Mechanism | Use when |
|---|---|
waitForExistence(timeout:) - boolean, fastest | Single existence check |
XCTestExpectation + waitForExpectations(timeout:) | Custom predicate |
XCTWaiter - multi-expectation, returns enum | Composing several conditions |
Predicate-based waits expose no polling-interval setting - prefer
waitForExistence for simple existence checks, escalate only when
the wait is on a custom predicate.
Windows - FlaUI Retry primitives (FlaUI Retry wiki) parameterise any UI
poll with explicit timeout and interval TimeSpan values.
Defaults are not documented - pass them explicitly. Typical
interval: 100 to 200ms (10ms hammers UIA; 1s hides 100ms races).
| Primitive | Use when |
|---|---|
Retry.WhileNull(func, timeout, interval) | Element fetch |
Retry.WhileFalse(func, timeout, interval) | Boolean state |
Retry.WhileException(func, timeout, interval) | Transient throws during element creation |
Linux - AT-SPI manual polling. No built-in retry primitive; the
dogtail / pyatspi community pattern is an explicit time.time()
polling loop with timeout + interval (100 to 250ms balances
responsiveness against at-spi2-registryd D-Bus traffic).
macOS - per Apple - Running tests serially or in parallel,
parallelisation is opt-in. The cited page is under Apple's modern
documentation/testing/ (Swift Testing) namespace; the same opt-in
design applies to XCTest test plans, which are configured in Xcode
(Edit Scheme -> Test -> Options -> Execute in parallel on Simulator).
Tests sharing mutable state must opt out; performance bundles must
disable parallelisation (parallel introduces timing noise). On
macOS the Simulator clones spin per worker - real disk + RAM cost.
Windows - UIA is per-session: one AutomationElement tree per interactive Windows session. Two workers in the same session race for foreground (the Windows foreground-lock hazard). Scaling: one runner per VM, or one RDP / per-user session per worker.
Linux - at-spi2-registryd is bound to one D-Bus session.
Workers writing events into the same session race for focus.
Scaling: one Xvfb + dbus-launch per worker, or one container per
worker with its own session bus.