Docs/Core Concepts/Action Execution

Action Execution

Learn how to interact with web pages using Predicate's realistic action execution. Predicate uses real mouse simulation and keyboard events, not just JavaScript DOM manipulation.

Why Realistic Actions Matter

Many websites detect and block simple JavaScript-based automation. Predicate uses real browser events to ensure your actions work on any website.

Traditional Approach (Often Blocked)

# JavaScript-only clicks - easily detected
element.click()  # Triggers only click event

# No mouse movement, no hover states
# Many sites detect this as a bot

Predicate Approach (Realistic)

# Real mouse simulation
click(browser, element_id)
# - Moves mouse to element
# - Triggers mouseover, mouseenter
# - Triggers mousedown, mouseup, click
# - Updates hover states

Core Actions

Click

Simulate a real mouse click with realistic events:

from predicate import snapshot, find, click

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

# Click with options
click

What Happens:

  1. Mouse moves to element center
  2. Triggers mouseover, mouseenter, mousemove
  3. Triggers mousedown
  4. Triggers mouseup
  5. Triggers click
  6. Element receives focus if applicable

Type Text

Type text with realistic keyboard events:

from predicate import snapshot, find, type_text

snap = snapshot(browser)
email_input = find(snap, "role=textbox text~'email'")
type_text(browser, email_input.id, "user@example.com")

Features:

Press Key

Press special keys and keyboard shortcuts:

from predicate import press_key

# Press Enter
press_key(browser, "Enter")

# Press Escape
press_key(browser, "Escape")

# Press Tab
press_key(browser, "Tab")

Hover

Move mouse over an element without clicking:

from predicate import snapshot, find, hover

snap = snapshot(browser)
menu = find(snap, "role=button text~'Products'")
hover(browser, menu.id)

# Dropdown menu appears
submenu

Common Patterns

Login Flow

from predicate import PredicateBrowser, snapshot, find, type_text, click

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

    snap = snapshot

Form Submission with Enter Key

# Fill search box and press Enter
snap = snapshot(browser)
search = find(snap, "role=textbox text~'search'")
type_text(browser, search.id, "wireless mouse")
press_key(browser, "Enter")
# Hover to reveal dropdown, then click
snap = snapshot(browser)
products_menu = find(snap, "role=button text~'Products'")
hover(browser, products_menu.id)

# Wait for dropdown to appear
snap = snapshot(browser)

Best Practices

1. Always Take Fresh Snapshots

# Good - fresh snapshot after each action
snap1 = snapshot(browser)
click(browser, button.id)
snap2 = snapshot(browser)  # Fresh snapshot

# Avoid - reusing stale snapshot
snap = snapshot(browser)
click(browser, button.id)
find(snap, "...")  # Snapshot is stale!

2. Check Element Exists Before Acting

snap = snapshot(browser)
button = find(snap, "role=button text~'submit'")

if button:
    click(browser, button.id)
else:
    print("Submit button not found")

3. Use Appropriate Delays for Realism

# Too fast - might trigger bot detection
type_text(browser, input.id, "text", delay=0)

# More realistic - 50-100ms between keystrokes
type_text(browser, input.id, "text", delay=75)

4. Handle Focus States

# Some forms require focus before typing
snap = snapshot(browser)
input_field = find(snap, "role=textbox text~'email'")

# Click to focus, then type
click(browser, input_field.id)
type_text(browser, input_field.id, "user@example.com")

Action Options

Click Options

OptionTypeDescriptionDefault
button'left' | 'right' | 'middle'Mouse button'left'
click_countnumberNumber of clicks1
delaynumberDelay between mousedown/mouseup (ms)0

Type Options

OptionTypeDescriptionDefault
delaynumberDelay between keystrokes (ms)0
clearbooleanClear field before typingfalse

Next Steps