Skip to content

Element API

AXApp

Represents a connected application. Create via ax.app().

Properties

Property Type Description
pid int Process ID
bundle_id str \| None Bundle identifier (e.g., "com.apple.Safari")

Methods

find(query, timeout_ms=None)

Find a single element.

element = app.find("Save", timeout_ms=5000)

Parameters:

Name Type Description
query str Search query (title, role:X, identifier:X, or role:X title:Y)
timeout_ms int \| None Timeout in milliseconds (retry until found or timeout)

Returns: AXElement

Raises: RuntimeError if not found


find_by_role(role, title=None, identifier=None, label=None)

Find an element by accessibility role with optional attribute filters.

button = app.find_by_role("AXButton", title="Save")

Returns: AXElement


wait_for_element(query, timeout_ms=5000)

Poll until a matching element appears or timeout expires.

button = app.wait_for_element("Done", timeout_ms=5000)

Returns: AXElement

Raises: RuntimeError if element did not appear within timeout


wait_for_idle(timeout_ms=5000)

Wait for the application to become idle using EspressoMac SDK or heuristic fallback.

if app.wait_for_idle(timeout_ms=3000):
    print("App is idle")

Returns: bool


is_idle()

Non-blocking check if the application is currently idle.

Returns: bool


main_window()

Get the main window.

window = app.main_window()

Returns: AXElement


windows()

Get all windows of the application.

windows = app.windows()

Returns: list[AXElement]


screenshot()

Capture application screenshot.

png_bytes = app.screenshot()

Returns: bytes (PNG data)


is_running()

Check if application is still running.

Returns: bool


terminate()

Send SIGTERM to the application process.


AXElement

Represents a UI element (AXUIElementRef wrapper).

Properties

Property Type Description
role() str \| None Accessibility role (e.g., "AXButton")
title() str \| None Element title/label
value() str \| None Current value
description() str \| None Accessibility description
label() str \| None Accessibility label
identifier() str \| None Accessibility identifier
enabled() bool Is element enabled
focused() bool Is element focused
exists() bool Is element still present in UI
bounds() tuple \| None (x, y, width, height) in screen points

Actions

click(mode=None)

Click the element. Default mode is BACKGROUND.

element.click()  # Background (default)
element.click(mode=ax.FOCUS)  # Focus mode

double_click(mode=None)

Double-click the element (two presses with 50ms gap).

element.double_click()

right_click(mode=None)

Right-click (triggers AXShowMenu to open contextual menu).

element.right_click()

type_text(text, mode=None)

Type text into element. Defaults to FOCUS mode (text input requires focus).

element.type_text("Hello World!")

Warning

Text input requires focus mode. Passing BACKGROUND explicitly will raise RuntimeError.


set_value(value)

Set element value directly via AXValue attribute. Works in background mode.

element.set_value("New value")

find(query, timeout_ms=None)

Find a descendant element within this element.

button = toolbar.find("Save")

screenshot()

Capture element screenshot (bounding rect only).

png_bytes = element.screenshot()

Returns: bytes (PNG data)