In the previous chapter of IWebElement Commands, we learned different types to actions which can be performed on a WebElement object. Thus the next thing to do is to interact with a web page to use WebElement Commands/Actions. First thing to locate an element on the web page before interacting with it and locating elements can be done on the IWebDriver Instance(driver) itself or on a WebElement. WebDriver gives us Find Element and Find Elements methods to locate element on the web page.
As in the previous chapters, we learned that every method of the WebDriver either returns something or return void(means return nothing). The same way FindElement method of IWebDriver returns WebElement.
But the FindElement() method accepts something as a Parameter/Argument and which is By Object. By is the mechanism used to locate elements within a document with the help of locator value. A normal syntax of By looks like this:
IWebElement UserName = driver.FindElement(By.Id("UserName"));
//This can also be written as
By Locator = By.Id("UserName");
IWebElement UserName = driver.FindElement(Locator);
Locating Element using By Strategy
Locating elements in WebDriver is done by using the FindElement(By.Locator()) method. The FindElement methods take a locator or query object called 'By'. In the Visual Studio code window type driver.FindElement(By dot), Visual Studio IntelliSense will populate the list of different locators. 'By' strategies are listed below.
Browser tools for Element Inspector
- Firefox: Firebug add on. Right click on any element and select Inspect Element or F12
- Chrome: Build in Page analyzing feature (right click --> Inspect Element / F12)
- IE: Developers Tool (Tools --> Developers Tools/ F12)
I would suggest to take a look at the small chapter of Finding Elements using Browser Inspector before moving on to this chapter.
By ID
By By.Id(string idToFind) - This is the most efficient and preferred way to locate an element, as most of the time IDs are unique. It takes a parameter of String which is a Value of ID attribute and it returns a BY object to FindElement() method.
Command - driver.FindElement(By.Id("Element ID"));
With this strategy, If no element has a matching id attribute, a NoSuchElementException will be raised.
Example: If an element is given like this:
Actual Command
IWebElement element = driver.FindElement(By.Id("submit"));
// Action can be performed on Input Button element
element.Submit();
Note: Common pitfalls that UI developers make is having non-unique id’s on a page or auto-generating the id, both should be avoided.
By Name
By By.Name(string nameToFind) - This is also an efficient way to locate an element but again the problem is same as with ID that UI developer make it having non-unique names on a page or auto-generating the names. It takes a parameter of String which is a Value of NAME attribute and it returns a BY object to FindElement() method.
Command - driver.FindElement(By.Name("Element NAME"));
With this strategy, the first element with the name attribute value matching the location will be returned. If no element has a matching name attribute, a NoSuchElementException will be raised.
Example: If an element is given like this:
Actual Command
IWebElement element = driver.FindElement(By.Name("firstname"));
// Action can be performed on Input Text element
element.SendKeys("ToolsQA");
By ClassName
By By.ClassName(string clasNameToFind) - This finds elements based on the value of the CLASS attribute. It takes a parameter of String which is a Value of CLASS attribute and it returns a BY object to FindElement() method.
Command - driver.FindElement(By.ClassName("Element CLASSNAME"));
If an element has many classes then this will match against each of them.
Example: If an element is given like this:
Actual Command
IWebElement parentElement = driver.FindElement(By.ClassName("button"));
IWebElement childElement = parentElement.FindElement(By.Id("submit"));
childElement.Submit();
Note: This method is a life saver. As said, class can contain many elements, many times when you end up with duplicate IDs and Names, just go for the ClassName first and try to locate the element with ID. That will work fine, as the selenium will look for the ID which is in the mentioned class.
By TagName
By By.TagName(string tagNameToFind) - With this you can find elements by their TAGNAMES. It takes a parameter of String which is a Value of TAG attribute and it returns a BY object to FindElement() method.
Command - driver.FindElement(By.TagName("Element TAGNAME"));
Locating Element By Tag Name is not too much popular because in most of cases, we will have other alternatives of element locators. But yes if there is not any alternative then you can use element's DOM Tag Name to locate that element in WebDriver.
Example: If an element is given like this:
Actual Command
IWebElement element = driver.FindElement(By.TagName("button"));
// Action can be performed on Input Button element
element.Submit();
By LinkText & PartialLinkText
By By.LinkText(string linkTextToFind) - With this you can find elements of "a" tags(Link) with the link names. Use this when you know link text used within an anchor tag. It takes a parameter of String which is a Value of LINKTEXT attribute and it returns a BY object to FindElement() method.
By By.PartialLinkText(string partialLinkTextToFind) - With this you can find elements of "a" tags(Link) with the partial link names.
Command - driver.FindElement(By.LinkText("Element LINKTEXT"));
Command - driver.FindElement(By.PartialLinkText("Element LINKTEXT"));
If your targeted element is link text then you can use by link text element locator to locate that element. Partial Link Text is also same as Link text, but in this we can locate element by partial link text too. In that case we need to use By.PartialLinkText at place of By.LinkText.
Example: If an element is given like this:
Actual Command
IWebElement element = driver.FindElement(By.LinkText("Partial Link Test"));
element.Clear();
//Or can be identified as
IWebElement element = driver.FindElement(By.PartialLinkText("Partial");
element.Clear();
By XPath
By By.XPath(string xPathToFind)- It is the most popular and majorly used locating element technique or the easiest way to locate element in WebDriver. It takes a parameter of String which is a XPATHEXPRESSION and it returns a BY object to FindElement() method.
Command - driver.FindElement(By.XPath("Element XPATHEXPRESSION"));
The best thing in xpath is that it provides many different technique to locate elements. It gives you feature to locate single element in many ways.
We have a complete chapter on XPath techniques that we will come across during our learning journey on ToolsQA latter.
Difference between FindElement & FindElements Commands
The difference between FindElement() and FindElements() method is the first returns a WebElement object otherwise it throws an exception and the latter returns a List of WebElements, it can return an empty list if no DOM elements match the query.
FindElement()
- On Zero Match : throws NoSuchElementException
- On One Match : returns WebElement
- On One+ Match : returns the first appearance in DOM
FindElements()
- On Zero Match : return an empty list
- On One Match : returns list of one WebElement only
- On One+ Match : returns list with all matching instance
Practice Exercise 1
- Launch new Browser
- Open URL http://toolsqa.com/automation-practice-form/
- Type Name & Last Name (Use Name locator)
- Click on Submit button (Use ID locator)
Solution
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using NUnit.Framework;
namespace ToolsQA.Selenium_Basics
{
class FindElementCommands
{
[Test]
public void Test()
{
IWebDriver driver = new FirefoxDriver();
// Launch the ToolsQA WebSite
driver.Url = ("https://toolsqa.com/Automation-practice-form/");
// Type Name in the FirstName text box
driver.FindElement(By.Name("firstname")).SendKeys("Lakshay");
//Type LastName in the LastName text box
driver.FindElement(By.Name("lastname")).SendKeys("Sharma");
// Click on the Submit button
driver.FindElement(By.Id("submit")).Click();
}
}
}
Practice Exercise 2
- Launch new Browser
- Open URL http://toolsqa.com/automation-practice-form/
- Click on the Link "Partial Link Test" (Use 'PatialLinkTest' locator and search by 'Partial' word)
- Identify Submit button with 'TagName', convert it into string and print it on the console
- Click on the Link "Link Test" (Use 'LinkTest' locator)
Solution
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System;
namespace ToolsQA.Selenium_Basics
{
class FindElementCommands_2
{
[Test]
public void Test()
{
// Create a new instance of the FireFox driver
IWebDriver driver = new FirefoxDriver();
// Launch the Online Store WebSite
driver.Url = ("https://toolsqa.com/Automation-practice-form/");
// Click on "Partial Link Text" link
driver.FindElement(By.PartialLinkText("Partial")).Click();
Console.WriteLine("Partial Link Test Pass");
// Convert element in to a string
String sClass = driver.FindElements(By.TagName("button")).ToString();
Console.WriteLine(sClass);
// Click on "Link Text" link
driver.FindElement(By.LinkText("Link Test")).Click();
Console.WriteLine("Link Test Pass");
}
}
}