I have a fluent wait class that works pretty well for locating my page elements, however, when I am locating elements for lists I don't appear to be using the same wait. I currently need to add sleeps in my page elements that are used to create lists and then make a selection from that list. How can I leverage my fluent wait class with my lists?
here is an example of a web element and a list:
import com.xxx.utils.fluentWait;
public class FormBuilderPageElements extends fluentWait {
public FormBuilderPageElements(WebDriver driver) {
super(driver);
}
// Cancel confirm Submission
By cancelConfirmSubmission = By.cssSelector("button[data-test-id='confirmation-cancel-prompt']");
public WebElement cancelConfirmSubmission() {
return this.waitUntil(cancelConfirmSubmission);
}
// Used to locate and click on TABS, which one is determined by the number of the
// cssSelectors viewed in the console for that element.
public void clickATab(int whichOne) throws InterruptedException {
List<WebElement> allTextFields = driver.findElements(By.cssSelector("div[data-test-id='tab-content']"));
Actions action = new Actions(driver);
action.moveToElement(allTextFields.get(whichOne)).click().perform();
Thread.sleep(150);
}
This is what my fluent wait looks like:
package com.xxx.web_form;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
abstract class fluentWait {
protected WebDriver driver;
FluentWait<WebDriver> fluentWait;
protected fluentWait(WebDriver driver) {
this.driver = driver;
fluentWait = new FluentWait<WebDriver>(this.driver);
}
@SuppressWarnings("deprecation")
protected WebElement waitUntil(By elementToWaitFor, int timeout, int pollTimeout) {
fluentWait.withTimeout(timeout, TimeUnit.SECONDS);
fluentWait.pollingEvery(pollTimeout, TimeUnit.SECONDS);
fluentWait.ignoring(NoSuchElementException.class);
fluentWait.until(ExpectedConditions.elementToBeClickable(elementToWaitFor));
fluentWait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div[class='ui active loader loader']")));
return driver.findElement(elementToWaitFor);
}
protected WebElement waitUntil(By elementToWaitFor) {
return this.waitUntil(elementToWaitFor, 45, 1);
}
}
This is how I use the clickATab:
// Expand all closed tabs
formBuilder.clickATab(1);
2 Answers 2
This is the solution I came up with, the example above helped lead me here. Posting this in the case others run into a similar problem. This required a little refactoring in terms of how I identified lists and used them in different methods, but I've been able to remove a ton of wait time, my tests are running much faster now.
I'd appreciate feedback if this could be made more efficient or if I'm doing something wrong.
package com.xxx.web_form;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
abstract class fluentWait {
protected WebDriver driver;
FluentWait<WebDriver> fluentWait;
protected fluentWait(WebDriver driver) {
this.driver = driver;
fluentWait = new FluentWait<WebDriver>(this.driver);
}
@SuppressWarnings("deprecation")
protected WebElement waitUntil(By elementToWaitFor, int timeout, int pollTimeout) {
fluentWait.withTimeout(timeout, TimeUnit.SECONDS);
fluentWait.pollingEvery(pollTimeout, TimeUnit.SECONDS);
fluentWait.ignoring(NoSuchElementException.class);
fluentWait.until(ExpectedConditions.elementToBeClickable(elementToWaitFor));
fluentWait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div[class='ui active loader loader']")));
return driver.findElement(elementToWaitFor);
}
protected WebElement waitUntil(By elementToWaitFor) {
return this.waitUntil(elementToWaitFor, 45, 1);
}
protected List<WebElement> waitUntilList(final List<WebElement> elementsToWaitFor, Duration interval) {
fluentWait.withTimeout(interval);
fluentWait.pollingEvery(interval);
fluentWait.ignoring(NoSuchElementException.class);
fluentWait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div[class='ui active loader loader']")));
return (elementsToWaitFor);
}
protected List<WebElement> waitUntilList(By elementsToWaitFor) throws InterruptedException {
// loop until element list value is not 0
while (driver.findElements(elementsToWaitFor).size() == 0) {
for (int i = 0; i < 10; i++) {
if (i > 5) {
break;
}
System.out.println("Waiting for list element...");
Thread.sleep(1000);
}
}
return (driver.findElements(elementsToWaitFor));
}
}
Try with this.
protected List<WebElement> waitUntil(By elementToWaitFor, int timeout, int pollTimeout)
{
WebDriver driver = iDriver;
FluentWait<WebDriver> fluentWait = new FluentWait<WebDriver>(this.iDriver);
fluentWait.withTimeout(5, TimeUnit.SECONDS);
fluentWait.pollingEvery(1, TimeUnit.SECONDS);
fluentWait.ignoring(NoSuchElementException.class);
fluentWait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div[class='ui active loader loader']")));
List<WebElement> list= fluentWait.until(new Function<WebDriver,List<WebElement>>()
{
@Override
public List<WebElement> apply(WebDriver input) {
// TODO Auto-generated method stub
List<WebElement> list = driver.findElements(elementToWaitFor);
if(list.size() > 0)
throw new NoSuchElementException("List is not loaded");
else
return list;
}
});
return list;
}
PS: I couldn't executed this. I hope it works. If you find any issue, please let me know.
-
I was not able to get this example running in my project - just coming back to this now, I do not recall what did not work.QAPal– QAPal2019年04月18日 18:57:27 +00:00Commented Apr 18, 2019 at 18:57
Explore related questions
See similar questions with these tags.