【问题标题】:Explicit wait not working in Selenium Webdriver显式等待在 Selenium Webdriver 中不起作用
【发布时间】:2016-07-25 13:18:36
【问题描述】:

在我的代码中,我需要“请稍候...”上方面板中的阻塞 UI 首先消失,然后移至下方面板,因此我明确等待该特定块跨度。但是即使上面的面板被阻止了它的保存功能仍然在进行,下面的面板的点击功能会连续启动。

driver.findElement(By.id("saveHouseholdMember")).click();
WebDriverWait uiBlock = new WebDriverWait(driver, 30);
uiBlock.until(ExpectedConditions.invisibilityOfElementWithText(By.xpath("/html/body/div[2]/form[1]/div/table/tbody/tr/td/span"), "Please wait..."));
driver.findElement(By.id("disabilityFlagRadio")).click();

在这里,单击保存按钮时,该面板会被“请稍候...”消息阻止。驱动程序应该等到上面面板中的“请稍候...”文本消失,然后应该执行下面的书面点击功能,但它没有按预期发生。上述面板的保存通常需要 15 秒左右。

我也参考了下面的链接,但找不到有用的输入。 Wait is not working in selenium webdriver

【问题讨论】:

  • Selenium 是否有可能在显示“请稍候...”消息的面板出现之前超过等待时间?
  • +1,尝试先等待面板可见,以确保 selenium 开始等待面板在可见后消失。
  • 如果您确定该面板已显示,则可以等待显示下一个元素WebElement element = wait.until( ExpectedConditions.visibilityOfElementLocated(By.id("disabilityFlagRadio")));

标签: java selenium selenium-webdriver


【解决方案1】:

所以我的猜测是,您的测试是在面板出现之前找到并通过元素的不可见性检查。这是因为首先发生的事情存在竞争条件,Selenium 测试检查或使面板可见的网站。您可以(在某种程度上)通过首先检查出现的面板然后检查它是否消失来解决此问题。这限制了这方面的一些竞争条件。但是,它修复了竞态条件问题。在下面的示例中,如果面板出现然后消失之前硒代码执行寻找面板可见它将失败。最好的方法是查找导致面板消失的代码并在完成时设置的某种状态,但我不知道页面的代码或逻辑。一个例子是,如果 Web 开发人员有保存操作(在完成时)将 CSS 类添加到某个元素。然后您的测试可以等待一个元素获得该类。朴素的例子(有竞争条件):

// Do stuff to get to the page needed for the test
driver.findElement(By.id("saveHouseholdMember"))
      .click();
// Make sure the panel first appears and then disappears
By panelBy = By.xpath("/html/body/div[2]/form[1]/div/table/tbody/tr/td/span");
new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfElementLocated(panelBy));
new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(panelBy));
// Panel is gone, click the next button
driver.findElement(By.id("disabilityFlagRadio"))
      .click();

注意 30 在创建 Web 驱动程序等待时意味着它将持续检查处于所需可见性状态的匹配元素长达 30 秒。如果在那个时候没有找到具有正确可见性状态的匹配元素,则会抛出TimeoutException。另外,请注意面板由您提供的 XPath 定位。但是,我不推荐 XPath 表达式,因为它是绝对的。我尽可能避免使用 XPath 作为 Selenium 定位器,因为它在测试维护时阅读起来可能很脆弱且令人讨厌。通常,您可以通过其他定位器策略(例如 CSS 选择器、名称、id 等)以一种更清晰易读的方式获取相同的元素(更容易)。当您确实绝对需要 XPath(例如,您可能需要在页面上查找某些特定文本)时,请使用相对 XPath。对于下面的(简单的)示例:

<html>
    <body>
        <div>
            <span>
                <input name="foo"></input>
            </span>
        </div>
    </body>
</html>

如果您使用绝对 XPath 来查找该输入,它将如下所示:

By.xpath("/html/body/div/span/input")

但是,如果整个链的任何部分发生更改,该选择器就会中断(例如,添加一个根本不会改变行为的 div 会中断测试)。相反,您可以使用相对 XPath:

By.xpath("//input[@name='foo']")

请注意,即使这个示例也存在缺陷,并且只是相对 XPath 的示例。如果你真的看到了上面的 sn-p,你可能应该这样做:

By.name("foo")

【讨论】:

  • 你的解释非常好..真的很感激..但是你为什么要提供跨度可见性的解决方案,然后不可见跨度如果可以通过等待下一个元素作为WebElement element = wait.until( ExpectedConditions.visibilityOfElementLocated(By.id("disabilityFlagRadio")));来简单地实现它而不是@ ??
  • 在我看来,页面上有 2 个部分,第一部分影响上部,而 ID 为 disabilityFlagRadio 的部分位于下部。如果该 id 定位的元素在屏幕上可见,而上部正在保存,那么只需等待它可见将具有相同的竞争条件(例如,在“保存”弹出窗口出现之前,硒可能会找到该元素并说“是” ,这是可见的”)。但是,如果这是不正确的,并且该元素 only 在保存完成后显示,那么这将更简单/更好。
猜你喜欢
  • 2015-10-09
  • 2013-11-15
  • 2023-03-05
  • 1970-01-01
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
相关资源
最近更新 更多