In a browser test, a custom find step targets an element using the Locator field, which accepts CSS, XPath, and Playwright locator syntax as a single string. This article is a reference for the locator syntax mabl supports and how to write each type.
Browser tests only
Custom find steps are only supported in browser tests. To learn about targeting elements in a mobile app, see creating reliable find steps in mobile tests.
For a walkthrough of when and how to add a custom find step, see Create a custom find step. Before you reach for a locator, it's worth trying Configure Find first; it's easier to maintain and doesn't require knowledge of CSS, Playwright, or XPath query syntax.
Supported locator syntax
The Locator field accepts any Playwright locator that can be written as a string. The following table summarizes the syntax you can use.
| Locator type | How to write it | Example |
|---|---|---|
| CSS selector | Enter the selector directly, with no prefix. | button.add-to-cart |
| XPath expression | Add an xpath= prefix. |
xpath=//button[@id='submit'] |
| Ordinal selection | Add >> nth=0 for the first match or >> nth=-1 for the last. |
.list-item >> nth=0 |
| Chaining | Use >> to narrow from one locator to the next. |
li:has-text("Product 2") >> button:has-text("Add to cart") |
CSS selectors
CSS selectors work in the Locator field without a prefix. For example, button.add-to-cart targets a button with the add-to-cart class.
CSS is often the best starting point, because the syntax is quick to read and it can target elements inside a shadow DOM, which XPath can't reach. For guidance on choosing between CSS and XPath, see when to use CSS selectors vs. XPath expressions.
XPath expressions
To use an XPath expression, add an xpath= prefix so mabl knows to evaluate the string as XPath rather than CSS. For example, xpath=//button[@id='submit'] targets a button by its id.
XPath is useful when you need to find an element by its text.
Ordinal selection
When several elements match the same locator, use nth to target one by its position. Append >> nth= followed by the index:
-
>> nth=0targets the first match. -
>> nth=-1targets the last match.
For example, .list-item >> nth=0 targets the first element with the list-item class. Negative indexes count from the end, so nth=-1 is a reliable way to target the last match even when the number of matching elements changes between runs.
Chaining locators
Use >> to chain locators together, narrowing the search from one locator to the next. mabl evaluates each locator in order and scopes the next one to the results of the previous one.
For example, the following locator finds the list item that contains the text "Product 2," then finds the "Add to cart" button within that item:
li:has-text("Product 2") >> button:has-text("Add to cart")
Writing Playwright chains as a string
The Playwright documentation mostly shows locators chained in code, such as page.getByRole('listitem').filter({ hasText: 'Product 2' }). Because the Locator field takes a single string value, you express that same chain with >> instead:
role=listitem >> text=Product 2
For the full syntax reference, see Playwright locators.
Using variables in a locator
You can include mabl variable syntax in a locator to target elements with data-driven values. Reference a variable with the {{@varName}} format:
- CSS:
div.{{@sample_var}} - XPath:
xpath=//div[@class="{{@sample_var}}"]
When the step runs, mabl resolves the variable and evaluates the locator with the resolved value.