Webdriver,检测DOM更改并等待它

时间:2013-12-02 08:47:31

标签: java selenium webdriver selenium-webdriver

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

在页面上执行操作会导致此页面DOM发生更改(例如,Javascript灯箱),然后我的JUnit测试在DOM更改后期待新元素,但我的测试是获取旧DOM元素

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

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

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

请注意,现在有一条信息消息Your item ... has been added

现在我将关键字放在“搜索”文本框中并按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. 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);
        }
    }
    
  3. 我预计在clickAddAndClose()结束时,它会看到此页面仍在更新,因此它将等待信息消息更新。但这似乎也不起作用。

    这让我最后的选择是在clickAddAndClose()的末尾添加一个线程睡眠。我想避免使用它。

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

2 个答案:

答案 0 :(得分:1)

如果(因为似乎是这种情况)正在通过AJAX操作修改您的页面,则等待加载页面将不起作用。

不要等待页面加载,而是等待您测试的条件变为真。这样,您可以给AJAX操作执行时间,如果出现问题,超时时会出现错误。

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

itemDetailsPage

答案 1 :(得分:0)

好像你需要等到ajax完成它的工作。在类似的情况下,我使用了类似于描述here的waitForJQueryProcessing的方法。看一看,它可能会有所帮助。