2

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

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

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.

1
  • 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
    Commented Apr 18, 2019 at 18:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.