Element Selectors
Element selectors let a script describe the interface element it needs. Their syntax is similar to CSS: start with an element type, then narrow the result by title, state, or hierarchy.
const buttons = root.queryElements('Button[title="Save"]');In most cases, begin by selecting the target in Element Menu Mode. Open the Copy submenu and choose Copy Selector. Paste that result into your script, then simplify it for the way you plan to use it.
Start with a Copied Selector
Section titled “Start with a Copied Selector”Cursor Crane generates a selector that aims to identify the current element precisely. Interface titles, list contents, and web text can change, though. After copying a selector, run it once and remove unstable parts until only useful distinguishing conditions remain.
For example, this selector is very specific:
Window[title="Project Alpha"] Group Toolbar Button[title="Run"]If the project name changes often and the Run button in the toolbar is already distinctive, you can simplify it to:
Toolbar Button[title="Run"]Common Patterns
Section titled “Common Patterns”| Goal | Pattern | Example |
|---|---|---|
| Find by element type | Button, TextField, List | Button |
| Find by title | [title="..."] | Button[title="Save"] |
| Find by identifier | #id | Button#save-button |
| Find by state | :enabled, :focused | TextField:focused |
| Find any element | * | *[visible=true] |
You can usually use familiar names such as Button, TextField, StaticText, Window, List, Row, Table, and ScrollArea. Start with a copied selector when you are not sure which type to use.
Express Hierarchy
Section titled “Express Hierarchy”A space means “anywhere inside,” > means “directly inside,” and a comma means “match either”:
Window ButtonWindow > ButtonButton[title="Save"], Button[title="Cancel"]Window Buttonfinds buttons at any depth inside a window.Window > Buttonfinds only direct child buttons of a window.- The final line finds both Save and Cancel buttons.
Filter by Text and Attributes
Section titled “Filter by Text and Attributes”Attribute conditions support exact, starts-with, ends-with, and contains matching:
| Pattern | Meaning | Example |
|---|---|---|
= | Matches exactly | Button[title="Save"] |
^= | Starts with | StaticText[value^="Error"] |
$= | Ends with | TextField[title$="name"] |
*= | Contains | Button[label*="Continue"] |
Common attributes are title, label, value, enabled, visible, and focused. Wrap text containing spaces in single or double quotes.
Button[enabled=true]TextField[focused=true]StaticText[value*="Completed"]Choose a Result by Position
Section titled “Choose a Result by Position”| Pattern | Meaning |
|---|---|
:first | Takes the first matching result. |
:nth(n) | Takes the nth result, starting at 1. |
:enabled / :disabled | Keeps enabled or disabled elements only. |
:visible / :hidden | Keeps visible or hidden elements only. |
:focused | Keeps the currently focused element only. |
List Row:nth(2) Button:firstThis finds the second row in a list, then takes the first button in that row.
Query Visible Content
Section titled “Query Visible Content”queryElements() traverses children and is useful when you want to search a complete window. It can block noticeably for a large accessibility hierarchy. For long lists, tables, and scroll areas, queryVisibleElement() is better when you only care about the content a person can see right now:
const visibleButtons = root.queryVisibleElement('Button:enabled', 50);Both methods accept an optional second argument that limits how many results they return.
Use a Selector in a Script
Section titled “Use a Selector in a Script”Find the window first, then search from that window. The bundled example.element-query.js demonstrates the complete flow:
const application = ctx.elementInspector.getElementByPid(window.application.pid);const root = application?.getWindows().find( element => element.windowId === window.windowId);
const matches = root?.queryVisibleElement('Button[enabled=true]', 50) ?? [];Querying elements requires "accessibilityAPI" in meta.permissions. After finding an element, you can highlight it, move to it, set its value, or trigger one of its supported actions. See Script API for details.