java - Webdriver,检测DOM变化并等待

标签 java selenium webdriver selenium-webdriver

我在 Java 中使用 Webdriver,反复遇到一个问题,但目前还找不到合适的解决方案。

它与在页面上执行的操作有关,这些操作将导致该页面 DOM 发生更改(例如,Javascript lightbox),然后我的 JUnit 测试在 DOM 更改后期待新元素,但我的测试正在获取旧的 DOM 元素。

举个例子,我有一个如下场景。

首先点击下图中的“添加项目”按钮,出现灯箱: enter image description here

然后填写所有项目详细信息并单击“添加并关闭”。您将看到以下屏幕: enter image description here

请注意,现在有一条信息消息您的项目...已添加

现在我在搜索文本框中输入关键字并按 Enter 键,信息消息将更改为以下内容: enter image description here

在我的 JUnit 测试中,流程如下:

....
    itemDetailsPage.clickAddAndClose();
    itemDetailsPage.searchItemBy("Electricity");
    assertEquals("Your search for 'electricity' returned 2 results.",
        itemDetailsPage.getInfoMsg());
....

现在这个测试不是很稳健,因为如果网络很慢,大多数情况下,getInfoMsg()会返回之前的信息消息Your item ... has been added而不是最新的信息消息,这会导致测试失败。需要注意的是,这两条信息消息共享相同的 html 元素 id。

我试图在这里实现的解决方案是:

  1. 在 clickAddAndClose() 中添加显式等待 所以它看起来像:

    public void clickAddAndClose() {
        ...
        clickWhenReady(driver, By.id(addAndCloseButtonId));
        ...
        waitForElementByLocator(driver,By.id(itemInfoMsgId),10);
    }
    

    第二次等待被证明是无用的,因为当用户从添加项目灯箱添加项目时,itemInfoMsgId 已经存在。

  2. 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() 末尾添加线程 sleep 。我想避免使用它。

是否有解决此类问题的通用方法?如何检测页面 DOM 仍在变化并告诉 Webdriver 等待其完成刷新?

最佳答案

如果(看起来就是这样)您的页面正在被 AJAX 操作修改,则等待页面加载将不起作用。

不要等待页面加载,而是等待您正在测试的条件成为真。这样,您就可以为 AJAX 操作提供执行时间,如果出现问题,您将在超时时收到错误消息。

我通常使用 Selenium 的 Python 绑定(bind),自从我编写 Java 代码以来已经有一段时间了,但我相信它看起来像这样,用适合 itemDetailsPage 对象的类型替换 X:

new FluentWait<X>(itemDetailsPage)
    .until(new Function<X, Boolean>() {
        public Boolean apply(X itemDetailsPage) {
            return "Your search for 'electricity' returned 2 results." == itemDetailsPage.getInfoMsg();
        };
    });

关于java - Webdriver,检测DOM变化并等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20324099/

相关文章:

java - 无法定位使用 Selenium WebDriver (Java) 实现为 Span 的元素

python - Selenium Webdriver Python 并行

java - 如何设置tomcat应用服务器的home执行目录?

java - 如何根据java中的集合内容绘制图表

javascript - Python、BeautifulSoup、Selenium 网络抓取

selenium - BDD 测试应该由开发人员还是测试人员编写?

selenium - 无法使用 Selenium webdriver 访问下拉菜单,为什么?

java - 无法使用 selenium webdriver 在撰写电子邮件页面上的“收件人”(电子邮件 ID)字段中发送 key

java - 将新值附加到 javax.json.JsonObject

Java SSL DH key 对生成 - 质数错误