CSS selectors are used to decide the style to apply to an element on a web page. Selenium cleverly reuses them in order to choose the correct element to interact with. Here, we look at what CSS selectors are and some of the pitfalls of relying on them.
CSS, or cascading style sheets, is the standard approach to web design. Surprisingly, CSS was first proposed 25 years ago, making it almost as old as HTML itself. CSS is used by web browsers to determine how to style each element on the page. The cascading part of the name comes because CSS uses a hierarchy of styles. CSS is a very powerful and flexible approach to web design and has been the standard for the last 2 decades.
When a web page renders, the browser looks for the correct style to apply from the style sheet. It determines this using CSS selectors. Anyone who has created a .css file will be familiar with these, but you might not be aware of the details:
Simple Selectors: Type, Class, ID, Universal, and Attribute
E.g. h1, p, li, *
Combinators: Adjacent Sibling, General Sibling, Child, Descendant, and Column
E.g. ul > li, h3 + p, h2 ~ p
E.g. :active, :checked, :visited
E.g. p::first-line, li::after
By using these, you can define each element on your page and thus specify what style it should be given.
Selenium reuses CSS selectors in order to uniquely identify each element in your UI. It can then select that element and interact with it. For example, on the Facebook homepage you could use “css=input#email” or “css=input.inputtext” to specify the “email or phone” box on the login form.
Above, I said that Selenium can use CSS selectors to uniquely identify an element on the page. However, the nature of CSS means many elements will have multiple CSS selectors that could define them. The real trick with writing Selenium scripts is finding the selectors that uniquely identify the element. Remember, Selenium is a scripting language. This means it will select the first element that matches the pattern you specified.
A naive test engineer might try to use “css=input.inputtext” to complete the password on the Facebook homepage. But because this field comes after the email field, the wrong field will be selected. Instead, they should use “css=input#pass”.
So, how can you find the best selector to use? Fortunately, there are some tools that can help. And one of the simplest is Chrome’s Developer Tools. You can bring up the Developer Tools by pressing F12. But for this, we will use a different approach. Assume we want to find the selector for the main search box on the Google homepage.
Go to the Google home page. Right-click on the search box and choose “inspect”. This opens the Developer Tools with the correct element highlighted in blue.
Right-click on this highlighted text, choose “Copy>Copy Selector”.
Now the correct selector has been copied to your clipboard. In this case, it’s quite complex:
#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input
CSS selectors are pretty powerful, however, there are a few things to bear in mind.
Firstly, if your developers make even a minor change to the page, it could affect the selectors you use in your tests. This is especially true if you didn’t take care to use a unique selector. This is the biggest trigger for test failures and the associated maintenance.
Secondly, if an element exists within a child DOM, you can find the CSS selector, but Selenium won’t have access to it. The only way to access it is via an XPath. But note that Chrome Developer Tools also allow you to copy the XPath for an element.
Thirdly, sometimes it can be tempting to create really complicated CSS selectors in order to specify a unique element. But remember, it may be someone else who has to maintain your scripts later. So, try and choose the simplest selector that will achieve what you need.
Hopefully, you are now a bit more familiar with the concept of CSS selectors in Selenium. They are one of the most powerful ways to select elements in your UI. However, you will always be at risk of them changing as a result of code changes. This is why our Intelligent Test Agent uses a far more complex set of parameters to identify elements on your UI, vastly reducing test maintenance. These include CSS-selectors, but also include other factors like element visibility, server responses, the relative position of elements on the page, and Xpaths. These allow us to build a complete model of your UI, thus making our tests virtually maintenance-free.