Testland
Browse all skills & agents

appium-windows-driver

Authors and runs Appium 2.x tests against the Windows driver, the actively-maintained Node.js proxy in front of Microsoft's WinAppDriver: `appium driver install windows`, capabilities (`platformName: windows`, `appium:automationName: windows`, `appium:app`, `appium:appTopLevelWindow`, `appium:appArguments`), Windows gestures (`windows: scroll` / `clickAndDrag` / `keys`), PowerShell prerun/postrun hooks, and CI. Use when the stack already uses Appium for iOS / Android / Mac2 and Windows fits the existing client + capability model; to drive WinAppDriver directly from a Selenium-style client use winappdriver, and for a C#-only FlaUI client use flaui-tests.

Install with skills.sh (any agent)

npx skills add testland/qa --skill appium-windows-driver
View source

appium-windows-driver

Overview

Per the appium-windows-driver repository (opens in new window):

"Appium Windows Driver is a test automation tool for Windows devices and acts as a proxy to Microsoft's WinAppDriver server."

It is the Appium-ecosystem wrapper in front of Microsoft's WinAppDriver.exe (awd (opens in new window)). The Node.js driver itself is actively maintained (see awd (opens in new window) for the current release), while the underlying WinAppDriver service is described on the Appium ecosystem driver page (opens in new window) as "has not been maintained since 2022", which is why the wrapper now includes a built-in installer (appium driver run windows install-wad) to pin a known-good WinAppDriver version.

Sibling differentiation: winappdriver drives the same UIA surface directly via the Microsoft service - pick that skill if the project does not already use Appium or wants no Node.js dependency on the test host. Pick appium-windows-driver when the project already runs Appium for iOS / Android / Mac2 (per desktop-test-strategy-reference for the Mac2 sibling) and Windows is the next platform to add.

When to use

  • Project already runs Appium 2.x for mobile + Mac2 - add Windows with the same client.
  • Tests need Windows-specific gestures (windows: scroll, windows: clickAndDrag) beyond raw W3C WebDriver.
  • Tests need to execute PowerShell at session boundaries (appium: prerun / appium:postrun).
  • A consistent capability schema across platforms matters more than minimizing test-host dependencies.

How to use

  1. Install Appium + the Windows driver (appium driver install windows), pin the underlying WinAppDriver via appium driver run windows install-wad, then launch the server on 127.0.0.1:4723 (Install). Verify: curl http://127.0.0.1:4723/status returns HTTP 200 before proceeding; if it fails, the server is not listening - re-check the appium --port 4723 launch and the driver install.
  2. Declare session capabilities with the appium: vendor prefix - platformName: windows, appium:automationName: windows, appium:app (Declare session capabilities).
  3. Author a test that resolves a UIA element by Name / AccessibilityId and drives it end to end (Worked example).
  4. Add Windows-namespaced gestures (windows: scroll / clickAndDrag / keys), multi-window switching, and appium:prerun / appium:postrun PowerShell hooks as the suite needs them - see references/gestures-hooks-and-ci.md.
  5. Gate CI on a Windows runner; JUnit output feeds junit-xml-analysis - full workflow in references/gestures-hooks-and-ci.md.

Install

Per awd (opens in new window):

npm install -g appium
appium driver install windows

Then install the underlying WinAppDriver server via the driver- provided helper (awd (opens in new window)):

appium driver run windows install-wad
# Or pin a version:
appium driver run windows install-wad 1.2.1

The helper downloads the pinned WinAppDriver installer to C:\Program Files (x86)\Windows Application Driver\ - the standard Microsoft install path described in winappdriver.

Launch the Appium server:

appium --port 4723

Standard Appium 2.x defaults - listens on 127.0.0.1:4723. Sessions to this port forward Windows-specific calls to the WinAppDriver service, which Appium spawns automatically when the first session is created.

Declare session capabilities

Per awd (opens in new window):

