Selenium C# Tutorial: Using Implicit Wait in Selenium
Join the DZone community and get the full member experience.
Join For FreeWhile designing test automation scripts, it is quite imperative that we consider all the major challenges that might come while performing Selenium test automation. There are certain scenarios where the test script is trying to perform an operation on an element that is not loaded (or not yet visible) and the test ends up failing due to this. This happens as the web elements on the page are loaded dynamically via AJAX (Asynchronous JavaScript and XML) and JavaScript or any other front-end framework.
To tackle this issue we have ‘Wait’, which is one of the most important and widely used commands in Selenium test automation. It helps us to provide us ample wait or pause time in our script execution. Thereby ensuring that our scripts don’t fail while performing automation testing with Selenium.
In this article we will talk about what are Selenium waits, why are they important, & how to implement an Implicit Wait in Selenium C# with examples.
What Are Waits In Selenium?
Selenium WebDriver is said to have a blocking API. It is an out-of-process library that instructs the web browser what exactly needs to be done. On the other hand, the web platform has an asynchronous nature. This is the primary reason why the Selenium WebDriver does not track the real-time state of the DOM (Document Object Model).
Race conditions could occur in a scenario where the developer uses a Selenium command to navigate to a particular URL (or web page) and gets a No Element Found error while trying to locate the element. To overcome such issues that can lead to race conditions between the web browser and the WebDriver script, the WebDriverWait class in Selenium C# can be used.
Waits in Selenium enable the test execution to be paused for a specified time (ideally in a few seconds) to address issues that can occur due to time lag. The added delay is a counter-mechanism to ensure that the particular web element is loaded before any action is performed on the element.
Why Are Selenium ‘Waits’ Important?
The front-end of most of the web applications are built on JavaScript or AJAX, using frameworks such as React, Angular, or others that take a certain time for the web elements to load entirely on the browser.
When Selenium comes across operations on web elements that are still loading, it throws the ElementNotVisibleException. Selenium waits can resolve such problems.
In the code snippet, the test scenario for our Selenium C# tutorial is for flight search on a flight booking website, which generates a ‘NoSuchElementException’ when the search operation is performed using Selenium test automation script.
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System;
namespace Selenium_Demo
{
class Selenium_Demo
{
String test_url = "https://www.easemytrip.com";
IWebDriver driver;
[SetUp]
public void start_Browser()
{
// Local Selenium WebDriver
driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void test_search()
{
driver.Url = test_url;
IWebElement from_sector = driver.FindElement(By.Id("FromSector_show"));
from_sector.Click();
/* from_sector.FindElement(By.XPath("//*[@id='spn2']")).Click(); */
from_sector.FindElement(By.XPath("/html/body/form/div[10]/div/div[3]/div[1]/div[1]/div[1]/div[1]/div/div[2]/div/ul/li[1]")).Click();
IWebElement to_sector = driver.FindElement(By.Id("Editbox13_show"));
to_sector.Click();
to_sector.FindElement(By.XPath("/html/body/form/div[10]/div/div[3]/div[1]/div[2]/div[1]/div/div/div/div/ul/li[2]")).Click();
IWebElement ddate = driver.FindElement(By.Id("ddate"));
ddate.Click();
/* IWebElement snd_date = driver.FindElement(By.Id("snd_4_12/03/2020")); */
IWebElement snd_date = driver.FindElement(By.Id("trd_3_18/03/2020"));
snd_date.Click();
IWebElement src_btn = driver.FindElement(By.ClassName("src_btn"));
src_btn.Click();
IWebElement booknow_btn = driver.FindElement(By.XPath("//button[text()='Book Now']"));
booknow_btn.Click();
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
As the page load is not complete i.e. the search for flights from source to destination is in progress, the script fails to find the ‘Book Now’ button. This results in the ‘NoSuchElementException’ for our Selenium test automation script.
There are different types of waits in Selenium C# namely – Implicit wait, Explicit wait, and Fluent Wait. In this Selenium C# tutorial, we will have cover the Implicit wait in Selenium C#.
What Are Implicit Waits In Selenium C#?
Now moving ahead with our Selenium C# tutorial, Some developers use the System.Threading.Thread.Sleep(msecs) command to suspend the execution of the currently executing thread for a specified duration (specified in milliseconds). Usage of System.Threading.Thread.Sleep is considered to be a bad practice. The downside of this approach is that the Selenium WebDriver waits for irrespective of whether the web element is found or not. Usage of System.Threading.Thread.Sleep is considered to be a bad practice.
The shortcomings of the System.Threading.Thread.Sleep can be overcome using Implicit wait in Selenium C#. Implicit wait in Selenium halts the execution of the WebDriver for a specified duration of time until the desired web element is located on the page.
Unlike System.Threading.Thread.Sleep, the Implicit wait in Selenium does not wait for the complete time duration. Implicit wait in Selenium is also referred to as dynamic wait. If the particular web element is located before the expiry of the specified duration, it proceeds to execute the next line of code in the implementation.
If the particular web element is not located within the time duration, ElementNotVisibleException or NoSuchElementException is raised. Hence, implicit wait in Selenium tells the Selenium WebDriver to wait for a particular time duration (passed as a parameter), before the exception is raised.
The advantage of using implicit wait in Selenium C# is that it is applicable for all the web elements specified in the Selenium test automation script till the time WebDriver instance (or IWebDriver object) is alive.
Syntax of implicit wait in Selenium C#
xxxxxxxxxx
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(time_in_seconds);
The default time value for the implicit wait is zero. Implicit wait polls for the presence of the web element every 500 milliseconds. Now to take our Selenium C# tutorial further, we move on to the features of implicit wait in Selenium test automation.
When To Use Implicit Wait In Selenium?
Though there are different types of Selenium waits (explicit wait and fluent wait), there are some key features that differentiate implicit wait in Selenium from other types of waits.
a. Implicit wait applies to all the web elements in the test script
b. It is ideal for test scenarios when we are sure that the web elements will be loaded (or visible) within a specified duration
Example of Implicit Wait in Selenium C#
To demonstrate implicit wait in Selenium C#, we take the same example of EaseMyTrip. The major difference is that we have added an implicit wait of 30 seconds.
xxxxxxxxxx
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System;
namespace Selenium_Demo
{
class Selenium_Demo
{
String test_url = "https://www.easemytrip.com";
IWebDriver driver;
[SetUp]
public void start_Browser()
{
// Local Selenium WebDriver
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void test_search()
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);
driver.Url = test_url;
IWebElement from_sector = driver.FindElement(By.Id("FromSector_show"));
from_sector.Click();
/* from_sector.FindElement(By.XPath("//*[@id='spn2']")).Click(); */
from_sector.FindElement(By.XPath("/html/body/form/div[10]/div/div[3]/div[1]/div[1]/div[1]/div[1]/div/div[2]/div/ul/li[1]")).Click();
IWebElement to_sector = driver.FindElement(By.Id("Editbox13_show"));
to_sector.Click();
to_sector.FindElement(By.XPath("/html/body/form/div[10]/div/div[3]/div[1]/div[2]/div[1]/div/div/div/div/ul/li[2]")).Click();
IWebElement ddate = driver.FindElement(By.Id("ddate"));
ddate.Click();
/* IWebElement snd_date = driver.FindElement(By.Id("snd_4_12/03/2020")); */
IWebElement snd_date = driver.FindElement(By.Id("trd_3_18/03/2020"));
snd_date.Click();
IWebElement src_btn = driver.FindElement(By.ClassName("src_btn"));
src_btn.Click();
IWebElement booknow_btn = driver.FindElement(By.XPath("//button[text()='Book Now']"));
booknow_btn.Click();
/* Next Steps for booking tickets */
IWebElement insurance_checkbox = driver.FindElement(By.XPath("//div[@id='divInsuranceTab']//div[@class='insur-no']//span[@class='checkmark-radio']"));
/* Click on NO INSURANCE */
insurance_checkbox.Click();
IWebElement email_entry = driver.FindElement(By.Name("txtEmailId"));
email_entry.SendKeys("testing@gmail.com");
driver.FindElement(By.XPath("//span[text()='Continue Booking']")).Click();
IWebElement title = driver.FindElement(By.Id("titleAdult0"));
SelectElement titleTraveller = new SelectElement(title);
titleTraveller.SelectByText("MR");
driver.FindElement(By.XPath("//input[@placeholder='Enter First Name']")).SendKeys("Himanshu");
driver.FindElement(By.XPath("//input[@placeholder='Enter Last Name']")).SendKeys("Sheth");
driver.FindElement(By.XPath("//input[@placeholder='Mobile Number']")).SendKeys("9031111111");
driver.FindElement(By.XPath("//div[@class='con1']/span[@class='co1']")).Click();
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
As an implicit wait is added, a wait of 30 seconds is added to locate the ‘Book Now’ button.
xxxxxxxxxx
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);
Due to this wait, the page load gets completed and we proceed with the flight ticket booking for our Selenium C# tutorial.
Conclusion
In this Selenium C# tutorial, we had a look at why implicit wait in Selenium is necessary for Selenium test automation. The primary usage of Implicit wait in Selenium is to add a certain amount of delay of loading of the required web elements before an operation is performed on the element. Happy testing!
Published at DZone with permission of Himanshu Sheth. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments