Interacting with the Elements in the page | WebDriver methods to find an element

In the Previous Tutorial divided over 4 parts, we learned different ways to locate page elements –

In this tutorial, we will learn the WebDriver way to locate elements by using methods learned above. They are known as locators.

  1. id
  2. className
  3. xpath
  4. cssSelector
  5. name
  6. linkText
  7. partialLinkText
  8. 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 –

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 like id, type, size and maxlength:
<input id=”firstname” type=”text” size=”30″ maxlength=”50″></input>
  • We are interested in id attribute whose value is firstname.
  • 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.

  • 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.

35 thoughts on “Interacting with the Elements in the page | WebDriver methods to find an element”

  1. Nice one,,, eagerly waiting for the second part….Hard work you are doing

    "This Previous Tutorial" link is not working and also "facebook" link at the end

    Assignment after this tutorial would be over, should be :- login to gmail account using selenium

    Regards

    Gaurav Khurana

    http://www.udzial.com
    UdZial Means Share

    Reply
  2. Thanks Gaurav. Removed the orphan link as I did major shuffling in structure of this portal. Will check the Facebook link.
    I initially planned to give assignments after completion of all parts. But now I have given the assignment that you suggested. You really deserve credit. Please check the last point.
    You must have noticed new tutorials are coming at slow pace. But cant help it. I have to arrange bread and butter doing normal office job as well. 😉

    Reply
  3. Here is the script for the gmail login page (username and pw values modified, of course for privacy):
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;

    public class GmailScripts {

    public static void main(String[] args) {
    WebDriver driver = new FirefoxDriver();
    driver.get("http://mail.google.com&quot;);
    WebElement inpUserName = driver.findElement(By.name("Email"));
    inpUserName.sendKeys("JohnDoe");
    WebElement inpPassword = driver.findElement(By.xpath("//input[@type='password']"));
    inpPassword.sendKeys("password123");
    WebElement btnSubmit = driver.findElement(By.xpath("//input[@name='signIn']"));
    btnSubmit.click();
    // TODO Auto-generated method stub

    }

    }

    Reply
  4. import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;

    public class Login {

    public static void main(String[] args) {
    WebDriver driver = new FirefoxDriver();
    driver.get("http://www.gmail.com&quot;);

    WebElement inpEmail = driver.findElement(By.xpath("//input[@name='Email']"));
    inpEmail.sendKeys("user1984@gmail.com");

    WebElement inpPassword = driver.findElement(By.name("Passwd"));
    inpPassword.sendKeys("pass123");

    WebElement btnSubmit = driver.findElement(By.cssSelector("input[type='submit']"));
    btnSubmit.click();

    }

    }

    Reply
  5. Wow , i am so happy,, i automated ,, i was careful enough while pasting the code that i wont paste my password

    i am thinking to create such script for all my online accounts 🙂 🙂 really thanks a lot.

    Assignment 1
    ****************
    //input[contains(@src,'submit')]
    with css i am not able to do
    as we were told that
    css = a#id
    css = a.classname
    but submit button code does not has class nor id,, so not able to make it out

    input width="60" type="image" height="23" border="0" src="/images/forms/submit.gif" alt="Login" value="Login" name="login"

    Assignment 2
    ***************
    was so easy done 🙂

    Assignment 3
    *****************
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.By;

    public class GmailAutomaticLogin {

    public static void main(String[] args) {
    // TODO Auto-generated method stub

    WebDriver Gmail = new FirefoxDriver();
    Gmail.get("http://www.gmail.com&quot;);

    WebElement login = Gmail.findElement(By.name("Email"));
    login.sendKeys("my@gmail.com");

    WebElement password = Gmail.findElement(By.name("Passwd"));
    password.sendKeys("mypassword");

    WebElement signIn = Gmail.findElement(By.name("signIn"));
    signIn.click();
    }
    }

    Regards
    Gaurav Khurana

    http://www.Udzial.com
    Udzial Means share

    Reply
  6. Why do not you use Thread.Sleep(10000) to wait for 10,000 milli-seconds before quitting firefox. You may need to put Thread.Sleep inside try-catch block. Not to worry, eclipse is smarter enough to suggest that.

    Reply
  7. Oops I missed it…
    Assignment#1-
    First, I really liked the way you constructed xpath using partial value for 'src'

    input width="60" type="image" height="23" border="0" src="/images/forms/submit.gif" alt="Login" value="Login" name="login"

    These cssSelector should work –
    input[alt=Login]
    input[name=Login]
    input[value=Login]

    Reply
  8. Hi,

    for Step#1 – cant we use the syntax to search for the password field same as we did for username, for e.g. using:
    WebElement inpPassword = driver.findElement(By.name('password'));

    Reply
  9. Manali, surely we can so the same way as you typed. This was just to demonstrate different locators. For username we used name locator, for password we used xpath locator.

    Reply
  10. I did the assignments and feels great to execute your first script.

    Here's something for google search:
    public class manali {

    public static void main(String[] args) {

    WebDriver driver = new FirefoxDriver();
    driver.get("https://www.google.com&quot;);

    WebElement inpemail = driver.findElement(By.xpath("//input[@id='gbqfq']"));
    inpemail.sendKeys("India");

    //WebElement clkbutton = driver.findElement(By.cssSelector("button[name=btnG]"));
    WebElement clkbutton = driver.findElement(By.xpath("//button[@name='btnG']"));
    clkbutton.click();

    }

    }

    Reply
  11. no. first try locating the element that has text something like that – About 70,00,00,000 results . Assuming you have got eleSearchResult.. use eleSearchResult.getText and do some if-else coding…

    Reply
  12. After writing my script and comparing it to yours. I am getting an error message stating: "The method sendKeys(CharSequence[]) in the type WebElement is not applicable for the arguments (String)".

    Reply
  13. Hi Dan, It would be great if you can post your complete code along with package declarations here so that we can figure out what went wrong. I am suspecting it is picking different Implementation of sendKeys

    Reply
  14. Here is my code which is the same as yours.

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.ui.Select;

    public class ScriptClass {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.get("http://www.cosmotechies.com/teachmeselenium/p/automation-prictice.html&quot;);
    //First Name
    WebElement inpFirstName = driver.findElement(By.id("firstname"));
    inpFirstName.sendKeys("TestFirstName");
    ///Last Name
    WebElement inpLastName = driver.findElement(By.className("lastname"));
    inpLastName.sendKeys("TestLastName");
    //Gender radio button
    WebElement rdoGender = driver.findElement(By.xpath("//input[@value='Male']"));
    rdoGender.click();
    //Input selection
    WebElement chkLanguage= driver.findElement(By.cssSelector("input[value=java]"));
    chkLanguage.click();
    //Age selection
    WebElement lstAge = driver.findElement(By.name("age"));
    Select selectAge = new Select(lstAge);
    selectAge.selectByVisibleText("Over 50");
    //Submit
    inpFirstName.submit();
    driver.findElement(By.id("submit_htmlform")).click();
    driver.findElement(By.partialLinkText("GoToHomepage")).click();
    driver.quit();

    }

    }

    Reply
  15. I've fixed the typo error, but there are still two errors in the script. The first error is on the "inpFirstName.sendKeys" line and the second error is on the "inpLastName.sendKeys" line.

    Reply
  16. Everything is correct… wondering what could be the root cause…I would suggest let us create a new eclipse project and pick any other standard application and try to automate typing something to its input box using sendKeys. If you still face same issues that would be interesting one to watch out. Miracles do happen 🙂

    Reply
  17. Hi shadab,

    Your blog is really very great and awesome ! Please continue your service. This will help lot of innocent aspirants getting a career.

    From Css Selector I understand that a parent element is referenced to a child element wrt either id or class. This will be in the either format :

    parentelement#childid
    or
    parentelement.childclass

    But your css code snippet says :

    WebElement btnSubmit = driver.findElement(By.cssSelector("input[name=login]"));

    the quoted one is Xpath identifier. Css and xpath are contradicting in finding the element.

    Please explain me on this ?

    Regards,
    Bharathkumar AV

    Reply
  18. Hi Dan, The root cause is that in your eclipse project settings the compiler version is set to older ones like 1.4… Change it to 1.6 or 1.7… Or uncheck "Enable Project specific settings" in Java compiler option for eclipse… Google for more info..

    Reply
  19. Bharath… you are missing the point buddy… for CSS its "TagName#ID" or "TagName.Class"….. Also "input[name=login]" is not XPath, its also a form of CSS.. Remember, xpath starts with double or single forward-slash??? Here 'input' is TagName and 'name' is attribute that has value of 'login'…

    Reply
  20. Hi Yogesh.. you just need to write logic in such a way to keep the line of codes in a loop that should iterate for total no of records in that xls. Fetch one pair of credentials at a time and use them. You can use Apache POI to interact with xls.

    Reply

Leave a Reply