> ## Documentation Index
> Fetch the complete documentation index at: https://piyushvyas.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Selectors

> 10 selector types for targeting elements by purpose, not position

BAP uses semantic selectors that describe elements by their purpose instead of their DOM position. They survive layout changes, dynamic content updates, and A/B tests.

## Selector Types

| Type               | Syntax                 | Example                   | When to use                                            |
| ------------------ | ---------------------- | ------------------------- | ------------------------------------------------------ |
| **Stable ref**     | `@<ref>`               | `@submitBtn`              | Refs returned by `bap observe` -- most precise         |
| **Positional ref** | `e<N>`                 | `e15`                     | From snapshot refs (playwright-cli compatible)         |
| **Role**           | `role:<role>:"<name>"` | `role:button:"Submit"`    | Interactive elements by ARIA role -- most reliable     |
| **Text**           | `text:"<content>"`     | `text:"Sign in"`          | By visible text content                                |
| **Label**          | `label:"<text>"`       | `label:"Email"`           | Form inputs by associated label                        |
| **Placeholder**    | `placeholder:"<text>"` | `placeholder:"Search..."` | Inputs by placeholder attribute                        |
| **Test ID**        | `testid:"<id>"`        | `testid:"submit-btn"`     | By `data-testid` -- most stable for apps that use them |
| **CSS**            | `css:<selector>`       | `css:.btn-primary`        | CSS selector (fallback)                                |
| **XPath**          | `xpath:<path>`         | `xpath://button[@type]`   | XPath selector (fallback)                              |
| **Coordinates**    | `coords:<x>,<y>`       | `coords:100,200`          | Click by pixel coordinates (last resort)               |

## Priority and Recommendations

<Steps>
  <Step title="Start with stable refs from observe">
    Run `bap observe` and use the exact `@ref` values it returns. These are the most precise selectors because they map to a specific element in the registry.

    ```bash theme={null}
    bap observe
    # Output: @ep44e3j  button  "Submit"
    bap click @ep44e3j
    ```
  </Step>

  <Step title="Use semantic selectors when the target is obvious">
    Role selectors are the most reliable for interactive elements. Label selectors are best for form fields.

    ```bash theme={null}
    bap click role:button:"Submit"
    bap fill label:"Email" "user@example.com"
    ```
  </Step>

  <Step title="Fall back to text selectors for links and content">
    `bash bap click text:"Learn more" bap click text:"Next page" `
  </Step>

  <Step title="Use CSS/XPath only when semantic selectors cannot match">
    ```bash theme={null}
    bap click css:.custom-widget-btn
    bap click xpath://div[@class='grid']//button[2]
    ```
  </Step>
</Steps>

## Using Selectors in Commands

### Single commands

```bash theme={null}
bap click role:button:"Submit"
bap fill label:"Email" "user@example.com"
bap hover text:"Learn more"
bap click @ep44e3j
bap click e15
```

### In composite actions (`bap act`)

The step syntax is `action:selector=value` for fill/type and `action:selector` for click/check/hover:

```bash theme={null}
bap act fill:label:"Email"="user@example.com" \
        fill:label:"Password"="secret123" \
        click:role:button:"Sign in"
```

### In the TypeScript SDK

```typescript theme={null}
import { role, text, label, testId } from "@browseragentprotocol/client";

await client.click(role("button", "Submit"));
await client.fill(label("Email"), "user@example.com");
await client.click(text("Sign in"));
await client.click(testId("submit-button"));
```

### In the Python SDK

```python theme={null}
from browseragentprotocol import role, text, label, test_id

await client.click(role("button", "Submit"))
await client.fill(label("Email"), "user@example.com")
await client.click(text("Sign in"))
await client.click(test_id("submit-button"))
```

### In MCP tools

```
selector: "role:button:Submit"
selector: "text:Sign in"
selector: "label:Email address"
selector: "testid:submit-button"
selector: "ref:@submitBtn"
```

## Role Selector Examples

The role selector uses ARIA roles, which cover most interactive elements:

```bash theme={null}
role:button:"Submit"         # Buttons
role:textbox:"Email"         # Text inputs
role:link:"Home"             # Links
role:heading:"Welcome"       # Headings
role:checkbox:"Remember me"  # Checkboxes
role:combobox:"Country"      # Dropdowns
role:searchbox:"Search"      # Search inputs
role:listitem:"Item 1"       # List items
```

## Disambiguation

When multiple elements match a selector, BAP returns the first visible, interactive match. To disambiguate:

1. Use a more specific role (e.g., `role:button:"Submit"` instead of `text:"Submit"`)
2. Run `bap observe --max=100` to see all candidates and use the exact `@ref`
3. Combine with CSS if needed: `css:#login-form button[type=submit]`

<Warning>
  Identical elements (e.g., six "Add to cart" buttons) produce ambiguous `text:Add to cart`
  selectors. Use the specific `@ref` from `bap observe` or a CSS selector with an ID to target the
  right one.
</Warning>

## Fallback Behavior

If a semantic selector does not match, BAP returns a clear error message with the closest matches found on the page, helping the agent self-correct.
