NarendraR
NarendraR

Reputation: 7708

Can we pass a conditional parameter in ExplicitWait expected condition?

This is the website. What I'm trying to do is, click the button and get the text which show the IPAddress of your system.

I'm able to locate the element which is <span>but it shows the text once the get IP Address button clicked.

So my concern is can we use conditions in ExplicitWait ? for example

 driver.findElement(By.id("lblIPAddress")).getText().length()>0

This is conditional parameter which i want to use in ExplicitWait.

I'm using textToBePresentInElement method in Explicit wait but here I have to pass that string (IP Address: 123.201.110.30) hard coded.

WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("lblIPAddress")), "IP Address: 123.201.110.30"));

Even though I am able to get the text by invisibilityOf() method of the loader , once it get hidden then it span shows the IPAddress text.

wait.until(ExpectedConditions.invisibilityOf(driver.findElement(By.xpath("//div[@class='modal12']"))));
System.out.println("IP address After wait = "+ driver.findElement(By.id("lblIPAddress")).getText());

But my query is to use condition in Explicit wait where it wait for the given time to check the condition (check weather text is available in the element or not).

This is the code :

public static void main(String args[])
{

    System.setProperty("webdriver.chrome.driver", "D:\\Application\\chromedriver.exe");
    driver = new ChromeDriver(); 
    driver.manage().window().maximize();
    driver.get("https://www.aspsnippets.com/demos/1331/");
    driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
    driver.findElement(By.id("btnGet")).click();
    System.out.println(driver.findElement(By.id("lblIPAddress")).getText().length());
    System.out.println("IP Address = "+ driver.findElement(By.id("lblIPAddress")).getText());       
    WebDriverWait wait = new WebDriverWait(driver, 120);
    wait.until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("lblIPAddress")), "IP Address: 123.201.110.30"));
    System.out.println("IP address After wait = "+ driver.findElement(By.id("lblIPAddress")).getText());

}

Upvotes: 1

Views: 1773

Answers (3)

Vrushali
Vrushali

Reputation: 43

I know its late to answer this, but I tried it by following method

public class TestFluentWait {

public static void main(String[] args) {
    
    WebDriverManager.chromedriver().setup();
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.aspsnippets.com/demos/1331/");
    driver.findElement(By.id("btnGet")).click();
    
    Wait<WebDriver> wait = new WebDriverWait(driver,30);        
    WebElement ele = wait.until( new Function<WebDriver,WebElement>()
            {
                public WebElement apply(WebDriver driver)
                    {
                        WebElement reElement= driver.findElement(By.id("lblIPAddress"));
                        if(reElement.getText().length()>0)
                            return reElement;
                        else
                            return null;
                    }
            }
        );
    System.out.println("Text Is:"+ele.getText());
    driver.quit();
}

}

It works with FluentWait as well.

    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(Duration.ofSeconds(30))
            .pollingEvery(Duration.ofSeconds(5)).
            ignoring(NoSuchElementException.class);

Upvotes: 0

JeffC
JeffC

Reputation: 25611

You can use ExpectedConditions to handle this very simply. .textToBePresentInElementLocated() is a partial text match and can be used to wait for the IP to appear. Once it appears, you can fetch it using .getText() on the element. Code below is working and outputs "IP Address: x.x.x.x".

driver.findElement(By.id("btnGet")).click();
new WebDriverWait(driver, 10).until(ExpectedConditions.textToBePresentInElementLocated(By.id("lblIPAddress"), "IP Address:"));
System.out.println(driver.findElement(By.id("lblIPAddress")).getText());

Upvotes: 0

Gaurang Shah
Gaurang Shah

Reputation: 12920

I don't think you can use conditions in Explicit Wait (Expected Conditions) however, you can use any custom condition in FluentWait.

If you are using Java 8, you could write a function which takes condition and executes it.

for your case, you could write something like this.

@Test
public void testFluentWait(){

    driver = new ChromeDriver();
    driver.get("https://www.facebook.com/");
    WebElement element = driver.findElement(By.name("websubmit"));

    waitUntilElementHasText(element);

    //If you are using Java 8
    waitUntilCondition(() -> element.getAttribute("type").contains("submit"));

}

//Only if you are using Java 8
public boolean waitUntilCondition(Callable<Boolean> condition){

    Wait wait = new FluentWait<WebDriver>(driver)
            .withTimeout(30, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);


    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
                return condition.call();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }
    });

    return false;
}

public boolean waitUntilElementHasText(final WebElement element){

    Wait wait = new FluentWait<WebDriver>(driver)
            .withTimeout(30, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);


    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            return element.getText().length() > 0;
        }
    });

    return element.getText().length() > 0;
}

Upvotes: 2

Related Questions