Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Selenium Webdriver findElements(By.Id) timeout when the element isn't in the DOM?

I am writing a test where I want to verify that an element is NOT present on a page (displayed or otherwise). I've read in various articles (like this one) how to do the element detection with a list that's empty or not. That works just fine for the opposite test that verifies the elements ARE present. However, when the element is not present, I am consistently getting a WebDriverException timeout after 60 secs of spinning: See screenshot here

The element detection function is as such:

public bool isButtonPresent(string buttonType)
    {
        switch (buttonType)
        {
            case "Button 1":
                return !(Driver.FindElements(By.Id("Button 1 ID Here")).Count == 0);
            case "Button 2":
                return !(Driver.FindElements(By.Id("Button 2 ID Here")).Count == 0);
            case "Button 3":
                return !(Driver.FindElements(By.Id("Button 3 ID Here")).Count == 0);
        }
        return false;
    }

Thank you for your time!

like image 670
Elininja Avatar asked Oct 25 '16 16:10

Elininja


2 Answers

Here are the options:
Option 1:

// Specify the amount of time the driver should wait when searching for an element if it is not immediately present. Specify this time to 0 to move ahead if element is not found.
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));  
// InvisibilityOfElementLocated will check that an element is either invisible or not present on the DOM.
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(byLocator));  

With this approach, if your next action is to click on any element, sometimes you will get an error (org.openqa.selenium.WebDriverException: Element is not clickable at point (411, 675)) with Chrome browser. it works fine with Firefox.

Option 2:

// Set the implicit timeout to 0 as we did in option 1
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));  
WebDriverWait wait = new WebDriverWait(Driver.Browser, new TimeSpan(0, 0, 15));
try
{
   wait.Until(FindElement(By));
}
catch(WebDriverException ex) // Catch the WebDriverException here
{
   return;
}  

Here we are making implicit wait to 0 and finding element. if element is is not present it will try for next 15 seconds (you can change this number by your convenience). if there is time out, complete the function.

Option 3:

Sudeepthi has already suggested it.

Drivers._driverInstance.FindElement(by).Displayed;
like image 70
CSharp Avatar answered Sep 29 '22 06:09

CSharp


Will something like this work?

public static bool IsElementPresent(By by)
{
    try
    {
       bool b = Drivers._driverInstance.FindElement(by).Displayed;
       return b;
    }
    catch
    {
       return false;
    }
}
like image 45
Sudeepthi Avatar answered Sep 29 '22 07:09

Sudeepthi