Why this post?
Testers need to know multiple ways of locating an element in a webpage as different strategies have to be used based on the context since each has its own advantage. The Cascading Style Sheet(CSS) is defined to structure and style the HTML in the webpage. These CSS patterns can be used to uniquely identify elements in the webpage. This post will help you get started with CSS selectors. I have modeled this post to address the difficulties I faced learning CSS selectors online.
Setup
A couple of difficulties I faced while learning CSS is that most posts are pretty mundane and very abstract. I have made an effort to not do the same. Every example I have used in this post is derived from the Qxf2 tutorial page that will never change. That way you can practice writing CSS selectors to your heart’s content.
Install the CSS and XPath checker plugin for Chrome, open the tutorial page on a new tab and follow along.
Overview
This post has been structured in a way that it:
1. gets you started with the basic patterns
2. introduces you to positional pseudo-classes
3. tabulates a few useful patterns.
1)Basic patterns
Basic patterns include identifying elements by their tag, by their id, by their name attribute and their class. For example, let us try deriving CSS selectors for the Phone No text field in the tutorial page.
To view the html properties of the Phone No field, right click on it and select inspect.
To select the Phone No textfield,
or
Although #phone can be used to locate the text field,there can be other CSS locators too for the Phone No text field.You can practice the remaining basic patterns (HTML tag, id, class) by referring to the table below.
Selector | Example | Example Description |
element | input | This pattern selects all input elements in the web page. |
.class | div.checkbox (or) .checkbox | This pattern selects the element with the class .checkbox |
[attribute=’value’] | input[type=’phone’] (or) [type=’phone’] | This pattern selects the input element whose type attribute value is phone. |
Consider the following HTML property for the Example Table,
The CSS selector for the above table can be [name='Example Table']
or to specify that the value starts with a particular word [name^='Example']
or [name$='Table']
if the value ends with word Table. [name*='Example] or [name*='Table']
can be used to specify that the value of the attribute contains the particular word.
2)Pseudo-class
Sometimes you are lucky and every element in your application has a name or an id or a unique class. However, when you start dealing with tables and dynamic data, it is good to know about Pseudo-classes. Pseudo-classes are used to locate an element based on their state/position. Pseudo-classes are preceded by ‘:’. Let us try writing selectors for the buttons in the example form with pseudo-classes.
Let us try deriving a CSS selector for the Click me! button using a pseudo-class. The HTML snippet for the Click me! button is,
The CSS selector using pseudo-class is,
Now the HTML snippet for Gender button is,
The CSS selector for the Gender button can be,
Do you notice 2 matches instead of one? Wondering why?? The Click me! button despite being the only child is also taken into consideration for the first-child
pseudo class. Hence the pseudo-class has to be used in combination with any other basic patterns. Therefore the CSS selector for the gender button is,
It is not possible to discuss all the Pseudo-classes(for more pseudo classes click here.) but anyone who wants to learn CSS should start by knowing the difference between the most commonly used position based pseudo-classes – nth-child
and nth-of-type
classes. Let us try and learn the difference with the following example,
Consider the HTML properties of the Example Form in the tutorial page:
<div class="form-group"> <label for="name">Name:</label> <input type="name" class="form-control" name="name" id="name" > </div> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" name="email"> </div> <div class="form-group"> <label for="pwd">Phone No:</label> <input type="phone" class="form-control" name="phone" id="phone"> </div> |
The CSS selector to select the email text field would be div.form-group:nth-child(2)
. The nth-child pseudo-class here would select any element that is a div
and is the second child. The CSS selector for the above element can also be
div.form-group:nth-of-type(2) |
The nth-of-type
pseudo-class selects any element that is second of the type
Imagine if developer decides to have a gender button next to the name field, the HTML properties after the new change would look like this,
<div class="form-group"> <label for="name">Name:</label> <input type="name" class="form-control" name="name" id="name" > </div> <span class="form-group"> <button class="btn btn-primary dropdown-toggle status" type="button" data-toggle="dropdown">Gender </button> </span> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" name="email"> </div> <div class="form-group"> <label for="pwd">Phone No:</label> <input type="phone" class="form-control" name="phone" id="phone"> </div> |
Now,
div.form-group:nth-child(2) |
Would not identify any element as the div
element is no longer the second child. Whereas,
div.form-group:nth-of-type(2) |
Would select the email text field as the second div
element corresponds to the email text field
3)Other important patterns:
Sometimes the you need to identify elements relative to another well identified element. This section will show you how. Generally these patterns are used in combination with pseudo-classes(except :not
which is already a pseudo-class).
Consider the following HTML snippet,
To select the child of any element,
And to select the grandchild of any element,
The element>child
pattern is used to select the child of that element. In order to select the child and grandchild of any element element grandchild
pattern can be used. The reason why you see 4 matches is because there are 4 th
elements in the Example Table.
Try out the other useful patterns in the following table,
Selector | Example | Example Description |
element+element | label+input | This pattern is used to select the input element that is immediately next to the label element |
element~element | label~input | This pattern is used to select the input that is after the label element. Unlike the previous example the input element doesn’t necessarily have to be next to label |
element,element | input#name,input#random | This pattern selects both elements or any element that is present |
not | :not(input) | This pattern selects every element that is not an input element |
References
1. Flukeout-CSS diner game :flukeout CSS Diner
2. Chris Coyier’s piece on pseudo-class: https://css-tricks.com/pseudo-class-selectors/
3. How to use CSS selectors for identifying webelements post on softwaretestinghelp.com: http://www.softwaretestinghelp.com/css-selector-selenium-locator-selenium-tutorial-6/
4. w3schools.com: http://www.w3schools.com/cssref/css_selectors.asp
A fun practice exercise!
Someone gamified learning to write CSS selectors and we love it!! Checkout flukeout CSS Diner. I know we mentioned this a couple of times, but it is worth repeating again!
If you liked this article, learn more about Qxf2’s testing services for startups.
My expertise lies in engineering high-quality software. I began my career as a manual tester at Cognizant Technology Solutions, where I worked on a healthcare project. However, due to personal reasons, I eventually left CTS and tried my hand at freelancing as a trainer. During this time, I mentored aspiring engineers on employability skills. As a hobby, I enjoyed exploring various applications and always sought out testing jobs that offered a good balance of exploratory, scripted, and automated testing.
In 2015, I joined Qxf2 and was introduced to Python, my first programming language. Over the years, I have also had the opportunity to learn other languages like JavaScript, Shell scripting (if it can be called a language at all), and more recently, Rust. Despite this exposure, Python remains my favorite language due to its simplicity and the extensive support it offers for libraries.
In my free time, I like to watch football (I support Arsenal Football Club), play football myself, and read books.
Wow, marvelous weblog layout! How lengthy have you been blogging for? you made blogging glance easy. The overall look of your website is fantastic, as well as the content.