Skip to content

Selectors ​

Identify UI elements with core, relational, and state selectors on Android and iOS.

Selectors identify the UI element a command acts on, for example the target of tapOn, assertVisible, copyTextFrom or scrollUntilVisible. Astra Scout uses the accessibility tree of the device to find elements, so your flows interact with the app the way a user would.

This page covers the selector fields that Astra Scout supports on Android and iOS. The syntax is identical to Maestro flow YAML.

Support at a glance ​

SelectorAndroidiOSNotes
textYesYesRegular expression, matches the whole text.
idYesYesRegular expression.
indexYesYes0-based.
pointYesYesCoordinates, used by tapOn and similar commands.
above, below, leftOf, rightOfYesYesPosition relative to an anchor.
childOf, containsChild, containsDescendantsYesYesHierarchy relations.
enabled, selected, focusedYesYesBoolean state.
checkedYesNoIgnored on iOS with a warning.
width, height, toleranceYesYesSize in pixels as reported by the accessibility tree.
traitsNoNoParsed but never matched. See Not supported.
cssNoNoWeb only; Astra Scout does not run web flows.

When a flow uses a selector field the current platform does not support, the field is ignored and the run log shows a warning such as "checked" is not supported on ios. The step then runs with the remaining fields, so it may match a different element than you expect.

Core selectors ​

Regular expressions

