CSS Selector In Selenium WebDriver: As an automation test engineer, you know the importance of the Locators in the Selenium WebDriver testing tool. In our previous post, we have discussed how we can locate an element using ID, Name, Class Name, Tag Name, Link Text, Partial Link Text. Those are very common attributes by using those you can easily identify a static element. Still, for handling or locate dynamic elements of a webpage, you can use two powerful location strategies like XPath and CSS Selector.
Read Also: XPath Locators in Selenium
For better understanding about XPath in detail, we have tried to cover all possible scenarios in a Separate post, and you can check that by following this link. But in this post, we are going to cover how to locate an element using the CSS Selector in detail with real-time examples.
What is CSS?
The full form of CSS is Cascading Style Sheets, which is a simple design language that is mainly developed to make the webpage presentable because CSS handles the looks and feels part of a web page.
Difference Between CSS Selector VS XPath
You can find Xpath and CSS selectors are the most used location strategy to locate the element on the webpage. But there is a strong competition going on discussion among which is more powerful between XPath and CSS Selector. But those are in favor of CSS selector they are mentioning that the CSS Selector is more acceptable due to the following reasons
- CSS is more readable (Simpler)
- CSS is faster (Especially IN IE)
and some are mentioning that By using XPath, you can traverse all the elements of a webpage wherein CSS selectors you can traverse only down to the DOM.
But in our point of view, it is better to master in both CSS selector and XPath.
CSS Selectors in Selenium
Let us discuss the different ways of identifying the elements using the CSS selector. Few basic keywords are used to locate elements like:
- ID
- Class
- Attribute
- Sub-String
- Inner String
A dot (.) Operator Select the Class Selector
The Dot operator (.) represents a class in selenium, so by using the dot operator, you can identify web elements that are specified with the class attribute. For Example
<p class= “pages-sub-title”> SoftwareTestingo Test blog post on validating CSS Selectors </p>
If you remember in Xpath for locating this element we can write the XPath like this //p[@class = ’value’] but in CSS we can have identified the same element by the following syntax:
.[“Class Value”]
“.pages-subtitle”
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_Class { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector(".pages-sub-title")); String elementText=text.getText(); System.out.println("Element Text: "+elementText); Thread.sleep(5000); driver.close(); } }
Output:
Element Text: SoftwareTestingo Test blog post on validating CSS Selectors
ID Selector
Here “#” represents ID, which is used to locate the element which is specified with the ID attribute. Let’s take an example for better understand.
<li id="menu-item-143" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-143"> <a href="https://softwaretestingo.blogspot.com/2020/08/css-selector.html">Product Updates</a> </li>
If you can see the above example, then to locate in XPath, we can write this by //li[@id=’menu-item-143′], but for the same web element, we can write like this #menu-item-143.
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_ID { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("#menu-item-143")); String elementText=text.getText(); System.out.println("Element Text: "+elementText); Thread.sleep(5000); driver.close(); } }
Output:
Element Text: Product Updates
Attribute Selector
When we see the page source of some web pages then we can see like below:
<div class="modal fade" id="whitepaper-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <span class="close" data-dismiss="modal" style="top: 4px; position: absolute; right: 10px;"> <span aria-hidden="true">×</span> </span>
Where you can see the above source code, you can find out some attributes are like key-value pairs, for example, ‘role = dialog,’ ‘data-dismiss = modal’ etc. For locating such web elements in XPath, we are writing the syntax like this tag name [@attribute key = ‘attribute value’ ].
The Same we can write in CSS Selector by like this
div[role=’dialog’] or [role=’dialog’]
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_Attribute { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("div[role='dialog']")); String elementText=text.getText(); System.out.println("Element Text: "+elementText); Thread.sleep(5000); driver.close(); } }
Output:
Element Text: SoftwareTestingo
SubString Match
As of now, we are discussing the simple ways to locate web element, let us go a little bit deeper and try to understand how we can more efficiently locate elements with the help of powerful querying technique such as:
- ^ indicated a prefix
- $ indicating suffix
- * indicating substring
If you observe, then you can find out these are much similar to the Xpath functions like starts-with, contains, and ends with. Let us start to understand by taking some real-world examples
<div id=”123_randomId”>
<div id=”randomId_456″>
<div id=”123_pattern_randomId”>
^ indicated prefix
If the attribute value of an element is frequently changing, but the value starting a few characters are constant. Still, the rest of the characters are changing, and then, in that case, you can use the wild prefix character (^) for uniquely identify the element. the syntax is like below:
tag[attribute^=’starting text’]
Example:
input[id^=’user’]
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_Prefix { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("div[id^='123_ra']")); String elementText=text.getText(); System.out.println("Get Element Text Using Prefix Locator: "+elementText); Thread.sleep(5000); driver.close(); } }
$ indicating suffix
Similarly, prefix if the last characters are constant, but the starting characters are changing, then to locate such an element, we can use the wild suffix character ($). the syntax looks like this:
tag[attribute$=’ending text’]
input[id$=’message’]
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_Suffix { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("div[id$='456']")); String elementText=text.getText(); System.out.println("Get Element Text Using Suffix Locator: "+elementText); Thread.sleep(5000); driver.close(); } }
* Indicating a substring match
Suppose you don’t have complete attribute details, or you have partial attribute value details in that case when we are using XPath that time we are using the contains() functions. Similarly, when we are using CSS selector at that time, we can use an asterisk (*) and the syntax looks like below:
tag[attribute*=’containing text’]
Example:
input[id*=’er-messa’]
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_Substring { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("div[id*='pattern']")); String elementText=text.getText(); System.out.println("Get Element Text Using Substring Locator: "+elementText); Thread.sleep(5000); driver.close(); } }
How to Navigate to Child Elements
At the time discussing Xpath, we have discussed how we can access the child elements with the help of the Axes concept. Similarly, here also some advanced techniques present to deal with the child and grandchild elements. That is:
- Direct Child
- Grand Child
- Nth Child
Direct Child
For locating an Immediate child of a node in Xpath, we are using ‘/,’ but in CSS, we can use the ‘>’ to identify the immediate child element.
Path: //div/a
CSS: div > a
package com.selenium.practice.locator; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_DirectChild { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); List<WebElement> list=driver.findElements(By.cssSelector("ul[id*='browsers']>li")); System.out.println("Printing All Elements Text In Console"); for(int i=0;i<list.size();i++) { System.out.println(list.get(i).getText()); } Thread.sleep(5000); driver.close(); } }
Child or Grand Child Element Locate
If an element has child element or there are some grandchild elements are present then to locate those elements we are using “//”. for the same operation you can use the white space like below:
XPath: //div//a
CSS: div a
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_GrandChildElement { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("ul p")); String elementText=text.getText(); System.out.println("Get Grand Child Element Text Using CSS Selector: "+elementText); Thread.sleep(5000); driver.close(); } }
Nth Child
When we are dealing with the table or ordered or unordered list this concept will be more helpful. Here N represents the number of the desired number element. Let us take a simple example to understand it:
<ul id=”browsers”>
<li>Chrome</li>
<li>Firefox</li>
<li>Edge</li>
<li>Safari</li>
</ul>
If you see the above code, you can find that’s a list and from that, our requirement is to select the 2nd element from that list. We Can achieve that by following the below CSS Selector syntax:
#browsers li:nth-child(2)
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_SelectNthChildEx1 { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); //Select 2nd Child Element WebElement text=driver.findElement(By.cssSelector("#browsers li:nth-child(2)")); String elementText=text.getText(); System.out.println("Get 2nd Child Element Text Using CSS Selector: "+elementText); Thread.sleep(5000); driver.close(); } }
There is another way to locate the second element and that is
ul#browsers li:nth-of-type(2)
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_SelectNthChildEx2 { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); //Select 2nd Child Element WebElement text=driver.findElement(By.cssSelector("#browsers li:nth-of-type(2)")); String elementText=text.getText(); System.out.println("Get 2nd Child Element Text Using CSS Selector: "+elementText); Thread.sleep(5000); driver.close(); } }
Similarly, we can easily select the last element in the list by using this
ul#browsers li:last-child
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_SelectLastChild { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); //Select Last Child Element WebElement text=driver.findElement(By.cssSelector("#browsers li:last-child")); String elementText=text.getText(); System.out.println("Get Last Child Element Text Using CSS Selector: "+elementText); Thread.sleep(5000); driver.close(); } }
<div id="123_randomId">123</div> <div id="randomId_456">456</div> <div id="123_pattern_randomId">789</div>
From the above list if we want to select the 123 elements then for that element the CSS value is
div[id^=’123_rand’]
Locate Immediate Element Using CSS Selector
But based on the 123 elements how you can select the immediate element then you can use this
div[id^=’123_rand’] + div
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_ImmediateElement { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html"); Thread.sleep(10000); WebElement text=driver.findElement(By.cssSelector("div[id*='123_randomId']+div")); String elementText=text.getText(); System.out.println("Get Immediate Element Text Using CSS Selector: "+elementText); Thread.sleep(5000); driver.close(); } }
Multiple Attribute In CSS Selector
When we are Locating some elements by using CSS selector sometimes it is very much difficult to locate an element using a single attribute. In that case, to locate that specific element we have to use multiple attributes so that we can be more specific with the selection criteria in order to locate the correct element as per our requirement.
For examples let’s see the below piece of code:
<div class=”ajax_enabled” style=”display:block”>Sample Ajax</div>
In the above code snippet, the value of display can be changed to None or block, its totally depend upon the ajax call. So to locate such elements we have to use both class and style.
Show in the below example we are trying to explain to you how to locate such elements by using multiple attributes.
package com.selenium.practice.locator; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_MultipleAttributeEx { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector-adv-example.html"); Thread.sleep(10000); //Use Of Multiple Attribute WebElement text=driver.findElement(By.cssSelector("div[class='ajax_enabled'][style='display:block']")); String elementText=text.getText(); System.out.println("Get The Element Text Using Multiple Attribute: "+elementText); Thread.sleep(5000); driver.close(); } }
Attribute NOT contain a specific value
During testing a scenario where you don’t want to select which have some specific values in an attribute. in the above all scenarios we have to understand how you can select the elements based on the values but now we are going to understand how not to select by specific attribute value.
<div class="day past calendar-day-2017-02-13 calendar-dow-1 unavailable">123</div> <div class="day today calendar-day-2017-02-14 calendar-dow-2 unavailable">456</div> <div class="day calendar-day-2017-02-15 calendar-dow-3">789</div> <div class="day calendar-day-2017-02-16 calendar-dow-4">111</div>
In the above example, we don’t want to select those elements whose attribute value contains unavailable, So we can achieve that by like below:
div[class*=calendar-day-]:not([class*=’unavailable’])
package com.selenium.practice.locator; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class CSSSelector_NotAttributeEx { public static void main(String[] args) throws InterruptedException { WebDriver driver; System.setProperty("webdriver.chrome.driver","Path Of Browser Driver"); driver=new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector-adv-example.html"); Thread.sleep(10000); List<WebElement> list=driver.findElements(By.cssSelector("div[class*=calendar-day-]:not([class*='unavailable'])")); System.out.println("Printing All Elements Text In Console Which Does Not Have Unavailable"); for(int i=0;i<list.size();i++) { System.out.println(list.get(i).getText()); } Thread.sleep(5000); driver.close(); } }
Leave a Reply