【问题标题】:What is the best wait strategy in Selenium for interacting with a WebElementSelenium 中与 WebElement 交互的最佳等待策略是什么
【发布时间】:2020-04-11 23:56:55
【问题描述】:

我刚开始为新的 WebApplication 实现一些 UI 测试,并注意到有时当我等待元素存在时测试会失败,而在等待元素可见时相同的测试会成功。

所以我的问题是,网络元素是否有固定顺序变为“现有”、“可点击”、“可见”、“显示”等,或者这完全取决于开发人员如何实现网页,或者可能用于实现应用程序的 JS 框架?

【问题讨论】:

    标签: c# selenium selenium-webdriver webdriverwait expected-condition


    【解决方案1】:

    确切地说,Selenium 可以处理 WebElement 的 3 种不同状态,HTML DOM

    • 元素是存在,即存在
    • 元素可见
    • 元素是交互式/可点击

    老实说,您不必跟踪网络元素变为现有可点击可见的顺序>显示

    • 如果您的用例是验证任何元素的存在,您需要将WebDriverWait 设置为ExpectedConditionsElementExists(),这是检查元素是否存在于页面的 DOM。这并不一定意味着该元素是可见的。所以有效的代码行将是:

      IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementExists(By.CssSelector("element_cssSelector")));
      
    • 如果您的用例是提取任何元素的任何属性,您需要诱导WebDriverWaitExpectedConditions 设置为ElementIsVisible(locator),这是检查元素是否存在于页面的 DOM 并且可见。可见性意味着元素不仅被显示,而且具有大于 0 的高度和宽度。因此,在您的用例中,代码行将是:

      IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementIsVisible(By.ClassName("element_classname")));
      
    • 如果您的用例是在任何元素上调用 click(),则您需要诱导 WebDriverWaitExpectedConditions 设置为 ElementToBeClickable(),这是检查元素是否可见的期望,并且启用,以便您可以单击它。因此,在您的用例中,代码行将是:

      new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("element_xpath"))).Click();
      

    【讨论】:

    • 元素是否可以点击而不可见?
    • @Frank 简而言之,元素在其核心处可点击意味着,该元素可见且已启用。然而,还有一些其他方面,例如。 Z轴,这将超出本题的范围。
    【解决方案2】:

    这完全取决于页面的编写方式。 Web 元素不会从一种状态演变为另一种状态。它可能会发生变化,但由于某些动态内容、页面上执行的操作等原因。

    这些状态告诉我们什么:

    1. Existing - 当元素在页面 DOM 中时。它不一定必须是可见的或可交互的。它是基本状态,因为元素不能有其他状态,没有存在。使用driver.FindElement(By.Xpath(".//*")) 将找到页面上的所有元素。
    2. 已显示 - 当元素存在时,它可能是可见的。使用IWebElement.Displayed(C# 语法)检查元素是否显示。
    3. 可点击 - 有时当您尝试点击元素时,可能会抛出异常,表示其他东西会获得点击。要处理这些问题,请参阅this answer

    如何检查元素是否存在?如果您只是在搜索元素,则在未找到元素时会抛出异常。我建议使用 WebDriverWait,在特定时间段内寻找元素来处理加载:

    Wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSecond));
    Wait.Until(d => d.FindElement(by));
    

    【讨论】:

    • 我现在明白显示和可见是对同一状态的两种描述。另一个问题:Selenium 是否有可能在没有引发异常的情况下单击一个元素,但也没有执行单击,因为该元素在单击时可能不可见?
    • 我会说这取决于。可以使用Javascript 对给定元素执行单击,即使“正常”单击不起作用。根据我的经验,如果元素不显示,Selenium 的点击将不会成功。
    猜你喜欢
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多