Docs/SDK/Action API

Action API

Interact with elements on the page using clicks, typing, and keyboard input.

click() - Click by Element ID

Clicks an element by ID. Uses Playwright mouse click by default, with optional human-like cursor movement via CursorPolicy (NEW in 2026-01-15).

from predicate import click

result = click(browser, button.id)
if result.success:
    print(f"Click succeeded: {result.outcome}")
    if result.url_changed:
        print(f"Navigated to: {browser.page.url}")

Parameters:

Returns: ActionResult with:

Human-like Cursor Movement (CursorPolicy)

Use CursorPolicy(mode="human", ...) to move the cursor along a human-like path before clicking. This is useful for demos, bot-detection sensitive pages, and trace/debugging.

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

with PredicateBrowser() as browser:
    browser.page.goto("https://example.com")
    browser.page.wait_for_load_state("networkidle")

    snap = snapshot(browser)
    link = find(snap, "role=link")
    if not link:
        raise RuntimeError("No link found on page")

    policy = CursorPolicy(
        mode="human",
        steps=18,  # more steps => smoother
        duration_ms=350,
        jitter_px=1.2,
        overshoot_px=6.0,
        pause_before_click_ms=30,
        seed=123,  # optional: deterministic for demos/tests
    )

    result = click(browser, link.id, use_mouse=True, cursor_policy=policy)
    print("clicked:", result.success, "outcome:", result.outcome)
    print("cursor meta:", result.cursor)

click_rect() / clickRect() - Click by Coordinates

Clicks at the center of a rectangle. Shows visual feedback (red border).

from predicate import click_rect

# Click at specific coordinates
click_rect(browser, {"x": 100, "y": 200, "w": 50, "h": 30})

# Click using element's bounding box
snap = snapshot(browser)
element = find(snap, "role=button")
click_rect(browser, {
    "x": element.bbox.x,
    "y": element.bbox.y,
    "w": element.bbox.width,
    "h": element.bbox.height
})

# Without highlight (for headless/CI)
click_rect(browser, {"x": 100, "y": 200, "w": 50, "h": 30}, highlight=False)

Parameters:

type_text() / typeText() - Type into Input

Types text into an input field.

from predicate import type_text

# Find input and type
snap = snapshot(browser)
email_input = find(snap, "role=textbox")
type_text(browser, email_input.id, "user@example.com")

Parameters:

Human-like Typing

Use the delay_ms parameter to add realistic delays between keystrokes:

from predicate import type_text

# Instant typing (default)
type_text(browser, input.id, "Hello world")

# Human-like typing with 10ms delay between keystrokes
type_text(browser, input.id, "Hello world", delay_ms=10)

scroll_to() / scrollTo() - Scroll Element into View

Scrolls an element into view using the native browser scrollIntoView() API.

from predicate import scroll_to

# Scroll element to center of viewport with smooth animation
scroll_to(browser, element.id, behavior="smooth", block="center")

# Instant scroll to top of viewport
scroll_to(browser, element.id, behavior="instant", block="start")

Parameters:

Returns: ActionResult

press() - Keyboard Input

Presses a keyboard key (Enter, Escape, Tab, etc.).

from predicate import press

press(browser, "Enter")   # Submit form
press(browser, "Escape")  # Close modal

Parameters:

Returns: ActionResult

Complete Example

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

with PredicateBrowser(api_key="sk_...") as browser:
    browser.page.goto("https://example.com/login")
    
    # Take snapshot
    snap = snapshot(browser)
    
    # Find and fill email
    email_input = find(snap, "role=textbox")
    type_text(browser, email_input.id, "user@example.com")
    
    # Find and fill password
    snap = snapshot(browser)
    password_input = find(snap, "role=textbox", importance>500)
    type_text(browser, password_input.id, "password123")
    
    # Find and click submit button
    snap = snapshot(browser)
    submit_btn = find(snap, "role=button text~'Submit'")
    click(browser, submit_btn.id)
    
    # Or press Enter
    # press(browser, "Enter")