git:20260725.3237dd1 to git:20260725.89d9e8f

17 added, 192 removed. Audit A to A.

---
name: desktop-test-strategy-reference
- description: "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, a per-OS decision matrix, the per-OS asynchronous-wait hierarchies (XCTest waitForExistence/XCTestExpectation/XCTWaiter, FlaUI Retry primitives, AT-SPI manual polling), per-OS parallel-test policy, foreground-lock and UAC / TCC / AT-SPI elevation hazards, and the Microsoft-blessed high-DPI / per-monitor test matrix. Use when choosing how to test or automate a desktop GUI application (desktop app testing, GUI automation, automate desktop UI) on Windows, macOS, or Linux - the strategic reference before picking a desktop test stack, ahead of the per-tool implementation skills."
+ description: "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 when choosing how to test or automate a desktop GUI application (desktop app testing, GUI automation, automate desktop UI) on Windows, macOS, or Linux - the strategic reference before picking a desktop test stack, ahead of the per-tool implementation skills."
metadata:
keywords: "desktop, ui-automation, xctest, at-spi, electron, qt"
---
# desktop-test-strategy-reference
## Overview
Desktop GUI testing is fragmented along two axes: **operating system**
(Windows / macOS / Linux) and **UI toolkit** (native, Electron, Qt,
GTK, Cocoa, WPF, WinUI, Win32). Unlike the web - where a single
DOM-driving tool (Playwright / Selenium) covers every browser - each
desktop OS exposes its own accessibility tree, and that tree is the
substrate every reliable desktop test driver uses.
Per [Microsoft Learn - UI Automation Win32 overview][msuia]:
[msuia]: https://learn.microsoft.com/windows/win32/winauto/entry-uiauto-win32
> "Microsoft UI Automation is an accessibility framework that
> enables Windows applications to provide and consume programmatic
> information about user interfaces (UIs). … UI Automation also
> allows automated test scripts to interact with the UI."
Per [Apple - *Testing with Xcode*, UI Testing chapter][appleuit]:
[appleuit]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/09-ui_testing.html
> "UI Testing rests upon two core technologies: the XCTest framework
> and Accessibility."
Per the [at-spi2-core project][atspi2core]:
[atspi2core]: https://gitlab.gnome.org/GNOME/at-spi2-core
> "Base DBus XML interfaces for accessibility, the accessibility
> registry daemon, and atspi library."
This skill is a **pure reference** consumed by the per-tool
skills below and by anyone choosing a desktop test stack.
## How to use this reference
1. **Pick OS + toolkit** from the per-OS / per-toolkit decision matrix.
2. **Choose stable locators** for that backend from the locator-strategy table.
- 3. **Apply the matching async-wait primitive** for the OS (XCTest waiters / FlaUI Retry / AT-SPI polling).
- 4. **Pre-handle the OS elevation hazard** (UAC / TCC / AT-SPI) before it blocks the run.
+ 3. **Apply the matching async-wait primitive** for the OS (XCTest waiters / FlaUI Retry / AT-SPI polling) - see [references/async-waits-and-concurrency.md](references/async-waits-and-concurrency.md).
+ 4. **Pre-handle the OS elevation hazard** (UAC / TCC / AT-SPI) before it blocks the run - see [references/platform-hazards-and-dpi.md](references/platform-hazards-and-dpi.md).
## When to use
- Starting a new desktop test program - which OS + toolkit needs
which driver?
- Auditing an existing desktop test suite - is the right backend
in use, or is the suite working around a wrong-tool fit?
- Cross-platform desktop app (Electron, Qt, .NET MAUI) - which test
tools cover which platforms?
- Onboarding a tester from web E2E - what's the mental-model
difference between DOM-driving and accessibility-tree-driving?
## The three OS backends
Every reliable desktop driver routes through one of three OS-native
accessibility trees. Direct pixel / coordinate scripting (SikuliX,
AutoIt screen scraping) is in the **anti-pattern** column below.
### Windows - Microsoft UI Automation (UIA)
UI Automation (UIA) is Microsoft's accessibility framework for
Windows desktop applications, replacing the older Microsoft Active
Accessibility (MSAA) interface ([msuia][msuia]). UIA exposes an
`AutomationElement` tree with **control patterns** (`InvokePattern`,
`ValuePattern`, `SelectionPattern`, etc.) that describe what each
element does, not just how it looks.
Per [msuia][msuia]:
> "UI Automation is designed for experienced C/C++ developers. In
> general, developers need a moderate level of understanding about
> Component Object Model (COM) objects and interfaces, Unicode, and
> Windows API programming."
Higher-level language bindings (C#, PowerShell, Python via `pywinauto`)
sit on top. **For test-automation purposes**, the WinAppDriver and
- Appium-Windows projects expose UIA as a W3C WebDriver endpoint -
+ Appium-Windows projects expose UIA as a W3C WebDriver endpoint -
which is what most QA toolchains actually drive.
### macOS - Apple Accessibility + XCTest
macOS GUI testing uses the same `XCTest` framework that ships with
Xcode for unit and integration tests. Per [appleuit][appleuit]:
> "UI testing rests upon two core technologies: the XCTest
> framework and Accessibility."
The three foundational classes ([appleuit][appleuit]) are:
| Class | Role |
|---|---|
| `XCUIApplication` | The application under test |
| `XCUIElement` | A single UI element in the accessibility tree |
| `XCUIElementQuery` | A query that resolves to zero or more `XCUIElement` |
The general UI-test pattern per [appleuit][appleuit]:
> "Use an XCUIElementQuery to find an XCUIElement. Synthesize an
> event and send it to the XCUIElement. Use an assertion to compare
> the state of the XCUIElement against an expected reference state."
Xcode's **Accessibility Inspector** (bundled with Xcode → Xcode →
Open Developer Tool → Accessibility Inspector) is the read-side
companion: it walks the same tree the tests see, lets the engineer
verify accessibility identifiers exist before writing the query, and
flags WCAG-style accessibility gaps in the same pass.
### Linux - AT-SPI
The Linux desktop accessibility stack is **AT-SPI** (Assistive
Technology Service Provider Interface). Per [atspi2core][atspi2core],
the canonical implementation `at-spi2-core` provides "Base DBus XML
interfaces for accessibility, the accessibility registry daemon,
and atspi library." The registry daemon (`at-spi2-registryd`)
exposes a system-wide D-Bus service that assistive tools - and test
clients - connect to.
GTK applications expose AT-SPI automatically via the `atk` bridge
(`at-spi2-atk`); Qt applications expose AT-SPI via the
`QAccessible` infrastructure (see `qt-test-framework` SKILL for
the Qt-specific path); Electron and Chromium apps on Linux expose
their own AT-SPI surface.
Python clients ([dogtail][dogtail], `pyatspi`) and the GNOME
inspector tool **Accerciser** walk the registry to drive tests.
[dogtail]: https://gitlab.com/dogtail/dogtail
## The toolkit overlays
Two cross-toolkit families need explicit treatment because they
ride on top of (or around) the OS backends:
### Electron
Electron apps are Chromium + Node.js wrapped in a native window. They
expose two parallel surfaces:
1. **Renderer process** - a normal Chromium DOM. Page-level
Playwright / Selenium / Puppeteer drive this just like a browser
tab.
2. **Main process** - the Node.js process that owns native windows,
menus, IPC, file dialogs, lifecycle.
A **packaged** Electron app cannot be driven by browser-only
Playwright - the entry point is the packaged binary, not a URL. The
**Playwright `_electron` API** (`electron-playwright` SKILL in this
plugin) launches the packaged binary, exposes the main process as a
typed `ElectronApplication` handle, and returns Chromium-window
pages for the renderer. Legacy alternative (deprecated 2021):
Spectron - covered as a legacy reference in `electron-spectron`.
### Qt
Qt has its own first-party test framework - **QtTest** - that lives
in the application's process and emits events directly into the
`QObject` event queue. It does **not** go through the OS
accessibility tree by default. For UI tests of Qt apps that need
to be driven from outside the process, the OS-native drivers
(WinAppDriver on Windows, XCTest on macOS, AT-SPI on Linux via
Qt's `QAccessible`) are the path. See `qt-test-framework` SKILL.
## Per-OS / per-toolkit decision matrix
| App type | Windows driver | macOS driver | Linux driver |
|---|---|---|---|
| Win32 / WinForms / WPF | WinAppDriver, Appium-Windows | n/a | n/a |
| WinUI 3 / UWP | WinAppDriver, Appium-Windows | n/a | n/a |
| Cocoa / SwiftUI / AppKit | n/a | XCTest UI (XCUIApplication) | n/a |
| GTK | n/a | n/a | AT-SPI (dogtail / pyatspi) |
| Qt - in-process | QtTest (`QTEST_MAIN`) | QtTest | QtTest |
| Qt - out-of-process | WinAppDriver (via UIA) | XCTest UI | AT-SPI (via QAccessible) |
| Electron - renderer only | Playwright `_electron` page handle | Playwright `_electron` page handle | Playwright `_electron` page handle |
| Electron - main + IPC | Playwright `_electron` | Playwright `_electron` | Playwright `_electron` |
Cross-references to per-tool SKILLs:
- `winappdriver` - WinAppDriver against UIA
- `appium-windows-driver` - Appium-Windows driver (newer
WinAppDriver wrapping)
- `xctest-mac-desktop` - XCTest UI for macOS
- `at-spi-linux` - AT-SPI via dogtail / pyatspi
- `qt-test-framework` - QtTest in-process
- `electron-playwright` - Playwright `_electron` API
- `electron-spectron` - legacy reference for migrations
## Locator strategy across backends
The portable lesson from web E2E (per
`playwright-testing` in the qa-web-e2e plugin) - **accessibility-first locators** - carries directly over: every
desktop backend resolves elements through the same accessibility
tree assistive technology uses.
| Backend | Stable locator | Brittle locator |
|---|---|---|
| UIA (WinAppDriver, Appium-Windows) | `AutomationId` (preferred - locale-independent), `ControlType` + property combo (disambiguation when no AutomationId) | `Name` (last resort - Name **is the localised label**, fails across language packs); absolute screen coordinates; XPath (officially supported by WinAppDriver but the community-canonical guidance treats it as fragile and slow) |
| XCTest (macOS) | `accessibilityIdentifier`, role-based queries (`buttons["Submit"]`) | Label-based queries when the label is localised; image matching; hard-coded coordinates |
| AT-SPI (Linux) | Object `name` field set explicitly on the widget (GTK `widget.set_property('name', ...)`, Qt `QObject::setObjectName`) | Visible label or role-only queries (collapse under localisation and theme changes); pixel coordinates |
| QtTest in-process | Qt object name (`setObjectName("…")`) | child-index navigation through `QWidget` tree |
| Electron renderer (Playwright) | `getByRole` / `getByLabel` on the renderer DOM | CSS class chains; Electron debug-build internal IDs |
The single biggest portability win across desktop platforms is:
**every app under test sets a stable accessibility identifier on
every interactive widget.** Without it, the tree's only resolution
key is the human-visible label, which collapses under localisation.
**Localisation rule of thumb:** if the test passes on a US-English build
but the same app ships in 20 locales, every `Name` / label-based locator
is a latent failure. AccessibilityId / AutomationId / object name are
locale-independent by design - make the developer set them at the source.
## Coverage scope per layer
| Layer | What it can cover | What it cannot cover |
|---|---|---|
| Unit test (XCTest / QtTest / .NET MSTest) | Pure logic, view-model bindings, `QObject` signals | OS-level dialog interactions, IME input, multi-window focus |
| In-process UI test (XCUIApplication-in-app, QtTest with `QTest::mouseClick`) | App-internal widget events | Cross-app drag-drop, system shortcuts, OS file pickers |
| Out-of-process UI driver (WinAppDriver / AT-SPI / Playwright `_electron`) | Full end-to-end including file dialogs, menus, system tray | Pre-login OS UI, GPU-accelerated rendered surfaces (canvas, WebGL) that don't expose the accessibility tree |
| Visual snapshot | Pixel-level regressions, font rendering | Logic, state, async behaviour |
Cross-references for the upstream + downstream slots:
- Unit testing - see the per-language `qa-unit-tests-*` plugins.
- Visual regression - see
`qa-visual-regression` for
desktop screenshot comparison patterns.
- CI integration - desktop runners cost more than web runners;
see the `winappdriver` and `xctest-mac-desktop` SKILLs for
GitHub-hosted vs self-hosted considerations.
- ## Asynchronous waits per OS
-
- 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][appwait1],
- [Asynchronous Tests and Expectations][appwait2]):
-
- [appwait1]: https://developer.apple.com/documentation/xctest/xcuielement/2879412-waitforexistence
- [appwait2]: https://developer.apple.com/documentation/xctest/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][flauiretry]) 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).
-
- [flauiretry]: https://github.com/FlaUI/FlaUI/wiki/Retry
-
- | 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).
-
- ## Concurrency: per-OS parallel-test policy
-
- **macOS** - per [Apple - Running tests serially or in parallel][appleparallel],
- 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.
-
- [appleparallel]: https://developer.apple.com/documentation/testing/parallelization
-
- **Windows** - UIA is per-session: one AutomationElement tree per
- interactive Windows session. Two workers in the same session race
- for foreground (see below). 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.
-
- ## Platform foreground + elevation hazards
-
- The two failure classes most often misdiagnosed as "flaky tests"
- on desktop are actually documented platform behaviours.
-
- ### Windows foreground-lock
-
- Per [Microsoft - SetForegroundWindow][winsetfg] and
- [Microsoft - LockSetForegroundWindow][winlockfg]:
-
- [winsetfg]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
- [winlockfg]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-locksetforegroundwindow
-
- `SetForegroundWindow` can be refused by Windows. The foreground
- process can also call `LockSetForegroundWindow` to suppress
- foreground transfer entirely. The system re-enables the transfer
- when the user presses ALT or interacts with a background window -
- neither of which happens in CI. Modal dialogs and active menus
- also suppress it. Symptoms in test logs: a click "succeeds" but
- the next action observes the previous window.
-
- Mitigations:
-
- - Activate the app explicitly (`app.Activate()` in FlaUI,
- `app.activate()` in XCUITest, `pyatspi` window-activation event
- on Linux) before every Act that depends on focus.
- - On CI Windows runners, disable foreground-lock for the test session:
- `HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout = 0`.
- - Avoid running other apps in the same session during the test.
-
- ### Windows UAC: the secure desktop is unreachable
-
- Per the WinAppDriver maintainers
- ([issue #306][wad306], [issue #2033][wad2033]):
-
- [wad306]: https://github.com/microsoft/WinAppDriver/issues/306
- [wad2033]: https://github.com/microsoft/WinAppDriver/issues/2033
-
- The UAC consent prompt renders on a **secure desktop** that lives
- outside the standard accessibility tree. WinAppDriver / UIA cannot
- interact with the consent button - by Windows design, not driver
- bug. Three supported workarounds:
-
- - Run the test session itself elevated (the simplest, the prevailing
- CI pattern); the UAC prompt then never appears for in-session
- privileged actions.
- - Pre-disable UAC in the CI VM image (`EnableLUA=0` in the registry - locks the VM to test use only).
- - Send `Alt+Y` / `Alt+N` keystrokes hoping the secure desktop has
- focus (unreliable and version-dependent; not recommended).
-
- ### macOS TCC privacy prompts
-
- Per [Jamf - *Resetting Transparency, Consent, and Control Prompts
- on macOS*][jamftcc]:
-
- [jamftcc]: https://docs.jamf.com/technical-articles/Resetting_Transparency_Consent_and_Control_Prompts_on_macOS.html
-
- TCC-gated prompts (Automation, Accessibility, Screen Recording,
- Files & Folders) render out of the AUT process and cannot be
- reliably driven by XCUITest. The supported pattern is to bring the
- prompt back to a known state before the test:
-
- ```bash
- tccutil reset Automation com.example.MyApp
- tccutil reset Accessibility com.example.MyApp
- tccutil reset ScreenCapture com.example.MyApp
- ```
-
- Or, on managed CI fleets, pre-grant via an MDM PPPC (Privacy
- Preferences Policy Control) profile so the prompt never appears.
-
- ### Linux: AT-SPI requires session-wide accessibility on
-
- Per [dogtail on GitLab][dogtail] and the [Ubuntu DogtailTutorial][ubuntudogtail]:
-
- [ubuntudogtail]: https://wiki.ubuntu.com/Testing/Automation/DogtailTutorial
-
- On modern GNOME (X11 or Wayland), AT-SPI is off by default. Enable
- it session-wide **before** launching the AUT:
-
- ```bash
- gsettings set org.gnome.desktop.interface toolkit-accessibility true
- ```
-
- This only takes effect for newly-spawned processes - start the AUT
- after the gsettings call, not before. Accerciser is the GNOME
- inspector and the canonical pre-write verification tool: walk the
- tree in Accerciser before writing the first locator.
-
- ## High-DPI / per-monitor test matrix
-
- Per [Microsoft - *High DPI Desktop Application Development on
- Windows*][msdpi]:
-
- [msdpi]: https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
-
- > "Common scenarios where display scale factors change include:
- > multiple-monitor setups where each display has a different
- > scale factor..."
-
- Microsoft enumerates concrete test scenarios that desktop apps
- must cover and that test matrices routinely miss:
+ ## Operating the tests - deep references
- | Scenario | What can break |
- |---|---|
- | Multi-display with different scale factors | Window placement, image asset selection (1x vs 2x), font hinting |
- | Dock / undock with mixed DPI | Live scale-factor change events; window jumps to wrong monitor |
- | Remote Desktop from high-DPI client to low-DPI host | Mouse hit-test coordinates, font rendering, accessibility-tree positions |
- | Live scale-factor change (drag between monitors) | Per-monitor V2 awareness needed; otherwise app is bitmap-stretched |
+ Once the stack is chosen, the operational depth lives in two
+ companion references:
- The recommended awareness level for the AUT is **per-monitor V2**.
- CI matrix: at minimum one mixed-DPI lane (2-monitor: 100% + 200%)
- in addition to a single-monitor 100% lane. macOS Retina has
- analogous behaviour (1x vs 2x asset selection); Linux per-monitor
- scaling lands in GNOME 47+ but is still maturing.
+ - **Asynchronous waits + concurrency** - per-OS retry primitives
+ (XCTest waiters, FlaUI `Retry`, AT-SPI polling) and the per-OS
+ parallel-test policy: [references/async-waits-and-concurrency.md](references/async-waits-and-concurrency.md).
+ - **Platform hazards + high-DPI** - foreground-lock, UAC secure
+ desktop, macOS TCC prompts, AT-SPI session enablement, and the
+ per-monitor DPI test matrix: [references/platform-hazards-and-dpi.md](references/platform-hazards-and-dpi.md).
## Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Image-recognition / pixel-matching as the primary driver (SikuliX-only, AutoIt screen scraping) | Brittle to font / theme / DPI / OS-chrome changes; opaque to localisation | Use the OS accessibility tree; reserve image matching for canvas-rendered content only |
| Hard-coded screen coordinates | Multi-monitor / DPI / window-state dependent | Resolve via accessibility identifier; click resolves to the element's hit-test centre |
| Win32 message sending (`SendMessage` / `PostMessage`) for modern apps | Doesn't reach UIA-only WinUI / WPF controls; bypasses event ordering | Route through UIA (WinAppDriver) - the documented control-pattern API |
| Using only XCTest on a packaged macOS app shipped to the App Store via TestFlight | Loses cross-platform consistency with Windows + Linux | Pair with a higher-level cross-platform layer (Appium Mac2 driver) only when the same test source must run on multiple OSes; otherwise XCTest is the right tool on macOS |
| Spectron for new Electron projects (archived 2022) | No maintenance, no support for modern Electron | Use Playwright `_electron` (`electron-playwright` SKILL) |
| Driving Qt apps with Win32-only tools when accessibility isn't wired in | Qt's `QAccessible` interface must be enabled; without it UIA sees no children | Verify with Accessibility Insights for Windows before writing tests; enable `QAccessible` in the Qt build |
| Running desktop UI tests on GitHub-hosted Linux runners with no virtual display | `at-spi2-registryd` requires a session bus | Self-hosted runners with a real (or `Xvfb` / `dbus-launch` synthetic) session, or use Windows / macOS hosted runners for those OS-specific suites |
## Limitations
- **Apple developer documentation is behind a Cloudflare-style
challenge** on most "https://developer.apple.com/documentation/…"
pages - automated fetches return the SPA shell only. This
reference cites Apple's stable-archive `testing_with_xcode` chapter
([appleuit][appleuit]) for prose; per-API surface (XCUIApplication,
XCUIElement) is treated as a stable identifier in the
`xctest-mac-desktop` SKILL.
- **No single cross-platform driver.** Tools that claim to be one
(Appium across Windows + macOS + Linux desktop) are thin facades
over the per-OS backends - coverage gaps follow the underlying
backend's gaps.
- **GPU-accelerated content** (canvas, WebGL, custom-painted Qt
widgets, Win32 DirectComposition surfaces) does not expose itself
to the accessibility tree by default; any driver routed through
the tree sees them as opaque rectangles.
- **Cross-process focus + window-Z order** is OS-policy-dependent
(Windows foreground-lock, macOS Stage Manager); tests that assume
a window is foreground often need explicit `app.activate()` calls.
- **Localisation collapses label-based locators.** The per-tool
SKILLs all push toward `AutomationId` / `accessibilityIdentifier`
/ object name for this reason.
## References
- Microsoft UI Automation overview - [msuia][msuia].
- Apple *Testing with Xcode* - UI Testing chapter
([appleuit][appleuit]).
- - Apple - XCUIElement.waitForExistence ([appwait1][appwait1])
- and Asynchronous Tests and Expectations ([appwait2][appwait2]).
- - Apple - Running tests serially or in parallel
- ([appleparallel][appleparallel]).
- - Microsoft - SetForegroundWindow ([winsetfg][winsetfg]),
- LockSetForegroundWindow ([winlockfg][winlockfg]),
- High-DPI Desktop Application Development on Windows
- ([msdpi][msdpi]).
- - WinAppDriver UAC issue threads ([wad306][wad306], [wad2033][wad2033]).
- - FlaUI Retry wiki ([flauiretry][flauiretry]).
- - Jamf - Resetting TCC prompts on macOS ([jamftcc][jamftcc]).
- at-spi2-core - [atspi2core][atspi2core].
- dogtail (Python AT-SPI client) - [dogtail][dogtail].
- - Ubuntu DogtailTutorial - [ubuntudogtail][ubuntudogtail].
+ - Operational depth (with their own citations): async waits +
+ concurrency in [references/async-waits-and-concurrency.md](references/async-waits-and-concurrency.md);
+ foreground / elevation hazards + high-DPI matrix in
+ [references/platform-hazards-and-dpi.md](references/platform-hazards-and-dpi.md).
- Per-tool implementation SKILLs:
`winappdriver`, `appium-windows-driver`, `xctest-mac-desktop`,
`at-spi-linux`, `qt-test-framework`, `electron-playwright`,
`electron-spectron`.
- Web-side neighbour:
`playwright-testing` - DOM-driving for browser apps (the contrast surface for
desktop drivers).
- Architecture-pattern sibling:
`object-model-patterns` (in the qa-test-review plugin) - Pattern 7 (Screen Object) is the desktop analog of POM and
cites this skill for the backend substrate.