我是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会等待呢?
注意:正如我提到的,我已经有了解决方法,我真的只想知道为什么隐式等待不能解决我的问题。谢谢。
请记住,以下几种情况有所不同:
我的猜测是,如果某些页面使用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(); }