Stable Refs
When you runbap observe, each interactive element gets a stable ref like @submitBtn or @e7f3a2:
@submitbtn works whether you observed the page 1 second or 30 seconds ago, even if the DOM shifted.
Identity Signals
BAP uses a priority-ordered set of signals to identify elements:HTML id
Fairly stable, but can be auto-generated by frameworks.
Element: <input id="email-field" /> Ref: @emailfieldaria-label
Human-readable, good for accessibility-conscious apps.
Element:{" "} <button aria-label="Close dialog">X</button> Ref: @closedialogRef Generation
ThegenerateStableRef() function follows this priority:
@ prefix distinguishes stable refs from positional e<N> refs.
Identity Comparison
BAP compares element identities using a weighted scoring system:| Signal | Weight | Description |
|---|---|---|
testId | 3 | Highest weight — developer-controlled |
id | 3 | High weight — usually stable |
ariaLabel | 2 | Medium-high — accessibility attribute |
role | 2 | Medium — ARIA role |
name | 2 | Medium — accessible name |
tagName | 1 | Low — HTML tag |
parentRole | 1 | Low — structural context |
siblingIndex | 1 | Low — position among siblings |
compareIdentities() function returns a confidence score between 0 and 1. A score of 1.0 means perfect match; a score below 0.5 suggests the elements are different.
PageElementRegistry
Each page maintains an element registry that maps stable refs to element info:Registry Lifecycle
- Created when a page is first observed
- Updated on each
bap observe— existing elements getlastSeenrefreshed, new elements are added - Preserved across session park/restore (dormant sessions keep registries)
- Cleaned up when entries go stale (not seen for 60 seconds)
Size Limits
The registry is capped at 2,000 entries per page (ELEMENT_REGISTRY_MAX_SIZE). When exceeded, the oldest entries by lastSeen are evicted first. This prevents unbounded memory growth on pages with heavy DOM churn.
Stale Entry Cleanup
ThecleanupStaleEntries() function runs in two phases:
- Time-based: Remove entries not seen for longer than
ELEMENT_STALE_THRESHOLD(60 seconds) - Size-based: If still over 2,000 entries, evict the oldest by
lastSeen
Self-Healing Selectors
When a primary selector fails (element moved or was removed), BAP tries fallback identity signals in order:data-testid(if available)aria-label+rolecombinationidattributenameattribute
resolveSelectorWithHealing() mechanism means agents can use the same ref across page navigations and dynamic content updates without manual correction.
Alternative Selectors
EachInteractiveElement returned by observe includes an alternativeSelectors array, ordered by reliability:
testIdselector (if element hasdata-testid)roleselector (ARIA role + name)id-based CSS selector (with special character escaping)textselectorcssselector (computed CSS path)