text and id are regex-based, so dynamic values are easy to handle. Remember to escape special characters such as $ or [ with a backslash (\).

Platform specifics

  • Flutter: Use visible text or Semantics Labels (for text), or Semantics Identifiers (for id). Internal Flutter keys are not supported.
  • Android Compose: Use Modifier.semantics { testTagsAsResourceId = true } so your test tags are discoverable as IDs.

text ​

The text selector finds elements by the string displayed on screen. On Android this includes contentDescription, and on iOS it includes accessibilityLabel.

  • Regex by default: every text selector is treated as a regular expression.
  • Shorthand: you can skip the key and pass a string directly to commands such as tapOn or assertVisible.
yaml
- tapOn: Login              # Shorthand (matches exactly "Login")
- tapOn:
    text: ".*Continue.*"    # Regex for partial match
- assertVisible: Submit     # Shorthand for visibility check

id ​

The id selector targets the technical identifier of a view. It is recommended for dynamic content, icons without text, and localized apps where the visible text changes with the language.

  • Android: maps to the resource ID.
  • iOS: maps to the accessibilityIdentifier.
yaml
- tapOn:
    id: login_button
- assertVisible:
    id: header_icon

index ​

When several elements match the same criteria (for example three Add to Cart buttons on one screen), index picks one. The index is 0-based.

yaml
# Taps the third element with the ID "buy_button"
- tapOn:
    id: buy_button
    index: 2

point ​

The point selector targets screen coordinates. Use it for elements that are not in the accessibility tree, or to tap a specific area of a large view.

  • Relative position: percentages, for example "50%, 50%" for the center.
  • Absolute coordinates: exact pixels, for example "100, 200".
yaml
- tapOn:
    point: "50%, 50%"   # Taps the center of the screen
- tapOn:
    point: "100, 250"   # Taps 100 pixels from the left, 250 from the top

Relational selectors ​

Relational selectors identify a view by its relationship to another view. They are useful when elements have generic names (like several "Buy" buttons) or lack a stable text or id but always sit near a known anchor.

SelectorDescription
aboveMatches a view located vertically above an anchor element.
belowMatches a view located vertically below an anchor element.
leftOfMatches a view located to the left of an anchor element.
rightOfMatches a view located to the right of an anchor element.
containsChildMatches a parent that has a direct child matching the given criteria.
childOfMatches an element that is a direct child of the given parent.
containsDescendantsMatches a view that contains all the given descendants, at any depth.

Usage tips

  • Compound selectors: the positional selectors (above, below, leftOf, rightOf) compare screen bounds. leftOf means "left of" by coordinate only, not necessarily next to or aligned with the anchor. Combine them with other fields (id, text, enabled, and so on) for precision: tapOn: { id: "icon", rightOf: "Settings", enabled: true }.
  • Anchor reliability: use the most stable element (typically static text or a unique ID) as the anchor.

Alignment selectors ​

above and below match views above or below a reference element:

yaml
# Tap a view located below the "Email" label
- tapOn:
    below: Email

# Tap a view located above the "Checkout" title
- tapOn:
    above: Checkout

leftOf and rightOf match views positioned side by side, such as icons next to labels:

yaml
# Tap the view to the right of an input field
- tapOn:
    rightOf:
      id: input_text

# Tap the view to the left of a specific phrase
- tapOn:
    leftOf: I agree to the terms

You can nest above or below to assert vertical order:

yaml
- assertVisible:
    text: Top Thing
    above:
      text: Middle Thing
      above:
        text: Bottom Thing

Parent-child relationships ​

These selectors navigate the accessibility tree instead of using screen position.

containsChild (direct child only) ​

Matches a parent that has a direct child matching the given selector.

yaml
# Tap the container that directly contains the text "Order 12345"
- tapOn:
    containsChild:
      text: Order 12345

childOf (direct parent only) ​

Matches an element that is a direct child of a specific parent. Useful when the same child exists in several containers.

yaml
# Tap the Delete button inside the Basket
- tapOn:
    text: Delete
    childOf:
      id: basket_container

containsDescendants ​

Matches a view that contains all the specified descendants at any depth, not only direct children. Use it for cards, rows and grouped layouts where the relevant elements are nested.

yaml
# Find a list item that contains both a product name and a price
- assertVisible:
    id: list_item
    containsDescendants:
      - text: Wireless Headphones
      - text: $99.99

State selectors ​

State selectors filter elements by their current status. Use them to check that an element is ready, that a previous action updated it, or to find one element among several identical ones (for example the selected tab). All state selectors take a boolean.

SelectorAndroidiOSDescription
enabledYesYesWhether the element is interactive or grayed out.
selectedYesYesWhether the element is marked as selected (tabs, segmented controls).
focusedYesYesWhether the element has keyboard input focus.
checkedYesNoToggle state of checkboxes, radio buttons and switches.

Usage tips

State selectors work best combined with core selectors, for example tapOn: { text: "Next", enabled: true }.

yaml
# Assert that the login button is disabled initially
- assertVisible:
    id: login_button
    enabled: false

# Tap the button once it becomes active
- tapOn:
    id: login_button
    enabled: true

# Verify that the search field has focus
- assertVisible:
    id: search_input
    focused: true

# Find the Profile tab only if it is the selected one
- tapOn:
    text: Profile
    selected: true

On Android, checked works for checkboxes, radio buttons and switches:

yaml
- assertVisible:
    id: remember_me_checkbox
    checked: true

WARNING

checked is not supported on iOS. The field is ignored with a warning, so the step matches regardless of the toggle state. On iOS, assert on the element's visible label or value instead.

Dimension matchers ​

Dimension selectors match elements by their size on screen.

SelectorDescription
widthMatches an element with a specific width in pixels.
heightMatches an element with a specific height in pixels.
toleranceAllows minor rendering or rounding differences when matching dimensions.

Usage tips

Be careful with hardcoded pixel values when you run flows on devices with different screen densities. Combine width and height with other selectors, and use a higher tolerance to keep flows stable across devices.

width and height match the pixel dimensions reported by the accessibility tree:

yaml
# Taps a button that is exactly 200px wide
- tapOn:
    id: action_button
    width: 200

# Asserts that the profile header has a height of 350px
- assertVisible:
    id: profile_header
    height: 350

tolerance sets a buffer, because a 100px button may report 99px or 101px depending on scaling. With tolerance: 5, any element within plus or minus 5 pixels of the target dimension matches.

yaml
# Matches an icon that is 48px square, with 2px of wiggle room
- assertVisible:
    id: settings_icon
    width: 48
    height: 48
    tolerance: 2

Not supported ​

These selector fields from Maestro are not available in Astra Scout:

  • traits (text, long-text, square): the field is parsed but not used for matching, so the step behaves as if it were absent. Use text, id, width/height with tolerance, or relational selectors instead.
  • css: for web apps only. Astra Scout runs Android and iOS flows.

For the commands that accept selectors, see the command reference.