top of page
Search

Element Selector Hierarchy Guide for Software Testing

  • Writer: Mark Shepstone
    Mark Shepstone
  • Jun 23
  • 9 min read
Element Selector Hierarchy Guide for Software Testing

Before We Begin

This guide dives into a technical topic about how software testers pick out parts of a webpage or app in order to test them. If you're not a tester or deeply involved in software, some sections may feel complex, but we'll attempt to make it clear.


Introduction

What is this guide about? This guide helps anyone involved in testing websites or applications to understand how to find and identify elements (like buttons, text boxes, links) on a webpage in a way that won't break when the page gets updated.


Think of it like the different ways of giving directions to your house:

  1. At the third stop turn left, we are the 7th house on the left

  2. In Valencia street, we are the blue house next to the Oak tree


Which is better in the long run? The first one may be more direct but is easily ‘broken’ as if someone builds a new house etc you wont be at the correct house anymore, whereas the second option is more robust for the long run as it uses names and attributes to target your choice.

In testing


Why does this matter? When tests break frequently due to small website changes, it creates extra work and reduces trust in the testing. Robust element identification keeps tests working even when developers make updates to the website's appearance or layout.


Who should read this?

  • Manual testers learning automation

  • Test managers overseeing automation projects

  • Business analysts writing test requirements

  • Anyone working with testing tools like Zamaqo’s ZATS, Selenium, Cypress, or Playwright

  • Developers who want to make their websites easier to test


Understanding Element Selectors

What are element selectors? Element selectors are like "addresses" or "names" that help testing tools find specific parts of a webpage - like a submit button, a username field, or a product title. Just like your home has multiple ways to identify it (street address, GPS coordinates, "the house with the red door"), webpage elements can be identified in multiple ways.


