Selectors
A selector is how you tell the bot which element to act on: this button, that field, that cell. It’s the most important concept in browser (Browser) and desktop (Desktop) automation: without a good selector, the activity doesn’t know where to click or what to read, and the bot fails.
The good news is that you rarely ever write a selector by hand: you capture it by pointing the mouse with UI Discover. This page explains what a selector is and how it’s made, so you understand what you’re capturing, know how to adjust it when a page changes, and build selectors that don’t break over time.
What problem does it solve?
Section titled “What problem does it solve?”A web page or window does not have “fixed coordinates”: a button changes position if the window is enlarged, if a notice appears above it, or if the app is updated. Pointing by coordinates (click on pixel 320,540) is fragile: the first time something moves, the bot clicks in the wrong place.
A selector, on the other hand, identifies the element by what it is, not by where it is: “the button whose text is Save”, “the field whose id is usuario”. This way the bot finds it even if it has moved.
Anatomy of a selector
Section titled “Anatomy of a selector”A selector is a hierarchy of nodes, from the window or browser (the root) to the specific element you want to interact with (the sheet). Each node is a level of that hierarchy and has a type and attributes.
| Node type | Represents | Attribute examples |
|---|---|---|
wnd | A window of the operating system (the app, the browser) | app, title, cls |
webctrl | A web part (within the browser) | tag, id, aaname, name, type, idx |
frame | An iframe (page embedded within another) | src, name, idx |
ctrl | A native desktop control (button, field, list…) | controlType, automationId, name, idx |
In the UI Discover editor you see those nodes as cards: the last one (the • elemento) is the target, and the previous ones (• contexto) are its ancestors, which help locate it without ambiguity.
A selector also stores two auxiliary data that are automatically captured and serve as a safety net (we explain them in How to find the item):
- Backing CSS — a CSS selector for the element.
- XPath — the absolute path of the element in the document.
The attributes
Section titled “The attributes”An attribute is a clue to identify the element. You don’t need all of them: the fewer and more stable, the better. These are what a selector can use:
| Atributo | Significado | Contexto |
|---|---|---|
app | Window Executable (chrome.exe, notepad.exe) | window |
title | Window or page title | window |
cls | CSS (web) class or Win32 window class | ambos |
tag | Etiqueta HTML (BUTTON, INPUT, TABLE, TR, TD…) | web |
id | HTML element id attribute — most stable | web |
aaname | Accessible name: the visible text or aria-label of the element | web |
name | Atributo name del HTML (muy estable en formularios) | web |
type | Atributo type (submit, text, checkbox…) | web |
href | Destination of a link | web |
src | Origin of a frame or image | web |
idx | 1-based index between siblings of the same type (tiebreaker) | ambos |
controlType | UIA control type (Button, Edit, List…) | desktop |
automationId | Control AutomationId — most stable on desktop | desktop |
name | Nombre accesible del control de desktop | desktop |
Matching modes: the value of an attribute
Section titled “Matching modes: the value of an attribute”Here’s the part that makes a selector robust or brittle. The value of any attribute can be written in four ways, and choosing well is what prevents the bot from breaking when the text changes.
| Mode | How to write | Matches… | Example |
|---|---|---|---|
| Literal | The text as is | Exact match (case insensitive) | usuario |
| Wildcard | With * at the start, end or both | Any text at the * position | Pedido * matches Pedido 1024 |
| Expression | Empezando por = | Whatever expression returns when executing | = "fila-" + indice |
| Regex | Between bars /patrón/ | The regular expression pattern | /^Order-\d+$/ |
This is best understood with a real case:
- An invoice whose title is “Order 1024” today and “Order 1025” tomorrow. If you capture the literal
Pedido 1024, the selector works once and fails the next day. Change the value toPedido *and it will work always. - In a loop that loops through rows, the
idxattribute can be an expression:= fila + 1. Thus the same activity points to row 1, 2, 3… as the loop progresses. This is what turns a static selector into a dynamic one.
How to find the element (resolution order)
Section titled “How to find the element (resolution order)”When the activity runs, Zoan Automation tries to locate the element by trying strategies from most stable to most fragile, and sticks with the first one that works. Knowing this order helps you understand why a selector is good or bad — and it’s exactly what the Validate button in UI Discover measures.
In the browser, the order for each node is:
id→ the most stable.data-testid→ estable en apps modernas.name→ muy estable en formularios.aria-label→ preciso e independiente del idioma.placeholder→ for unlabeled fields.aaname(texto / nombre accesible).- CSS del nodo (
tag+cls+type). - Backup CSS (the security net captured by targeting).
- Absolute XPath → last resort, fragile to structure changes.
On the desktop the logic is parallel, prioritizing automationId and name of control over position.
Anchors: when the element has nothing of its own
Section titled “Anchors: when the element has nothing of its own”Sometimes the target element has no unique attributes: a field with no id, no name, no label — just a blank box next to the text “Last Name”. How to distinguish it from the other ten empty fields on the screen?
With an anchor: you locate the objective in relation to a reference element that is identifiable. “The field that is to the right of the LastName label.”
| Relationship | The goal is… |
|---|---|
right_of | to the right of the anchor |
left_of | to the left of the anchor |
below | debajo del ancla |
above | encima del ancla |
nearest | closest to anchor (no direction) |
Each anchor has a maximum distance (in pixels, 250 by default): if there are no candidates within that radius in the given ratio, the anchor is not applied. You capture and set anchors from UI Discover.
Best practices for robust selectors
Section titled “Best practices for robust selectors”- Capture, don’t write. Use UI Discover: point and click. Only adjust by hand what is necessary.
- Less is more. Remove attributes that do not provide uniqueness. A single
idis enough; addingcls,idxand position only makes it more fragile. - Prioriza lo estable:
id/automationId>name/aria-label/aaname> clases >idx/ XPath. - Use wildcards for text that changes. Any number, date or folio in a value → convert it to
*or regex. - Use anchors, not positions. Before setting
idx, look for stable nearby text. - Validate on the actual page. Press Validate and chase the green. Orange and purple are warnings that it will break soon.
- Refetch after a redesign. If the target application is updated, refetch the affected selectors; It’s faster than debugging bugs.
Next steps
Section titled “Next steps”- UI Discover — the tool to capture selectors by pointing the mouse.
- Browser — activities that use selectors on web pages.
- Desktop — activities that use selectors in Windows applications.
- Expressions — to construct dynamic attribute values.