Desktop E2E (Windows) — Edho Ferdian Mode
SkillDev toolsEnd-to-end testing for Windows native desktop applications (WPF, WinForms, Win32/MFC, Qt 5/6) using pywinauto over the Windows UI Automation API. The native-automation driver that e2e-testing-edho-ferdian's Phase 0 detects as option 4 but has no content behind, journey mapping and the Page Object Model come from there; the pywinauto mechanics live here. Use when the target is a desktop .exe rather than a browser page, when a desktop GUI test suite is being set up or is flaky, or when adding AutomationIds to make an app testable. Trigger phrases: "test aplikasi desktop", "pywinauto", "WPF/WinForms/Qt test", "UI Automation", "test .exe ini".
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; ahel provides instructions and does not run this skill.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the Desktop E2E (Windows) skill
What this skill tells your AI
The instructions your AI receives, as published by edhoferdian/eef in skills/desktop-e2e-edho-ferdian/SKILL.md and read by ahel’s review.
Where this sits
e2e-testing-edho-ferdian owns the process: Phase 1 journey mapping,
Phase 2 Page Object Model, Phase 3 flake quarantine, Phase 4 artifact capture.
All four are driver-agnostic and apply unchanged here — do not restate or fork
them. This skill supplies only what changes when the driver is native Windows
automation instead of a browser:
| Concept | Browser (Playwright) | Here (pywinauto + UIA) |
|---|---|---|
| Locator | role / data-testid / CSS | AutomationId → Name → ClassName+index |
| Wait | auto-waiting locators | spec.wait("visible") / wait_until(...) |
| Artifact | screenshot / video / trace | window capture / ffmpeg gdigrab / step trace |
| Isolation | browser context | fresh process + redirected APPDATA/TEMP |
Not for: web apps (use Playwright), Electron/CEF/WebView2 (the HTML layer needs browser automation, UIA only sees the shell), mobile, or anything that does not need a running GUI.
How it works
Everything routes through Windows UI Automation, an accessibility API built into Windows. Each UI framework ships a UIA provider of varying quality:
pytest → pywinauto (uia backend) → Windows UI Automation API → app's UIA provider → running .exe
| Framework | AutomationId source | Reliability |
|---|---|---|
| WPF | x:Name maps directly | Excellent |
| UWP / WinUI 3 | native | Excellent |
| Qt 6.x | setAccessibleName; accessibility on by default | Excellent |
| WinForms | AccessibleName | Good |
| Qt 5.15+ | needs QT_ACCESSIBILITY=1 | Good |
| Qt 5.7–5.14 | needs QT_ACCESSIBILITY=1; manual objectName | Fair |
| Win32 / MFC | resource control IDs appear as numeric strings | Fair |
Phase 0′ — Environment check (before anything else)
pip install pywinauto pytest pytest-html pytest-timeout Pillow
from pywinauto import Desktop
Desktop(backend="uia").windows() # must list top-level windows
Install Accessibility Insights for Windows (free, Microsoft) — it is the DevTools equivalent for this stack. Inspect the UIA tree there before writing a locator; guessing at AutomationIds is the main time sink here.
If UIA is unreachable, or the target turns out to be Electron/WebView2, stop
and say so — report VERIFIED: NO — no usable native automation driver, the
same convention the rest of this ecosystem uses. Never fabricate a run.
Testability first
The single highest-leverage action is giving every interactive control a stable AutomationId before writing tests. Per framework:
- WPF —
x:Name="btnLogin"in XAML; nothing else needed. - WinForms —
btnLogin.AccessibleName = "btnLogin"; - Qt — set both, via one helper, and centralize the string constants in a
header so tests and app cannot drift:
void setTestId(QWidget* w, const char* id) { w->setObjectName(id); w->setAccessibleName(id); // becomes the UIA Name property } - Win32 / MFC — resource IDs surface as numeric AutomationId strings;
prefer
SetWindowTextfor a readable Name.
A test suite written against ClassName + index because the app has no
AutomationIds will be rewritten within a release. Fixing testability in the app
is cheaper than the flakiness it prevents — say so when the app owner resists.
References
references/pywinauto-harness.md— the Page Object base class, locator priority, wait patterns, artifact capture, the opt-in per-step trace, and the flaky-cause table.references/isolation-and-ci.md— the three isolation tiers (tmp_path env redirect / Job Object / Windows Sandbox), hang prevention, and the GitHub Actionswindows-latestworkflow.references/qt-and-fallback.md— Qt-specific quirks (combo popups, dialogs as top-level windows, table cells, self-drawn widgets) and the screenshot-matching fallback with its DPI rules.
Language routing (fixed — see skill-authoring-edho-ferdian's canonical contract)
Communication to the user in Bahasa Indonesia; test code, page-object names,
and assertions in English — fixed, never ask. Full contract:
skill-authoring-edho-ferdian §7.
Global rules
- AutomationId first, always. Name second, ClassName+index only when forced, coordinates never as a primary strategy.
- Never
time.sleep()as synchronization.wait_visible/wait_gone/wait_untilexist for exactly this. - Fresh process per test. A session-scoped app fixture leaks state between tests and turns every failure into an archaeology exercise.
- Assert content and state, never pixel geometry.
lblStatus == "Logged in"is a test;btn.rectangle().left == 120is a trap. - Redact typed text in traces. Never enable trace text capture on a login or payment flow.
- Quarantine, don't delete — the protocol in
e2e-testing-edho-ferdian/references/flake-quarantine.mdapplies verbatim; the Python spelling is@pytest.mark.skip(reason="...")/@pytest.mark.skipif(os.environ.get("CI") == "true", reason="...").
Signals
- GitHub stars
- 21
- Last commit
- Sep 2026
ahel review
K1binfo
installs-packagesK1binfo
installs-packages (in references/pywinauto-harness.md)
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Item type
- skill
- Key
desktop-e2e-edho-ferdian- Source
- github.com/edhoferdian/eef
Related picks
Skill · davila7
The pick for C / C++python-performance-optimization
Skill · wshobson
The pick for Pythonpython-pro
Skill · jeffallan
The pick for Pythonhandsontable-playwright-e2e
Skill · handsontable
The pick for End-to-end testingmstar-e2e
Skill · btspoony
The pick for End-to-end testingteach
Skill · mattpocock
More in Dev tools