【发布时间】:2013-12-02 08:47:30
【问题描述】:
我在 Java 中使用 Webdriver,但我反复遇到一个问题,我还没有找到合适的解决方案。
这与在页面上执行会导致该页面 DOM 更改的操作有关(例如,Javascript 灯箱),然后我的 JUnit 测试在 DOM 更改后期待新元素,但我的测试正在获取旧的 DOM 元素.
举个例子,我有一个场景如下。
首先点击下图中的“添加项目”按钮,出现灯箱:
然后填写所有项目详细信息,然后单击“添加并关闭”。您将看到以下屏幕:
请注意,现在有一条信息消息Your item ... has been added。
现在我在搜索文本框中输入关键字并按回车键,信息消息将更改为以下内容:
在我的 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在用户从添加项目灯箱添加项目时已经存在。 -
在
clickAddAndClose()末尾添加waitForPageLoaded()方法以尝试等待页面完成重新加载。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 等到它完成刷新?
【问题讨论】:
-
尝试在预期条件下使用stalenessOf 方法。当元素不再存在于 DOM 中时,它返回 True。之后使用你的第二个等待语句
标签: java selenium webdriver selenium-webdriver