在Selenium Webdriver中,ExpectedCondition.elementToBeClickable不会等到进度条消失

时间:2016-07-30 11:32:19

标签: java selenium selenium-webdriver

这个问题类似于下面的问题:
即如何等到进度条消失 How to wait dynamically until the progress bar to load completely in Selenium Webdriver?

我的情况有点不同。在我的方案中,当进度条出现时,所有元素都被禁用。我正在使用明确的等待,但仍然得到例外。

示例: 在注册页面中提供所有详细信息后,脚本会点击"创建帐户"按钮。此时会出现一个循环进度条,它会持续1或2秒。如果输入的密码无效,则会在“注册”页面的顶部显示错误消息。我现在需要点击"取消"按钮并重复此过程。

当进度条出现时,整个页面被禁用。只有在进度条消失后,用户才能继续。

这是我的代码:

    WebDriverWait myWaitVar = new WebDriverWait(driver,20);

点击"创建帐户"按钮显示进度条。代码现在应该等到"取消"按钮出现。

//Click on the "Create Account" button.
driver.findElement(By.id("createAccount")).click();

//Wait till the "Cancel" button shows up -- this may take some time.
myWaitVar.until(ExpectedConditions.elementToBeClickable (By.id("cancelRegister")));

//Click on the "Cancel" button.
driver.findElement(By.id("cancelRegister")).click();

当我执行上面的代码时,我总是在最后一行得到NoSuchElementException

我尝试使用ExpectedCondition.visibilityOfElement(),但这也会产生NoSuchElementException

我能让它发挥作用的唯一方法就是强迫它进入睡眠状态:

Thread.sleep(3000);

脚本在睡眠时工作正常。

为什么没有WebDriverWait等到进度条消失?代码成功解析elementToBeClickable(),但它总是在"取消"单击按钮。

2 个答案:

答案 0 :(得分:5)

如果condition为true,则

ExpectedConditions.elementToBeClickable返回元素表示如果元素出现在页面上并且可单击,则返回元素,无需再次找到此元素,只需省略最后一行,如下所示: -

//Click on Create Account btn:
driver.findElement(By.id("createAccount")).click();

//Wait till "Cancel" button is showing up. At cases, it may take some time.
WebElement el = myWaitVar.until(ExpectedConditions.elementToBeClickable(By.id("cancelRegister")));
el.click();

Edited1 : - 如果由于其他元素收到点击而无法点击,您可以使用JavascriptExecutor执行点击操作,如下所示:

//Click on Create Account btn:
driver.findElement(By.id("createAccount")).click();

//Wait till "Cancel" button is showing up. At cases, it may take some time.
WebElement el = myWaitVar.until(ExpectedConditions.elementToBeClickable(By.id("cancelRegister")));
((JavascriptExecutor)driver).executeScript("arguments[0].click()", el); 

Edited2 : - 从提供的异常看来,进度条仍然覆盖在cancelRegister按钮上。因此,最好的方法是先等待进度条的隐身,然后等待cancelRegister按钮的可见性,如下所示:

//Click on Create Account btn:
driver.findElement(By.id("createAccount")).click();

//Now wait for invisibility of progress bar first 
myWaitVar.until(ExpectedConditions.invisibilityOfElementLocated(By.id("page_loader")));

//Now wait till "Cancel" button is showing up. At cases, it may take some time.
WebElement el = myWaitVar.until(ExpectedConditions.elementToBeClickable(By.id("cancelRegister")));
el.click();

希望它有效......:)

答案 1 :(得分:2)

您可以在那里等待以确保进度条消失。

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
   .withTimeout(30, SECONDS)
   .pollingEvery(5, SECONDS)
   .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
 public WebElement apply(WebDriver driver) {
   return (driver.findElements(By.id("progressbar")).size() == 0);
 }
});