# ego-browser Locator Types: Complete Guide to Element Selection Methods

> Discover ego-browser locator types for element selection. Explore 11 methods like CSS, XPath, text matching, attributes, and ARIA roles for robust automation.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-08-04

---

**ego-browser supports 11 distinct locator types including CSS selectors, XPath expressions, text/label/placeholder matching, attribute-based locators (alt, title, href, testid), ARIA role queries, and internal scope filters, all parsed in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) by the `parseLocator` function.**

The `ego-browser` library from the `citrolabs/ego-lite` repository provides a flexible element selection system that accommodates multiple locator strategies within a unified syntax. Understanding the available **ego-browser locators** and their specific parsing rules allows you to target DOM elements precisely without brittle selection logic. Each locator string is processed by the `parseLocator` function in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) and transformed into executable JavaScript that runs within the browser context.

## How Locator Parsing Works

At the core of element resolution is the `parseLocator` function defined in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts). This parser examines the locator string and returns a structured object containing a `kind` property that determines which resolution strategy to apply. The parser handles prefix detection (such as `css:`, `xpath=`, or `text:`) and extracts relevant parameters like selector values, attribute names, or ARIA roles before generating the final JavaScript execution code through helper functions like `buildLocatorFindJs` and `buildLocatorCountJs`.

## Complete List of Supported Locator Types

### CSS Selectors

The most common locator type supports standard CSS selector syntax with an optional explicit prefix.

- **Explicit syntax**: `css:button.primary`
- **Implicit syntax**: `button.primary` (parsed as CSS when no other prefix matches)
- **With indexing**: Supports `nth=` or `last=` prefixes for zero-based indexing

According to the source code at lines 36-39, when `value.startsWith("css:")` is detected, the parser returns `{kind:"css", selector:…}`. If an `nth` prefix is present and no other locator type matches, the parser falls back to CSS resolution (lines 112-117).

### XPath Expressions

For complex DOM traversal or attribute-based queries that exceed CSS selector capabilities.

- **Syntax**: `xpath=//div[@role='button']`
- **Implementation**: Detected by `value.startsWith("xpath=")` (lines 112-117)
- **Output**: Returns `{kind:"xpath", xpath:…}` for direct XPath evaluation in the browser

### Text Content Locators

Target elements based on their visible text content with two precision modes.

- **Fuzzy match**: `text:Submit` (substring match)
- **Exact match**: `text=Submit` (strict equality)
- **Source location**: Lines 44-51 in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)

Both variants return `{kind:"text", …}` objects, but the exact match uses strict equality operators in the generated JavaScript while the fuzzy variant uses substring matching.

### Form Association Locators

Locate input elements by their associated labels or placeholder text.

**Label text** (lines 61-68):
- **Syntax**: `label:Username`
- Returns `{kind:"label", …}` to find inputs associated with the specified label text

**Placeholder** (lines 69-76):
- **Syntax**: `placeholder:Search…`
- Returns `{kind:"placeholder", …}` for input elements containing the specified placeholder attribute

### Attribute-Based Locators

Select elements by specific HTML attributes beyond standard IDs or classes.

**Alt attribute** (lines 77-84):
- **Syntax**: `alt:Logo`
- Targets images and other elements by their alternative text

**Title attribute** (lines 85-92):
- **Syntax**: `title:Welcome`
- Matches elements by their tooltip text

**Href** (lines 40-43):
- **Syntax**: `href:/login`
- Returns `{kind:"href", href:…}` for exact URL matching on anchor tags

**Test ID** (lines 93-100):
- **Syntax**: `testid:login-button`
- Returns `{kind:"testid", …}` for data-testid attribute selection (common in testing frameworks)

### ARIA Role Locators

Select elements by their accessibility role with optional accessible name filtering.

