Winlenium is a CLI tool for automated testing of Windows programs via the MS UI Automation framework.
Project description
Winlenium
A command-line tool for automated testing of Windows applications using the
Microsoft UI Automation framework. Winlenium exposes a set of shell commands
(click, type, key, inspect, wait, and others) that locate UI elements
by selector and perform actions on them. Designed for CI/CD pipelines, test
scripts, and any workflow where you need to drive a Windows GUI without writing
UIA code.
Winlenium is published on PyPI, so you
can install it directly with uv or pip, or run it on demand with uvx.
Table of Contents
- Installation
- Quick Start
- Commands
- Element Selectors
- Window Selectors
- Usage Examples
- Output Formats
- Exit Codes
- Agentic Usage Examples
- Documentation
Installation
Requirements
- Windows 10 or 11 with a desktop session (UI Automation requires an active desktop)
- Python 3.12+
- uv (recommended package manager)
Install Python and uv with winget:
winget install Python.Python.3.12
winget install astral-sh.uv
Verify both are available:
python --version
uv --version
Install with uv
# Install the CLI globally in uv's tool directory
uv tool install winlenium
# Verify installation
winlenium --version
Install with pip
pip install winlenium
Run without installing
# Run the published CLI directly from PyPI
uvx winlenium --version
After installation the winlenium command is available in your shell. If you
want to work from source, run tests, or contribute changes, see
DEVELOPMENT.md.
Quick Start
Launch Notepad, type some text, and save the file:
# 1. Start Notepad and wait for its window
winlenium run notepad.exe
# 2. Type text into the editor
winlenium type --text "Hello from Winlenium" --window-name "Untitled - Notepad"
# 3. Save the file with Ctrl+S
winlenium key --keys "Ctrl+S" --window-name "Untitled - Notepad"
# 4. Wait for the Save As dialog
winlenium wait --name "Save As" --timeout 5000
# 5. Type a filename and press Enter
winlenium type --text "demo.txt" --window-name "Save As"
winlenium key --keys "Enter" --window-name "Save As"
Commands
Process and Window Management
| Command | Description |
|---|---|
run |
Launch an executable and wait for its main window |
close |
Close a window (WindowPattern) or terminate a process |
focus |
Bring a window to the foreground and set input focus |
window |
Manage window state (minimize, maximize, restore) |
list-windows |
List all top-level windows, optionally filtered by PID |
list-processes |
List running processes that have visible windows |
Element Interaction
| Command | Description |
|---|---|
click |
Click a UI element (--button left|right|middle, --count 1|2) |
type |
Send text input to an element or the focused control |
key |
Send a key combination (e.g. Ctrl+S, Alt+F4) |
move |
Mouse move, hover, or drag-and-drop |
scroll |
Scroll within a scrollable element |
toggle |
Toggle a checkbox or toggle button |
select |
Select an item in a list, combo box, or tab control |
expand |
Expand a tree node, menu, or dropdown |
collapse |
Collapse a tree node, menu, or dropdown |
set-value |
Set an element's value via ValuePattern |
Inspection and Queries
| Command | Description |
|---|---|
inspect |
Print the accessibility tree of a window or element |
get-value |
Read an element's value (ValuePattern) |
get-property |
Read a specific UIA property (e.g. IsEnabled) |
wait |
Wait for an element to appear or disappear |
screenshot |
Capture a screenshot of a window or element |
clipboard |
Get or set clipboard content (get / set) |
tray |
Interact with system tray icons (list, click, inspect) |
Run winlenium <command> --help for the full list of options for any command.
Element Selectors
Most commands accept the following options to locate a UI element:
| Option | Description |
|---|---|
--name |
Match element by its Name property |
--automationid |
Match element by AutomationId |
--controltype |
Match element by ControlType (e.g. Button, Edit) |
--pid |
Scope the search to a process ID |
--index |
Select the Nth match (0-based) when multiple elements match |
Selectors can be combined to narrow the search:
winlenium click --name "OK" --controltype Button --window-name "My App"
At least one selector (--name, --automationid, --controltype, --pid,
or --path) must be provided.
Path Selector
The --path option provides a powerful way to locate elements by their
position in the UI tree using a slash-separated path of selectors:
# Direct child traversal (/ means direct child)
winlenium click --path "Pane/Button[@Name='OK']" --window-name "My App"
# Descendant search (// searches at any depth)
winlenium click --path "Pane//Button[@Name='OK']" --window-name "My App"
# Control type only
winlenium inspect --path "Window/Pane/Button" --window-name "My App"
# Index-based disambiguation (0-based)
winlenium click --path "Pane/Button[1]" --window-name "My App"
# AutomationId
winlenium click --path "Pane[@AutomationId='nav']/Button[@Name='Submit']" --window-name "My App"
Segment syntax: ControlType[@Attr='value'][index]
| Component | Example | Description |
|---|---|---|
| Control type | Button |
Matches elements of this control type |
[@Name='…'] |
[@Name='OK'] |
Matches by Name property |
[@AutomationId='…'] |
[@AutomationId='btn1'] |
Matches by AutomationId |
[N] |
[2] |
Zero-based index for disambiguation |
Path separators:
/— direct child (depth 1)//— descendant at any depth
--path is mutually exclusive with --name, --automationid,
--controltype, and --index. The --pid and --window-* options can still
be used with --path.
Window Selectors
Commands that interact with elements inside a window accept window selector options to first locate the correct window:
| Option | Description |
|---|---|
--window-name |
Match window by Name property |
--window-automationid |
Match window by AutomationId |
--window-controltype |
Match window by ControlType |
--window-pid |
Match window by process ID |
--window-index |
Select the Nth matching window (0-based) |
--window-handle |
Match window by native handle (hex 0x1A2B or decimal) |
Combine window and element selectors for precise targeting:
winlenium click --name "OK" --controltype Button --window-pid 1234 --window-index 0
Usage Examples
Discover running applications
# Find all processes with "notepad" in the name
winlenium list-processes --name notepad --format json
# List all windows belonging to a process
winlenium list-windows --pid 12345
Inspect the accessibility tree
# Show the first two levels of a window's element tree
winlenium inspect --window-name "Untitled - Notepad" --depth 2
# Inspect a specific element
winlenium inspect --name "Text Editor" --window-name "Untitled - Notepad"
Interact with UI controls
# Click a button
winlenium click --name "Submit" --controltype Button --window-name "My App"
# Toggle a checkbox
winlenium toggle --name "Enable feature" --window-name "Settings"
# Select a tab or list item
winlenium select --name "Advanced" --window-name "Settings"
# Expand a tree node
winlenium expand --name "Documents" --window-name "Explorer"
# Set a slider or text field value directly (no keystrokes)
winlenium set-value --name "Volume" --value "75" --window-name "Settings"
Read element state
# Check if a button is enabled
winlenium get-property --name "Submit" --property IsEnabled --window-name "My App"
# Read the current value of a text field
winlenium get-value --name "Username" --window-name "Login"
Mouse actions
# Hover over an element
winlenium move --name "Help" --hover --window-name "My App"
# Drag and drop
winlenium move --name "DragItem" --to-name "DropTarget" --window-name "My App"
# Scroll down three increments
winlenium scroll --name "ItemList" --direction down --amount 3 --window-name "My App"
Screenshots
# Capture a window screenshot to a file
winlenium screenshot --window-name "My App" --output screenshot.png
# Capture a specific element
winlenium screenshot --name "Chart" --window-name "Dashboard" --output chart.png
Window management
# Bring a window to the foreground
winlenium focus --window-name "Notepad"
# Minimize / maximize / restore
winlenium window minimize --window-name "Notepad"
winlenium window maximize --window-pid 12345
winlenium window restore --window-handle 0x1A2B3C
# Close a window gracefully
winlenium close --window-name "Save As"
# Force-terminate a process
winlenium close --pid 12345 --force
Clipboard
winlenium clipboard set --text "Copied text"
winlenium clipboard get
Tray icons
# List all tray icons
winlenium tray list --format json
# List only visible tray icons
winlenium tray list --area visible
# Click a tray icon by name substring
winlenium tray click --name "Volume"
# Right-click a tray icon to open its context menu
winlenium tray click --name "Volume" --button right
# Inspect a tray icon's accessibility tree
winlenium tray inspect --name "Volume" --format json
Context menus
# Right-click an element to open its context menu
winlenium click --name "TextArea" --window-name "Notepad" --button right
# Click a menu item in the popup (WinUI apps keep menus inside the window)
winlenium click --name "Undo" --controltype MenuItem --window-pid 12345
# Double-click an element
winlenium click --name "Word" --button left --count 2
Modal dialogs
# Trigger a dialog (e.g. Save As in Notepad)
winlenium key --keys "Ctrl+Shift+S" --window-name "Notepad"
# Wait for the dialog to appear inside the parent window
winlenium wait --name "Save as" --controltype Window \
--window-handle 0x4303e4 --timeout 5000
# Discover the dialog handle via inspect (look for is_modal=true)
winlenium inspect --window-handle 0x4303e4 --format json --depth 1
# Interact with controls inside the dialog, scoped by its handle
winlenium type --name "File name:" --text "demo.txt" --window-handle 0x3b03e2
winlenium click --name "Save" --window-handle 0x3b03e2
# Wait for the dialog to disappear
winlenium wait --name "Save as" --controltype Window \
--window-handle 0x4303e4 --until gone --timeout 5000
Wait for elements
# Wait for an element to appear (default)
winlenium wait --name "Success" --window-name "My App" --timeout 10000
# Wait for a dialog to disappear
winlenium wait --name "Loading" --until gone --timeout 15000
Output Formats
Commands that produce output accept --format text (default) or
--format json:
# Human-readable text output
winlenium inspect --window-name "Notepad"
# Machine-readable JSON for scripting
winlenium inspect --window-name "Notepad" --format json
Exit Codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Error (element not found, invalid selector, etc.) |
2 |
Timeout (element did not appear within the limit) |
Agentic Usage Examples
The original idea behind Winlenium was to let AI agents automate tedious manual testing on Windows. Instead of writing test scripts by hand, you describe a scenario in natural language and let the agent drive the GUI through the CLI.
The examples below use Codex as the agent, but any AI agent that can call a CLI will work the same way.
See the examples directory for full reports generated by these scenarios.
In every scenario the first step is the same: the agent learns the available
commands by running uvx winlenium --help and
uvx winlenium <command> --help, and then carries out the task.
Application Walkthrough
Ask the agent to navigate through an application and produce a Markdown document that describes every screen, lists available options, and includes screenshots.
Example prompt:
Learn what Winlenium can do by running `uvx winlenium --help` and
`uvx winlenium <command> --help`. Then launch [Your App], navigate through
every screen and dialog, and build a Markdown document that:
- Lists each screen with a description of available options and controls.
- Includes a full-window screenshot of every screen.
- Includes close-up screenshots of individual noteworthy elements.
Save the document as walkthrough.md and screenshots in a screenshots/ folder.
Do not automate the process, just go manually and use winlenium to interact with the app.
Run it with Codex:
codex exec --yolo "Learn what Winlenium can do by running 'uvx winlenium --help' and 'uvx winlenium <command> --help'. Then launch [Your App], navigate through every screen and dialog, and build a Markdown document that lists each screen with a description of available options and controls, includes a full-window screenshot of every screen, and close-up screenshots of noteworthy elements. Save the document as walkthrough.md and screenshots in a screenshots/ folder. Do not automate the process, just go manually and use winlenium to interact with the app."
Accessibility Audit
Ask the agent to navigate through an application, evaluate it from a screen reader user's perspective, and compile a detailed accessibility report.
Example prompt:
Learn what Winlenium can do by running `uvx winlenium --help` and
`uvx winlenium <command> --help`. Then launch [Your App] and perform an
accessibility audit. Navigate through every screen and dialog and for each
screen inspect the UI Automation tree and check how usable it is for a person
relying on a screen reader. Compile a report where every issue includes:
1. The screen where the issue occurs.
2. The exact Winlenium command to inspect the problematic element.
3. A screenshot of the screen and, if possible, of the problematic element
itself.
Save the report as accessibility-audit.md and screenshots in a screenshots/
folder.
Do not automate the process, just go manually and use winlenium to interact
with the app.
Run it with Codex:
codex exec --yolo "Learn what Winlenium can do by running 'uvx winlenium --help' and 'uvx winlenium <command> --help'. Then launch [Your App] and perform an accessibility audit. Navigate through every screen and dialog and for each screen inspect the UI Automation tree and check how usable it is for a screen reader user. Compile a report where every issue includes the screen, the exact Winlenium command to inspect the problematic element, and screenshots. Save the report as accessibility-audit.md and screenshots in a screenshots/ folder. Do not automate the process, just go manually and use winlenium to interact with the app."
Test Case Automation
Ask the agent to execute a manual test case against your application: launch it, perform the described steps, verify expected outcomes, and produce a pass/fail report with screenshots.
Example prompt:
Learn what Winlenium can do by running `uvx winlenium --help` and
`uvx winlenium <command> --help`. Then execute the following test case
against [Your App]:
1. Launch the application.
2. Open Settings and enable the "Dark mode" toggle.
3. Verify the title bar background color changed.
4. Disable the toggle and verify it reverts.
For each step, take a screenshot. Produce a Markdown report with
pass/fail status for every step, the Winlenium commands used, and
the screenshots.
Save the report as test-report.md and screenshots in a screenshots/ folder.
Run it with Codex:
codex exec --yolo "Learn what Winlenium can do by running 'uvx winlenium --help' and 'uvx winlenium <command> --help'. Then execute the following test case against [Your App]: 1. Launch the application. 2. Open Settings and enable the Dark mode toggle. 3. Verify the title bar background color changed. 4. Disable the toggle and verify it reverts. For each step, take a screenshot. Produce a Markdown report with pass/fail status for every step, the Winlenium commands used, and the screenshots. Save the report as test-report.md and screenshots in a screenshots/ folder."
Documentation
- Development guide — setup, testing, and contribution workflow
- Changelog
- LLM agent rules
- Agentic workflows examples
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file winlenium-0.3.0.tar.gz.
File metadata
- Download URL: winlenium-0.3.0.tar.gz
- Upload date:
- Size: 28.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77da8e71e8c59d14a99bee7f2f5aa99be678e068ad67f404ae3ca1fc9bc1b482
|
|
| MD5 |
6cef8cbb8301799a7ebadb834c10809f
|
|
| BLAKE2b-256 |
d33747044b2df8a283cce60eeef8ba991bde50288541901ad891b20e727291b0
|
File details
Details for the file winlenium-0.3.0-py3-none-any.whl.
File metadata
- Download URL: winlenium-0.3.0-py3-none-any.whl
- Upload date:
- Size: 46.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a68b553e5884126a9e08f427fc9d2801fd0d4928665dee7b2362b127eeeb498d
|
|
| MD5 |
7af4c4d8606bed1a1678f47b7380ff9c
|
|
| BLAKE2b-256 |
471423b2c47300ff7d1dbf24529008c704c351cf7c9e1e815e410f5c981cdfc6
|