Docs/Core Concepts/Smart Waiting

Smart Waiting

Learn how to wait for elements to appear, disappear, or change state using Sentience's intelligent waiting system. No more arbitrary sleep() delays or flaky tests.

Why Smart Waiting Matters

Web pages load asynchronously. Forms submit in the background. Modals fade in. Traditional approaches use fixed delays that are either too short (causing failures) or too long (wasting time).

The Problem with Fixed Delays

# Bad: arbitrary sleep
button.click()
time.sleep(5)  # Too long or too short?
next_element.click()  # Might not exist yet!

The Sentience Solution

# Good: wait for semantic condition
click(browser, submit_btn.id)
result = wait_for(browser, "role=heading text~'Success'", timeout=10.0)

if result.found:
    print("Form submitted successfully!")

Core Waiting Functions

wait_for()

Wait for an element matching a semantic query to appear:

from sentience import wait_for

# Wait for success message
result = wait_for(browser, "role=heading text~'Success'", timeout=10.0)

# Check result
if result.found:
    print(f"Found: {result.element.text}")
else:
    print("Element not found within timeout")

# Wait for loading to disappear
result = wait_for(
    browser,
    "role=status text~'Loading'",
    timeout=30.0,
    wait_for_disappear=True
)

Parameters:

Returns:

wait_for_condition()

Wait for a custom condition using a predicate function:

from sentience import snapshot, find, wait_for_condition

def has_items_in_cart():
    snap = snapshot(browser)
    cart_count = find(snap, "role=status text~'items'")
    if cart_count:
        # Extract number from text like "3 items"
        count = int(cart_count.text.split()[0])
        return count > 0
    return False

# Wait until cart has items
success = wait_for_condition(browser, has_items_in_cart, timeout=10.0)

if success:
    print("Cart has items!")

Common Patterns

Wait for Page Load

from sentience import SentienceBrowser, wait_for

with SentienceBrowser(api_key="sk_...") as browser:
    browser.page.goto("https://example.com")

    # Wait for main content to load
    result = wait_for(browser, "role=main", timeout=10.0)

    if result.found:
        print("Page loaded successfully!")
    else:
        print("Page failed to load")

Wait for Form Submission

from sentience import snapshot, find, click, wait_for

# Submit form
snap = snapshot(browser)
submit_btn = find(snap, "role=button text~'submit'")
click(browser, submit_btn.id)

# Wait for success or error message
success = wait_for(browser, "text~'success'", timeout=10.0)
error = wait_for(browser, "text~'error'", timeout=1.0)

if success.found:
    print("Form submitted successfully!")
elif error.found:
    print(f"Form error: {error.element.text}")
else:
    print("Form submission status unknown")

Wait for Loading to Complete

from sentience import click, wait_for

# Click button that triggers loading
click(browser, button.id)

# Wait for spinner to appear
wait_for(browser, "role=status text~'loading'", timeout=2.0)

# Wait for spinner to disappear
result = wait_for(
    browser,
    "role=status text~'loading'",
    timeout=30.0,
    wait_for_disappear=True
)

if result.found:
    print("Loading complete!")

Wait for Modal to Appear

from sentience import click, wait_for, find, snapshot

# Open modal
snap = snapshot(browser)
open_btn = find(snap, "role=button text~'open'")
click(browser, open_btn.id)

# Wait for modal
modal = wait_for(browser, "role=dialog", timeout=5.0)

if modal.found:
    # Interact with modal
    snap = snapshot(browser)
    close_btn = find(snap, "role=button text~'close'")
    click(browser, close_btn.id)

Wait for Element Count

from sentience import snapshot, query, wait_for_condition

def has_search_results():
    snap = snapshot(browser)
    results = query(snap, "role=article")
    return len(results) > 0

# Search and wait for results
type_text(browser, search_box.id, "wireless mouse")
press_key(browser, "Enter")

success = wait_for_condition(browser, has_search_results, timeout=10.0)

if success:
    snap = snapshot(browser)
    results = query(snap, "role=article")
    print(f"Found {len(results)} results")

Best Practices

1. Use Appropriate Timeouts

# Short timeout for expected fast operations
wait_for(browser, "role=alert", timeout=2.0)

# Longer timeout for slow operations
wait_for(browser, "text~'Processing complete'", timeout=60.0)

2. Always Check Return Values

# Good - check if element was found
result = wait_for(browser, "role=button text~'Next'", timeout=5.0)
if result.found:
    click(browser, result.element.id)
else:
    print("Next button not found")

# Avoid - assuming success
result = wait_for(browser, "role=button text~'Next'", timeout=5.0)
click(browser, result.element.id)  # Might crash if not found!

3. Combine with Error Handling

try:
    result = wait_for(browser, "role=heading text~'Success'", timeout=10.0)
    if result.found:
        print("Operation successful!")
    else:
        print("Success message not found")
except Exception as e:
    print(f"Error while waiting: {e}")

4. Use Semantic Queries for Robustness

# Good - semantic query (survives redesigns)
wait_for(browser, "role=button text~'continue'", timeout=5.0)

# Avoid - ID-based (breaks on changes)
wait_for(browser, "id=btn-continue-2024", timeout=5.0)

Configuration Options

wait_for() Options

ParameterTypeDescriptionDefault
querystringSemantic queryRequired
timeoutnumberMax wait time (seconds)Required
wait_for_disappearbooleanWait for disappearancefalse
poll_intervalnumberCheck interval (seconds)0.5

wait_for_condition() Options

ParameterTypeDescriptionDefault
conditionfunctionPredicate functionRequired
timeoutnumberMax wait time (seconds)Required
poll_intervalnumberCheck interval (seconds)0.5

Next Steps