Skip to content

Element

Element is a lazy selector bound to a device: nothing is looked up until an action or query runs, and each one needs exactly one match. element.wait() returns an ElementWait. Guide: Elements and text, Gestures, Waits.

Element

A selector bound to a device.

Nothing is resolved until a method is called; every call sends the selector to the device again, so an Element can be kept for the whole test. Actions require exactly one match and raise CommandError (AMBIGUOUS/NOT_FOUND) before any input otherwise.

Methods:

Name Description
exists

True when at least one node matches right now (any number of matches is fine).

count

Matches in the selector's scope right now, ignoring its match limit.

snapshot

State of the one matching node at this instant (AMBIGUOUS/NOT_FOUND otherwise).

text

Raw accessibility text of the one matching node, or None when it has none. On API 26+

is_enabled

snapshot().enabled of the one matching node.

is_checked

snapshot().checked of the one matching node.

tap

Click at the centre of the one matching node's visible bounds.

long_tap

Long click on the one matching node.

double_tap

Two taps at the centre of the one matching node's visible bounds, inside Android's

ime_action

Run the one matching text field's keyboard action (Search, Go, Send, Done, … as the

perform_action

Perform a standard accessibility action on the one matching node, as a screen

perform_custom_action

Perform the custom accessibility action labelled label (exactly) on the one matching

set_progress

Set the one matching range node (SeekBar, Slider, RatingBar) to value in its own

drag_to

Press the one matching node until it is a long press, move the finger to the centre of

pinch_open

Two fingers moving apart from the one matching node's centre, across percent of its size.

pinch_close

Two fingers moving together towards the one matching node's centre, across percent of its size.

fling

One fast swipe across the one matching node towards direction's content edge (as for

set_text

Accessibility text replacement (ACTION_SET_TEXT) on the one matching node.

type_text

Tap the one matching node, wait until it reports focus, then type value.

clear_text

set_text(""): ACTION_SET_TEXT on the one matching node, not read back.

swipe

One swipe gesture across the node in the direction the finger moves (UP/DOWN/LEFT/RIGHT).

scroll

One scroll gesture on the one matching node towards direction's content edge

scroll_until

Client-side loop: checks whether target exists inside this container

wait

An ElementWait on this selector (default timeout timeouts.wait).

descendant

The node matching other somewhere below this one.

child

The direct child of this node matching other.

first

Accept the first match in accessibility order instead of requiring exactly one.

at

Accept the index-th match (0-based) in accessibility order.

device

device: Device

The device this element is looked up on.

selector

selector: Selector

The selector resolved again by every action.

exists

exists(timeout: float | None = None) -> bool

True when at least one node matches right now (any number of matches is fine).

count

count(timeout: float | None = None) -> int

Matches in the selector's scope right now, ignoring its match limit.

snapshot

snapshot(timeout: float | None = None) -> ElementSnapshot

State of the one matching node at this instant (AMBIGUOUS/NOT_FOUND otherwise).

text

text(timeout: float | None = None) -> str | None

Raw accessibility text of the one matching node, or None when it has none. On API 26+ an empty field reports its hint here; snapshot().showing_hint says so.

is_enabled

is_enabled(timeout: float | None = None) -> bool

snapshot().enabled of the one matching node.

is_checked

is_checked(timeout: float | None = None) -> bool

snapshot().checked of the one matching node.

tap

tap(timeout: float | None = None) -> None

Click at the centre of the one matching node's visible bounds.

long_tap

long_tap(timeout: float | None = None) -> None

Long click on the one matching node.

double_tap

double_tap(timeout: float | None = None) -> None

Two taps at the centre of the one matching node's visible bounds, inside Android's double-tap window.

ime_action

ime_action(timeout: float | None = None) -> None

Run the one matching text field's keyboard action (Search, Go, Send, Done, … as the app configured it) exactly as the keyboard's action key does, through accessibility ACTION_IME_ENTER. API 30+: older devices raise CommandError (UNSUPPORTED / REQUIRES_API_30) before any input, since pressing Enter is not equivalent. The field must have input focus (tap it first): Android offers the action only then, and a node that does not offer it raises ACTION_REJECTED before any input.

perform_action

perform_action(action: StandardAction, timeout: float | None = None) -> None

Perform a standard accessibility action on the one matching node, as a screen reader does: no touch, so a covered node is no obstacle. The node must offer it (snapshot().actions); otherwise CommandError (ACTION_REJECTED / ACTION_NOT_OFFERED) before any input. A node that refuses an offered action is ACTION_REJECTED. Only Android's answer is reported: assert what the app did.

perform_custom_action

perform_custom_action(label: str, timeout: float | None = None) -> None

Perform the custom accessibility action labelled label (exactly) on the one matching node: the "Archive" or "Delete" a list item offers screen reader users instead of a swipe (snapshot().custom_actions). Not offered, or offered twice under that label: ACTION_REJECTED / ACTION_NOT_OFFERED before any input.

set_progress

set_progress(value: float, timeout: float | None = None) -> None

Set the one matching range node (SeekBar, Slider, RatingBar) to value in its own units (snapshot().range) through accessibility ACTION_SET_PROGRESS: exact, where a drag would land on whatever pixel maps to. A node without the action, or a value outside its min..max, is ACTION_REJECTED (ACTION_NOT_OFFERED / OUT_OF_RANGE) before any input; the view is not left to clamp it.

