Selenium C# Tutorial: Using Explicit and Fluent Wait in Selenium
Join the DZone community and get the full member experience.
Join For FreeWait is an important command used in test automation for handling dynamic loading of web elements on a web page (or web application). The wait command in Selenium helps to ensure that our web application is less flaky and more reliable.
In this tutorial, I’m going to walk you through two types of Selenium waits in the WebDriver - Explicit wait and Fluent waits.
What Is Explicit Wait?
Unlike implicit wait, explicit wait in Selenium C# frameworks will wait for certain conditions to occur. The conditions could be waiting for the presence of the web element, waiting for the element to be clickable, waiting for the element to be visible, etc.
Explicit wait in Selenium is also called smart wait as the wait is not for the maximum time-out. If the condition for the explicit wait is satisfied, the wait condition is exited and the execution proceeds with the next line of code. Depending on the test scenario, you should choose the best-suited wait condition for the explicit wait.
Unlike implicit wait that applies till the time the Selenium WebDriver instance (or IWebDriver object) is alive, explicit wait in Selenium works only on the particular web element on which it is set, rather than all the elements on the page.
Explicit wait in Selenium can be used in test scenarios where synchronization is needed i.e. loading of the web page is complete and you are waiting for the element (under test) to be visible.
The figure shows what happens under the hoods when explicit wait in Selenium is triggered:
These steps are followed in sequence when Explicit Wait command is executed:
xxxxxxxxxx
a. The wait time is entered as a part of explicit wait command [e.g. WebDriverWait wait = WebDriverWait(driver, TimeSpan.FromSeconds(10));]
b. Condition mentioned in .until() method is checked
c. If the condition is not satisfied, a thread sleep is called at the frequency mentioned in the .pollingInterval property. By default, the polling interval is 250 ms.
d. Step (c) is repeated till the timeout of the wait time mentioned in step (a) or exit before timeout is performed, if required web element is located. The status of .until() condition is monitored at the end of every polling duration
Features of Explicit Wait in Selenium
Apart from the explicit wait, developers also have the choice of using implicit wait command in Selenium. Explicit wait in Selenium has a number of key features (or differences) than other types of Selenium waits:
Unlike implicit wait, the explicit wait command in Selenium is documented and has a defined behavior.
Explicit wait executes on the local part of Selenium i.e. the programming language of your code, whereas implicit wait works on the remote part of Selenium i.e. the one controlling the web browser.
It can work with any possible condition (e.g. elementToBeClickable, alertIsPresent, invisibilityOfElementWithText, stalenessOf, etc.) unlike implicit wait that only works on findelement methods.
Explicit wait in Selenium can also be used in case you are checking for the absence of a web element on the page.
The delay between retries can be customized using adjusting the .pollingInterval property which is by default set to 250 ms. On the other hand, delay in implicit waits can only be customized through the global timeout.
WebDriverWait and Expected Condition
Explicit wait in Selenium is facilitated by WebDriverWait and ExpectedCondition classes. WebDriverWait is present in the OpenQA.Selenium.Support.UI namespace in C#. ExpectedCondition provides a set of conditions on which wait can be performed.
When a search process for a particular web element is performed, the Selenium WebDriver polls the browser for the presence of the element in the DOM (Document Object Model). Below are some of the exceptional situations:
NoSuchElementException - The element is not present in the DOM when the search operation is performed.
StaleElementReferenceException - The web element is present in the DOM when the search is initiated but the element might have become stale (or its state in the DOM could have changed) when the search call is made.
ElementNotVisibleException - The web element is present in the DOM but it is not yet visible when the search process is initiated.
ElementNotSelectableException - The element is present on the page but it cannot be selected.
NoSuchFrameException - The WebDriver tries switching to a frame which is not a valid one.
NoAlertPresentException - The WebDriver attempts switching to an alert window which is not yet available.
NoSuchWindowException - The WebDriver attempts switching to a window that is not a valid one.
For avoiding these exceptions, the description of the exception should be passed to the IgnoreExceptionTypes() method:
xxxxxxxxxx
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
ExpectedConditions class in Selenium supplies a set of conditions that can be waited for using WebDriverWait. ExpectedConditions is present in the OpenQA.Selenium.Support.UI.ExpectedConditions namespace.
Some of the common methods exposed by the ExpectedConditions class:
AlertIsPresent()
ElementIsVisible()
ElementExists()
ElementToBeClickable(By)
ElementToBeClickable(IWebElement)
ElementToBeSelected(By)
ElementToBeSelected(IWebElement)
ElementToBeSelected(IWebElement, Boolean)
TitleContains()
UrlContains()
UrlMatches()
VisibilityOfAllElementsLocatedBy(By)
VisibilityOfAllElementsLocatedBy(ReadOnlyCollection<IWebElement>)
StalenessOf(IWebElement)
TextToBePresentInElement()
TextToBePresentInElementValue(IWebElement, String)
More details about the ExpectedConditions class can be found here.
Demonstration of Explicit Wait in Selenium
To demonstrate the usage of explicit wait in Selenium, we perform a search for LambdaTest on Google. For the examples demonstrated in this Selenium C# tutorial, we use the NUnit test framework.
xxxxxxxxxx
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System;
namespace Selenium_ExplicitWait_Demo
{
class Selenium_ExplicitWait_Demo
{
String test_url = "https://www.google.com/ncr";
IWebDriver driver;
[SetUp]
public void start_Browser()
{
// Local Selenium WebDriver
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void test_search()
{
String target_xpath = "//h3[.='LambdaTest: Cross Browser Testing Tools | Free Automated ...']";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Url = test_url;
driver.FindElement(By.Name("q")).SendKeys("LambdaTest" + Keys.Enter);
/* IWebElement firstResult = driver.FindElement(By.XPath(target_xpath)); */
IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(target_xpath)));
SearchResult.Click();
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
The OpenQA.Selenium.Support.UI & SeleniumExtras.WaitHelpers namespaces are included to use WebDriverWait and ExpectedConditions respectively.
An explicit wait in Selenium with a timeout of 10 seconds is set using the WebDriverWait class.
xxxxxxxxxx
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
The ExpectedCondition used is ElementExists. An explicit wait in Selenium is performed till the time the required web element is not found (via XPath) or a timeout occurs i.e. the web element does not exist on the DOM.
xxxxxxxxxx
IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(target_xpath)));
As shown in the VS-2019 screenshot, the target web page opens up after search and the test result is Success.
Now that we’ve covered what is explicit wait in Selenium test Automation and what are its features in this tutorial. We’ll now move onto the fluent wait in Selenium and discuss it in further detail.
What Is Fluent Wait?
Fluent Wait is another Wait variant in Selenium that lets you control the maximum amount of time the Selenium WebDriver needs to wait for the defined condition to appear. Fluent Wait in Selenium can be achieved by defining the frequency at which the WebDriver checks for the element before it throws ElementNotVisibleException.
One major difference between fluent wait and explicit wait in Selenium test automation is that the polling frequency (.pollingInterval) at which the presence for the web element is checked is controllable in fluent wait in Selenium, whereas it is 250 ms in explicit wait.
If the polling frequency in fluent wait is not set, it defaults to 250 ms. The user also has the flexibility to ignore exceptions that may occur during the polling period using the IgnoreExceptionTypes command. The DefaultWait class in C# is used to configure the timeout and polling interval on the fly.
Syntax of Fluent Wait command in Selenium
xxxxxxxxxx
/
* Selenium C# tutorial-Syntax of Fluent Wait in Selenium*/
/* DefaultWait Class used to control timeout and polling frequency */
/* /* https://www.selenium.dev/selenium/docs/api/dotnet/html/T_OpenQA_Selenium_Support_UI_DefaultWait_1.htm */
DefaultWait<IWebDriver> fluentWait = new DefaultWait<IWebDriver>(driver);
/* Setting the timeout in seconds */
fluentWait.Timeout = TimeSpan.FromSeconds(5);
/* Configuring the polling frequency in ms */
fluentWait.PollingInterval = TimeSpan.FromMilliseconds(polling_interval_in_ms);
Demonstration of Fluent Wait in Selenium
To demonstrate fluent wait in Selenium test automation, the same test scenario which we used for the explicit wait in Selenium, i.e. searching for LambdaTest on Google and clicking on the matching result.
xxxxxxxxxx
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System;
namespace Selenium_ExplicitWait_Demo
{
class Selenium_ExplicitWait_Demo
{
String test_url = "https://www.google.com/ncr";
IWebDriver driver;
[SetUp]
public void start_Browser()
{
// Local Selenium WebDriver
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void test_search()
{
String target_xpath = "//h3[.='LambdaTest: Cross Browser Testing Tools | Free Automated ...']";
/* Explicit Wait */
/* WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); */
DefaultWait<IWebDriver> fluentWait = new DefaultWait<IWebDriver>(driver);
fluentWait.Timeout = TimeSpan.FromSeconds(5);
fluentWait.PollingInterval = TimeSpan.FromMilliseconds(250);
/* Ignore the exception - NoSuchElementException that indicates that the element is not present */
fluentWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
fluentWait.Message = "Element to be searched not found";
driver.Url = test_url;
driver.FindElement(By.Name("q")).SendKeys("LambdaTest" + Keys.Enter);
/* Explicit Wait */
/* IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(target_xpath))); */
IWebElement searchResult = fluentWait.Until(x => x.FindElement(By.XPath(target_xpath)));
searchResult.Click();
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
The polling frequency is set to 250 ms and timeout for locating the web element is set to 5 seconds. NoSuchElementException is ignored in case if the web element is not found on the DOM.
xxxxxxxxxx
DefaultWait<IWebDriver> fluentWait = new DefaultWait<IWebDriver>(driver);
fluentWait.Timeout = TimeSpan.FromSeconds(5);
fluentWait.PollingInterval = TimeSpan.FromMilliseconds(250);
/* Ignore the exception -NoSuchElementException that indicates that the element is not present */
fluentWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
fluentWait.Message = "Element to be searched not found";
The .until() method is used to search for the intended web element. The element is searched until the timeout (of 5 seconds) happens or until the element is found.
IWebElement searchResult = fluentWait.Until(x => x.FindElement(By.XPath(target_xpath)));
As seen in the execution snapshot; the element is found, the target page is opened, and the WebDriver session is terminated.
Wrapping it Up
In this tutorial, we had a detailed look at explicit and fluent wait in Selenium. Both explicit and fluent wait in Selenium is ideal for performing waits on web elements in modern-day websites as the wait can be used alongside ExpectedConditions.
Explicit and Fluent Wait in Selenium looks for the presence of the web element at regular intervals till the element is found or there is a timeout occurrence. By using Fluent wait in Selenium test automation, you can control the polling frequency (which is set the default to 250 ms) and also configure exceptions that have to be ignored during the polling period. That’s all for now. Happy Testing!!!☺
Published at DZone with permission of Himanshu Sheth. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments