Dynamic Wait in Selenium C#

In this tutorial, we will discuss Explicit Wait which is also known as Dynamic Wait, and what is WebDriverWait class.

What are Dynamic Wait and WebDriverWait Class

The main difference between explicit wait and the dynamic wait is that we can define the wait logic which is not possible with the implicit wait.

For using the dynamic wait we need to use WebDriverWait class. So for creating the dynamic wait we need to follow a certain sequence of steps.

Prerequisite:

the very important step is to set the “Implicit Wait” to 1 second. (If we are not doing this step in that case our wait logic will not work as expected.)

Step1: create the instance of the “WebDriverWait” class.

Step2: specify the “PollingInterval“.

Step3: specify the “Exception” to ignore.

Step4: Create a “Function” for wait logic.

Step5: call the “Until” method with the wait logic.

In our visual studio, we will create a method in TestWebDriverWait.cs

[TestMethod]
public void TestDynamicWait()
{
NavigationHelper.NavigateToUrl("https://www.udemy.com/");
ObjectRepository.Driver.Manage().Timeouts(). ImplicitlyWait(TimeSpan.FromSecon(1));
WebDriverWait wait=new WebDriverWait(ObjectRepository.Driver.TimeSpan.FromSecond(50));
wait.PollingInterval= TimeSpan.FromMilliseconds(250);
wait.IgnoreExceptinTypes(typeof(NoSuchElementException),typeof(ElementNotVisibleException));
wait.Until(waitforSearchbox());
}
private Func<IWebDriver,bool> waitforSearchbox()
{
return ((x) =>
{
Console.WriteLine("Waiting for Search Box");
return x.FindElements(By.XPath("//[@type='search']")).Count==1;
});
}

Explanation of code:

So TestDynamicWait() and the attribute with this method is [TestMethod]. So we are going to Navigate to this page with NavigationHelper. NavigateToUrl("https://www.udemy.com/");

After that set the implicit wait to 1 second so ObjectRepository.Driver.Manage().Timeouts(). ImplicitlyWait(TimeSpan.FromSecon(1));

Now create the object of WebDriverWait class if we go to the class definition of this we can see there it takes two arguments first one is the IWebDriver and the second one is the TimeSpan.

So here in WebDriverWait wait=new WebDriverWait(ObjectRepository.Driver.TimeSpan.FromSecond(50));  the duration of timeout is 50 seconds after 50 seconds it throws us TimeoutException.

wait.PollingInterval= TimeSpan.FromMilliseconds(250); when we set this property in that case after every 250 milliseconds it is going to evaluate our wait logic.

And while evaluating the wait logic if there is an exception we want to ignore so we need to specify the IgnoreExceptionTypes() method.

So we are specifying NoSuchElementException and ElementNotVisibleException while evaluating the wait logic if any one of these exceptions occurs so it will ignore them.

After that wait.Until() inside the Until method, we will define the wait logic in the form of a function for this we have to create a function that takes<IWebDriver, TResult> these are generics.

In order to create a function we use access specifier private and Func is a delegate here we specify the type of function which Until method will accept.

The first is “IWebDriver” and the second argument is generic let’s say “bool” which means whatever the anonymous function which we are going to use inside the function, can take input variable as of type IWebDriver but that anonymous function should return us a value of type boolean.

Then waitforSearchbox(). We will go to that particular webpage and inspect that Search box for finding the XPath of this element we will write the CSS locator $x("//input[@type= 'search']") so we’ll get its XPath.

So here we will use return and create the anonymous function ((x) => implies and { }here we are going to return x as we can see here is x automatic of type IWebDriver and this is because the input type to this function is IWebDriver so x.FindElements(By.XPath())

And the XPath of the element is ("//input[@type='search']")).Count==1;  here we are using the FindElements method and we already know that it is going to return us the list of elements, we are comparing its size with 1.

If it’s 1 that means it is able to locate the element if it is not 1 that means the size is 0 or more than 1, in that case, we can say either the element is not present there or there are duplicate elements with this XPath.

Once this is done we will call this method in Until method. Whatever the return type of this function will become the return type of Until method. Our function return type is bool so the Until method will also return us the bool value.

We will use Console.WriteLine to make sure that we are executing this dynamic block of code. Now put a breakpoint on Until method line, build the solution, and run the script in debug mode.

So now what will happen it will wait for that particular Searchbox to appear if it is not there it will keep on waiting for that. After every 250 milliseconds, it will check for the Searchbox whether it has appeared or not.

Output: so it hit the breakpoint now if we go back to our previous page and we are going to continue its execution. The particular method will wait for that particular element to appear.

So the maximum value for the wait is 50 seconds after that it is going to throw us the exception that is TimeoutException and every 250 milliseconds it is going to evaluate this condition.

If we again go back to the page so we can see here it is able to locate the element and then it proceeds with the normal execution.

If we look at the output of our Test we can see here “Waiting for Search Box” – “Waiting for Search Box” – and so on.

It is coming because after every 250 milliseconds it is evaluating the wait condition. Once it is able to locate the element so the condition is true and the wait will be over.

Example of function for returning string-

private Func<IWebDriver,string> waitforTitle()
{
return((x)=>
{
if(x.Title.Contains("Main"))
    return x.Title;
 return null;
 });
}

In our TestDynamicWait() add this line.

Console.WriteLine(wait.Until(waitforTitle()));

Output: so it has hit the Debug point if we do a stepover now with the current title there is no “Main” string that is present inside the title, so it is kept on waiting until unless it finds a title that has the string “Main”.

If we go back to the previous page there we have a title with the “Main” string. So after that, it is going to terminate our wait.

If we look at the output of our Test it’s showing ‘Bugzilla Main Page’ and this is coming from that Console statement.

Here we are returning a string in function so the return type of Until method will also become a string.

Example of function for returning Web Element-

private Func<IWebDriver,IWebElement> waitforElement()
{
return ((x)=>
{
Console.WriteLine("waiting for element");
if(x.FindElements(By.XPath("//input[@type='search']")).Count==1)
    return x.FindElements(By.XPath("//input[@type='search']"));
 return null;
});
}

Inside the TestDynamicWait() add this line

wait.Until(waitforElement()).SendKeys("java");

Output: it has hit the breakpoint again we are going to the previous page and we will do a stepover, so again it is waiting for that particular element to appear.

Again we will go to the next page where this element is present. So we can see here as soon as it is able to locate the element it is supplying the string in that element.

With the use of dynamic wait, there are very less chances that your script will fail unless there is some bug.

So the most important part of this dynamic wait is to create the function which will contain the wait logic. So in this manner, we can create Dynamic Wait using WebDriverWait class.