- **Syntax**: `role:button[name=Submit]`
- **Pattern**: `/^role:([A-Za-z0-9_-]+)(?:\[name=(.+)\])?$/`
- **Implementation**: Lines 101-111
- Returns `{kind:"role", role:…, name:…}` where the name parameter is optional

### Internal Query Locators

Reserved for internal scope filtering and component boundaries.

- **Syntax**: `internal:scope:…` or `internal:filter:…`
- **Implementation**: Lines 31-33
- Returns `{kind:"query", selector:…}` for internal use by other helper functions

## Practical Code Examples

The following examples demonstrate how to use each locator type with the `js()` helper function, which evaluates selectors in the browser context:

```typescript
// CSS selector (explicit)
await js('loc=css:button.primary');

// CSS selector (implicit)
await js('button.primary');

// XPath expression
await js('xpath=//div[@role="button"]');

// Link URL (exact match)
await js('href:/login');

// Text content (fuzzy match)
await js('text:Submit');

// Text content (exact match)
await js('text=Submit');

// Label association
await js('label:Username');

// Placeholder text
await js('placeholder:Search…');

// Alt attribute
await js('alt:Logo');

// Title attribute
await js('title:Welcome');

// Test ID attribute
await js('testid:login-button');

// ARIA role with accessible name
await js('role:button[name=Submit]');

// Internal scope query
await js('internal:scope:button.primary');

```

## Key Implementation Files

The locator system spans three primary files in the `ego-browser` package:

- **[`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)**: Contains the `parseLocator` function and all parsing logic referenced above, plus JavaScript code generation functions like `buildLocatorFindJs` and `buildLocatorCountJs`.
- **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)**: Exposes the public `js()` and `cdp()` helper functions that consume parsed locators and execute them in the browser context.
- **[`src/locator-query.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/locator-query.ts)**: Generates the DOM query expressions used by text, label, placeholder, and other content-based locator kinds.

## Summary

- **ego-browser** provides 11 distinct locator types parsed in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) by the `parseLocator` function.
- **CSS selectors** support both explicit (`css:`) and implicit syntax, with optional `nth=` or `last=` indexing prefixes.
- **Text matching** offers fuzzy (`text:`) and exact (`text=`) variants for content-based selection.
- **Attribute locators** include `label`, `placeholder`, `alt`, `title`, `href`, and `testid` for targeting specific HTML properties.
- **XPath expressions** support full DOM traversal via the `xpath=` prefix.
- **ARIA roles** support optional accessible name filtering via the `role:button[name=Submit]` syntax.
- All locators compile to JavaScript through `buildLocatorFindJs` and execute within the browser runtime.

## Frequently Asked Questions

### What is the difference between `text:` and `text=` in ego-browser?

The `text:` prefix performs a fuzzy substring match against element text content, while `text=` requires an exact string match. According to lines 44-51 in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts), both return a `kind:"text"` object, but the generated JavaScript uses different comparison operators—substring inclusion for `text:` and strict equality for `text=`.

### Can I use `nth` or `last` modifiers with any locator type?

The `nth=` and `last=` prefixes primarily target CSS selectors. When these prefixes are present and the value does not match other locator patterns (like `xpath=` or `href:`), the parser falls back to CSS resolution at lines 112-117. For other locator types like text or attributes, you typically filter results after retrieval rather than using index prefixes.

### How does ego-browser resolve ARIA role locators with accessible names?

The parser uses the regex `/^role:([A-Za-z0-9_-]+)(?:\[name=(.+)\])?$/` at lines 101-111 to extract the role and optional name parameter. If provided, the name filter matches against the element's accessible name computation, allowing precise targeting of buttons, links, or other widgets that share the same role but serve different functions.

### Which locator type should I use for data-testid attributes?

Use the `testid:` prefix (e.g., `testid:login-button`). As implemented at lines 93-100 in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts), this locator type specifically targets elements by their `data-testid` attribute, returning `{kind:"testid", …}` for robust test automation that avoids brittle CSS or XPath selectors.