简体   繁体   English

使用 Java 的 Selenium WebDriver 测试中的 waitForVisible/waitForElementPresent 是否等效?

[英]Equivalent of waitForVisible/waitForElementPresent in Selenium WebDriver tests using Java?

With "HTML" Selenium tests (created with Selenium IDE or manually), you can use some very handy commands like WaitForElementPresent or WaitForVisible .通过“HTML” Selenium 测试(使用 Selenium IDE 或手动创建),您可以使用一些非常方便的命令,例如WaitForElementPresentWaitForVisible

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

When coding Selenium tests in Java (Webdriver / Selenium RC—I'm not sure of the terminology here), is there something similar built-in ?在 Java(Webdriver / Selenium RC——我不确定这里的术语)中编写 Selenium 测试时,是否有类似的内置内容

For example, for checking that a dialog (that takes a while to open) is visible...例如,检查对话框(需要一段时间才能打开)是否可见...

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

What's the cleanest robust way to code such check?编写此类检查的最干净可靠的方法是什么?

Adding Thread.sleep() calls all over the place would be ugly and fragile, and rolling your own while loops seems pretty clumsy too...在各处添加Thread.sleep()调用将是丑陋和脆弱的,并且滚动你自己的 while 循环似乎也很笨拙......

Implicit and Explicit Waits 隐式和显式等待

Implicit Wait隐式等待

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available.隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用)时轮询 DOM 一段时间。 The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.默认设置为 0。设置后,将在 WebDriver 对象实例的生命周期内设置隐式等待。

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

Explicit Wait + Expected Conditions显式等待 + 预期条件

An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code.显式等待是您定义的代码,用于在进一步处理代码之前等待特定条件发生。 The worst case of this is Thread.sleep(), which sets the condition to an exact time period to wait.最糟糕的情况是 Thread.sleep(),它将条件设置为要等待的确切时间段。 There are some convenience methods provided that help you write code that will wait only as long as required.提供了一些方便的方法来帮助您编写仅在需要时等待的代码。 WebDriverWait in combination with ExpectedCondition is one way this can be accomplished. WebDriverWait 与 ExpectedCondition 相结合是实现此目的的一种方式。

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

This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds.这在抛出 TimeoutException 之前最多等待 10 秒,或者如果它找到该元素将在 0 - 10 秒内返回它。 WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. WebDriverWait 默认每 500 毫秒调用一次 ExpectedCondition,直到它成功返回。 A successful return is for ExpectedCondition type is Boolean return true or not null return value for all other ExpectedCondition types.成功返回是针对 ExpectedCondition 类型是布尔值返回 true 或不为 null 所有其他 ExpectedCondition 类型的返回值。


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

Element is Clickable - it is Displayed and Enabled.元素是可点击的 - 它被显示和启用。

From WebDriver docs: Explicit and Implicit Waits来自WebDriver 文档:显式和隐式等待

Well the thing is that you probably actually don't want the test to run indefinitely.问题是您可能实际上不希望测试无限期地运行。 You just want to wait a longer amount of time before the library decides the element doesn't exist.您只想在库决定元素不存在之前等待更长的时间。 In that case, the most elegant solution is to use implicit wait, which is designed for just that:在这种情况下,最优雅的解决方案是使用隐式等待,它专为此而设计:

driver.manage().timeouts().implicitlyWait( ... )

Another way to wait for maximum of certain amount say 10 seconds of time for the element to be displayed as below:另一种等待最大特定数量的方法是 10 秒的时间来显示元素,如下所示:

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

            }
        });
public static boolean waitForUntilVisible(WebDriver driver, Integer time, By by ) {
    WebDriverWait wait = new WebDriverWait(driver,  Duration.ofSeconds(time));

    try {
        wait.until( ExpectedConditions.presenceOfElementLocated(by) ); 
    }catch(NoSuchElementException e) {
        return false;
    }catch (TimeoutException e) {
        return false;
    }
    return true;
}

For individual element the code below could be used:对于单个元素,可以使用以下代码:

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);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM