Let's discuss CssSelector, a lesser-known figure in the Selenium community.

Photo by KOBU Agency on Unsplash

Let's discuss CssSelector, a lesser-known figure in the Selenium community.

As we know, to identify an element in the Application Under Test, the tool needs to identify the element and this is the place where the tool needs to be performant enough, in the case of selenium we have plenty of options like Id, xPath, CSS, etc

ID

These are simple and unique, so they operate quickly, but it is hard for a developer to utilize them for every other DOM element.

driver.findElement(By.id("unique_key"));

XPath

XPATH is a query language for XML-like documents, so they require an additional layer of translation to be processed by the browser, which can introduce performance overhead.

to fetch xpath for any Element in the website, follow the below steps

  • Open developer tools of the browser

  • Navigate to the element in the DOM

What we get is : /html/body/div[1]/div[3]/form/div[1]/div[1]/div[4]/center/input[1]

xpath is nothing but a path for Selenium to locate the element

string searchBtnXpath = "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[4]/center/input[1]";
driver.findElement(By.xpath(googleSearchBtnXpath));

cssSelector

If you want your scripts to be effective even when there isn't an element's id, cSS Selector is the way to go.

CSS selectors have native browser support, making them faster in execution. Browsers are optimized to handle CSS selectors efficiently, as they are part of the fundamental web technologies.

Let's discuss how we could use CSS in place of xPath

  • When we have id for an element
string searchBtnId = "UniqueBtn";
driver.findElement(By.xpath($"//div[@id='{searchBtnId}']"));
driver.findElement(By.cssSelector($"#{searchBtnId}")); // # is used for id
  • When we need to point to a class

      string searchBtnClass = "className";
      driver.findElement(By.xpath($"//div[@class='{searchBtnId}']"));
      driver.findElement(By.cssSelector($".{searchBtnId}")); // . is used for class
    
  • When we have a single type of element on a page

string imageTypeElement = "img";
driver.findElement(By.xpath($"//{imageTypeElement}"));
driver.findElement(By.cssSelector($"{imageTypeElement}"));
  • When we need to point a direct child
driver.findElement(By.xpath("//div/a"));
driver.findElement(By.cssSelector("div > a"));
  • When we need to avoid any changes and point to a sub-child by skipping layers

    • xpath does it with two-forward slashes {//}

    • css does it with a whitespace

 driver.findElement(By.xpath("//div//a"));
driver.findElement(By.cssSelector("div a"));

When we want to select an element whose identifier is not given but we know it's sibling's identifier

<form class = "form-signin" role = "form" action = "/index.php" method = "post">
<input type = "text" id = "username" name = "username" placeholder = "username" required autofocus></br> 
<input type = "password" placeholder = "password" required> 
<button type = "submit" name = "login">Login</button> 
</form>

Now, suppose we want to enter details in the password text bow, how do we do this is

string xPathForPassword = "//input[@id='username']/following-sibling:input[1]";
string cssForPassword = "#username + input";

//To select button using usernane
string cssForButton = "#username + button[type="submit"]";

A scenario where we have only a class name and want to select a specific element type

<input class="control" type = "text"></br> 
<label class="control">Name:</label>

css for label will be
cssOption1: label.control 
cssOption2: label[class='control'] #it will select the element which has only one class 'control'
xpath : //label[@class='control']

To have multiple conditions for an element

string xPath = "//input[@name='login'and @type='submit']";
string css = "input[name='login'][type='submit']";

To select items from a list, to select 3rd item from list

<ul id = "cars">
<li>Car1</li>
<li>Car2</li>
<li>Car3</li>
<li>Car4</li>
</ul>

cssOption1: #cars li::nth-of-type(3)
cssOption2: #cars li::nth-child(3)
cssOption3: #cars *::nth-child(3)
xpath : //ul[@id='cars']/li[3]
  • The special case when we need to work with partial string matching

      TO LOCATE A div WHOSE ID STARTS WITH 'Prefix_'
      toMatchPrefix: div[id^='Prefix_']
    
      TO LOCATE A div WHOSE ID ENDS WITH '_Suffix'
      toMatchSuffix: div[id$='_Suffix']
    
      TO LOCATE A div WHOSE ID CONTAINS 'subString'
      toMatchSuffix: div[id*='subString']