当元素不在DOM中时,为什么Selenium Webdriver findElements(By.Id)超时?

时间:2016-10-25 16:00:47

标签: c# selenium selenium-webdriver

我正在编写一个测试,我想验证页面上是否存在元素(显示或其他)。我已经阅读了各种文章(如this one)如何使用空列表或不空列表进行元素检测。这适用于验证元素存在的相反测试。但是,当元素不存在时,我在旋转60秒后始终获得WebDriverException超时:See screenshot here

元素检测功能如下:

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;
    }

感谢您的时间!

4 个答案:

答案 0 :(得分:2)

这样的事情会起作用吗?

public static bool IsElementPresent(By by)
{
    try
    {
       bool b = Drivers._driverInstance.FindElement(by).Displayed;
       return b;
    }
    catch
    {
       return false;
    }
}

答案 1 :(得分:1)

以下是选项:
选项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));  

使用这种方法,如果您的下一个操作是单击任何元素,有时您会在Chrome浏览器中收到错误(org.openqa.selenium.WebDriverException:Element无法在点(411,675)点击)。它适用于Firefox。

选项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;
}  

这里我们将隐式等待0和查找元素。如果元素不存在,它将在接下来的15秒内尝试(您可以方便地更改此数字)。如果有时间,请完成功能。

选项3:

Sudeepthi已经提出过这个建议。

Drivers._driverInstance.FindElement(by).Displayed;

答案 2 :(得分:1)

  

忘记 ExpectedConditions WebDriverWait 了-两者都不能很好地工作

  1. 如果您有 ImplicitWait ,则完全忽略 WebDriverWait 。因此,您不能将ImplicitWait上的默认超时设置为10秒,然后仅用1秒创建一个WebDriverWait实例来检查是否存在元素
  2. WebDriverWait 忽略,IgnoreExceptionTypes = WebDriverTimeoutException ,因此您始终需要尝试捕获

使用以下方法,您将获得一个简单而舒适的解决方案,并且只需最少的代码即可工作:

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);

结果将是所需的IWebElement或Null

  

不幸的是自2016年以来未实现从 ImplicitWait 中获取当前值的吸气剂。因此,您只能将值重置为固定值,而不能在之前动态读取它。

答案 3 :(得分:0)

另一个解决方案是使用显式等待。在Java(伪代码;你必须翻译)这样的东西可以工作:

wait.until(ExpectedConditions.not(ExpectedConditions.invisibilityOfElementLocated(by)), 10, 1000)

将等到元素出现在页面上,每秒轮询十秒钟。