This article covers some of the most important CSS selectors for Selenium WebDriver, explaining the syntax and how to identify web elements. At the end of the post, you can find a downloadable CSS selectors cheat sheet 🤩
Table of Content
- What are CSS selectors?
- CSS selectors vs XPath
- Retrieving CSS selectors with TestProject
- How to use CSS selectors in your Selenium tests
- CSS selectors cheat sheet
- Advantages of using CSS selectors
- Conclusions [+Downloadable Cheat Sheet]
CSS selector is one of the best locator strategies for elements. Similar to XPath, it works when we don’t have unique IDs, names, or class names. The way CSS selectors work is by identifying the elements based on an attribute and its value. Chrome’s developer tools for example can help you get an element’s CSS selector, by right-click -> Copy -> Selector:
While in the Developer Tools, Elements tab, you can use the Search option to filter based on CSS selectors, and the console will highlight all the matching elements.
In my opinion, it’s not really a matter of one being better than the other. There will be cases where you prefer to use XPath instead of CSS selectors, and cases where you prefer CSS selectors instead of XPath. You can choose multiple locator strategies in the same test, depending on what works on the specific elements you want to interact with.
However, it’s considered that XPath is more computer-readable, while CSS selectors are easier to read by us humans.
There are some CSS selectors which can be easily translated to XPath since both types of locators allow identifying elements based on custom attributes and values, as well as finding child or descendant elements.
At the same time, you will see that some of the selectors explained in this article (such as visited links, or enabled elements) do not have an equivalent in XPath, so the only way to locate elements will be using a CSS selector.
On the other hand, XPath allows identifying parents and ancestors, which is not allowed in CSS.
Whether you are writing your own test code, or have recorded tests, you can use the TestProject for element identification.
In recorder mode, you can highlight an element, click ‘double-shift’ (or on the three dots menu) to freeze the element, and hover the Attributes menu item:
From the last menu, you can see the element’s attributes, and you can also opt to save the element. TestProject will automatically generate the correct XPaths and CSS Selectors for the element. You can also copy to clipboard any other attribute value if you want to build your own, more specific, locators.
Selenium allows us to locate elements by various strategies, but right now we’ll focus just on CSS selectors. The important thing to note is that if we try to locate a specific element, we have to be sure that the locator is unique, otherwise our tests will simply interact with the first element that matches the provided locator. On the other hand, there will be cases where we want to identify all the elements with a shared trait (for example, all links with class “product”).
In Selenium WebDriver, both scenarios can be easily achieved.
To interact with a single element, we will use the findElement() method, like this (the example is in Java, but the principle is the same in all programming languages):
This means that the (first) element that matches our locator will be the one returned by this line of code.
For multiple elements, we have the findElements() method (pretty intuitive, right? 😊):
This method will look for ALL elements that match the given CSS selector.
OK, now that we know how to use and obtain some CSS selectors, let’s look at a cheat sheet, which will go through most selectors. You’ll find examples and explanations for each of the selectors.
These are the most common selectors you will probably use. They relate directly to either an id, a class name, or an element’s attribute. The syntax is rather simple (all items are optional here, but can be combined in any number):
- The element type (e.g. button, input); if left empty, the selector will match any element type
- The id, preceded by the # (number sign) character
- The class, preceded by the . (dot) character
- (custom) attributes and their values, written between square brackets
As is the case with all locators, make sure they are unique if you are trying to identify a single element.
|Id||#name||Locates any element with the id “name”|
|input#name||Locates elements of input type with the id “name”|
|Class||.btn||Locates any element with the class “btn”|
|button.btn||Locates elements of button type with the class “btn”|
|.btn.btn-primary||Locates any element with both “btn” and “btn-primary” classes. This is particularly useful for elements we can only identify through multiple classes, because in these cases we cannot use the Selenium locator ClassName|
|Attribute||[name=’submit’]||Locates any element with the “submit” name. Any attribute can be used in place of the name.|
|button[name=’submit’]||Locates button elements with the “submit” name.|
|[id=’password’][placeholder=’Enter your password’]||Locates elements with id value “password” and with the placeholder value “Enter your password”|
CSS selectors allow us to also filter based on sub-strings. So in addition to the examples above, where we use exact values for ID, class, or attribute, we can also use just part of the text of the attribute:
|Begins with||[placeholder^=’Enter’]||Locates elements with placeholder value starting with the string “Enter”|
|Ends with||[placeholder$=’password’]||Locates elements with placeholder value ending with the string “password”|
|Contains||[placeholder~=’password’]||Locates elements with placeholder value containing the string “password”|
|[placeholder*=’password’]||Locates elements with placeholder value containing the string “password”|
As you probably know already, the HTML code has a tree structure, so the relationship between its elements is parent-child (vertically) and sibling (horizontally). Based on this, we can use CSS selectors to locate elements based on their parents, ancestors, and siblings.
|Child||div > input||Locates input elements that are direct descendants of a div element|
|Descendant||form input||Locates input elements that are descendants of a form element (on any level, the form does not need to necessarily be a parent)|
|First child||div button:first-child||Locates the first child of a div element|
|nth-child||div button:nth-of-type(2)||Locates the second button child of a div element|
|div button:nth-child(2)||Locates the second child of a div element, which is a button element|
|Last child||div button:last-child||Locates the last child of a div element|
|Sibling||h1 ~ p||Locates the p elements that follow an h1 element|
|Next sibling||h1 + p||Locates the p elements that follow directly after an h1 element (it doesn’t just have to be the first p element, but the immediate sibling)|
You can also identify elements based on some specific characteristics, which are preceded by the : (semi-colon) character. Let’s check some of them below:
|Unvisited links||a:link||Locates unvisited links|
|Visited links||a:visited||Locates visited links|
|Enabled elements||button:enabled||Locates enabled buttons|
|Disabled elements||button:disabled||Locates disabled buttons|
|Focused elements||input:focus||Locates the input element which has the focus|
|Checked check-box||input:checked||Locates the input elements which are checked|
|Read-only elements||input:read-only||Locates the read-only input elements|
|Mandatory elements||input:required||Locates the input elements which are required|
- CSS selectors are a great alternative for elements that don’t have unique IDs, or the IDs are dynamic and cannot be hard-coded in the tests.
- They allow identifying elements based on custom attributes, that are specific to your application, without always relying on IDs and classes.
- A great advantage for locating elements by class name using CSS selectors is that you can locate an element by multiple classes (which cannot be achieved by Selenium when using the find by class methods).
- The elements can be identified by any combinations of their attributes and the values of the attributes, including partial matches, and even hierarchical relations with other elements
- You can mix multiple attributes of the same element.
The CSS selector is one of the most versatile locator strategies for identifying web elements when working with Selenium.
👉 Download the cheat sheet of the CSS selectors presented in the article here 👈
Hope you enjoy it! ✨