The main types of "addresses" for webpage elements:

  • ID Attributes: Like a unique house number - each element gets its own special identifier (<input id="username">)

  • Class Attributes: Like neighborhood names - multiple elements can share the same class for styling (<button class="submit-button">)

  • Data Attributes: Like special testing labels that developers add specifically to help with testing (<button data-testid="submit-button">)

  • Accessibility Attributes: Labels that help screen readers and assistive technology understand what elements do (<button aria-label="Close dialog">)

  • CSS Selectors: Patterns that describe elements based on their properties and relationships to other elements (.submit-button, div > p)

  • XPath: A more complex addressing system that describes the exact path through the webpage structure to find an element (//button[@id='submit-button'])


Think of it like finding a book in a library:

  • Via ID = "The book with barcode 12345" (unique identifier)

  • Via Class = "All books in the Science Fiction section" (grouped by category)

  • Via Data attribute = "The book with the special 'STAFF-PICK' sticker" (added specifically for identification)

  • Via XPath = "Go to Floor 2, Section A, Shelf 3, Position 7" (exact location path)


Recommended Selector Hierarchy

The Goal: Choose the "address" that's least likely to change when developers update the website, while still accurately finding your target element.

Here's our recommended order from most reliable to least reliable:


1. Data Attributes (Most Preferred)

What this means: These are special labels that developers add to webpage elements specifically for testing purposes.

Real-world analogy: Like putting a "FOR TESTING - DO NOT REMOVE" sticker on equipment in a factory.

When development teams add data-* attributes specifically for testing, these are the gold standard. They're designed to remain stable during UI refactoring.


Examples:

html

<button data-testid="submit-button">Submit</button>

<input data-testid="email-input" type="email" placeholder="Enter email">

<div data-testid="product-card" class="card">Product Details</div>


How testing tools find these:

  • CSS: [data-testid="submit-button"]

  • XPath: //button[@data-testid='submit-button']

Why this is best: Developers promise to keep these labels stable specifically for testing. It's like having a permanent address that won't change even if you renovate your house.


2. ID Attributes

What this means: These are unique names given to specific elements on a webpage - like how each person has a unique social security number.

Real-world analogy: Like your driver's license number - it's unique to you and doesn't change even if you move or change your appearance.

ID attributes provide good stability when used consistently with meaningful names (not randomly generated or purely for styling).


Examples:

html

<input type="text" id="username">

<form id="registration-form">

<nav id="main-navigation">


How testing tools find these:

  • CSS: #username, #registration-form, #main-navigation

  • XPath: //input[@id='username'], //form[@id='registration-form'], //nav[@id='main-navigation']


Why this works: IDs are unique per page and mainly used to identify important parts of the page rather than just for decoration.


3. Meaningful Class Names (Use with Caution)

What this means: These are group names that describe what elements do, rather than how they look.

Real-world analogy: Like calling someone "the teacher" vs "the person in the blue shirt" - job titles are more stable than clothing choices.

Classes that clearly describe functionality can work, but exercise caution since they're often tied to CSS styling and may change during redesigns.


Examples:

html

<button class="submit-button">Submit</button>

<div class="error-message">Invalid input detected</div>

<section class="user-profile">Profile Information</section>


How testing tools find these:

  • CSS: .submit-button, .error-message, .user-profile

  • XPath: //button[@class='submit-button'], //div[@class='error-message'], //section[@class='user-profile']


Caveat: Choose classes that describe what something does (like "submit-button") rather than how it looks (like "big-red-button"). The function is less likely to change than the appearance.


4. Accessibility Attributes

What this means: These are labels that help people with disabilities understand what elements do - like audio descriptions for screen readers.

Real-world analogy: Like Braille labels on elevator buttons - they're added specifically to help people navigate and understand, so they rarely change.

Attributes like aria-label and aria-labelledby provide stable locators, especially for elements lacking other identifying attributes.


Examples:

html

<button aria-label="Close dialog">×</button>

<input aria-label="Search products" type="search">

<img aria-label="Company logo" src="logo.png">


How testing tools find these:

  • CSS: [aria-label="Close dialog"], [aria-label="Search products"], [aria-label="Company logo"]

  • XPath: //button[@aria-label='Close dialog'], //input[@aria-label='Search products'], //img[@aria-label='Company logo']


When to use: Great for accessibility testing and when other stable identifiers aren't available. These labels are maintained for legal compliance and user experience.


5. Relative XPaths (Use judiciously)

What this means: These are directions that start from a reliable landmark and navigate to your target.

Real-world analogy: Like saying "Find the McDonald's, then look for the blue car in its parking lot" instead of giving the car's exact GPS coordinates.

When other options aren't available, craft relative XPaths starting from stable anchor elements.


Examples:

xpath

//div[@data-component='product']/h2

//form[@id='checkout']//input[@type='email']

//section[@class='user-profile']//button[contains(text(), 'Edit')]


In plain English, these mean:

  • "Find the product component, then find the heading inside it"

  • "Find the checkout form, then find any email input inside it"

  • "Find the user profile section, then find any button that says 'Edit'"

Why use carefully: More complex navigation can break if the page structure changes, even though we're starting from a reliable point.


6. Complex CSS Selectors (Avoid When Possible)

What this means: These are overly complicated directions that depend on the exact layout and structure of the page.

Real-world analogy: Like directions that say "Go to the mall, enter through the main entrance, take the second left, go up the escalator, turn right at the third store, then find the blue kiosk" - too many steps that could change.

Overly complex CSS combinations that rely heavily on exact HTML structure become fragile during testing.


Examples of what to avoid:

css

div#content > ul.list > li:nth-child(3) > a

.header .nav ul li:first-child a.active

body > div:nth-of-type(2) > section.main > article:last-child


In plain English, these mean:

  • "Find the content area, then the list inside it, then exactly the 3rd item, then the link in that item"

  • "Find the header, then navigation, then list, then first item, then active link"

  • "Find the 2nd div in the page body, then main section, then the last article"

Why to avoid: If developers add, remove, or rearrange any elements in these paths, your test will break. It's like a house of cards - remove one piece and it all falls down.


7. Absolute XPaths 

(short term =yes ….but least preferred for the long run)

What this means: These are exact step-by-step directions from the very top of the webpage to your target element. Confusingly as it seems these work well during testing as they are often quite verbose, but they have a major flaw the verbosity is actually a weakness in the longrun.


Real-world analogy: Like finding a particular tree in a forest by saying "Walk straight from the forest entrance and find the 10th tree, then turn right and find the 8th tree - this is the tree you need." At first you think this is great , I can find the exact “Tree” (using our analogy) but come back a few months later and new trees may have grown so following those same directions will lead you to a completely different tree!


Full XPaths starting from the document root are the least desirable option for automated testing, but sometimes they're the only option available as they are relatively easy to find using browser tools. However, expect these to break every time there is a change made to the site.


Examples of what to avoid:

xpath

/html/body/div[1]/div[2]/p

/html/body/main/section[3]/div[1]/form/input[2]

/html/body/div[@class='wrapper']/header/nav/ul/li[4]/a


In plain English, these mean:

  • "Start at the top of the page, go to the 1st div, then 2nd div inside that, then find the paragraph"

  • "Start at the top, go to main content, then exactly the 3rd section, then 1st div, then form, then 2nd input"

  • "Start at the top, go to wrapper div, then header, then nav, then list, then exactly the 4th item, then link"


Why they fail:

  • Too Fragile: Any change anywhere in the page structure breaks the entire path

  • Hard to Understand: Nearly impossible to read and figure out what you're actually looking for

  • Can't Reuse: Only works on one specific page in one specific state


Best Practices

Communication and Collaboration

For Non-Technical Team Members:

  • Ask developers to add special testing labels (data-testid) to important elements

  • Request that important buttons and forms have meaningful, stable names

  • Advocate for testing considerations during design meetings

  • Document which elements are critical for your business processes


For Everyone:

  • Work with development teams to include data-* attributes for testing

  • Establish clear guidelines for creating testable UIs

  • Advocate for testing considerations during development


Selector Selection Guidelines

  • Prioritize Stability: Choose selectors least likely to change

  • Favor Semantic Meaning: Use descriptive attributes over styling-related ones

  • Regular Maintenance: Periodically review and update brittle selectors

  • Document Your Choices: Explain selector decisions for future maintainers


Simple Decision Tree:

  1. Does it have a testing label? → Use it! (data-testid)

  2. Does it have a unique, meaningful ID? → Good choice

  3. Does it have a class that describes its function? → Acceptable, but monitor for changes

  4. Does it have accessibility labels? → Useful backup option

  5. Do you need complex navigation? → Use sparingly and document well

  6. Are you considering absolute paths? → Stop! Find a better option


Why do elements have multiple selectors?

Simple Explanation: Just like you can identify your friend as "Sarah from accounting," "the tall blonde woman," "the person wearing the red jacket," or "the one sitting by the window," webpage elements can be identified in multiple ways.


Why this flexibility exists:

Different Levels of Specificity: Some identifiers are very specific (like your social security number), while others are more general (like "people wearing blue shirts"). Web developers can choose how specific they want to be.


Multiple Purposes: Elements serve different functions - they might need a unique identifier for programming, a class name for styling, and a label for accessibility. Each serves a different purpose.


Relationships Matter: Sometimes we identify things by their relationships - "the button next to the search box" or "the first item in the list." CSS and XPath can describe these relationships.


Page States: Elements might look different when you hover over them or click them. Special selectors can target these different states.


Maintenance and Readability: Different team members might prefer different approaches based on their role - designers think in terms of styling, developers think in terms of functionality, and testers think in terms of stability.


Real-world comparison: Think about how you might describe your car:

  • License plate number (unique identifier)

  • "The red Honda" (description)

  • "The car in the driveway" (location-based)

  • "Mom's car" (relationship-based)

Each description works, but some are more reliable than others depending on the situation!


Conclusion

The Bottom Line: Choosing the right way to identify webpage elements is like choosing the right way to give directions - you want something that will still work even if minor things change along the way.


Key Takeaways:

  • Best Choice: Testing labels added by developers (data-testid) - these are like permanent landmarks

  • Good Choice: Unique IDs with meaningful names - like street addresses that don't change

  • Okay Choice: Functional class names - like business names that might change but probably won't

  • Backup Choice: Accessibility labels - like official building names that are legally required

  • Risky Choice: Complex navigation paths - like giving directions with too many turns

  • Avoid: Absolute paths from the top of the page - like GPS coordinates that become wrong if anything moves


Remember: The best selector accurately finds your element while surviving webpage updates. When in doubt, talk to your development team about making the website more testing-friendly.


For Managers and Business Analysts: Investing time in proper element identification saves money and frustration later. Advocate for testing-friendly development practices from the start of your projects.


For Testers New to Automation: Start with the stable options at the top of our hierarchy. As you gain experience, you'll develop an intuition for which selectors will stand the test of time.


 
 
bottom of page