Skip to content

Selectors ​

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

A selector tells Astra Scout which element on the screen a command should act on, for example the element to tapOn, assertVisible, copyTextFrom or scrollUntilVisible.

To find elements, Astra Scout reads the accessibility tree of the device. That is the list of elements the operating system describes to assistive tools such as VoiceOver, with each element's text, ID, and position. So a selector matches what a user sees, or what a developer has labeled in the app.

Astra Scout supports these selector fields on Android and iOS. You write selectors in flow YAML.

Support at a glance ​

SelectorAndroidiOSNotes
textYesYesMatched as a regex; must match the whole text.
idYesYesMatched as a regex.
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.
traitsNoNoIgnored. See Not supported.
cssNoNoWeb only. Astra Scout does not run web flows.

If a flow uses a field the current platform does not support, Astra Scout ignores that field and writes a warning in the run log, such as "checked" is not supported on ios. The step still runs with the remaining fields, so it may pick the wrong element.

Core selectors ​

Regex

text and id are read as regex (regular expressions): a pattern that describes text, for example .* means "any characters, any number of times". Use regex to match text that changes, such as Welcome back, .*. If the text you need has a special character such as $, [ or (, put a backslash (\) before it, for example \$99.

Platform specifics

  • Flutter: use visible text or a Semantics Label for text, and a Semantics Identifier for id. Astra Scout does not support Flutter Keys.
  • Android Compose: add Modifier.semantics { testTagsAsResourceId = true } so test tags work as id.

text ​

The text selector finds elements by the text shown on screen. On Android this includes contentDescription, and on iOS it includes accessibilityLabel (a description label the developer sets on the element).

  • Always a regex: every text is read as a regex and must match the whole text of the element.
  • Shorthand: skip the text key and pass a string directly to commands such as tapOn or assertVisible.
yaml
- tapOn: Login              # Shorthand (matches the exact text "Login")
- tapOn:
    text: ".*Continue.*"    # Regex: matches an element whose text contains "Continue"
- assertVisible: Submit     # Shorthand for visibility check

id ​

The id selector targets the identifier a developer sets on a view. Use it for content that changes, icons without text, and localized apps (where the visible text changes with the language).

  • Android: the resource ID.
  • iOS: 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 a coordinate on the screen. 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 find a view by its position or relationship to another view. Use them when several elements have the same name (like several "Buy" buttons), or when an element has no stable text or id but always sits 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 (children, grandchildren...), at any depth.

Usage tips

  • Combine fields: the positional selectors (above, below, leftOf, rightOf) compare coordinates on the screen. leftOf only means "to the left", not necessarily right next to or in line with the anchor. Combine them with id, text, enabled and so on to pick precisely: tapOn: { id: "icon", rightOf: "Settings", enabled: true }.
  • Pick a stable anchor: use the element that changes least, usually fixed text or a unique ID.

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 use the parent-child relationships in the accessibility tree, not 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 (children, grandchildren, and so on) 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 state. Use them to check that an element is ready, that a previous action changed its state, or to pick one element among several identical ones (for example the selected tab). The value is always true or false.

SelectorAndroidiOSDescription
enabledYesYesThe element can be tapped, or is grayed out.
selectedYesYesThe element is selected (tabs, segmented controls).
focusedYesYesThe element is receiving keyboard input.
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 whether the toggle is on or off. On iOS, check the element's visible text or value instead.

Dimension matchers ​

Dimension selectors match elements by their size on screen, in pixels.

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

Fixed pixel sizes break easily when a flow runs on devices with different screen resolutions. Combine width and height with other selectors, and set a wide enough tolerance.

width and height match the size (in pixels) that the accessibility tree reports:

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 allows a small difference, because a 100px button may report 99px or 101px depending on the screen scale. With tolerance: 5, an element whose size differs by at most 5 pixels from your value 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 two selector fields do not work in Astra Scout:

  • traits (text, long-text, square): Astra Scout ignores this field, so the step runs 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.

The commands that accept selectors are listed in the command reference.