Locators
Locators are the foundation of web automation testing - they tell RocketQA how to find and interact with elements on your web pages. This comprehensive guide covers everything you need to know about creating, organizing, and maintaining effective locators.
What Are Locators?
Section titled “What Are Locators?”Locators are selectors that identify specific elements on web pages. In RocketQA, they’re defined in a YAML file (locators.yml
) using CSS selectors, XPath expressions, or text-based selectors.
Basic Locator Structure
Section titled “Basic Locator Structure”pageName: elementName: "selector" anotherElement: "another-selector"
Used in tests as:
When click $pageName.elementNameThen $pageName.anotherElement is visible
Locator Types and Strategies
Section titled “Locator Types and Strategies”1. CSS Selectors (Recommended)
Section titled “1. CSS Selectors (Recommended)”CSS selectors are the most commonly used locator type due to their performance and readability.
Basic CSS Selectors
Section titled “Basic CSS Selectors”basicSelectors: # By ID (most reliable) loginButton: "#login-btn"
# By class errorMessage: ".error-text"
# By attribute submitButton: "[type='submit']"
# By tag name mainHeading: "h1"
# Combination primaryButton: "button.btn-primary"
Advanced CSS Selectors
Section titled “Advanced CSS Selectors”advancedSelectors: # Child selectors firstNavItem: "nav > ul > li:first-child"
# Descendant selectors footerLinks: "footer a"
# Attribute contains emailField: "[name*='email']"
# Pseudo-selectors lastMenuItem: ".menu-item:last-child" checkedCheckbox: "input[type='checkbox']:checked"
# Multiple conditions activeNavLink: "nav a.active[href='/dashboard']"
2. XPath Expressions
Section titled “2. XPath Expressions”XPath provides powerful traversal capabilities, especially useful for complex element relationships.
Basic XPath
Section titled “Basic XPath”xpathSelectors: # Simple XPath loginButton: "//button[@id='login']"
# By text content welcomeMessage: "//h1[text()='Welcome']"
# Contains text errorMessage: "//*[contains(text(), 'Error occurred')]"
# By position firstProduct: "(//div[@class='product'])[1]"
Advanced XPath
Section titled “Advanced XPath”advancedXPath: # Parent traversal inputLabel: "//input[@name='email']/../label"
# Following sibling nextButton: "//button[text()='Back']/following-sibling::button"
# Complex conditions specificUser: "//tr[td[1][text()='John'] and td[2][text()='Doe']]"
# Attribute conditions enabledButton: "//button[@disabled='false' or not(@disabled)]"
# Multiple text conditions complexElement: "//*[contains(text(), 'Username') and @class='field-label']"
3. Data Test IDs (Best Practice)
Section titled “3. Data Test IDs (Best Practice)”The most reliable approach is using data-testid
attributes specifically for testing.
<!-- HTML with test IDs --><button data-testid="submit-form">Submit</button><div data-testid="user-profile">Profile Content</div><input data-testid="search-input" type="text">
# locators.yml using test IDstestIdSelectors: submitButton: "[data-testid='submit-form']" userProfile: "[data-testid='user-profile']" searchInput: "[data-testid='search-input']"
# With additional conditions activeTab: "[data-testid='tab'][aria-selected='true']"
4. Text-Based Locators
Section titled “4. Text-Based Locators”Select elements by their visible text content.
textBasedSelectors: # Exact text match loginLink: "text=Login"
# Partial text match welcomeMessage: "text*=Welcome"
# Case insensitive submitButton: "text=/submit/i"
# Multiple text options confirmButton: "text=OK,text=Confirm,text=Yes"
Locator Organization Strategies
Section titled “Locator Organization Strategies”1. Page-Based Organization
Section titled “1. Page-Based Organization”Organize locators by page or view:
homepage: navigation: logo: ".site-logo" menuButton: ".hamburger-menu" searchBox: "#global-search" hero: headline: ".hero-title" ctaButton: ".hero-cta" footer: socialLinks: ".social-links a"
loginPage: form: emailField: "#email" passwordField: "#password" submitButton: "#login-submit" links: forgotPassword: ".forgot-password" signUp: ".signup-link"
dashboard: sidebar: navigation: ".sidebar-nav" userMenu: ".user-menu" content: mainArea: ".dashboard-content" widgets: ".widget"
2. Component-Based Organization
Section titled “2. Component-Based Organization”Organize by reusable UI components:
components: modal: overlay: ".modal-overlay" container: ".modal-container" header: ".modal-header" closeButton: ".modal-close" content: ".modal-body" footer: ".modal-footer"
dataTable: container: ".data-table" headers: ".table-header th" rows: ".table-row" cells: ".table-cell" pagination: ".pagination"
notification: container: ".notification" message: ".notification-message" icon: ".notification-icon" closeButton: ".notification-close"
3. Hierarchical Organization
Section titled “3. Hierarchical Organization”Create nested structures that mirror your application:
ecommerce: header: logo: ".header-logo" navigation: categories: ".category-nav" searchBox: ".search-input" cartIcon: ".cart-icon" userActions: login: ".login-link" profile: ".profile-dropdown"
productCatalog: filters: container: ".filters-panel" category: ".filter-category" price: ".filter-price" brand: ".filter-brand" products: grid: ".products-grid" card: ".product-card" image: ".product-image" title: ".product-title" price: ".product-price"
checkout: steps: shipping: ".checkout-shipping" payment: ".checkout-payment" review: ".checkout-review" forms: billingAddress: ".billing-form" shippingAddress: ".shipping-form" paymentMethod: ".payment-form"
Selector Best Practices
Section titled “Selector Best Practices”1. Reliability Hierarchy (Best to Worst)
Section titled “1. Reliability Hierarchy (Best to Worst)”- Test-specific attributes:
[data-testid='element']
- Semantic attributes:
[aria-label='Close dialog']
- Stable IDs:
#user-profile
- Stable classes:
.navigation-menu
- Structural CSS:
nav > ul > li
- XPath with text:
//button[text()='Submit']
- Complex CSS:
.container:nth-child(3) > div
- Brittle selectors: Avoid generated classes, positions
2. Writing Robust Selectors
Section titled “2. Writing Robust Selectors”# Good: Stable and meaningfulgoodSelectors: submitButton: "[data-testid='submit-form']" userProfile: "#user-profile-section" navigationMenu: "[role='navigation']" errorMessage: ".validation-error"
# Avoid: Fragile and likely to breakavoidThese: fragileButton: ".css-1a2b3c4" # Generated class positionBased: "div:nth-child(5) > span:nth-child(2)" textOnly: "Submit" # Text might change complexPath: "html > body > div > div > main > section > div > button"
3. Naming Conventions
Section titled “3. Naming Conventions”Use clear, descriptive names that reflect the element’s purpose:
namingExamples: # Good: Descriptive and clear loginSubmitButton: "#login-form-submit" userProfileDropdown: ".user-profile-menu" productSearchInput: "[name='product-search']" checkoutTotalPrice: ".checkout-summary-total"
# Avoid: Vague or unclear btn1: "#btn-1" field: ".input" element: ".element" thing: ".some-class"
Testing and Validating Locators
Section titled “Testing and Validating Locators”Test selectors in browser console:
// Test CSS selectorsdocument.querySelector('#login-button')document.querySelectorAll('.product-card')
// Test XPath$x("//button[text()='Submit']")$x("//div[@class='user-profile']")
// Check element propertiesconst element = document.querySelector('#user-name');console.log(element.textContent);console.log(element.getAttribute('data-testid'));
Troubleshooting Common Issues
Section titled “Troubleshooting Common Issues”1. Element Not Found
Section titled “1. Element Not Found”# Problem: Element not foundproblematicSelector: ".dynamic-class-123"
# Solutions:solutions: useTestId: "[data-testid='stable-identifier']" useRole: "[role='button'][aria-label='Submit']" useStructural: "form .submit-button" waitForElement: ".appears-after-loading"
2. Multiple Elements Found
Section titled “2. Multiple Elements Found”# Problem: Selector matches multiple elementsambiguousSelector: ".button"
# Solutions:specificSelectors: firstMatch: ".button:first-of-type" byContext: ".login-form .button" byText: "button:has-text('Login')" byPosition: "(.button)[1]" # XPath
3. Dynamic Content
Section titled “3. Dynamic Content”# Problem: Content changes dynamicallydynamicContent: # Use partial matches notification: "[class*='notification']"
# Use stable attributes userInfo: "[data-user-id]"
# Use structural relationships siblingElement: ".username + .user-role"
Next Steps
Section titled “Next Steps”Mastering locators enables you to:
- ✅ Create reliable, maintainable element selectors
- ✅ Organize locators for team collaboration
- ✅ Handle dynamic and complex web applications
- ✅ Debug and troubleshoot element selection issues
Continue with:
- Test Files - Advanced feature file techniques and patterns
🎯 Locator Master! You now have the knowledge to create robust, maintainable locators for any web application. Next, let’s explore advanced test file techniques!