Why is my explicit wait not working in Selenium .Net?

199 Views Asked by At

I've written a C# extension method that accepts a By for an element and tries to wait for up to 5 seconds while repeatedly polling the page to see if the element is present.

Here's the code:

public static IWebElement FindWithWait(this ISearchContext context, By by)
{
    var wait = new DefaultWait<ISearchContext>(context)
    {
        Timeout = TimeSpan.FromSeconds(5)
    };
    wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
    return wait.Until(ctx =>
    {
        Console.WriteLine($"{DateTimeOffset.Now} wait is trying...");
        return ctx.FindElement(by);
    });
}

For the purpose of this question, here's how I invoke the method:

    Console.WriteLine($"{DateTimeOffset.Now} before");
    try 
    {
        var element = driver.FindWithWait(By.Id("not_in_page"));
    }
    catch (Exception ex) 
    { 
        Console.WriteLine($"{DateTimeOffset.Now} exception:" + ex);
    }  
    Console.WriteLine($"{DateTimeOffset.Now} after");

Given that an element with id #not_in_page does not exist in the page and that the default polling time for the Until() method is 500 milliseconds, I would expect the code to print out something like:

11/4/2019 11:20:00 AM +02:00 before
11/4/2019 11:20:00 AM +02:00 wait is trying...
11/4/2019 11:20:01 AM +02:00 wait is trying...
11/4/2019 11:20:01 AM +02:00 wait is trying...
11/4/2019 11:20:02 AM +02:00 wait is trying...
11/4/2019 11:20:02 AM +02:00 wait is trying...
11/4/2019 11:20:03 AM +02:00 wait is trying...
11/4/2019 11:20:03 AM +02:00 wait is trying...
11/4/2019 11:20:04 AM +02:00 wait is trying...
11/4/2019 11:20:04 AM +02:00 wait is trying...
11/4/2019 11:20:05 AM +02:00 wait is trying...
11/4/2019 11:20:05 AM +02:00 after

However, what I'm actually getting is :

11/4/2019 11:20:00 AM +02:00 before
11/4/2019 11:20:00 AM +02:00 wait is trying...
11/4/2019 11:21:00 AM +02:00 exception: OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL ######### timed out after 50 seconds. ---> #########
11/4/2019 11:21:00 AM +02:00 after

Note that the polling seems to happen only once and that the exception was thrown 60 seconds after starting to poll.

Is wait.Until() subject to an implicit wait of 60 seconds? How can I instead make it ignore it and poll once every 500 milliseconds?

1

There are 1 best solutions below

0
On BEST ANSWER

Oh brother. I realized what was going right after submitting the question.

The reason why the waiting... message is only printed once and why the exception is thrown after 60 seconds is that somewhere earlier in my code, the implicit wait was set to 60 seconds. Having removed that, the code acted as expected.

The solution to make the explicit wait poll every 500 milliseconds as expected is to never set the implicit wait for the driver being used.

An alternative approach is much too nasty for my liking: I could try to capture the implicit wait value at the start of my extension method, then set it to 0 and poll and finally reset it to the captured value.

Bottom line - It's a bad idea to mix implicit and explicit waits for a given driver instance.