find
The find action locates an element in the current interface based on its display text or a CSS/XPath selector. After finding the element, you can optionally interact with it, such as clicking it or typing into it.
If multiple elements match the specified criteria (elementText and/or selector), the step operates on the first matched element. Ensure your criteria uniquely identify the target element.
Specify the target element directly with a string for basic text or selector lookup. Use an object for more detailed options and interactions:
- String Shorthand: Provide the display text or CSS/XPath selector directly as the value for the
findkey. If elements are found by both text and selector, the element found by matching text is used.- Example:
"find": "Login"or"find": "#username".
- Example:
- Object Format: Use an object with the following properties:
elementText: (Optional) The display text of the element to find. If combined withselector, the element must match both. See How text matching works below.selector: (Optional) The CSS selector or XPath selector of the element to find. If combined withelementText, the element must match both. At least one ofelementTextorselectoris required.timeout: (Optional) Maximum duration in milliseconds to wait for the element to exist (default: 5000).moveTo: (Optional) Move the cursor to the element. An element that isn’t visible is scrolled into view. Defaults tofalse. A barefindleaves the viewport and cursor where they’re already sitting. Set this explicitly when a step should scroll, or when a recording needs the cursor to travel to the element.click: (Optional) Click the element after finding it. Can betrue(for a default left click),"left","right","middle", or an object like{ "button": "right" }or{ "duration": 800 }(a long-press / press-and-hold, in milliseconds).type: (Optional) Type keys after finding the element. Requires the element to be made active first (for example, by usingclick: true). Accepts a string or an object like{ "keys": "my text", "inputDelay": 100 }. Seetypefor details.surface: (Optional) The browser session, window, or tab the element lives in, such as{ "browser": "chrome", "tab": "cart" }or a named browser{ "browser": "firefox", "name": "admin" }. It can also be the native app surface the element lives in, such as{ "app": "notepad" }or a specific app window{ "app": "notepad", "window": { "title": "/Open/" } }. Omit it to act on the active surface, the most recently opened, focused, or explicitly targeted one, whether a browser tab or an app window. Specifying a surface switches the active surface for the steps that follow. On an app surface,elementText,elementId, andelementAriamap to native controls.selectorthere accepts a native locator, either XPath or a~-prefixed accessibility ID, instead of a CSS selector. See Test across multiple tabs, windows, and browsers, Target an app surface, and App windows below.
How text matching works
elementText (and the string shorthand’s text form) matches an element’s
full visible text with whitespace normalized. Doc Detective trims leading and
trailing whitespace and collapses internal runs of spaces, tabs, and newlines to a
single space. Two consequences follow from this:
- Framework-rendered text just works. Frameworks like React and Svelte often
split an element’s text across several DOM text nodes, sometimes with an empty
leading node. The match uses the element’s whole text. A heading like
Garden companion APItherefore matches even when it isn’t a single, tidy text node. The result stays the same on Chrome and Firefox no matter how each browser’s driver reports whitespace. - It’s a whole-element match, not a substring.
elementTextmatches an element whose entire normalized text equals your string. A broadselectorlikebodycombined withelementTexttherefore won’t match, since the body’s text is the whole page. Target a tighter element, or match a substring with a regular expression by wrapping the value in slashes:"elementText": "/Garden companion API/".
App windows
On Windows and macOS app surfaces, window selects which of the app’s windows the step acts on. That includes dialogs and secondary document windows:
"window": { "title": "Create New Data Source" }selects by title; wrap the value in slashes for a regex ("/Data Source/")."window": -1selects the newest window (typically a dialog the app just opened).- A plain string or
{ "name": … }matches the window title exactly. - On macOS, a non-negative
"window": 2selects by position; on Windows, positional indexes aren’t supported (select by title or-1instead).
Window selection is sticky. Later steps on the same app surface act in the selected window until another selector changes it. click, type, screenshot, record, swipe, and closeSurface all accept the same selector. Android and iOS app surfaces are single-window, so a window selector there fails with guidance to omit it.
On Windows, resolving a selector probes the app’s candidate windows to read their titles, which can briefly bring each probed window to the foreground. This matters for recordings: if a record is running, a probe can flash another window into a frame or two of the capture. Select the window before starting the recording (selection is sticky) to avoid it.
Mobile app surfaces auto-scroll. On an Android or iOS app surface, an element that isn’t on screen makes find scroll toward content further down the list before giving up. It takes up to 5 scroll steps, within timeout. That matches how browser find scrolls elements into view. click and element-targeted type locate elements the same way, so they inherit this. For a different gesture, sideways or a precise drag, use swipe.
Setting Variables: to capture a found element’s attributes into variables for later steps, use the step-level variables object. You can assign values based on the element using expressions like $$element.text.
Outputs: the action also exposes outputs.found, a boolean indicating whether an element matching your criteria was located. To capture it for later steps, use the step-level variables object with the expression $$found.
For comprehensive options, see the
findreference.
Examples
Here are a few ways you might use the find action: