How to call selenium fluentwait method from another class and avoid thread sleep

30 views Asked by At

Hello my problem is i want to wait for a specific element till load/clickable therefore im using fluent wait avoiding thread.sleep and also to avoid code duplication i create a .java class that includes fluent wait method and calling it in necessary test script but the problem is when i use fluent wait on the script code block it works but when i call it from another .java file it does not here is the code examle i have to add a thread.sleep function but i want to avoid it

package Athlete;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;

import java.time.Duration;

public class FluentHelper {

    public static WebElement waitForElement(WebDriver driver, By by, int timeoutSeconds, int pollingIntervalMillis) {
        Wait<WebDriver> wait = new FluentWait<>(driver)
                .withTimeout(Duration.ofSeconds(timeoutSeconds))
                .pollingEvery(Duration.ofMillis(pollingIntervalMillis))
                .ignoring(Exception.class);

        return wait.until((ExpectedCondition<WebElement>) webDriver -> webDriver.findElement(by));
    }
}

This is my FluentWait class

package Athlete;

import java.time.Duration;
import java.util.Properties;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;


public class eSignReportCreate {

    public static void main(String[] args) {
        try {
            WebDriver driver = new ChromeDriver();
            ApiRequest apiRequest = new ApiRequest();
            Properties configProperties = ConfigReader.getConfigProperties();
            
            //FluentWaitHelper waitHelper = new FluentWaitHelper(driver, 30, 1000);
                       
            String webUrl = configProperties.getProperty("webUrl");
            String token = apiRequest.getTokenFromApi();
            String eImzaPassword = configProperties.getProperty("eImzaKey");
            String idNumber = IdEnum.ID_NUMBER_1.getIdNumber();
            // Initialize your Selenium WebDriver (Make sure you have the necessary WebDriver executable)
           // System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); // Specify the path to chromedriver
            
            driver.manage().window().maximize();
            driver.get(webUrl + token);             
            driver.findElement(By.linkText("Kapat")).click();
            driver.findElement(By.xpath("//a[@class='ob-click-me k-button' and contains(text(),'Yeni Kayıt')]")).click();
            driver.findElement(By.linkText("Kapat")).click();
            driver.findElement(By.name("IdentityNumber")).sendKeys(idNumber);
            driver.findElement(By.id("sorgulabtn")).click();

//            FluentWait<WebDriver> wait = new FluentWait<>(driver)
//                  .withTimeout(Duration.ofSeconds(30))
//                  .pollingEvery(Duration.ofMillis(300))
//                  .ignoring(ElementNotInteractableException.class);
//
//              wait.until(d -> {
//                  WebElement nextButton = driver.findElement(By.id("nextBtn"));
//                  if (nextButton.isDisplayed() && nextButton.isEnabled()) {
//                      nextButton.click();
//                      return true;
//                  }
//                  return false;
//              });
            WebElement nextButton = FluentHelper.waitForElement(driver, By.id("nextBtn"), 20, 1000);
            Thread.sleep(5000);
            nextButton.click();

here is the automation script itself as you can understand the comment part is working as i said. this is also working with thread.sleep() how can i get rid of thread sleep because when i do it does not click the nextButton

1

There are 1 answers

2
sashkins On

The commented code from the eSignReportCreate class and the code from the FluentHelper.waitForElement do a bit different things.

FluentHelper.waitForElement just waits for the element to appear in DOM, and it returns 'true' shortly if the element appears.
You didn't specify the exact error you have, but I may assume (from the ignored ElementNotInteractableException exception) that you can't click the nextButton because it is not interactable yet.

When webDriver.findElement() returns the WebElement, it does not always mean that the element is ready to handle the events assigned to it.

In the commented code, besides finding the element you are checking for the element to be displayed and enabled + you are clicking on it (again, with caught exception (!))

You need to modify the FluentHelper.waitForElement by adding additional checks (like isDispayed/isEnabled) after the findElement, but from my point of view, the standard ExpectedConditions.elementToBeClickable should work fine for your case.