Smart Locators Node
The Smart Locators node allows you to automate interactions with web pages using Playwright's semantic locators — based on ARIA roles, labels, placeholders, and other accessibility attributes. This approach is more resilient than CSS selectors, as it reflects how users actually find elements on the page.
Tip: For new web flows recorded by the extension, prefer Smart Web Flow. If you prefer traditional CSS selectors and XPath in legacy flows, use the Web Flow node.
Overview
| Property | Value |
|---|---|
| Type | smart-locators |
| Category | Web |
| Color | 🔵 Blue (#3b82f6) |
| Input | in |
| Output | out |
General Configuration
Identical to the Web Flow node:
| Field | Type | Default | Description |
|---|---|---|---|
| Session Mode | new / reuse | new | New session or reuse an existing one |
| Session ID | string | — | Session ID to reuse |
| Headless | boolean | true | Run without a visible graphical interface |
| Storage Strategy | inMemory / persisted | inMemory | Persist cookies/localStorage |
| Storage Key | string | — | Identifier for the persisted storage |
| Browser | chromium / firefox / webkit | chromium | Browser to use for the execution |
| Device | desktop / mobile | desktop | Emulation mode |
| Viewport | preset or custom | 1920x1080 | Window size (Desktop mode) |
| Width / Height | number | — | Custom dimensions (when custom) |
| Device Model | string | iPhone 14 | Device to emulate (Mobile mode) |
| Accessibility Scan | boolean | false | Run built-in accessibility diagnostics |
| Performance Audit | boolean | false | Collect page-load and network metrics during execution |
| Max Page Load (ms) | number | 4000 | Threshold used to fail the node when page load exceeds the limit |
| Max API Response (ms) | number | 1500 | Threshold used to flag slow API responses captured in the session |
| Fail on Request Errors | boolean | true | Fails the node when monitored APIs return HTTP/network errors |
| Self Healing | boolean | false | Tries to recover locators when the element changes and the original locator no longer resolves the target |
The Browser & Device options are identical to the Web Flow node — see the Web Flow documentation for details on viewport presets and available mobile devices.
Performance Audit
When Performance Audit is enabled, Smart Locators monitors the active Playwright session and generates visual performance evidence per screen.
The feature collects:
- Page Load
- FCP (First Contentful Paint)
- LCP (Largest Contentful Paint)
- total request count
- API request count
- request/API errors
- slow APIs per screen
In addition to the global summary, QANode generates per-screen checkpoints with:
- screen name
- URL
- step that originated the navigation
- chart of slowest APIs
- separate API error chart when errors exist on that screen
Performance Outputs
When the audit is enabled, the node exposes:
performancePassedperformanceRequestCountperformanceApiRequestCountperformanceErrorCountperformanceSlowRequestCountperformance
The performance object contains a structured summary of the execution, including per-screen checkpoints.
Self Healing
When Self Healing is enabled, Smart Locators can automatically recover semantic locator actions when the original locator no longer finds the expected element.
In addition to the semantic locator itself, the engine considers:
- element text and accessible name
rolelabel,placeholder,title, and other relevant attributes- structural page context such as container, form, heading, and relative position
This helps in scenarios such as:
- text changes with the same meaning
- uppercase/lowercase changes
- text with or without accents
- short variations such as
Login→Sign InorNext→Continue
The feature is conservative: it only applies recovery when it finds a candidate clearly stronger than the others, avoiding guesses on ambiguous screens.
When a step is recovered, the execution shows:
- the affected step
- the recovery confidence
- the locator used
- an Apply to Flow option to update the flow with the recovered locator
Locator System
Location Methods
Instead of CSS selectors, Smart Locators uses Playwright's semantic methods:
| Method | Description | Example |
|---|---|---|
getByRole | Locates by ARIA role | Button "Sign In", Link "Home" |
getByText | Locates by visible text | Text "Welcome" |
getByLabel | Locates by associated label | Field with label "Email" |
getByPlaceholder | Locates by placeholder | Field with placeholder "Enter your name" |
getByAltText | Locates by alt text | Image with alt "Logo" |
getByTitle | Locates by title | Element with title "Close" |
getByTestId | Locates by data-testid | data-testid="submit-btn" |
Locator Configuration
| Field | Type | Description |
|---|---|---|
| Method | string | Location method |
| Value | string | Text/value to search for |
| Name | string | Role name (only for getByRole) |
| Exact | boolean | Exact match (false = contains) |
| Nth | number | Element index (when there are multiple) |
Available ARIA Roles
For the getByRole method, the following roles are available:
| Interaction Roles | Structure Roles | Feedback Roles |
|---|---|---|
button | heading | alert |
checkbox | list | alertdialog |
combobox | listitem | dialog |
link | navigation | progressbar |
listbox | region | status |
menu | row | tooltip |
menuitem | cell | — |
option | grid | — |
radio | tab | — |
searchbox | tablist | — |
slider | tabpanel | — |
spinbutton | toolbar | — |
switch | tree | — |
textbox | treeitem | — |
Usage example:
Method: getByRole
Value: button
Name: Sign In
Equivalent in Playwright: page.getByRole('button', { name: 'Sign In' })
Available Actions
| Action | Color | Description |
|---|---|---|
| navigate | Blue | Navigate to URL |
| switchPage | Purple | Switch to another page or tab |
| click | Yellow | Click on element |
| dblclick | Yellow | Double click |
| fill | Green | Fill field (instant) |
| type | Green | Type character by character |
| check | Green | Check checkbox/radio |
| uncheck | Green | Uncheck checkbox |
| selectOption | Purple | Select dropdown option |
| hover | Cyan | Hover mouse over element |
| focus | Light Blue | Focus on element |
| press | Green | Press a key |
| assert | Red | Verify condition |
| extract | Cyan | Extract data |
| extractList | Emerald | Extract list of repeated elements |
| wait | Purple | Wait for condition |
| scroll | Yellow | Scroll page |
| refresh | Orange | Reload page |
| clock | Teal | Control the browser clock |
| frame | Gray | Switch frame |
| rightClick | Yellow | Right-click |
| upload | Blue | Upload files |
| dialog | Purple | Handle dialogs (alert/confirm) |
| drag | Rose | Drag and drop |
| evaluate | White | Execute JavaScript on the page |
| screenshot | Blue | Capture screenshot |
Action Details
navigate
Navigates to a URL.
| Field | Type | Description |
|---|---|---|
| URL | string | Destination URL (supports {{ }}) |
switchPage
Switches the active page when a click, link, or action opens a new tab/window and the next steps must continue there.
| Field | Type | Description |
|---|---|---|
| Mode | string | Last opened tab, next, previous, or match by URL/title |
| URL contains | string | Optional URL fragment used to find the tab |
| Title contains | string | Optional page title fragment |
| Wait Until | string | Loading event expected after switching |
| Timeout (ms) | number | Maximum time to find/load the tab |
Modes:
| Mode | Description |
|---|---|
last | Uses the last opened tab |
next | Uses the next tab relative to the current one |
previous | Uses the previous tab |
match | Finds a tab by URL and/or title fragment |
When the extension identifies links that open a new tab, it can insert this step automatically. In manual flows, add switchPage after the click that opens the tab.
click
Clicks on a semantically located element.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
| Retries | number | Number of attempts (default: 3) |
The click waits for the element to be visible, scrolls to it if necessary, and then clicks. If it fails, it retries.
Example:
Method: getByRole
Value: button
Name: Submit
Retries: 3
dblclick
Double-clicks on an element.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
| Retries | number | Number of attempts |
fill
Fills an input field instantly (replaces the value).
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
| Text | string | Text to fill (supports {{ }}) |
| Clear First | boolean | Clears the field first |
Uses Playwright's locator.fill() — ideal for simple fields.
type
Types text character by character, simulating real typing.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
| Text | string | Text to type |
| Delay (ms) | number | Interval between keys (default: 50ms) |
| Clear First | boolean | Clears the field first |
Uses Playwright's locator.pressSequentially() — ideal for fields with:
- Autocomplete (suggestions appear as you type)
- Input masks (phone numbers, zip codes)
- On-keypress validation (validates each key)
Example:
Locator: getByPlaceholder → "Phone"
Text: 123.456.789-00
Delay: 100ms
check / uncheck
Checks or unchecks a checkbox/radio button.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
Example:
Method: getByLabel
Value: I accept the terms of use
selectOption
Selects an option from a dropdown (<select>).
| Field | Type | Description |
|---|---|---|
| Locator | locator | Dropdown configuration |
| Select By | string | value, label, or index |
| Value | string | Corresponding value |
hover
Hovers the mouse over an element.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
| Retries | number | Number of attempts |
| Wait After (ms) | number | Wait time after hover |
focus
Sets focus on an element.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Locator configuration |
press
Presses a keyboard key in the context of an element.
| Field | Type | Description |
|---|---|---|
| Locator | locator | Element that will receive the key |
| Key | string | Key name (Enter, Tab, Escape, etc.) |
| Wait After (ms) | number | Wait time after pressing |
drag
Drags a semantically located element and drops it on another locator or at recorded coordinates.
| Field | Type | Description |
|---|---|---|
| Source Locator | locator | Element that will be dragged |
| Target Locator | locator | Element where it will be dropped, when available |
| Drop X / Y | number | Absolute coordinates shown when the target has no reliable locator |
| Wait After (ms) | number | Wait time after dropping |
Smart Locators tries to use Playwright semantic locators such as getByRole, getByText, getByLabel, and getByTestId. When a page has repeated elements and the step comes from the extension, the JSON may include internal position metadata to help the executor choose the element closest to the original gesture. These metadata fields are not shown as primary fields in the panel.
For drag/drop components, QANode also tries to promote the semantic locator to the real interactive container. This is useful when the clicked text is inside another draggable element, for example:
- A
<p>inside a draggable card - An image inside a
draggablecontainer - A drop area marked by class or drop attributes
If the semantic target is too generic or fails, but Drop X / Y is available, Smart Locators can use the recorded coordinates as fallback. This allows automation of canvas, Kanban, and drop areas that do not have their own text, role, or label.
Best practices:
- Prefer components with accessible names (
aria-label, visible text, labels) - Use
data-testidordata-qafor critical cards, columns, and drop areas - Avoid icon-only buttons without
aria-label - Review recordings that depend on
nth, especially when there are repeated texts - Use
beforeandafterscreenshots to visually prove the movement
assert
Verifies conditions on the page. Offers multiple verification modes:
| Field | Type | Description |
|---|---|---|
| Name | string | Assertion identifier |
| Locator | locator | Target element (when applicable) |
| Mode | string | Verification type |
| Expected Text | string | Expected value |
| Continue on Failure | boolean | Do not fail the entire node |
Assert Modes:
| Mode | Description | Requires Locator |
|---|---|---|
visible | Element is visible | Yes |
hidden | Element is hidden | Yes |
textContains | Text contains value | Yes |
textEquals | Text is exactly the value | Yes |
hasCount | Element count | Yes |
enabled | Element is enabled | Yes |
disabled | Element is disabled | Yes |
checked | Checkbox/radio is checked | Yes |
hasValue | Input has specific value | Yes |
hasAttribute | Element has attribute with value | Yes |
hasURL | Page URL contains/equals | No |
hasTitle | Page title contains/equals | No |
Examples:
// Verify that the "Submit" button is visible
Mode: visible, Locator: getByRole("button", "Submit")
// Verify that message contains "Success"
Mode: textContains, Locator: getByText("Success"), Expected: "Success"
// Verify URL after login
Mode: hasURL, Expected: "/dashboard"
// Verify that field is disabled
Mode: disabled, Locator: getByLabel("Email")
extract
Extracts data from an element.
| Field | Type | Description |
|---|---|---|
| Name | string | Extraction name |
| Locator | locator | Locator configuration |
| Attribute | string | What to extract |
Available attributes:
| Attribute | Description |
|---|---|
text | Visible text (textContent) |
innerText | Inner text |
innerHTML | Inner HTML |
inputValue | Input field value |
href | URL of links |
src | URL of images |
value | Generic value |
extractList
Iterates over a list of repeated elements (table rows, cards, list items) and extracts named fields from each, producing an array of objects as output.
| Field | Type | Description |
|---|---|---|
| Name | string | Extraction name (key in the output array) |
| Container Locator | locator | Locator configuration to find the list container |
| Item Selector | string | CSS selector relative to the container that selects each repeated item |
| Fields | array | List of fields to extract from each item |
Fields configuration:
| Sub-field | Type | Description |
|---|---|---|
| Field Name | string | Key in the output object |
| Selector | string | CSS selector relative to the item |
| Attribute | string | What to extract: text (default), innerHTML, href, src, value |
Output example:
{
"extracts": {
"products": [
{ "name": "Item A", "price": "$10.00" },
{ "name": "Item B", "price": "$25.00" }
]
}
}
Recording with the extension: Use Ctrl+Shift+E in the Chrome Recorder to record a list extraction in two steps: first click the repeating item, then click the fields to extract within it.
wait
Waits for a condition.
| Mode | Description |
|---|---|
timeout | Waits for a fixed time |
visible | Waits for element to become visible |
hidden | Waits for element to disappear |
networkIdle | Waits for network requests to finish |
scroll
Scrolls the page.
| Mode | Description |
|---|---|
toLocator | Scrolls to the element |
by | Scrolls a fixed number of pixels |
toBottom | Scrolls to the bottom of the page |
refresh
Reloads the page. Same configuration as Web Flow.
clock
Controls the browser clock using Playwright's page.clock. This is the same action available in Web Flow and can be used to validate date/time behavior without depending on the machine's real clock.
| Field | Type | Description |
|---|---|---|
| Operation | setFixedTime / fastForward / pauseAt / resume | Clock operation to execute |
| Date / Time | string | Date/time used by setFixedTime and pauseAt |
| Duration | string / number | Virtual time advanced by fastForward (1000, 05:00, 02:34:10) |
| Reload Page After Apply | boolean | Reloads the page after applying the clock when enabled |
| Reload Wait Until | load / domcontentloaded / networkidle | Load event used when reload is enabled |
New clock steps start with reload disabled. Enable reload only when the application depends on page load to recalculate dates or times.
frame
Switches to an iframe. Supports name and main modes (return to main context).
Evidence (Screenshots per Step)
Identical to Web Flow — each step can have individual screenshot capture configuration.
Accessibility Testing
Smart Locators supports automatic accessibility scanning with built-in axe-core. When enabled, the node audits the page after each step that captures a screenshot, identifying WCAG/ARIA violations and visually marking the affected elements.
Smart Locators already uses semantic locators based on ARIA roles — combining it with accessibility scanning is especially useful for verifying that the elements you interact with pass accessibility criteria.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
| Accessibility Scan | boolean | false | Enables axe-core scanning |
| Fail When Severity >= | none / minor / moderate / serious / critical | serious | Minimum severity level that fails the node |
How It Works
After each step that takes a screenshot, axe-core is injected into the page and scans the document for violations. Violations are drawn over the screenshot as colored boxes around the affected elements, plus a summary panel in the corner:
| Severity | Color | Description |
|---|---|---|
| Critical | 🔴 Red | Blocks access for users with disabilities |
| Serious | 🟠 Orange | Causes significant difficulty |
| Moderate | 🟡 Yellow | Causes some difficulty |
| Minor | 🔵 Blue | Recommended improvement |
At the end of execution, the following are generated automatically:
- Per-step screenshots — overlay with colored boxes + panel
Critical N / Serious N / Moderate N / Minor N+ top 2 rules - Severity chart —
{id}-accessibility-severity-chart.png— distribution by level - Rules chart —
{id}-accessibility-rule-chart.png— top 8 most violated rules - JSON report —
{id}-accessibility-report.json— full data for all violations
Pass/Fail Criteria
The node fails if there is any violation with severity equal to or above the configured threshold. Use none to never fail (collect metrics without blocking the flow).
Example: Verify login form accessibility
Node configuration:
Accessibility Scan: true
Fail When Severity >= : serious
Steps:
1. navigate → https://mysite.com/login (no screenshot = no scan)
2. fill → getByLabel("Email") → "..." → screenshot after → scan executed
3. fill → getByLabel("Password") → "..." → screenshot after → scan executed
4. click → getByRole("button", { name: "Sign In" }) → screenshot after → scan executed
5. wait → networkIdle
6. assert → "loginOk" → textContains → getByText("Welcome") → screenshot → scan executed
If any step has a serious or critical violation, the node fails with:
"Accessibility findings at or above "serious" were detected."
Outputs
| Output | Type | Description |
|---|---|---|
sessionId | string | Browser session ID |
extracts | object | Extracted data (key → value) |
asserts | object | Assertion results (key → boolean) |
accessibilityPassed | boolean | Whether it passed the severity criteria (when enabled) |
accessibilityViolationCount | number | Total violation instances found |
accessibility | object | Full accessibility report |
accessibility.threshold | string | Configured threshold |
accessibility.scanCount | number | Number of checkpoints scanned |
accessibility.counts | object | { minor, moderate, serious, critical } — aggregated totals |
accessibility.steps | array | Per-checkpoint details (url, counts, topRules) |
accessibility.rules | array | Top 10 violated rules across the entire flow |
Complete Example: Login with Smart Locators
Step 1: navigate → https://mysite.com/login
Step 2: fill → getByLabel("Email") → "{{ variables.EMAIL }}"
Step 3: fill → getByLabel("Password") → "{{ variables.PASSWORD }}"
Step 4: click → getByRole("button", { name: "Sign In" })
Step 5: wait → networkIdle
Step 6: assert → "loginOk" → textContains → getByText("Welcome")
Step 7: extract → "userName" → getByRole("heading") → text
When to Use Smart Locators vs Web Flow
| Scenario | Recommendation |
|---|---|
| Site with good accessibility practices | Smart Locators |
| Site with data-testid on all elements | Web Flow |
| Forms with labels | Smart Locators |
| Elements without text or role | Web Flow (CSS/XPath) |
| Accessibility testing | Smart Locators |
| Legacy / sites without semantics | Web Flow |
Tips
- Prefer
getByRole— it is the most resilient and reflects how assistive technologies find elements - Use
getByLabelfor form fields — it is more stable than CSS getByTestIdis great for elements without a clear role/label- Use the type action (instead of fill) for fields with masks or autocomplete
- The Nth field allows you to select a specific element when multiple ones match the locator
