Selenium WebDriver:Fluent等待按预期工作,但隐式等待没有

emu*_*ahy 27 selenium webdriver

我是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);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,我宁愿使用隐式等待而不是这样.我的网页驱动程序配置如下:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

这没有解决问题,我得到一个NoSuchElementException.另外,我没有注意到10秒的暂停 - 它只是立即出错.我已经验证了代码中的这一行是用调试器命中的.我究竟做错了什么?为什么implicitlyWait不等待元素出现,但FluentWait呢?

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

Hed*_*ley 27

请记住,几种情况之间存在差异:

  • 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();
}
Run Code Online (Sandbox Code Playgroud)