2019-03-20

CSS selectors guidelines for smooth test automation with Selenium

Mind exploding trying to locate a DOM element and after 20 minutes you get a selector like that?
.elem__container_search div:nth-child(1) .row1 tr:nth-child(5) input:nth-child(2)
or even worse you have to switch to xpath? And after a while you realize it is not correct spending more time? Or someone changed input elements order and your tests are broken?

You should be able to address any important application element in a page with no pain in seconds with a CSS selector: .last-update is better than .row1 tr:nth-child(5) input:nth-child(2), do you agree?

If your answer is yes, this article if for you!

Do not blame developers, provide guidelines and examples

First of all do not blame developers for poor CSS selectors, provide guidelines and examples instead! Nowadays is even more important providing guidelines because with some Javascript frameworks you might see cryptic, sometimes random (!!!), codes as classes and ids not usable for our purposes.

Test robustness, test automation development and maintenance time are affected by poor selectors

In other terms a bad page design affects productivity:
  • you should locate an element in seconds instead of minutes (.last-update vs .row1 tr:nth-child(5) input:nth-child(2))
  • the .row1 tr:nth-child(5) input:nth-child(2) selector might not be valid for users with different roles while .last-update will be always valid
  • if the elements order change, no broken tests and .last-update will remain still valid (with xpath or selectors like .row1 tr:nth-child(5) input:nth-child(2) you will get broken tests)
... so less time wasted and more money with good conventions.

Define frontend development conventions together and follow them


If you are using a framework or a CMS probably there will be already a good selectors guideline so you can make it yours if it fits your needs, extend it if needed and contribute back with improvements.

You can write examples for common use case so that everyone speaks the same language. E.g., define a naming convention for elements with status class="wifi wifi--state-on" / class="wifi wifi--state-off".

Alternatively you can adopt an existing and possibly widely used existing convention like BEM (Block Element Modifier - a methodology that provides a naming convention for frontend developers):
or any other similar initiative.

Final thoughts

Sometimes you don't control the web application you are testing so you need to explain what you are expecting and why it is important communicating the improvements in terms of better test automation robustness and development time.



It is also useful measuring the time wasted due to bad practice so that you might support better your proposal reporting to the management real numbers in terms of saved/lost money.

So my final suggestion is to find a solution together so that every future page will follow agreed guidelines according to existing best practice if possible.

And as a developer always keep in mind the following questions as double check:
  • am I able to locate this element with no pain?
  • am I able to understand the status of this element?