Locating an element in Selenium WebDriver in Java
In the last article, we saw the internal architecture of Selenium WebDriver(WD). Today, we will learn how to locate an element uniquely in Selenium WD using Java.
There are various ways to locate an element in Selenium. Among them, mostly common are:
- Using CSS Selector
- Using Attributes
- Using Xpath
First, we will discuss the CSS Selector.
We can find an element in Selenium in one of 2 ways.
- driver.findElement() method
- FindBy annotation
The usual way to find an element is the driver.findElement(). FindBy annotation is used with the PageFactory class, which supports Page Object Model design pattern in Selenium.
Selecting an element using CSS Selector
There are various techniques to locate an element using CSS Selector. First ,we will see how to use attributes. First ,we will see how to use attributes.
Browse to google.com . Let’s say we will locate the search box of the homepage.
If we inspect the element, we can see there are multiple attributes available to locate this element. If we use the ‘name’ attribute, we can locate the element in the following way,
@FindBy(css = “input[name = ‘q’]”)
WebElement searchBox ;(it can be any name)
So, if we want to use some other attributes, we will just switch the attribute name and its value respectively.
Now what if, one attribute couldn’t locate the element uniquely? In this case, we might need to use multiple attributes at once. We can do it in the following way,
@FindBy(css = “input[name = ‘q’][type = ‘text’]”)
In this way, we can use as many attributes as we want, to locate an element uniquely.
Now, there might be a chance that the attributes an element contains, can’t locate itself uniquely. In this case, what we have to do is backtracking to previous elements until it is considered as unique.
Let’s consider the search button of google home page.
If we write,
@FindBy(css = “input[value = ‘Google Search’]”)
It will locate two elements. So, to solve this issue, what we can write is,
@FindBy(css = “div.FPdoLc input[value = ‘Google Search’]”)
Now, if we check, we will see that the element has been located uniquely.
There is a new term here, i.e. div.FPdoLc.
Here, div is a previous tag of the input tag, and FPdoLc is the class name. So, as we can see, we can select a class using ‘.’ selector. We can also use it without referring to the tag name too.
@FindBy(css = “.FPdoLc input[value = ‘Google Search’]”)
If there are multiple classes available in a single element, we can take them simultaneously as per our need. For example, in the search button,
@FindBy(css = “.FPdoLc.tfB0Bf input[value = ‘Google Search’]”)
Now, as we are working with multiple tags to locate an element, we can use some techniques to solve our task more efficiently.
If two elements are in a nested format and we want to use both of them, we can use ‘>’ selector. But keep in mind that it can only select the very next element of the element that is written on the left side of the ‘>’ operator. An example will clear the matter properly.
Let’s consider the element of the search button again. Say, we want to locate the <center> tag. What we can write is,
@Findby(css = “.FPdoLc > center”)
Now if we want to move to the input tag too, we can write,
@FindBy(css = “.FPdoLc > center > input[value = ‘Google Search’]”)
So, if we want to access a child element, we can use ‘>’ selector.
There is another selector which is ‘+’. It is used to locate adjacent elements. If we take the search button scenario again; let’s say we want to locate the “I’m Feeling Lucky”’ button.
By inspecting the element, we are assured that the two <input> tags are adjacent. So, we can write,
@FindBy(css = “.FPdoLc > center > input + input”)
Now, what if we had 15 or 20 adjacent <input> tags here instead of only two? Do we have to write all the <input> tags with the ‘+’ selector, to reach our desired element?
The answer is “NO”. In that case, we have a css-selector called “nth-child(value)”
So, to select the “I’m feeling lucky” button, we can write,
@FindBy(css = “.FPdoLc input:nth-child(2)”)
It starts working from the first adjacent element. So the value inside of the parenthesis counts from top to bottom. Now, if we want to count from bottom to top, we can write,
@FindBy(css = “.FPdoLc input:nth-last-child(1)”)
This selector plays a crucial role when we locate a drop down menu value, where there are multiple <li> tags. It is also useful while locating a specific row from a table.
Till now, we have only selected elements using FindBy annotation. Now, we will see how to use driver.findElement(). The css-selection process will remain the same.
To select the search box of the google homepage, we will write,
WebElement searchBox = driver.findElement(By.cssSelector(“.FPdoLc input[value = ‘Google Search’]”))
So, today we have learned how to use CSS Selectors to locate an element uniquely. In the next article, we will discuss how to use attributes explicitly and how to use xpath. Till then, Happy Testing!