Selenium Locators — A Detailed Guide
Selenium is one of the most popular option for developers to run automation tests for web applications. The Selenium suite got excellent flexibility — it allows developers/teams to run the tests on a local machine or the cloud, interfacing through many commonly used programming languages including Python, Java, etc. Inspite of set of challenges in selenium, it’s the flexibility that makes selenium the best testing framework to adopt. In this post, we explore how to use locators in Selenium.
What is a Selenium Locator ?
Locator is a command that tells Selenium IDE which GUI elements (say Text Box, Buttons, Check Boxes, etc.) it needs to operate on. Identification of correct GUI elements is a prerequisite to creating an automation script. But accurate identification of GUI elements is more difficult than it sounds. Sometimes, you end up working with incorrect GUI elements or no elements at all. Selenium provides a number of Locators to precisely locate a GUI element
Steps to perform an automated step through selenium
1. Download browser drivers
2. Initiate a Selenium WebDriver
3. Instantiate a browser
4. Load web applications
5. Perform designated actions in a defined test
6. Assess if the test achieved the desired outcome
7. Close the WebDriver
Locators in Selenium come into action in the fifth step above, after the Selenium WebDriver is initialized and loaded the webpage to be tested. A locator enables testers to select an HTML DOM element to act on. This post examines various types of locators in Selenium WebDriver.
The different locators in Selenium are as follows:
· By CSS ID: find_element_by_id
· By CSS class name: find_element_by_class_name
· By name attribute: find_element_by_name
· By DOM structure or xpath: find_element_by_xpath
· By link text: find_element_by_link_text
· By partial link text: find_element_by_partial_link_text
· By HTML tag name: find_element_by_tag_name
While all these locators return single elements, one may use the .find_elements() method to find multiple elements.
Locate Elements by CSS ID
This is the simplest method to locate an element in HTML DOM. The CSS ID, stored in the id attribute of an HTML DOM element, is unique for every element in the page by design. Thus, an ID can uniquely identify an element.
To use this feature, one needs to call the .find_element_by_id() method of the webdriver class. Here is the sample for it.
from selenium import webdriverdriver = webdriver.Chrome(‘./chromedriver’)driver.get(“https://www.google.org")search_bar = driver.find_element_by_id(“id-search-field”)
If there is no DOM element with the ID that one is searching for, a NoSuchElementException is raised, which one can account for, by using a try-catch block.
Theoretically, every DOM element on a page should have a unique ID. However, in practical life, one does not commonly observe this. Most elements may not have an ID or may encounter two elements with the same ID. In such cases, one needs to use a different strategy to identify a DOM element uniquely.
Locate Elements by CSS Class
A second strategy of locating elements on a page is to search by the class name. The class name is stored in the class attribute of an HTML tag. By design, a CSS class applies to a group of DOM elements. The .find_element_by_class_name() method only returns the first element with the matching class. It raises a NoSuchElementException if there is no element with the given class name. Here is sample code snippet for it.
from selenium import webdriverdriver = webdriver.Chrome(‘./chromedriver’)driver.get(“https://www.google.org")# Returns first element with matching classfirst_search_bar = driver.find_element_by_class_name(“id-class-name”)
Locate Elements by Name
In HTML5, form elements often have a name attribute associated with them. The .find_element_by_name() method only returns the first element with the matching class. If there are multiple elements of the same name, the first matched element would be returned. No matching elements result in a NoSuchElementException error.
Consider the following form:
<form id=”loginForm”><input name=”name” type=”text” value=”First Name” /><input name=”name” type=”text” value=”Last Name” /><input name=”email” type=”text” value=”Business Email” /><input name=”password” type=”password” /><input name=”continue” type=”submit” value=”Sign Me Up” /></form>
The following code returns the email form element.
email_input = driver.find_element_by_name(“email”)
However, the following code only returns the first name form element.
name_input = driver.find_element_by_name(“name”)
Using the .find_element_by_name() method, it is not possible to get to the last name input form field in the example. We can use find_elements_by_name() which returns a list of elements and then we can choose from that list. This is also possible the next locator.
Locate Elements by XPath
If one has failed to identify an element by ID, class or name, one would need to locate the element through its XML path. This process may also be implemented while reading an XML document. In this blog, we explore the use of relative paths, as absolute paths are prone to errors with the slightest change in the HTML structure.
We will use the .find_element_by_xpath() method to locate an appropriate element in the document. The argument that the .find_element_by_xpath() method takes is the path to the element.
To find the email input field in the above example of an HTML form, one may use the following code:
email_input=driver.find_element_by_xpath(“//form[input/@name=’email’]”)
This code snippet searches for the first form element of the page. Within this form, it searches for an input with the name which equals the value email, thus narrowing down to the required element.
Next, let us try to locate the first and last names input element of the form above.
first_name=driver.find_element_by_xpath(“//form[@id=’loginForm’]/input[1]”)
last_name=driver.find_element_by_xpath(“//form[@id=’loginForm’]/input[2]”)
The method first searches for a form with the ID login form and then selects the first and second input elements of the form as the first and last names.
Other Single Element Locators
In addition to the popular methods that we have discussed, there are a few other element locators in the Selenium WebDriver that testers may wish to explore.
One can locate elements by their HTML tag name using the .find_element_by_tag_name() method.
page_heading = driver.find_element_by_tag_name(‘h1’)
One can also search for a hyperlink element using the link text. One can either use the .find_element_by_link_text() method to search for the exact link’s text, or .find_element_by_partial_link_text() method to search for partial text.
# Exact Link Textclick_here_link = driver.find_element_by_link_text(‘Click Here’)# Partial Link Textclick_here_link = driver.find_element_by_partial_link_text(‘Click’)
Locate Multiple Elements
In this tutorial, we have discussed methods that locate only single elements. One may want to select a group of elements and then iterate through them. The .find_elements() method helps in finding multiple elements in the DOM structure.
Here are common examples of the usage of the .find_elements() method. To find all input elements of a form with ID loginForm, use the following snippet –
from selenium.webdriver.common.by import Byall_inputs = driver.find_elements(By.XPATH, ‘//form[@id=’loginForm’]/input’)To locate all elements with a class name, use the following code –from selenium.webdriver.common.by import Byall_elements = driver.find_elements(By.CLASS_NAME, ‘my-css-class’)
Final Thoughts on Locators in Selenium
With this, we come to the end of the blog on locators in Selenium using Python. We discussed a variety of approaches to select elements within an HTML page. We first looked at single element selectors and then moved on to multiple element selectors in the Selenium WebDriver.