【问题标题】:Why does Selenium Webdriver findElements(By.Id) timeout when the element isn't in the DOM?当元素不在 DOM 中时,为什么 Selenium Webdriver findElements(By.Id) 会超时?
【发布时间】:2017-03-07 18:39:04
【问题描述】:

我正在编写一个测试,我想验证一个元素是否不存在于页面上(显示或以其他方式显示)。我在各种文章(如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;
    }

感谢您的宝贵时间!

【问题讨论】:

  • 顺便说一句,我正在运行 Selenium 2.53.1
  • 似乎激活了隐式等待。打电话之前先关掉FindElements:driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(0));
  • 这就像一个魅力弗洛伦特,谢谢!如果您可以将此解决方案放在答案中,我很乐意对其进行标记。此外,如果您对它的工作原理有更详细的解释,那将非常适合我和其他未来的观众。
  • 我认为某些代码破坏了功能。我在这里遇到了类似的问题stackoverflow.com/questions/31437515/…

标签: c# selenium selenium-webdriver


【解决方案1】:

这样的事情会奏效吗?

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

【讨论】:

  • 感谢 Sudeepthi,这已经通过了我的测试。 :) 问题是,这意味着 WebDriver 在捕获异常之前为每个按钮旋转一分钟。因此,当阳性病例只需要约 40 秒时,测试需要 4 分钟。我仍在寻找一种方法来使更有效的方法发挥作用。
【解决方案2】:

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

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

这将等到元素出现在页面上,每秒轮询一次,持续十秒。

【讨论】:

    【解决方案3】:

    以下是选项:
    选项 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 is not clickable at point (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;
    

    【讨论】:

      【解决方案4】:

      忘记 ExpectedConditionsWebDriverWait -- 两者都不能很好地工作

      1. 如果您有 ImplicitWait,则 WebDriverWait 将被完全忽略。因此,您不能将 ImplicitWait 的默认超时设置为 10 秒,然后创建一个只有 1 秒的 WebDriverWait 实例来检查元素是否存在
      2. WebDriverWait 忽略 IgnoreExceptionTypes = WebDriverTimeoutException,所以你总是需要一个try catch

      通过以下方法,您将获得一个使用最少代码的简单舒适的解决方案:

      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

      不幸的是ImplicitWait 获取当前值的 getter 自 2016 年以来未实施。所以只能将值重置为固定值,之前不能动态读取。

      【讨论】:

      • 我不再从事我提出这个问题的工作,所以我能做的最好的就是为有用的信息点赞。谢谢安德烈亚斯!
      【解决方案5】:

      在 javascript 中,它是:

      driver.manage().timeouts().implicitlyWait(10);
      

      【讨论】:

      猜你喜欢
      • 2021-12-09
      • 2018-10-02
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 2012-06-01
      • 1970-01-01
      相关资源
      最近更新 更多