Florian3007
Florian3007

Reputation: 97

ImplicitWait does not seem to work in Selenium Webdriver to wait for elements

I am trying to automate the Internet Explorer in c# using selenium-webdriver to fill a formular on an external website. Sometimes the code throws randomly errors (Unable to find element with name == xxx), because it cannot find the searched elements. It's not happening every time and not necessarily in the same places.

I've already tried setting an implicitWait with the following code which reduced the number of errors.

    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);

The external webpage changes the selection options (through reloading) from Dropdowns after selecting an option from another Dropdown. To additionally intercept these critical points, I wait 2 seconds before trying to find the Dropdown-options ByName().

    System.Threading.Thread.Sleep(2000);

The webpage takes less than half a second to reload this Dropdowns, so that 2 seconds should be enough.

Can you tell me what i'm doing wrong or why the webdriver seems to run so instably finding elements. I have also noticed that I am not allowed to do anything else on the computer as long as the program is running, otherwise the same error occurs more often.

My driver-options for internet explorer 8

        var options = new InternetExplorerOptions()
        {
            InitialBrowserUrl = "ExternalPage",
            IntroduceInstabilityByIgnoringProtectedModeSettings = true,
            IgnoreZoomLevel = true,
            EnableNativeEvents = false,
            RequireWindowFocus = false                
        };

        IWebDriver driver = new InternetExplorerDriver(options);
        driver.Manage().Window.Maximize();

My final solution working perfectly without a single error in more than 20 tests!

Added the following in the class

     enum type
     {
        Name,
        Id,
        XPath
     };

Added this behind my driver

    driver.Manage().Window.Maximize();
    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

Methode to wait for an element

    private static void waitForElement(type typeVar, String name)
    {
            if( type.Id)wait.Until(ExpectedConditions.ElementToBeClickable(driver.FindElement(By.Id(name)))); 
            else if(type.Name)wait.Until(ExpectedConditions.ElementToBeClickable(driver.FindElement(By.Name(name))));
            else if(type.XPath)wait.Until(ExpectedConditions.ElementToBeClickable(driver.FindElement(By.XPath(name))));                   
    }

And call the methode before calling any event with the element

    waitForElement(type.Id, "ifOfElement");

Upvotes: 0

Views: 1337

Answers (2)

iamsankalp89
iamsankalp89

Reputation: 4739

You can use Explicit wait like this example:

var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(10));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("your locator")));

Upvotes: 1

Koen Meijer
Koen Meijer

Reputation: 821

You have two more options in Selenium:

You can use explicit wait via the WebDriverWait object in Selenium. In this way you can wait for elements to appear on the page. When they appear the code continues.

An example:

IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://yourUrl.com");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
Func<IWebDriver, bool> waitForElement = new Func<IWebDriver, bool>((IWebDriver Web) => 
{Console.WriteLine(Web.FindElement(By.Id("target")).GetAttribute("innerHTML"));
}); 
wait.Until(waitForElement);

Furthermore you can use the FluentWait option. In this way you can define the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition.

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() 
        {
            public WebElement apply(WebDriver driver) {
            return driver.findElement(By.id("foo"));
        }
});

Upvotes: 1

Related Questions