CapabilityRequiredNotes
platformNameyes"Must be set to windows (case-insensitive)" (awd (opens in new window))
appium:automationNameyes"Must be set to windows (case-insensitive)" (awd (opens in new window))
appium:appyes (unless attaching)UWP app ID or full executable path (awd (opens in new window))
appium:appTopLevelWindowconditional"The hexadecimal handle of an existing application top level window" (awd (opens in new window))
appium:appArgumentsoptionalArgument string passed to the launched app (awd (opens in new window))
appium:prerunoptionalPowerShell script run before session start (awd (opens in new window))
appium:postrunoptionalPowerShell script run after session end (awd (opens in new window))

Example capability JSON:

{
  "platformName": "windows",
  "appium:automationName": "windows",
  "appium:app": "C:\\Windows\\System32\\notepad.exe",
  "appium:appArguments": "MyTestFile.txt"
}

Worked example

Drive one element end to end - launch Notepad, type into its editor, read the value back, and quit the session (Python client):

from appium import webdriver
from appium.options.windows import WindowsOptions
from selenium.webdriver.common.by import By

options = WindowsOptions()
options.platform_name = 'windows'
options.automation_name = 'windows'
options.app = r'C:\Windows\System32\notepad.exe'

driver = webdriver.Remote('http://127.0.0.1:4723', options=options)

editor = driver.find_element(By.NAME, 'Text editor')
editor.send_keys('Hello from Appium Windows')
assert 'Hello from Appium Windows' in editor.text

driver.quit()

Locators (AccessibilityId, Name, ClassName, etc.) carry the same UIA semantics as in winappdriver - the driver proxies them through to WinAppDriver unchanged.

Anti-patterns

Anti-patternWhy it failsFix
Omitting appium: prefix on driver capabilitiesAppium 2.x requires the vendor prefix on non-W3C-standard capsAlways prefix (appium:automationName, appium:app, etc.) (awd (opens in new window))
Targeting automationName: WinAppDriver (legacy)Appium 2.x driver expects windows, case-insensitiveUse windows per awd (opens in new window)
Hand-installing a random WinAppDriver MSIVersion mismatch with the Node driver's proxy codeappium driver run windows install-wad [version] (awd (opens in new window))
Running PowerShell hooks that block foreverSession creation hangs on the prerun scriptHooks must be short + non-interactive (awd (opens in new window))
Hard-coded appTopLevelWindow checked into the repoHex window handle is per-launch, not stableDiscover at runtime via windows: launchApp or fresh-launch via appium:app
Mixing the Mac2 driver's capability shape on Windowsappium:bundleId (Mac2) isn't valid for WindowsPer-platform capability blocks; share only the W3C-standard caps
Using windows: scroll with positive deltaY to scroll downWheel-delta sign mirrors Windows conventionNegative deltaY scrolls down (see gestures reference)

Limitations

  • Windows-only. The driver runs Appium against UIA on Windows 10/11. Cross-OS test sharing relies on parallel drivers (mac2, xcuitest, uiautomator2).
  • Underlying WinAppDriver maintenance gap. Per appiumdrivers (opens in new window), the WinAppDriver server "has not been maintained since 2022"; bugs in the UIA-to-WebDriver layer itself can only be patched in the Appium driver, not in the upstream service. NovaWindows is referenced on appiumdrivers (opens in new window) as "a drop-in replacement for the partially unmaintained Windows driver" - consider for new heavy use.
  • Appium server overhead. Adds a Node.js process layer in front of WinAppDriver - slightly slower session start than direct winappdriver. For tests where session startup time dominates (very short tests, large suites), direct WinAppDriver is faster.
  • PowerShell hooks run as the test user. They cannot bypass UAC or other security boundaries; design fixtures around the test user's permissions.
  • Same UIA constraints as direct WinAppDriver. GPU-rendered surfaces, DirectComposition, and apps that don't publish UIA are uncovered (see winappdriver limitations).

References

Appium Windows driver - gestures, hooks, and CI

