In the Previous Tutorial divided over 4 parts, we learned different ways to locate page elements –
- Part 1: Use basic attributes (id, class, name etc)
- Part 2: Introduction to XPath locators
- Part 3: XPath functions
- Part 4: CSS selectors
In this tutorial, we will learn the WebDriver way to locate elements by using methods learned above. They are known as locators.
- id
- className
- xpath
- cssSelector
- name
- linkText
- partialLinkText
- tagName
Let us start our learning journey by automating the Automation Practice page.
Creating a Project and writing the initial code
- Open eclipse and create a new Java project ‘AutomationPracticeBeginner’.
- Add Selenium Server to its build-path.
- Create a class ‘SubmitForm’ and write an empty main method.
- Inside main(), let us now instantiate WebDriver with ChromeDriver, maximize the browser and write code to navigate to our base URL – https://cosmocode.io/automation-practice
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class SubmitForm {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://cosmocode.io/automation-practice");
}
}
We have also imported packages for WebDriver (org.openqa.selenium.WebDriver
) and FirefoxDriver (org.openqa.selenium.chrome.ChromeDriver
). Although your IDE should have imported the packages automatically, still it is good to double-check.
- Open eclipse and create a new PyDev project ‘AutomationPracticeBeginner’.
- Create a PyDev Module ‘SubmitForm’.
- Let us now write code to open Chrome and navigate to our base URL – https://cosmocode.io/automation-practice/
from selenium import webdriver
# Change path accordingly
chrome_driver_path = "C:\teachmeselenium\chromedriver.exe"
driver = webdriver.Chrome(chrome_driver_path)
driver.maximize_window()
driver.get("https://cosmocode.io/automation-practice")
If you have any issue understanding the above steps you can take help from previous tutorials related to “Writing our first Selenium Script” –
I would recommend revisiting the previous tutorials on “How to locate elements on the page” if you are not able to recollect it –
- Part 1: Use basic attributes (id, class, name etc)
- Part 2: Introduction to XPath locators
- Part 3: XPath functions
- Part 4: CSS selectors
Open a new browser window and manually navigate to the Application Under Test i.e. https://cosmocode.io/automation-practice so that we can locate the UI elements before automating. This is the standard practice followed before writing the code.
Method to find the element
findElement()
- The WebDriver API has a method called
findElement()
that tries to find the element in the page based on the locator passed to it. - If the element is found on the page it will return that element otherwise, it will throw
NoSuchElementException
.
The Python bindings for Selenium WebDriver has provided the following methods to locate elements in a page:
- find_element_by_id
- find_element_by_name
- find_element_by_class_name
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_xpath
- find_element_by_css_selector
As evident from the method names
- It tries to find the element in the page based on the locator passed to it.
- If the element is found on the page it will return that element otherwise, it will throw NoSuchElementException.
WebDriver Locators
linkText
- Let us try to locate the first element in the “Automation Practice” page, that is a link with displayed text – “Click here to reload this page” –
- Since it has an anchor tag <a>, we can be sure it is a Link:
<a href="https://cosmocode.io/automation-practice/">Click here to reload this page</a>
We can locate this element by using its link text:
WebElement lnkReload = driver.findElement(By.linkText("Click here to reload this page"));
You would be needing to import the following package for By
:
org.openqa.selenium.By
Hey… what is that code all about?
In the first line, we are simply declaring an object reference ‘lnkReload’ of type ‘WebElement’. In next line, we are trying to find element through WebDriver ‘by’ using ‘linkText’ locator and passing it the full text displayed for that link – “Click here to reload this page”. If the element is found in the page it will assign it to ‘lnkReload’. Here onwards ‘lnkReload’ can be used to refer actual element in the page. If the element is not found in the page, it will throw a Java exception – “NoSuchElementException“
And what is ‘WebElement’? A Java class…?
It is a Java ‘Interface’, not a ‘Class’.
What? How can we create an Object of an Interface?
Good question buddy. When we write WebElement lnkReload;
, it doesn’t actually create an Object in memory. It just declares an Object Reference that can refer to an Object created in memory. driver.findElement()
returns an Object to which the lnkReload
object-reference points to.
reload_link = driver.find_element_by_link_text("Click here to reload this page")
id
- Let us now try to locate
First Name
input box.
- As we can see it has an
input
tag and attributes likeid
,type
,size
andmaxlength
:
<input id=”firstname” type=”text” size=”30″ maxlength=”50″></input>
- We are interested in
id
attribute whose value isfirstname
. - This is how we can use above info in Finding that element by WebDriver
id
locator:
WebElement inpFirstName = driver.findElement(By.id("firstname"));
first_name = driver.find_element_by_id("firstname")
class name
- Let us now try to locate ‘Last Name’ input field. As we can see it has ‘input’ tag and other attributes like class, type, size, and maxlength. We are interested in ‘class’ attribute whose value is ‘lastname’
<input class=”lastname” type=”text” size=”30″ maxlength=”50″></input>
We’ll try WebDriver’s className
locator – to use above info for finding that element:
WebElement inpLastName = driver.findElement(By.className("lastname"));
last_name = driver.find_element_by_class_name("lastname")
xpath
- As we can see in Automation Practice page the next field item is to select gender. It is a radio button.
- Let us inspect the desired radio button’s properties. Please keep in mind that our intention is to locate the actual element on which we can perform the action (radio-button in this case), not the label. So right-click just over the radio –
- Inspect the second radio-button:
<input type=”Radio” value=”Male” name=”gender”></input>
But there are no id, class or name properties for this element. How would I locate this object?
XPath locators are your saviour. If you are missing how to locate this element by using XPath, you may revisit the following tutorial – Part 3: XPath functions
Huh… I got it. We can write following XPath query to locate that element –
//input[@value='Male']
Yup, you are right.
This is how we can locate that element by using XPath locator
WebElement rdoGender = driver.findElement(By.xpath("//input[@value='Male']"));
gender = driver.find_element_by_xpath("//input[@value='Male']")
css selector
- The next field in the line is to select Language check-boxes. I’ll demonstrate the selection of only one check-box.
- Let us inspect first check-box i.e Java:
<input type=”Checkbox” value=”java” name=”language_java”></input>
- We can locate that element by using CSS like this:
input[value=java]
Here is the WebDriver’s cssLocator
that would find the element for you
WebElement chkLanguage=driver.findElement(By.cssSelector("input[value=java]"));
language=driver.find_element_by_css_selector("input[value=java]")
Why don’t you write code to locate all other known languages by using cssSelector?
Once you are done with it, try to locate the same elements by using XPath.
name
The next field is a drop-down list to select ‘Age’. As we can see this element has a name attribute:
<select name=”age”>
We will use WebDriver locator – name to find this element:
WebElement lstAge = driver.findElement(By.name("age"));
age = driver.find_element_by_name("age")
Next, we need to locate the ‘Submit’ button. Here is how it looks in source code
<input id="submit_htmlform" name="submit" onclick="return resetForm(this.form);" type="submit" value="Submit">
Stop spoonfeeding… I know how to do it. In fact, I can write four different locators to locate them.
By using id locator
WebElement btnSubmit = driver.findElement(By.id("submit_htmlform"));
By using name locator
WebElement btnSubmit = driver.findElement(By.name("submit"));
By using XPath locator
WebElement btnSubmit = driver.findElement(By.xpath("//input[@value='Submit']"));
And last but not least by cssSelector locator –
WebElement btnSubmit = driver.findElement(By.cssSelector("//input[value='Submit']"));
By using id locator
submit = driver.find_element_by_id("submit_htmlform")
By using name locator
submit = driver.find_element_by_name("submit")
By using XPath locator
submit = driver.find_element_by_xpath("//input[@value='Submit']")
And last but not least by cssSelector locator –
submit = driver.find_element_by_css_selector("//input[value='Submit']")
Impressed… I must say you are catching so fast. You can use any one of the above locators. However –
If you can locate an element easily by using one of its basic attributes like id, name, class etc you should first give it a preference over xpath or cssSelector. They can be relatively slower. In fact, XPath is the slowest, specially in IE browser.
Hence, you should use id locator for the above example.
partial link text
- Let us try to locate the next element in page –
- If you look carefully the displayed text of the link is – “random-text-xyz-i-wont-change-random-digit-123“.
- We can locate a link by using the partial portion of its displayed text. But we will only use partial link text – i.e. “i-wont-change” –
WebElement lnkPartialText = driver.findElement(By.partialLinkText("i-wont-change"));
WebElement lnkPartialText = driver.findElement(By.partialLinkText("i-wont-change"));
partial_link_text = driver.find_element_by_partial_link_text(“i-wont-change”))
Why the heck I would be needing to use partial link text?
Well, there could be plenty of reasons. Some portion of the link text is dynamic that gets changed every time you reload the page, the displayed text is too big or any other reason.
Complete code
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
public class SubmitForm {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://cosmocode.io/automation-practice/");
WebElement lnkReload;
lnkReload = driver.findElement(By.linkText("Click here to reload this page"));
WebElement inpFirstName = driver.findElement(By.id("firstname"));
WebElement inpLastName = driver.findElement(By.className("lastname"));
WebElement rdoGender = driver.findElement(By.xpath("//input[@value='Male']"));
WebElement chkLanguage=driver.findElement(By.cssSelector("input[value=java]"));
WebElement lstAge = driver.findElement(By.name("age"));
WebElement btnSubmit = driver.findElement(By.id("submit_htmlform"));
WebElement lnkPartialText = driver.findElement(By.partialLinkText("i-wont-change"));
}
}
from selenium import webdriver
chrome_driver_path = "C:\teachmeselenium\chromedriver.exe"
driver = webdriver.Chrome(chrome_driver_path)
driver.maximize_window()
driver.get("https://cosmocode.io/automation-practice");
reload = driver.find_element_by_link_text("Click here to reload this page")
first_name = driver.find_element_by_id("firstname"))
last_name = driver.find_element_by_class_name("lastname")
gender = driver.find_element_by_xpath("//input[@value='Male']")
language=driver.find_element_by_css_selector("input[value=java]")
age = driver.find_element_by_name("age")
submit = driver.find_element_by_id("submit_htmlform")
partial_link_text = driver.find_element_by_partial_link_text("i-wont-change"))
Hey, I really can’t understand what you want to achieve by locating all those elements. How the heck can I click on a link or enter some text into an input box?
Relax champ. The Next Tutorial would enable you to interact with those elements.