Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Selenium Webdriver, ExpectedCondition.elementToBeClickable is not waiting until the progress bar disappears

This question is similar to the one below:
i.e. How to wait till Progress bar disappears.
How to wait dynamically until the progress bar to load completely in Selenium Webdriver?

My situation is a bit different. In my scenario, all the elements are disabled when the progress bar appears. I am using explicit wait but still getting the exception.

Scenario: After providing all the details in the Signup Page the script clicks on the "Create Account" button. At this point a circular progress bar appears and it persists for 1 or 2 seconds. If the password entered is invalid the error message is displayed at the top of the Signup page. I now need to click on the "Cancel" button and repeat the process.

When the progress bar appears the whole page is disabled. The user will be able to continue only after the disappearance of the progress bar.

Here's my code:

WebDriverWait myWaitVar = new WebDriverWait(driver,20);

After clicking on the "Create Account" button the progress bar is displayed. The code should now wait until the "Cancel" button appears.

//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();

When I execute the above code I always get NoSuchElementException at the last line.

I tried with ExpectedCondition.visibilityOfElement() but this also produces NoSuchElementException.

The only way I can get it to work is by forcing it to sleep:

Thread.sleep(3000);

The script works fine with the sleep.

Why doesn't WebDriverWait wait until the progress bar disappears? The code successfully parses the elementToBeClickable() but it always throws an exception when the "Cancel" button is clicked.

like image 559
Ahamed Abdul Rahman Avatar asked Jul 30 '16 11:07

Ahamed Abdul Rahman


People also ask

What should be used in Selenium to wait for some conditions such as elementToBeClickable?

WebDriverWait command in Selenium WebElement firstResult = new WebDriverWait(driver, Duration. ofSeconds(10)) . until(ExpectedConditions. elementToBeClickable(By.

What is elementToBeClickable in Selenium?

The elementToBeClickable method in Expected Conditions in Selenium Java returns a WebElement if the located element is clickable (i.e. it can be clicked). The appropriate Selenium locator for locating the WebElement is passed to the method.

How wait until element is not present in Selenium?

This can be achieved with synchronization in Selenium. We shall add an explicit wait criteria where we shall stop or wait till the element no longer exists. Timeout exception is thrown once the explicit wait time has elapsed and the expected behavior of the element is still not available on the page.


2 Answers

ExpectedConditions.elementToBeClickable returns element if condition will be true means it returns element if element appears on the page and clickable, No need to find this element again, just omit last line as below :-

//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 :- If you're unable to click due to other element receive click you can use JavascriptExecutor to perform click as below :

//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 :- It seems from provided exception, progress bar still overlay on cancelRegister button. So best way is to wait for invisibility of progress bar first then wait for visibility of cancelRegister button as below :

//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();

Hope it works...:)

like image 177
Saurabh Gaur Avatar answered Sep 29 '22 09:09

Saurabh Gaur


You can have a wait there to make sure that progress bar disappears.

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);
 }
});
like image 38
Priyanshu Shekhar Avatar answered Sep 29 '22 09:09

Priyanshu Shekhar