7

I have a big problem, and I don't find the solution.

I have 2 classes: Components_BI.cs with this component:

[FindsBy(How = How.XPath, Using = "//*[@id='body-container']/div/div[1]/div/div/button[contains(text(), 'Paraméterek')]")]
public IWebElement login_Check { get; set; }      

And Program.cs with this code:

WebDriverWait waiting = new WebDriverWait(PropertiesCollection.driver, TimeSpan.FromSeconds(30));
waiting.Until(ExpectedConditions.ElementExists((componentClass.login_Check)));

How to wait for this element with waiting.Until command?

1

2 Answers 2

5

The easiest way is to create your own ExpectedConditions class with methods accepting a WebElement as parameter, for example:

Wait.Until(MyConditions.ElementIsVisible(element));

With the implementation in the MyConditions class, which works exactly like the existing ExpectedConditions methods.

public static Func<IWebDriver, bool> ElementIsVisible(IWebElement element)
{
    return (driver) =>
    {
        try
        {
            return element.Displayed;
        }
        catch (Exception)
        {
            // If element is null, stale or if it cannot be located
            return false;
        }
    };
}
0

Forget the ExpectedConditions and the WebDriverWait -- both don't work really well.

  1. If you have a ImplicitWait, the WebDriverWait is completely ignored. So you can not set the default timeout over ImplicitWait to 10 seconds and then create a WebDriverWait instance with 1 second only to check, if a element is present
  2. WebDriverWait ignores the IgnoreExceptionTypes = WebDriverTimeoutException, so you need allways a try catch

With the following approach you have a simple and comfortable solution that works with a minimum of code:

using System.Linq;

#Decrease the timeout to 1 second
   Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);

#FindElements get an array and Linq take the first or null
   var result = Driver.FindElements(By.TagName("h7")).FirstOrDefault();

#Increase the timeout to 10 second
   Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);

The result will be the desired IWebElement or Null

Unfortunately the getter to get the current value from ImplicitWait is not implemented since 2016. So you can only reset the value to a fixed value and not dynamically read it before.

4
  • "Both don't work really well" - based on what? Implicit waiting is discouraged, so we use only explicit waits and they work like a charm.
    – FDM
    Commented Nov 12, 2018 at 15:11
  • @FDM- then have fun with SPAs they use dynamic elements and explicit waits. We work with a base implicit wait of 10 seconds so that dynamicly loaded elements will be catched and we want a explicit wait, to check if a element is there with a smaller amount of time. And when you read me first comment, you will also see, that the IgnoreException not really works, when you not can ignore the TimeoutException. Commented Nov 13, 2018 at 6:56
  • I'm testing nothing but SPAs. :) Of course you can't ignore a TimeoutException, that's the whole point of the Wait. You can't say to int.Parse(null) to not throw a NullReferenceException either.
    – FDM
    Commented Nov 13, 2018 at 12:33
  • Your response regarding the .Net versions of WebDriverWait and ExpectedConditions is a bit harsh... but not unwarranted. See this blog post Rantings of a Selenium Contributor
    – paulsm4
    Commented Feb 25, 2020 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.