Selectors
Prowl QA uses Playwright's selector engine. Choose selectors based on stability and maintainability.
Selector Priority (Best to Worst)
1. data-testid (best)
Explicit test hooks that don't change with UI refactors.
- click:
selector: "[data-testid='submit']"
2. Accessible roles
Semantic and resilient to styling changes.
- click:
selector: "role=button[name='Submit']"
3. Labels / Placeholders
Via shorthand, Prowl QA resolves these automatically.
- fill:
"Email": "user@test.com"
4. Text content
Via shorthand click, good for buttons and links.
- click: "Sign In"
5. CSS selectors (last resort)
Fragile — avoid class names that change.
- click:
selector: ".btn-primary" # Avoid if possible
Shorthand Resolution
When you use shorthand syntax, Prowl QA resolves selectors using Playwright's built-in locators:
| Shorthand | Resolution Strategy |
|---|---|
click: "Sign In" | role=button[name="Sign In"] first, then text=Sign In fallback |
fill: { "Email": "val" } | Playwright label matching, then placeholder matching |
select: { "State": "FL" } | Label, aria-label, or placeholder matching on <select> elements |
Shorthand click uses substring matching on button names. click: "Save" will match a button labeled "Save & New". For exact matching, use the explicit form: click: { selector: 'button:text-is("Save")' }.
Forbidden Selectors
Configure selectors that steps cannot target, as a safety guardrail:
# .prowlqa/config.yml
guardrails:
forbiddenSelectors:
- "[data-danger]"
- ".delete-btn"
- "#nuclear-option"
Forbidden selectors use substring matching. Forbidding "delete" will also forbid "undelete" or "delete-history".
Tips
- Ask your team to add
data-testidattributes to key interactive elements. This is the most reliable strategy. - Use
--headedand--slow-mo 1000to watch the browser in real time and verify your selectors. - Use
--traceand view withnpx playwright show-tracefor detailed selector diagnostics. - Check for iframes — elements inside iframes need frame-specific handling.
- Check for dynamic content — add
waitForNetworkIdleorwaitForSelectorbefore interacting with elements that load asynchronously.