我在Java中使用Webdriver,我反复遇到一个问题,我找不到合适的解决方案。
在页面上执行操作会导致此页面DOM发生更改(例如,Javascript灯箱),然后我的JUnit测试在DOM更改后期待新元素,但我的测试是获取旧DOM元素
举个例子,我有一个场景如下。
首先点击下图中的“添加项目”按钮,然后会出现灯箱:
然后填写所有项目详细信息,然后单击“添加并关闭”。您将看到以下屏幕:
请注意,现在有一条信息消息Your item ... has been added
。
现在我将关键字放在“搜索”文本框中并按Enter键,信息消息将更改为:
在我的JUnit测试中,流程如下:
....
itemDetailsPage.clickAddAndClose();
itemDetailsPage.searchItemBy("Electricity");
assertEquals("Your search for 'electricity' returned 2 results.",
itemDetailsPage.getInfoMsg());
....
现在这个测试不是很强大,因为如果网络很慢,大多数情况下,getInfoMsg()
将返回先前的信息消息Your item ... has been added
而不是最新的信息消息,这会导致测试失败。只是注意这两个信息消息共享相同的html元素ID。
我想在这里实现的解决方案是:
在clickAddAndClose()中添加显式等待 所以它看起来像:
public void clickAddAndClose() {
...
clickWhenReady(driver, By.id(addAndCloseButtonId));
...
waitForElementByLocator(driver,By.id(itemInfoMsgId),10);
}
第二次等待被证明是无用的,因为当用户从添加项目灯箱添加项目时,itemInfoMsgId
已经存在。
在waitForPageLoaded()
末尾添加clickAddAndClose()
方法,尝试等待页面完成重新加载。下面waitForPageLoaded()
的通用方法:
public void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState").equals("complete");
}
};
Wait<WebDriver> wait = new WebDriverWait(driver, 30);
try {
wait.until(expectation);
} catch (Throwable error) {
assertFalse("Timeout waiting for Page Load Request to complete.",
true);
}
}
我预计在clickAddAndClose()
结束时,它会看到此页面仍在更新,因此它将等待信息消息更新。但这似乎也不起作用。
这让我最后的选择是在clickAddAndClose()
的末尾添加一个线程睡眠。我想避免使用它。
是否有解决此类问题的通用方法?如何检测页面DOM仍在更改并告诉Webdriver等待它完成刷新?
答案 0 :(得分:1)
如果(因为似乎是这种情况)正在通过AJAX操作修改您的页面,则等待加载页面将不起作用。
不要等待页面加载,而是等待您测试的条件变为真。这样,您可以给AJAX操作执行时间,如果出现问题,超时时会出现错误。
我通常使用Selenium的Python绑定,自从我编写Java代码以来已经有一段时间了,但我相信它看起来像这样,X
被替换为适合{{1的类型object:
itemDetailsPage
答案 1 :(得分:0)
好像你需要等到ajax完成它的工作。在类似的情况下,我使用了类似于描述here的waitForJQueryProcessing的方法。看一看,它可能会有所帮助。