Selenium C# WebDriver: Wait until element is present

前端 未结 24 2855
礼貌的吻别
礼貌的吻别 2020-11-22 08:53

I want to make sure that an element is present before the webdriver starts doing stuff.

I\'m trying to get something like this to work:

WebDriverWait w         


        
相关标签:
24条回答
  • 2020-11-22 09:51

    WebDriverWait won't take effect.

    var driver = new FirefoxDriver(
        new FirefoxOptions().PageLoadStrategy = PageLoadStrategy.Eager
    );
    driver.Navigate().GoToUrl("xxx");
    new WebDriverWait(driver, TimeSpan.FromSeconds(60))
        .Until(d => d.FindElement(By.Id("xxx"))); // a tag that close to the end
    

    This would immediately throw an exception once the page is "interactive". I don't know why but the timeout acts as if not exist.

    Perhaps SeleniumExtras.WaitHelpers works but I didn't try. It's official but was split out into another nuget package. You can refer to C# Selenium 'ExpectedConditions is obsolete'.

    Myself is using FindElements and check whether Count == 0, if true, use await Task.Delay. It's really not quite efficient.

    0 讨论(0)
  • 2020-11-22 09:52

    Alternatively you can use implicit wait:

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

    An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

    0 讨论(0)
  • 2020-11-22 09:52

    We can achieve that like this:

    public static IWebElement WaitForObject(IWebDriver DriverObj, By by, int TimeOut = 30)
    {
        try
        {
            WebDriverWait Wait1 = new WebDriverWait(DriverObj, TimeSpan.FromSeconds(TimeOut));
            var WaitS = Wait1.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.PresenceOfAllElementsLocatedBy(by));
            return WaitS[0];
        }
        catch (NoSuchElementException)
        {
            Reports.TestStep("Wait for Element(s) with xPath was failed in current context page.");
            throw;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:54

    You can also use

    ExpectedConditions.ElementExists

    So you will search for an element availability like that

    new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementExists((By.Id(login))));
    

    Source

    0 讨论(0)
  • 2020-11-22 09:54
    public bool doesWebElementExist(string linkexist)
    {
         try
         {
            driver.FindElement(By.XPath(linkexist));
            return true;
         }
         catch (NoSuchElementException e)
         {
            return false;
         }
    }
    
    0 讨论(0)
  • 2020-11-22 09:54

    Since I'm separating page elements definitions and page test scenarios using already found IWebElement for visibility could be done like this:

    public static void WaitForElementToBecomeVisibleWithinTimeout(IWebDriver driver, IWebElement element, int timeout)
    {
        new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until(ElementIsVisible(element));
    }
    
    private 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 讨论(0)
提交回复
热议问题