在我的代码中,我需要“请等待......”在上面的面板中阻止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
答案 0 :(得分:2)
所以我猜测你的测试是在面板出现之前找到并移动元素的隐形检查。这是因为存在首先发生的竞争条件,Selenium测试检查或使面板可见的网站。您可以(通过首先检查出现的面板,然后检查它是否已消失)来解决此问题。这限制了一些竞争条件的方面。它确实不,修复竞争条件问题。在下面的示例中,如果面板出现然后消失 ,则执行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();
请注意,创建Web驱动程序等待时30
意味着它将继续检查所需可见性状态的匹配元素,最长可达30秒。如果在该时间内未找到具有正确可见性状态的匹配元素,则将抛出TimeoutException
。此外,请注意,该面板是由您提供的XPath定位的。但是,我并不建议使用XPath表达式,因为它是绝对的。作为Selenium定位器,我可能会避免使用XPath,因为它可能很脆弱且难以阅读以进行测试维护。通常,你可以通过其他定位器策略(例如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的一个示例。如果你真的看到了上面的代码片段,你应该这样做:
By.name("foo")