drag_to

drag_to(destination: Selector, timeout: float | None = None) -> None

Press the one matching node until it is a long press, move the finger to the centre of the one node matching destination (resolved on the same screen, before any input), hold there briefly and lift. Nothing is reported about what the app did with the drop.

pinch_open

pinch_open(percent: int = DEFAULT_GESTURE_PERCENT, timeout: float | None = None) -> None

Two fingers moving apart from the one matching node's centre, across percent of its size.

pinch_close

pinch_close(percent: int = DEFAULT_GESTURE_PERCENT, timeout: float | None = None) -> None

Two fingers moving together towards the one matching node's centre, across percent of its size.

fling

fling(direction: Direction, timeout: float | None = None) -> None

One fast swipe across the one matching node towards direction's content edge (as for scroll: DOWN flings towards content below). Returns once the finger lifts; the content may keep moving, so wait for what you need next.

set_text

set_text(value: str, timeout: float | None = None) -> None

Accessibility text replacement (ACTION_SET_TEXT) on the one matching node.

Fails with ACTION_REJECTED only when the node refuses the action. The field is not read back: assert the effect with a selector that survives the edit, e.g. app.wait(res("email")).text_equals("new").

type_text

type_text(value: str, await_focus: bool = True, timeout: float | None = None) -> None

Tap the one matching node, wait until it reports focus, then type value.

Three steps (tap, wait().focused() when await_focus, Device.type_text), so a failure says which one failed. Pass await_focus=False when focus goes elsewhere (a child or a separate input view) and wait for what that app needs yourself. The field is not read back: assert the effect yourself.

clear_text

clear_text(timeout: float | None = None) -> None

set_text(""): ACTION_SET_TEXT on the one matching node, not read back.

swipe

swipe(direction: Direction, distance_percent: int = DEFAULT_GESTURE_PERCENT, timeout: float | None = None) -> None

One swipe gesture across the node in the direction the finger moves (UP/DOWN/LEFT/RIGHT).

scroll

scroll(direction: Direction, distance_percent: int = DEFAULT_GESTURE_PERCENT, timeout: float | None = None) -> None

One scroll gesture on the one matching node towards direction's content edge (UiAutomator semantics: DOWN reveals content below). Nothing is reported about whether content moved; observe that with a query or wait.

scroll_until

scroll_until(target: Selector, direction: Direction = DOWN, max_scrolls: int = 20, distance_percent: int = DEFAULT_GESTURE_PERCENT, timeout: float | None = None) -> Element

Client-side loop: checks whether target exists inside this container (descendant) and, while it does not, scrolls once, up to max_scrolls scrolls within timeout seconds (default: the device's wait timeout). Returns the target as a lazy element scoped to this container, so a later action cannot hit a duplicate elsewhere on screen; a container with first()/at() cannot be carried into a relation, and then the bare target is used.

Raises WaitTimeoutError when the target never appeared. The list may have scrolled by then. Every step is an ordinary command, so a failing step raises its own CommandError.

wait

wait(timeout: float | None = None) -> ElementWait

An ElementWait on this selector (default timeout timeouts.wait).

descendant

descendant(other: Selector) -> Element

The node matching other somewhere below this one.

child

child(other: Selector) -> Element

The direct child of this node matching other.

first

first() -> Element

Accept the first match in accessibility order instead of requiring exactly one.

at

at(index: int) -> Element

Accept the index-th match (0-based) in accessibility order.

ElementWait

Returned by Device.wait / Element.wait. visible and gone poll on the device in a single RPC; property waits poll snapshots from the host.

Methods:

Name Description
visible

Wait until at least one node matches; polled on the device in one RPC. A timeout's

one

Wait until exactly one node matches — what a mutation such as tap() needs; polled

gone

Wait until no node matches; polled on the device in one RPC. A timeout's reason is

enabled

Wait until the one matching node is enabled.

disabled

Wait until the one matching node is disabled.

checked

Wait until the one matching node is checked.

unchecked

Wait until the one matching node is unchecked.

focused

Wait until the one matching node has focus.

text_equals

Wait until the one matching node's text equals expected.

text_contains

Wait until the one matching node's text contains part.

count

Wait until exactly expected nodes match.

device

device: Device

The device the wait runs on.

selector

selector: Selector

The selector being waited for.

timeout

timeout: float

How long each wait may take, in seconds.

visible

visible() -> Element

Wait until at least one node matches; polled on the device in one RPC. A timeout's reason is NO_MATCH.

one

one() -> Element

Wait until exactly one node matches — what a mutation such as tap() needs; polled on the device in one RPC. A timeout's reason is NO_MATCH or AMBIGUOUS with match_count from the last poll.

gone

gone() -> None

Wait until no node matches; polled on the device in one RPC. A timeout's reason is STILL_PRESENT with match_count.

enabled

enabled() -> Element

Wait until the one matching node is enabled.

disabled

disabled() -> Element

Wait until the one matching node is disabled.

checked

checked() -> Element

Wait until the one matching node is checked.

unchecked

unchecked() -> Element

Wait until the one matching node is unchecked.

focused

focused() -> Element

Wait until the one matching node has focus.

text_equals

text_equals(expected: str) -> Element

Wait until the one matching node's text equals expected.

text_contains

text_contains(part: str) -> Element

Wait until the one matching node's text contains part.

count

count(expected: int) -> Element

Wait until exactly expected nodes match.