Why I Avoid IDs and CSS Selectors as Locators

Priyanshu S Avatar

I know this topic might seem old, repetitive, and even boring. There are tons of articles online discussing the best locator strategies to make automated UI tests faster and more reliable.

So, what’s new I’m going to share?

Well, I’m not sure if it’s new, but I’ll share my personal experience with locators.

I view locators differently than how most automation engineers recommend. To me, locators represent the user’s interaction with the system, and I try to make them as close as possible to reflect how real users interact with the HTML elements.

For example, IDs are the most popular selectors due to their ease of use and uniqueness on a page. However, an ID might not be directly tied to the behavior or appearance of an element. On the other hand, CSS classes can also be renamed or modified without actually affecting how the element looks or functions.

This makes these attributes prone to unplanned changes. Alterations to these locators often don’t affect the user’s interaction with the application, but they can definitely break automated tests if used as selectors in the test.

As I mentioned, these changes are usually unplanned because Jira cards or task descriptions don’t capture details at such a granular level. As a result, QAs are often unaware of these changes until their automated tests start failing. Using these attributes as selectors in automated tests may not be the best idea, as these are prone to change often, increasing the effort to maintain UI automated tests.

What can’t be changed on the Page?

What cannot be changed so easily is the visible behaviour on the page. For example, a button labeled “Submit” can’t simply be renamed, as this could confuse users and disrupt their experience. Changes to visible text or element roles will always be planned because they impact user experience. These changes will always go through multiple conversations and will be informed to the team in advance.

Does this give you a clue about my locator strategy?

I prefer to use locators based on the role assigned to elements on the page and their visible text, unless my application visible text can be changed by language settings.

For instance, a button that submits a login form has an implicit role of “button” and is labeled as “Login” or “Submit.” So, my preferred locator for this button, which takes priority over IDs, CSS selectors, or any other HTML attributes—is getByRole in Playwright.

Example, page.getByRole('button', {name: 'Submit'})

Why Does getByRole Beat ID, CSS, or Other HTML Attributes?

As mentioned above, it’s highly unlikely that a button (which has aria-role as button) to submit a login form would be replaced with another HTML element having a different aria-role. Similarly, a developer can’t simply change the label on the login button to something else without a plan, as it could impact the user experience.

This combination—the element’s role and its label—makes for a robust choice when locating an element, as changes to this combination are rare. As a result, the likelihood of tests failing due to locator changes is significantly low compared to other locators.

If you want to dive deeper into getByRole and understand the concept of aria-role, I’ve written a detailed article, you can check out.

PlayWright official documentation about getByRole.

Does GetByRole work in Selenium WebDriver?

Selenium WebDriver does not have support for aria-role, only if an element has attribute as role then an Xpath or CSS can be used having role as attribute. Implicit roles, where role attribute is not present, aren’t supported by WebDriver.

Your subscription encourages me to write more insightful articles.

Subscribe to my newsletter and explore Quality Assurance beyond just manual and automation testing!

We don’t spam! Read our privacy policy for more info.

Thank you for reading this post, don’t forget to subscribe!

Priyanshu S Avatar