How To Use WebDriverWait In Selenium C#
Andreea Draniceanu
Posted On: February 10, 2023
186921 Views
18 Min Read
The more you work with Selenium automation, the more you will come across various exceptions, such as NoSuchElementException (when an element is not visible on the page) or StaleElementReferenceException. Or there will be times when you will try to interact with an element that is not yet in the state you expect it to be (e.g., clickable).
To do this, you can instruct Selenium WebDriver to wait for certain conditions to be met explicitly. Explicit waits in Selenium are a way to deal with the dynamic nature of web pages, where elements may take longer to load or become available for interaction. By using explicit waits, you can tell Selenium to wait for a specific condition to be met before executing the next step in your automation script. This allows for a more flexible and robust automation solution.
In this Selenium C# tutorial, I will show you how you can use the WebDriverWait in Selenium C# to increase the reliability of your test.
If you are preparing for an interview you can learn more through Selenium interview questions.
What are Selenium Waits?
Before we dig deeper, let’s understand the waits in Selenium and why we use them. Selenium WebDriver doesn’t keep track of the DOM’s live, active state. Its default page load method waits for the document.readyState to become “complete”. This can happen before all the elements on the page are loaded and can cause the tests to throw NoSuchElementException. You can refer to this blog on the most common Selenium exceptions to learn more about it.
Consider a test where you try to click on a button that has not yet loaded or is not yet enabled (though visible) on the page. If Selenium WebDriver attempts to click on a button that is not available in the DOM, it will throw a NoSuchElementException. You might also witness the Element Is Not Clickable at Point exception if the element is visible in the DOM but not clickable at a particular point.
This will cause all further steps to fail, although the application works as expected when clicking the button at the correct time. To prevent this, we use waits. With waits, we can tell our tests to wait a certain amount or for specific conditions before moving on to the next steps.
Types of Waits in Selenium C#
There are several ways to wait for a web element to appear on a web page. I will go through each one and then expand more on the explicit waits, which are the focus of this blog.
Thread.Sleep()
System.Threading.Thread.Sleep(milliseconds) is not a Selenium WebDriver method but a built-in one in .Net. What it does is it suspends the current thread for the number of milliseconds passed as a parameter.
However, this is not recommended when working with automated web UI testing, because it is very rigid – the specified time has to pass before moving to the next step, regardless of whether the element you are waiting for was loaded faster.
For example, if your web element takes 3 seconds to load, and the Sleep parameter is set to 5 seconds, the test will wait 5 seconds before moving to the next step:
1 2 |
Thread.Sleep(5000); driver.FindElement(By.Id("slowButton")).Click(); |
It might not sound like a big deal, but if you have hundreds of tests and many of them use Thread.Sleep(), which can add a lot of unnecessary wait time to the test execution. If the test takes around 5 seconds, adding up the Sleep time of another 5 seconds, that means doubling the time it takes to run the test!
Also, if the time it takes for the button to load exceeds those 5 seconds, you will still get a NoSuchElementException.
Implicit Wait
Then, we have the Selenium implicit wait:
1 |
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(20); |
The implicit wait in Selenium is dynamic – it waits until an element is visible on the page or until the given timespan has elapsed. If the element has not been found before the given time duration, an ElementNotVisibleException or NoSuchElementException will be thrown.
The Selenium implicit wait applies to all the web elements in the test script and is a much-preferred method to Thread.Sleep().
Explicit Wait
However, if you want even more flexibility, you should go for the explicit wait. The WebDriverWait in Selenium C# is part of the OpenQA.Selenium.Support.UI package.
WebDriverWait in Selenium C# allows Selenium not only to wait for an element to be visible on the web page but also until specific conditions are met.
1 2 |
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20)); wait.PollingInterval = TimeSpan.FromMilliseconds(200); wait.Until(ExpectedConditions.ElementIsVisible(By.Id("my-element']"))).Click(); |
This is how WebDriverWait in Selenium C# works:
- The condition is checked. If the condition is true, the next lines of code are executed.
- If the condition is false, a thread sleep is called at a polling interval. The default value of this polling interval is 250 ms, but a different value can be specified:
- After this interval elapses, the condition is rechecked.
- This step repeats until the given wait time expires or the condition is met.
1 |
wait.PollingInterval = TimeSpan.FromMilliseconds(200); |
Expected Conditions with Explicit Wait
Here are some examples of Expected Conditions in Selenium I have used the most in my tests (your tests might have different needs, but these are just to illustrate how explicit waits can be useful):
- ElementExists: waits for the element to exist in the DOM of the page, even if it’s not visible.
- ElementIsVisible: waits for the element to be visible on the page. There are cases when the element can exist in the DOM but is not yet displayed on the page, so we cannot interact with it.
- ElementToBeClickable: wait for an element to become clickable – can be useful when a button is quickly loaded on the page but cannot be clicked right away because it is disabled or cannot be clicked until a different action is performed.
- AlertIsPresent: waits for the presence of an alert – alerts are usually triggered by another action, and it can take some time to display them. If you interact with an element on the alert (like dismiss/confirm the alert or try to confirm its text) too soon, you can get a NoAlertPresentException.
- InvisibilityOfElementLocated: waits for an element to not be visible on the page. For instance, you want to check that after inserting invalid data in an input field, the warning message is no longer displayed when the correct data is entered.
- TextToBePresentInElement: waits for a given text to be displayed inside a certain web element.
- ElementToBeSelected: waits for an element to be selected – can be used for checkboxes that are automatically selected through other actions.
Run your C# automation scripts across 3000+ environments. Try LambdaTest Now!
Demonstration: How to use WebDriverWait in Selenium C#
In this section, we will go over an example of using WebDriverWait in Selenium C# to handle the dynamic nature of web pages. The WebDriverWait class is a useful tool for waiting for specific conditions to be met before executing the next step in your automation script. This helps to make your scripts more flexible and robust, allowing for a better automation solution.
Test Scenario
- Navigate to the JQuery Download Progress Bar page.
- Click the Start Download button.
- Click the Close button when it’s available:
You will notice that it is not visible from the beginning; you will have to wait for it to be displayed.
Implementation
If this is your first test, you will need to create a new project. In this WebDriverWait in Selenium C# tutorial, I’ll be using the MSTest framework, which is Microsoft’s tool for running tests in .NET applications. If you prefer to work with NUnit, you can check out the Selenium NUnit tutorial.
To learn more about MSTest, NUnit, and other popular unit testing frameworks like xUnit, you can go through this blog on NUnit vs xUnit vs MSTest.
Finally, we will be executing the test on the LambdaTest cloud grid. Cloud testing platforms like LambdaTest allow you to perform cross browser testing at scale over an online device farm of 3000+ browsers and browser versions.
Subscribe to LambdaTest YouTube Channel and stay updated with detailed tutorials around Selenium testing, Cypress testing, and more.
- To create a new test project in Visual Studio, select the MSTest Test Project type:
- Install the following NuGet packages from the Package Manager:
- Selenium.WebDriver: For this WebDriverWait in Selenium C# tutorial, I am using version 3.141.0, which is still one of the most used versions in existing Selenium projects.
- Selenium.Support: It should be the same version as the Selenium.WebDriver package; this is the package that contains the Selenium WebDriverWait.
- Install the NuGet packages from the UI, from the Tools menu → NuGet Package Manager → Manage NuGet Packages for Solution… and search for them in the list:
- Before running the tests, please set the environment variables LT_USERNAME & LT_ACCESS_KEY from the terminal. The account details are available on your LambdaTest Profile page.
- Create a new class containing the following code:
Or you can run the install command from the Package Manager Console (Tools menu → NuGet Package Manager → Package Manager Console):
PM> NuGet\Install-Package Selenium.WebDriver -Version 3.141.0
I used the LambdaTest Capabilities Generator to create the configuration where I want to run my tests. You can create your custom setup, depending on the configuration you want to use in your tests. I’m keeping it simple, testing on Windows 11 with Chrome version 101 and a resolution of 1280×800.
For macOS:
export LT_USERNAME=LT_USERNAME
export LT_ACCESS_KEY=LT_ACCESS_KEY
For Linux:
export LT_USERNAME=LT_USERNAME
export LT_ACCESS_KEY=LT_ACCESS_KEY
For Windows:
set LT_USERNAME=LT_USERNAME
set LT_ACCESS_KEY=LT_ACCESS_KEY
Code Walkthrough
The using statements in any C# class contain the packages that will be used:
The [TestClass] attribute from MSTest marks the class as a test class:
In the next part, I’m declaring all the variables that will be used in the methods:
The driver is a new instance of the IWebDriver interface. Through it, we control the browser.
The next lines of code are related to my LambdaTest Account because I want my tests to run on cloud Selenium Grid. This way, I can specify configurations where my tests will run, which can be different from my local configuration.
This brings us to the next part:
This method is triggered before each test case. It will create a new browser instance with specific capabilities.
The next method is the actual test:
The [TestMethod] attribute informs that the method is a test method. The Navigate().GoToUrl() is the Selenium C# method to go to a specific URL.
Then, the FindElement() in Selenium is the method that allows us to identify web elements on the web page based on locators, such as
- ID
- Name
- Class Name
- XPath
- CSSSelector
- Link text or partial link text
For the first element I’m interacting with, I’m using the ID locator in Selenium. It’s usually recommended because it should be unique. To retrieve this information from the browser, right-click the element and select Inspect. This will open up (if it’s not already open) the Developer Tools, where you can see the details of the element:
Next, I’m using the actual explicit wait:
I created a new variable of type WebDriverWait, giving it a time span of 20 seconds – this is the maximum amount of type I am instructing Selenium to wait for my condition to be met.
Next, I am using a polling interval of 200 milliseconds – this is completely optional, but I wanted to show you how it can be used. Selenium will retry to find the web element every 200 milliseconds.
Finally, I specified the condition I wanted to wait for, which was for the button to become clickable. The button doesn’t have an Id, so I am using an XPath with a combination of 2 attributes: text and class name. I can see this in Developer Tools as well:
1 |
<button type="button" class="ui-button ui-corner-all ui-widget">Close</button> |
The last method is the cleanup, marked by the attribute [TestCleanup], which will run after every test. It simply closes the browser using the Selenium Quit() method.
1 2 3 4 5 |
[TestCleanup] public void Cleanup() { driver.Quit(); } |
Execution
The test will be visible in Visual Studio’s test explorer, and you can run it from there. If you choose to run it locally, you will see the browser open up and perform all the steps. If you are using cloud Selenium Grid, like me, you will see the test result when it finishes running:
And you will see the results online:
You can also see all the retries performed before the element was found:
However, my test was successful because after waiting less than the given time, the element was found and clickable.
Demonstrate your expertise and knowledge in using Selenium for C# automation testing with this Selenium C# 101 certification. This will enhance your technical skills and establish your credibility as a tester.
Conclusion
Having the option to wait for web elements to be loaded or meet a certain condition can be very important in automated UI testing.
In this blog on WebDriverWait in Selenium C#, I covered how to create explicit waits using WebDriverWait in Selenium C# to create more stable tests and why they can be preferred to implicit waits. I also showed how you can run the tests on the cloud, so you don’t have to use your local settings and configuration, and how to see the results on the LambdaTest cloud Selenium Grid.
Frequently Asked Questions (FAQs)
What is the default wait in Selenium C#?
In Selenium C#, there is no default wait time specified. When interacting with elements on a web page, if the element is not immediately available, Selenium will throw an exception. To handle the dynamic nature of web pages and wait for elements to become available, you can use the WebDriverWait in Selenium C# or other wait mechanisms.
How to wait until page loaded in C# Selenium?
In Selenium C#, you can wait until a page has fully loaded using the WebDriverWait class and the ExpectedConditions.ElementExists method.
What is the use of WebDriverWait?
WebDriverWait is a vital tool in automated testing. With its use, a content writer can pause test execution until a specific condition is met within a given timeframe. This ensures efficient handling of dynamic web elements and eliminates the risk of synchronization issues during test automation.
How to use wait () in Selenium?
The wait() function in Selenium is used to introduce a pause during test execution. It helps synchronize actions with the webpage’s loading or elements’ visibility. By using wait(), you can ensure that the test script waits for a specific condition to be met before proceeding further.
What is the difference between wait and WebDriverWait?
“Wait” is a basic method that pauses program execution for a set duration. “WebDriverWait” is a Selenium class providing more advanced waiting capabilities. It enables waiting for specific conditions to be met before continuing execution, enhancing automated testing by synchronizing with web elements’ state changes or timeouts.
Is WebDriver wait a class or interface?
WebDriverWait is a class in Selenium, not an interface. It provides a convenient way to wait for specific conditions to be met before performing actions in test automation. It is commonly used to handle synchronization issues and ensure reliable and efficient test execution.
How to add two conditions in webdriverwait?
To add two conditions in WebDriverWait, you can use the ‘and’ operator. For example:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, ‘element_id’)) and EC.visibility_of_element_located((By.CLASS_NAME, ‘element_class’)))
How to import webdriverwait?
To import WebDriverWait in Python, use the following code:
"from selenium.webdriver.support.ui import WebDriverWait"
Make sure you have the Selenium WebDriver library installed and import it in your script to use WebDriverWait for implementing explicit waits in your web automation tasks.
Why do we use waits in Selenium?
In Selenium, we use waits to ensure proper synchronization between the test script and the web page. It allows us to pause the execution until a certain condition is met, such as an element becoming visible or clickable. This helps avoid timing issues and improves the reliability of automated tests.
What exception does WebDriverWait throw?
The WebDriverWait class, typically used in Selenium for browser automation, throws the TimeoutException when the specified condition is not met within the given time limit.
Got Questions? Drop them on LambdaTest Community. Visit now