57

使用“HTML”Selenium 测试(使用 Selenium IDE 创建或手动创建),您可以使用一些非常方便的命令,例如WaitForElementPresentor WaitForVisible

<tr>
    <td>waitForElementPresent</td>
    <td>id=saveButton</td>
    <td></td>
</tr>

在 Java 中编码 Selenium 测试时(Webdriver / Selenium RC——我不确定这里的术语),是否有类似的内置功能

例如,为了检查一个对话框(需要一段时间才能打开)是否可见......

WebElement dialog = driver.findElement(By.id("reportDialog"));
assertTrue(dialog.isDisplayed());  // often fails as it isn't visible *yet*

编写此类检查的最简洁可靠的方法是什么?

在所有地方添加Thread.sleep()调用将是丑陋和脆弱的,并且滚动你自己的while循环似乎也很笨拙......

4

5 回答 5

112

隐式和显式等待

隐式等待

隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用)时轮询 DOM 一段时间。默认设置为 0。一旦设置,就会为 WebDriver 对象实例的生命周期设置隐式等待。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

显式等待 +预期条件

显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。最坏的情况是 Thread.sleep(),它将条件设置为要等待的确切时间段。提供了一些方便的方法来帮助您编写只等待所需时间的代码。WebDriverWait 与 ExpectedCondition 结合使用是实现此目的的一种方式。

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(
        ExpectedConditions.visibilityOfElementLocated(By.id("someid")));
于 2012-06-08T14:35:27.927 回答
10
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

这会在抛出 TimeoutException 之前等待最多 10 秒,或者如果它发现元素将在 0 - 10 秒内返回它。默认情况下,WebDriverWait 每 500 毫秒调用一次 ExpectedCondition,直到它成功返回。对于 ExpectedCondition 类型的成功返回是 Boolean 返回 true 或所有其他 ExpectedCondition 类型的非空返回值。


WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

元素是可点击的 - 它被显示并启用。

来自WebDriver 文档:显式和隐式等待

于 2014-02-16T05:27:14.310 回答
0

那么问题是您实际上可能不希望测试无限期地运行。在库决定元素不存在之前,您只想等待更长的时间。在这种情况下,最优雅的解决方案是使用隐式等待,它就是为此而设计的:

driver.manage().timeouts().implicitlyWait( ... )
于 2012-06-07T23:24:44.050 回答
0

另一种等待最大一定量的方法是 10 秒的时间以显示元素,如下所示:

(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver d) {
                return d.findElement(By.id("<name>")).isDisplayed();

            }
        });
于 2019-07-05T05:15:06.203 回答
-4

对于单个元素,可以使用以下代码:

private boolean isElementPresent(By by) {
        try {
            driver.findElement(by);
            return true;
        } catch (NoSuchElementException e) {
            return false;
        }
    }
for (int second = 0;; second++) {
            if (second >= 60){
                fail("timeout");
            }
            try {
                if (isElementPresent(By.id("someid"))){
                    break;
                }
                }
            catch (Exception e) {

            }
            Thread.sleep(1000);
        }
于 2012-11-16T07:54:07.113 回答