一尘不染

Selenium WebDriver:流畅的等待按预期方式工作,但隐式等待不起作用

selenium

我是Selenium WebDriver的新手,正在尝试了解“等待”元素出现的正确方法。

我正在测试一个带有单选按钮答案的问题的页面。选择答案时,JavaScript可能启用/禁用页面上的某些问题。

问题似乎是Selenium的“单击速度太快”,而不是等待Javascript完成。我尝试用两种方式解决此问题-
显式等待解决了该问题。具体来说,这可以解决我的问题:

private static WebElement findElement(final WebDriver driver, final By locator, final int timeoutSeconds) {
    FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(500, TimeUnit.MILLISECONDS)
            .ignoring(NoSuchElementException.class);

    return wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver webDriver) {
            return driver.findElement(locator);
        }
    });
}

但是,我 宁愿 使用隐式等待代替此方法。我将我的Web驱动程序配置如下:

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

这不能解决问题,并且我得到了NoSuchElementException。另外,我没有注意到10秒钟的暂停-
它只是立即出错。我已经验证了代码中的这一行是否已被调试器击中。我究竟做错了什么?为什么隐式等待不等待元素出现,而FluentWait会等待呢?

注意:正如我提到的,我已经有了解决方法,我真的只想知道为什么隐式等待不能解决我的问题。谢谢。


阅读 566

收藏
2020-06-26

共1个答案

一尘不染

请记住,以下几种情况有所不同:

  • DOM中根本不存在的元素。
  • 元素存在于DOM中但不可见。
  • DOM中存在但未启用的元素。(即可点击)

我的猜测是,如果某些页面使用javascript显示,则元素已经存在于浏览器DOM中,但不可见。隐式等待仅等待元素出现在DOM中,因此它会立即返回,但是当您尝试与该元素进行交互时,您会收到NoSuchElementException。您可以通过编写一个辅助方法来检验此假设,该方法显式等待元素可见或可单击。

一些示例(在Java中):

public WebElement getWhenVisible(By locator, int timeout) {
    WebElement element = null;
    WebDriverWait wait = new WebDriverWait(driver, timeout);
    element = wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
    return element;
}

public void clickWhenReady(By locator, int timeout) {
    WebDriverWait wait = new WebDriverWait(driver, timeout);
    WebElement element = wait.until(ExpectedConditions.elementToBeClickable(locator));
    element.click();
}
2020-06-26