View source (opens in new window)

Appium Windows driver - gestures, hooks, and CI

Deep reference for appium-windows-driver SKILL.md. Consult when adding Windows-specific gestures, multi-window flows, PowerShell session hooks, or wiring the driver into CI on a Windows runner.

Windows-specific gestures

Per awd (opens in new window), the driver adds Windows-namespaced extensions on top of the W3C WebDriver baseline:

CommandPurpose
windows: scroll"Mouse wheel gesture" with deltaX / deltaY parameters (awd (opens in new window))
windows: clickAndDrag"Drag-and-drop operations" (awd (opens in new window))
windows: keys"Customized keyboard input with virtual key codes" (awd (opens in new window))
windows: launchAppOpen another app window within the same session (awd (opens in new window))

Scroll a list inside the app under test (negative deltaY scrolls down):

driver.execute_script('windows: scroll', {
    'elementId': list_element.id,
    'deltaY': -300,   # negative scrolls down
})

Drag a file across panels:

driver.execute_script('windows: clickAndDrag', {
    'startElementId': source.id,
    'endElementId':   target.id,
})

Multi-window sessions

Per awd (opens in new window), "It is possible to switch between app windows using WebDriver Windows API" and windows: launchApp "creates new app windows within the same session". This is the cross-app workflow path (e.g., test a deep-link flow that crosses from a desktop app into the Settings app):

settings_handle = driver.execute_script('windows: launchApp', {
    'app': 'ms-settings:',
})
driver.switch_to.window(settings_handle)

Pre/post-run PowerShell hooks

Per awd (opens in new window), appium:prerun and appium:postrun accept PowerShell scripts that the driver executes around session lifecycle. This is the canonical place to:

  • Set up fixture data (write a config file to the user's %AppData%).
  • Suppress / replay the Windows lock screen if the app under test triggers a UAC prompt.
  • Tear down user-data state between tests.
{
  "platformName": "windows",
  "appium:automationName": "windows",
  "appium:app": "MyApp",
  "appium:prerun": {
    "script": "Copy-Item .\\fixtures\\config.json $env:APPDATA\\MyApp\\config.json -Force"
  },
  "appium:postrun": {
    "script": "Remove-Item $env:APPDATA\\MyApp\\config.json -Force"
  }
}

Run and parse results

# Pytest example
pytest tests/windows --junitxml=reports/windows-junit.xml

JUnit XML output feeds junit-xml-analysis (in the qa-test-reporting plugin) for the cross-runner aggregation pipeline.

CI integration

# .github/workflows/appium-windows.yml
jobs:
  test:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: npm install -g appium
      - run: appium driver install windows
      - run: appium driver run windows install-wad
      - name: Enable Developer Mode
        run: |
          reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" `
            /t REG_DWORD /f /v AllowDevelopmentWithoutDevLicense /d 1
      - name: Start Appium
        run: |
          Start-Process -FilePath "appium" -ArgumentList "--port 4723" -PassThru
          Start-Sleep -Seconds 5
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install Appium-Python-Client pytest
      - run: pytest tests/windows --junitxml=reports/windows-junit.xml
      - uses: actions/upload-artifact@v4
        if: always()
        with: { name: junit, path: reports/ }

Same hosted-vs-self-hosted runner caveats as winappdriver - UIA requires an interactive desktop session, so Session-0 Windows containers won't work without extra display setup.

Related skills

at-spi-linux

Authors Linux desktop UI tests via AT-SPI - the DBus-based Assistive Technology Service Provider Interface implemented by `at-spi2-core` (registry daemon + `libatspi` C library + ATK GTK bridge). Covers enabling toolkit accessibility (`gsettings set org.gnome.desktop.interface toolkit-accessibility true`), driving GTK + Qt apps through Python `dogtail` (object-oriented + procedural APIs), inspecting the tree with Accerciser, scripting via `pyatspi`, and CI integration on headless Linux runners with `Xvfb` + `dbus-launch`. Use for Linux-side desktop tests of GTK applications, Qt apps with QAccessible enabled, and Electron apps on Linux.

desktop-test-strategy-reference

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.

electron-playwright

Authors Playwright `_electron` tests for packaged Electron desktop apps - launches the app via `electron.launch({ args })`, returns an `ElectronApplication` handle, drives renderer windows as Playwright `Page` objects, and probes the main process via `electronApp.evaluate(({ app, BrowserWindow }) => …)`. Distinct from ordinary browser page automation: this wraps the `_electron` API for launching packaged Electron apps and probing main + renderer processes. Use for end-to-end tests of Electron apps where main-process state, IPC, and renderer DOM must all be asserted from one suite.

electron-spectron

Legacy reference for Spectron - Electron's original ChromeDriver-based testing framework, officially deprecated 2022-02-01 at v19.0.0. Documents what Spectron was, the architectural reason it became unmaintainable, the migration path to Playwright `_electron`, and the residual support contract for projects still on Spectron. Use only when auditing a legacy suite or planning a migration off Spectron - for new work use Playwright's `_electron` API.

flaui-tests

Authors and runs FlaUI-based Windows UI tests - the .NET-native wrapper around Microsoft UI Automation (UIA2 + UIA3). Covers the `FlaUI.Core` / `FlaUI.UIA2` / `FlaUI.UIA3` NuGet packages, `Application.Launch` / `Application.Attach` lifecycles, `ConditionFactory` + `FindFirstDescendant` locator patterns, `Retry` waits, and xUnit / NUnit / MSTest harness integration. Use when the test stack is C# / .NET-first and the team wants idiomatic in-process UIA calls rather than the HTTP/JSON wire protocol of `winappdriver` or the Appium proxy layer of `appium-windows-driver`.

qt-test-framework

Authors and runs Qt Test - the first-party C++ unit + GUI test framework that ships with Qt 6 (via the `QtTest` module header). Covers the `QTEST_MAIN` / `QTEST_APPLESS_MAIN` / `QTEST_GUILESS_MAIN` entry-point macros, the `QObject` private-slot test pattern, `QVERIFY` / `QCOMPARE` / `QFETCH` assertions, GUI event simulation (`QTest::mouseClick`, `QTest::keyClick`, `QTest::touchEvent`), `QSignalSpy` for signal introspection, `QBENCHMARK` for performance regression, and the `-o file,junitxml` CI output. Use for in-process testing of Qt widgets, QObject signal/slot chains, and Qt Quick / QML application logic; for out-of-process Qt-app driving, use an OS-native accessibility driver instead.

winappdriver

Authors and runs Windows UI tests against WinAppDriver, Microsoft's W3C-WebDriver service for UWP / WPF / WinForms / Win32 apps: installing + launching `WinAppDriver.exe` on `127.0.0.1:4723`, declaring `app` / `platformName` / `appArguments` / `appTopLevelWindow` capabilities, finding elements by `AccessibilityId` / `Name` / `ClassName`, and Windows-runner CI. Use when driving a native Windows app from a Selenium-style client (C#, Java, Python, Ruby, JS); for the actively-maintained Appium 2.x wrapper over the same server use appium-windows-driver, for a C#-only FlaUI client use flaui-tests, and to choose among Windows desktop drivers first use desktop-test-strategy-reference.

xctest-mac-desktop

Authors and runs XCTest UI + unit tests for macOS desktop apps - the Apple-first-party test framework that ships with Xcode. Covers the `XCTestCase` subclass + `test*` method-naming convention, `XCUIApplication` / `XCUIElement` / `XCUIElementQuery` for UI tests, accessibility-identifier-based locators (the stable replacement for label-based queries), `XCTAssert*` macros, `measureBlock:` for performance regressions, and `xcodebuild test` for CI execution. Use when the macOS app is built with Xcode and the test target is in-tree alongside the app - for cross-OS sharing see Appium Mac2 driver as a separate path.