Using Fluent Wait When Finding List WebElements



  • 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);
    


  • 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));
        }
    }
    


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2