Skip to main content
The wait command polls for an element matching specified filters, blocking until the element appears or a timeout is reached.

Overview

agent-native wait <app> [options]
This command is essential for handling dynamic UIs, page loads, and asynchronous operations where elements may not be immediately available.

Arguments

app
string
required
Application name or bundle identifier

Options

--role
string
Filter by accessibility role
--title
string
Filter by title (substring match)
--label
string
Filter by label (substring match)
--identifier
string
Filter by identifier (substring match)
--timeout
number
default:"10.0"
Maximum time to wait in seconds
--interval
number
default:"0.5"
Polling interval in seconds (how often to check)
--format
string
default:"text"
Output format: text or json

Examples

Wait for button to appear

agent-native wait Safari --role Button --title "Continue"
Output:
Found: Button "Continue"

Wait for alert dialog

agent-native wait MyApp --role Alert --timeout 5

Wait with custom interval

agent-native wait Safari --role StaticText --label "Loading" --interval 0.1 --timeout 30

JSON output

agent-native wait Slack --role Button --title "Send" --format json
Output:
{
  "found": true,
  "element": {
    "role": "AXButton",
    "title": "Send",
    "label": null,
    "value": null,
    "enabled": true,
    "path": "Application/Window[0]/Group[2]/Button[1]",
    "actions": ["AXPress"],
    "childCount": 0
  }
}

Common use cases

Wait for page load

# Navigate to page
agent-native fill @n5 "https://example.com"
agent-native key Safari return

# Wait for page to load
agent-native wait Safari --role StaticText --title "Welcome" --timeout 15

Wait for dialog to appear

# Trigger action that shows dialog
agent-native click @n10

# Wait for dialog
agent-native wait MyApp --role Alert --timeout 5

# Interact with dialog
agent-native click MyApp --role Button --title "OK"

Wait for async operation

# Start upload
agent-native click @n15

# Wait for success message
agent-native wait MyApp --role StaticText --label "Success" --timeout 60

# Verify result
MESSAGE=$(agent-native get text MyApp --role StaticText --label "Success")
echo "Operation result: $MESSAGE"

Wait for element to be ready

# Wait for button
agent-native wait Safari --role Button --title "Submit"

# Wait a bit more for it to be enabled (if needed)
sleep 0.5

# Check if enabled before clicking
if [ "$(agent-native is enabled Safari --role Button --title Submit)" = "true" ]; then
  agent-native click Safari --role Button --title "Submit"
fi

Timeout behavior

When the timeout is reached without finding the element:
agent-native wait Safari --role Button --title "NonExistent" --timeout 2
Output:
Error: No element matching [role=Button, title=NonExistent] found within 2.0s
Exit code: non-zero

Error handling in scripts

Basic error handling

#!/bin/bash

if agent-native wait MyApp --role Button --title "Continue" --timeout 10; then
  echo "Button appeared, continuing..."
  agent-native click MyApp --role Button --title "Continue"
else
  echo "Timeout: Button did not appear"
  exit 1
fi

Retry logic

#!/bin/bash

MAX_RETRIES=3
COUNT=0

while [ $COUNT -lt $MAX_RETRIES ]; do
  if agent-native wait MyApp --role Alert --timeout 5; then
    echo "Alert appeared"
    break
  else
    echo "Attempt $((COUNT+1)) failed, retrying..."
    COUNT=$((COUNT+1))
    
    # Trigger action again
    agent-native click @n10
  fi
done

if [ $COUNT -eq $MAX_RETRIES ]; then
  echo "Failed after $MAX_RETRIES attempts"
  exit 1
fi

Fallback actions

#!/bin/bash

# Try to wait for success message
if agent-native wait MyApp --role StaticText --label "Success" --timeout 10; then
  echo "Operation succeeded"
elif agent-native wait MyApp --role StaticText --label "Error" --timeout 2; then
  ERROR=$(agent-native get text MyApp --role StaticText --label "Error")
  echo "Operation failed: $ERROR"
  exit 1
else
  echo "Unknown state: timeout waiting for result"
  exit 2
fi

Performance considerations

Polling interval

The --interval option controls how often the command checks for the element:
# Check every 100ms for quick responses
agent-native wait MyApp --role Button --title "OK" --interval 0.1
Use for:
  • Quick UI updates
  • Animations
  • Immediate feedback
Very small intervals (< 0.1s) may impact system performance without meaningful speed gains.

Timeout tuning

Choose appropriate timeouts based on expected operation duration:
# Quick operations (UI animations)
agent-native wait MyApp --role Button --title "Next" --timeout 2

# Normal operations (page transitions)
agent-native wait Safari --role WebArea --timeout 10

# Slow operations (network requests)
agent-native wait MyApp --role StaticText --label "Complete" --timeout 30

# Very slow operations (file uploads, processing)
agent-native wait MyApp --role Button --title "Done" --timeout 120

Advanced patterns

Wait for element to disappear

#!/bin/bash

# Wait for loading spinner to appear
agent-native wait MyApp --role ProgressIndicator --timeout 5

# Then wait for it to disappear by polling
while agent-native find MyApp --role ProgressIndicator --max 1 2>/dev/null | grep -q "Found 1"; do
  echo "Still loading..."
  sleep 0.5
done

echo "Loading complete"

Wait for multiple conditions

#!/bin/bash

# Wait for either success or error
while true; do
  if agent-native wait MyApp --role StaticText --label "Success" --timeout 1 2>/dev/null; then
    echo "Success!"
    break
  elif agent-native wait MyApp --role StaticText --label "Error" --timeout 1 2>/dev/null; then
    echo "Error occurred"
    exit 1
  fi
  
  ELAPSED=$((ELAPSED + 1))
  if [ $ELAPSED -gt 30 ]; then
    echo "Timeout after 30 seconds"
    exit 2
  fi
done

Wait with progress indication

#!/bin/bash

echo -n "Waiting for dialog"
START=$(date +%s)

while ! agent-native wait MyApp --role Alert --timeout 1 2>/dev/null; do
  echo -n "."
  NOW=$(date +%s)
  ELAPSED=$((NOW - START))
  
  if [ $ELAPSED -gt 30 ]; then
    echo " timeout!"
    exit 1
  fi
done

echo " appeared!"

Tips

Use specific filters to avoid matching unintended elements. Combine multiple filters for precision.
Set realistic timeouts based on your application’s behavior. Too short causes false failures; too long wastes time.
For very dynamic UIs, consider using --interval 0.1 or lower to catch short-lived elements.
The wait command returns immediately when the element is found - you don’t always wait the full timeout.
  • find - Search for elements without waiting
  • snapshot - Create element reference map
  • is enabled - Check if element is interactive
  • get text - Read element content after waiting

Build docs developers (and LLMs) love