Locators in Selenium are one of the most powerful commands. Its ideally the building block of the Selenium automation scripts. It helps locate the GUI elements through which multiple user actions can be performed. These are one of the important parameters for scripting, and if they end up to be incorrect or brittle, they may lead to script failure. A good scripting base foundation requires elements to be located appropriately. For this, we have multiple locators in Selenium WebDriver. Below is the list of these locators of Selenium WebDriver :
- ID
- Name
- Linktext
- Partial Linktext
- Tag Name
- Class Name
- DOM Locator
- CSS Selector
- Xpath
Using the above locators in Selenium WebDriver you can locate elements through “findElement/findElements” syntax. I will be demonstrating that for each locator of Selenium, in detail below. However, before we dig in to locate these elements through the above ways, let’s see how to find elements in DOM(Document object model).
Steps To Find Element In DOM:
- Open the target application and click on F12 or right click and select inspect.
- A console window would open known Developer tools.
- A section name as ‘Element’ would be default opened. This is where we locate elements through. To the left most, you can observe a mouse icon. As you hover on it, it would state ’select an element in the page to inspect it’. Click on it and navigate to the element you wish to locate to. As you click on the element you want to locate, the DOM would be highlighted for that element, something like below:
- This is it, the selected row in the DOM is the context from where you need to fetch your values from, in the example above, the highlighted DOM value is:
<a href="https://accounts.lambdatest.com/register" target="_blank">Free Sign Up</a>
Now you can choose the tagname i.e ‘a’ and text i.e ‘Free Sign Up’ to locate your element.
The above technique will be used throughout my article for demonstrating the CSS locators in Selenium WebDriver . Now, we look on how to find locators in Selenium WebDriver.
ID Locator In Selenium
This is the most common way of locating elements considering that they are unique to each element in the DOM(Document Object Model). Based on the World Wide Web Consortium(W3C) ID’s should be unique to elements and hence are considered as the fastest and safest method to locate element. But unfortunately, developers may or may not follow this rule as browsers do allow bypassing this rule. Specifically, in the case of a table or list the ID’s may populate incrementally or dynamically depending upon the data, which leads to locating such elements through other means.
Below is an example of Makemytrip showcasing how ‘login’ field is been located via ID:
Below is the DOM structure of it:
<div class="inputM make_relative"> <input id="ch_login_email" type="text" required=""> <span class="inputM__highlight"></span> <span class="inputM__bar"></span> <label>Email/Mobile number</label> <div class="ch-error-msg ch-clearfix" id="ch_login_email_error" style="display:none"> <p class="o-i-error-icon"></p> <span class="ch-flL"> <span class="o-i-error-symbol"></span> </span> <span class="ch-flL ch-error-innertxt"></span> </div> </div>The syntax for locating via
Syntax for locating Username is= driver.findElement(By.id("ch_login_email"))
In case no such value matches with id, NoSuchElementException will be raised.
Name Locator In Selenium
An element can be defined via multiple attributes, one such is Name. Name locator in Selenium WebDriver can also be used to locate elements like ID locator. They may or may not be unique on a page, having multiple elements. In case there are elements with the same name, then the locator selects the first element with that name on the page.
In case no such name matches with the defined attribute value, NoSuchElementException will be raised
Below is a screenshot of the DOM for Lambdatest, where the ID locator name on sign up page for email field is highlighted.
Below is the DOM structure of it:
<input type="email" placeholder="Work Email*" name="email" value="" class="form-control sign-up-input-2 ">
Below is the syntax for locating the email field via name
Syntax for locating Email is =driver.findElement(By.name("email"));
Link Text Locator In Selenium
Elements can be located via link text as in hyperlinks. In a scenario where there are multiple links of the same text, the first link would be selected. Link texts are prefixed with the anchor text and this locator can only be used for anchor tag.
Below is an example of lambdatest homepage showcasing selection of the blog link on the header. The DOM below shows the highlighted element:
Below is the DOM structure of the same:
<a href="https://www.lambdatest.com/blog" target="_blank">Blog</a>
The syntax for selecting the linktext=driver.findElement(By.linkText("Blog"))
;
Usually this locator is used to check for navigation flow.
Partial Link Text Locator In Selenium
Locating element via Partial Link Text works similar to normal Link Text locator. The reason of using the Partial Link Text locator in Selenium WebDriver over the Link Text Locator is only due to the reason when you have a long linktext and you intent to use only partial text to perform further actions on it. Sometimes the intent of using this can also be to locate multiple links on a page with a common partial text.
Below is a snapshot of the LambdaTest DOM highlighting the element with the link name as ‘start testing’, here we are locating the link with partial text as ‘testing’.
Below is the DOM structure of it:
<a href="https://accounts.lambdatest.com/register" target="_blank">START TESTING <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
The syntax for locating via partial link text is: driver.findElement(By.PartialLinkText("Testing"));
Tag Name Locator In Selenium
As the name specifies, this css locator in Selenium WebDriver is used to identify elements with Tag names like div tag, a tag etc. A common example of this usage could be locating all links on your homepage and verifying whether they are functional or broken.
The below syntax for locating all links on Lambdatest home:
driver.findElements(By.tagName(a));
Class Name Locator In Selenium
Class Name locator helps in locating element defined through the class attribute. Below is an example of Lambdatest login DOM snapshot where login field is located via class name.
Below is the DOM structure:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
Syntax of locating element via class name:
driver.findElement(By.className("form-control mt-3 form-control-lg "));
DOM Locator In Selenium
In document object model(DOM) we locate element in terms of DOM model. As explained above we can identify element via ID and name through methods of the DOM like ‘getElementById’ and ‘getElementsByName’. The method getElementById will locate only one element at a time, whereas the other method is used to provide an array of elements located by that name. In order to access any specified element in case of an array of elements, we can use index.
The syntax used to access id and name through DOM is:
document.getElementById (“id”)
document.getElementsByNames (“name”)[index]
Below is the DOM structure of LambdaTest login page, where the intent is to locate the ‘remember me’ checkbox:
<input type="checkbox" name="remember" id="remember" class="form-check-input">
Example to access element via DOM ID is:
document.getElementById (“remember”)
document.getElementsByNames (“remember”)[0]
CSS Selector Locator In Selenium CSS Selector Locator In Selenium
Cascading style sheets are used to style your webpages and hence becomes one of the ways to locate your elements. If you are unable to access an element without ID or name, then CSS selector becomes one of the most obvious choices as compared to xpath.
Since multiple debates go around the corner for both of them, their usages for me depends on the complexity of the scenario, though majorly people prefer using CSS selector since those are faster as compared to xpath.
CSS Selectors can be located through various formats available:
- Tag and ID
- Tag and Class
- Tag and Attribute
- Tag, Class and Attribute
- Matches (Starts with, Ends with, Contains)
- Child elements
Tag and ID
To locate element via Tag and ID we use three components
Syntax: css=(Html tag )(#) (value of the ID attribute)
- Html tag: It is used to provide the tag we wish to locate, example input tag.
- # : This hash sign is used to represent the ID attribute. Keep in mind, when you wish to locate an element via ID through CSS selector then it required to have a hash sign on the same. For other attributes we need not use the hash sign.
- Value of the ID attribute: This represents the value of the ID we are using the locate the element.
Below is the DOM part indicating the login field of Makemytrip.com
<div class="inputM make_relative">
<input id="ch_login_email" type="text" required=""> <span class="inputM__highlight"></span> <span class="inputM__bar"></span> <label>Email/Mobile number</label> <div class="ch-error-msg ch-clearfix" id="ch_login_email_error" style="display:none"> <p class="o-i-error-icon"></p> <span class="ch-flL"> <span class="o-i-error-symbol"></span> </span> <span class="ch-flL ch-error-innertxt"></span> </div> </div>
In order to locate element via CSS selector, the following command can be written as:
driver.findElement(By.cssSelector("input# ch_login_email "))
Tag and Class
This locator works like ID, only difference is in its format. We use dot while denoting the class attribute value rather than hash in case of class.
Syntax:
css=(HTML tag)(.)(Value of Class attribute)
The below DOM snapshot and code highlights the class attribute to be accessed:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.cssSelector("form-control mt-3 form-control-lg"))
Tag and Attribute
As the name specifies the element can be locate via tag name and its corresponding attribute defined with value. In case if multiple elements have the same tag and attribute, the first one will be selected.
Syntax:
css=(HTML Page)[Attribute=Value]
Using the below DOM structure, the following code will be used to locate the web element:
<input type="phone" placeholder="Phone*" name="phone" value="" class="form-control sign-up-input-2 ">
driver.findElement(By.cssSelector("input[name= ‘phone’]"))
Tag, class and attribute
This locator is used in combination with class name and other attribute value.
Syntax:
css=(HTML tag>)(. )(Class attribute value)([attribute=Value of attribute])
Using the below DOM structure, to locate elements:
<button type="submit" class=" btn sign-up-btn-2 btn-block">Signup</button>
Syntax to locate element via class :
driver. findElement(By.cssSelector(“button. btn sign-up-btn-2 btn-block [type = submit]”))
Note: This combination can also be implied on ID. The only difference is to use hash rather than dot when using ID attribute and defining its ID value in place of class value.
Locating Elements via Matches
Selenium CSS selector,helps in matching multiple strings through the use of multiple patterns like ^, $, *. Below are quick details on the same:
Starts-With
This helps in locating element when we try to match elements with string that starts with a designated value
Syntax:
css=(HTML tag)([attribute^=start of the string])
Referencing below DOM structure to locate element:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.cssSelector("input[name^='em']"))
Ends-With
This helps in locating element when we try to match elements with string that ends with a designated value.
Syntax:
css=(HTML tag)([attribute$=end of the string])
Referencing below DOM structure to locate element:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.cssSelector("input[name$=’ail’]"))
Contains
This helps in locating element when we try to match elements with string that contains a designated value.
Syntax:
css=(HTML tag)([attribute*=partial string])
Using the same login DOM structure to locate element:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.cssSelector("input[class*=’control’]"))
Child Elements
With the use of child elements, we can locate elements inside other elements. This is helpful when trying to access data of a table or list of details etc.
Below is the DOM structure where I intent to access text written with ‘Screenshot’:
<ul class="overview-list">
<li class="automation">
<span>Automation Test</span></li>
<li class="realtime">
<span>Realtime Test</span></li>
<li class="screenshot">
<span>Screenshot Test</span></li>
<li class="responsive">
<span>Responsive Test</span></li></ul>
In order to locate element, the following syntax would be used:
Css= tagname.class name li:nth-of-child(index of the referenced child which in our case is 3)
driver.findElement(By.cssSelector(“ul. overview-list li:nth-of-child(3)”);
Similarly in order to access responsive we can use, last-child reference as below:
Css= ul. overview-list li:last-child
driver.findElement(By.cssSelector(“ul. overview-list li:last-child”);
Note: Do check our blog on CSS Selectors in Selenium Automation Scripts to help you understand this CSS locator in Selenium WebDriver better.
XPath Locator In Selenium
Xpath helps in locating elements on the web page using XML expressions. The basic syntax used for using XPath as a CSS locator in Selenium WebDriver is:
Xpath: //tagname[@attribute=’value’]
Here tagname signifies the tag in the DOM structure you are targeting to, for example an input tag or anchor tag etc. Attributes are defined via prefix ‘@’ and their corresponding value. Different attributes like name, id, class etc can be used here. There are multiple ways through which xpath can be defined:
- Standard Xpath
- Using Contains
- Using Xpath with AND & OR
- Using starts-with
- Using text in Xpath
Let’s take a quick look into their details:
Standard Xpath
This is like the one defined above in syntax.
A quick example is for the below DOM structure of LambdaTest I am referencing to:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
Syntax of xpath is: //input[@name= ’email’]
In order to locate element, it can be written as follows:
driver.findElement(By.xpath(“//input[@name= ’email’]”))
Contains
This works similar to CSS selector ‘contains’ symbol. It can be used when any element value changes dynamically and partially. For example, if value of login changes with the login text appended has been constant, then contains would be helpful in locating elements. Below is the referenced syntax of it:
Xpath: //tagname[contains(@attribute, ‘partial value of attribute’)]
Using the below DOM structure to locate the login field with class name:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.xpath(“//input[contains(@class, ‘form-control’)]”))
Xpath using ‘AND’ & ‘OR’
These are used when we want to locate an element via two condition sets. In case of ‘AND’ both the conditions should be true and for ‘OR’ either of the two should be true.
Syntax using OR :
Xpath=//input[@id='login_1' OR @name='login’]
Syntax using AND :
Xpath=//input[@id='login_1' AND @name='login’]
The below example highlights the login field DOM structure of Lamdatest using both the above ‘AND’ and ‘OR’ expressions:
<input type="email" name="email" value="" placeholder="Email" required="required" autofocus="autofocus" class="form-control mt-3 form-control-lg">
driver.findElement(By.xpath(“//input[@type='email' OR @name='email’]))
driver.findElement(By.xpath(“//input[@type='email' AND @name='email’]))
Starts-with
This is again like the functionality of CSS selector. It helps in locating element that starts with a specified attribute value. Syntax used is:
Xpath=//tagname[starts-with(@attribute,'starting name of the attribute value')]
Using the below DOM structure to locate the password field of signup form of Lambdatest:
<input type="password" placeholder="Desired Password*" name="password" class="form-control sign-up-input-2 " aria-autocomplete="list">
driver.findElement(By.xpath(“//input[starts-with(@name,'pass')]”))
Text
It helps to locate element via xpath using exact text match. Sometimes we have tags containing text, which we wish to locate element through. Locating element through text can help us achieve this.
Syntax:
Xpath=//div[text()='Logged In']
Below is an example of Lambdatest DOM structure of sign-up page, where I am trying to locate the sign-up text on that page.
<p class="signup-titel">SIGN UP</p>
Using above DOM structure, following is the use case of text:
driver.findElement(By.xpath(“//p[@text()=’ SIGN UP’]”))
Both CSS selector and Xpath are measured equally in terms of CSS locators in Selenium WebDriver. They both are useful with respect to complex scenarios. Choosing which one among the two is completely upon you and the scenario you opt to automate. The only key thing to remember is easy maintainability of your locators, this makes half of your job easier.
Best Practices For Using Locators In Selenium WebDriver
Keeping in mind which locator to choose is as important as ensuring you know all the locators. Certain best practices and rules have been laid down to ensure you make efficient use of locators in Selenium WebDriver. Listing few below:
- Do not locate elements that depends on information which may change as they may make your locators easy to break and less maintainable.
This is one of the key rules that one needs to keep in mind while writing better automation code using locators in Selenium WebDriver. If locator is dependent on a single entity like for instance class, name, id etc which if changed may need to be repaired but in case of complex locators like By.XPath(“//div[@class=”class-form_6180″]/div[5]/h3”)
, it may lead to frequent breakage if any of the div’s changes or the class name etc. Try to make your locators in Selenium WebDriver precise and dependent on single entity than multiple. Only in case you do not have any option left, move to complex locators, but make sure the dependent elements have less likelihood of changing.
- Ensure your locator In Selenium matches only the required information to be selected and not multiple other information present along with it.
This is contextual and depends upon your scenario. In case you wish to locate single element ensure it matches uniquely to only one element. It should never be the case, where there are multiple elements identified via locator and you opt to choose for the second or third selection. This can be a point of your script breakage, since if the page design changes or the assumed count on which the selected element appears changes, your locator will tend to break. So always make sure, your locator locates the exact match.
Secondly, if you are trying to look out for multiple matches (using ‘findElements’), ensure it matches all the desired elements you are looking out for.
- While using locators in Selenium, do not locate elements that depend on auto-generated values.
When new to this business this is something we get into. Usually ID’s are auto generated and while locating them and using them in scripts could be problematic. Every time the script or page containing those ID’s are run they tend to change and make your scripts fail. The easiest solution to figure out whether they are auto generated or not is watching them through minimum 2 runs and identifying them through the prefix/post fixed number associated with it. In case they are changed or incremented, you can conclude those are auto generated and you look out for other ways to locate those elements.
- While choosing locators of Selenium, do not use XPath or CSS Selector provided by the Dev Tools.
Yes, you read that right! Copying xpath or css selector from developer tools is something we believe is the easiest task to do, but believe me these are one of the problems that appears in the longer run, causing problems in the stability and readability of your scripts. Your browser providing you these values does not look out for meaningful XPath or CSS locators and give you complex ones, with multiple dependent factors, which I mentioned above may lead to frequent breakages. So even though this may look tempting and easier to do activity try refraining yourself from it.
These are some of the factors one should keep in mind while writing locators in Selenium WebDriver. The technique or strategy you use to locate elements can be any but make sure the above rules are fulfilled which helps to make your script easy to maintain and read. These locators in Selenium are the building blocks of your script, make sure they are correct and your road ahead on it is smoother and more focused towards other aspects of the functionality of your project as you automate them.
Top comments (0)