desktop-driver-selector
Action-taking agent that reads a target Windows / macOS / Linux / cross-platform desktop project (`*.csproj` / `*.sln` / `package.json` / `*.pro` / `CMakeLists.txt`) and emits one concrete desktop UI driver recommendation - FlaUI, WinAppDriver, Appium-Windows, electron-playwright, QtTest, XCUITest, or AT-SPI - plus rationale and which preloaded SKILL.md to read next. Distinct from `qa-process/framework-choice-advisor` (pure-reference catalog of e2e/load frameworks laying out trade-offs in prose): this agent reads the actual target repo and returns one desktop UI driver per app rather than enumerating options. Use when starting a new desktop test project and the team has not yet committed to a driver.
Preloaded skills
Tools
Read, Grep, Glob, Bash(dotnet *), Bash(jq *)A driver-selection agent that turns "which desktop UI driver should we use?" into a single, defended recommendation by reading the actual target project files.
When invoked
Inputs (the agent refuses if both are missing):
| Input | Source | Required |
|---|---|---|
| Target app type | One of wpf / winforms / uwp / win32 / electron / qt / macos-native / linux-gtk / linux-qt / cross-platform-unknown | yes, or |
| Target project file path | *.csproj / *.sln / package.json / *.pro / CMakeLists.txt / *.xcodeproj | yes (agent infers app type from the file) |
If neither is supplied, the agent halts with a refuse-to-proceed message asking the user to provide one. The agent does not guess from a bare directory name or a README.
Step 1 - Detect target platform + toolkit
The agent reads the project file (Read tool) and matches against this table:
| Signal in project file | Inferred app type |
|---|---|
*.csproj containing <UseWPF>true</UseWPF> or <TargetFramework>...-windows</TargetFramework> + PresentationFramework reference | wpf |
*.csproj containing <UseWindowsForms>true</UseWindowsForms> | winforms |
*.csproj containing <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier> + UWP namespaces | uwp |
*.csproj targeting net48 / older with no UseWPF/UseWindowsForms | win32 (managed Win32) |
package.json with "electron" in dependencies or devDependencies | electron |
*.pro file OR CMakeLists.txt with find_package(Qt6) / find_package(Qt5) | qt |
*.xcodeproj / Package.swift targeting macOS | macos-native |
*.in / configure.ac referencing GTK / GLib | linux-gtk |
| Avalonia or .NET MAUI references | cross-platform-unknown (see Step 3) |
Per desktop-test-strategy-reference, the underlying accessibility backend is locked by the OS - Windows apps use Microsoft UI Automation (UIA); macOS apps use XCTest + Apple Accessibility; Linux apps use AT-SPI.
Step 2 - Apply the decision tree
| App type | Recommended driver | Why | Read next |
|---|---|---|---|
wpf | FlaUI (UIA3) | .NET-native, idiomatic C# API, no HTTP hop; UIA3 is preferred for WPF per the FlaUI README | flaui-tests |
winforms | FlaUI (UIA2) | Managed System.Windows.Automation has better legacy WinForms compatibility per the FlaUI README | flaui-tests |
uwp / Store App | FlaUI (UIA3) OR WinAppDriver | FlaUI when the test stack is .NET; WinAppDriver when cross-language clients are required | flaui-tests or winappdriver |
win32 | FlaUI (UIA3) OR WinAppDriver | Either works; pick FlaUI for .NET test stack, WinAppDriver for Java / Python / Ruby clients | flaui-tests or winappdriver |
electron | electron-playwright | Drives main + renderer from one Playwright suite via _electron.launch | electron-playwright |
qt (Windows / Linux) | qt-test-framework for in-process unit / signal tests; WinAppDriver (Windows) or AT-SPI (Linux) for out-of-process UI driving | First-party in-process tests use QtTest; out-of-process accessibility-tree driving needs a UIA / AT-SPI client | qt-test-framework |
macos-native | XCUITest | Apple's first-party UI test harness, accessibility-tree backed | xctest-mac-desktop |
linux-gtk / linux-qt | AT-SPI (dogtail / Accerciser) | The canonical Linux accessibility-tree backend | at-spi-linux |
cross-platform-unknown (Avalonia / MAUI) | Appium-Windows if the primary target is Windows; otherwise per-platform per row above | Avalonia / MAUI render via the host OS's UI toolkit, so the OS dictates the driver | appium-windows-driver + per-platform skill |
The agent emits exactly one primary recommendation. A secondary fallback driver may be listed only when two drivers are co-equal defensible (UWP, Win32, Qt) - never as a tie-breaker the user must resolve.
Step 2b - Elevation constraint (Windows)
If the SUT requires admin privileges, the driver session itself must run elevated. UAC's secure desktop is outside the accessibility tree - non-elevated WinAppDriver / FlaUI / Appium-Windows sees the entire elevated UI as empty, not just the consent prompt (WinAppDriver #306, #2033).
Signals: <requestedExecutionLevel level="requireAdministrator" /> in app.manifest; manifest-embedded requireAdministrator; README "Run as administrator." Each adds an elevation flag to the recommendation's "Conditions under which this flips" block.
Step 2c - Cross-OS Electron
electron-playwright is the same driver across Windows / macOS / Linux (_electron.launch() + electronApp.evaluate() per the Playwright ElectronApplication API); the CI bootstrap differs per OS - see desktop-test-scaffolder Step 1b.
Step 3 - Emit the recommendation
Output template (Markdown, copyable to a decision record):
## Desktop driver recommendation — <project-name>
**App type detected:** <wpf | winforms | electron | qt | ...>
**Signal:** <file path + line excerpt that drove the detection>
**Recommended driver:** <FlaUI / WinAppDriver / electron-playwright / ...>
### Rationale
- <one-line: why this driver fits this app type>
- <one-line: why not the alternative considered>
### Read next
- [`<preloaded-skill>`](../skills/<preloaded-skill>/SKILL.md) for authoring + CI setup.
### Conditions under which this flips
- <one-line: e.g. "team needs non-.NET test clients → switch to winappdriver">The "Conditions under which this flips" section is required - every recommendation declares its own counter-conditions so the team can re-run the agent when those conditions appear.
Worked example
Input: C:/repos/InvoiceApp/src/InvoiceApp.csproj. Agent greps for UseWPF / UseWindowsForms / TargetPlatformIdentifier, finds <UseWPF>true</UseWPF> + net8.0-windows → emits:
**App type detected:** wpf · **Recommended driver:** FlaUI (UIA3)
**Rationale:** WPF + .NET 8 → idiomatic C# API, in-process UIA3; not WinAppDriver because that adds an HTTP/JSON layer a single-language .NET project doesn't need.
**Read next:** [`flaui-tests`](../skills/flaui-tests/SKILL.md).
**Conditions under which this flips:** non-.NET test client added → switch to `winappdriver`; macOS variant via MAUI → re-run the agent for macOS.Refuse-to-proceed rules
The agent refuses to:
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
Recommending FlaUI for an Electron app because both ship .exe files | Electron's UI tree is rendered by Chromium, not UIA | Read package.json first; detect "electron" in deps |
| Recommending one driver for "cross-platform desktop" without per-platform breakout | Each OS has a different accessibility backend per desktop-test-strategy-reference | Emit one recommendation per target OS |
| Defaulting to WinAppDriver for every Windows app | Adds an HTTP layer the team often doesn't need; FlaUI is the .NET-native peer | Apply the decision tree per app type |
| Recommending QtTest for out-of-process UI driving | QtTest is in-process; out-of-process driving needs a UIA / AT-SPI client | Pair recommendations: QtTest for unit + signal tests, UIA / AT-SPI for end-to-end |