Check if an element exists if the page is loaded. (Selenium)

Asked

Viewed 983 times

0

I am testing a piece of my application, so I created the following method to check if the element exists on the page:

public boolean existe(){
    try{
        driver.findElement(elemento);
        return true;
    }
    catch(NoSuchElementException e){
        return false;
    }
}

But I need to leave a timeout of Lenium configured in 60 seconds, IE, the instance waits up to 1 minute to find the element, if not find cause the exception and the treatment returns false. So I tried this way:

public boolean existe(){
    if(!driver.findElements(elemento).isEmpty()){
        return true;
    }else{
        return false;
    }
}

Still the check takes place for one minute even with the screen loaded. I’m trying to develop a way to search for the element and if it doesn’t exist at that moment it returns false. This way I control the load in the test and as soon as loaded the page makes the check.

3 answers

1

You can set the timeout in a specific function, so you wouldn’t be affecting the overall timeout behavior and you could set the timeout by parameters. The following example is an Extension method and was written in c# but the logic should remain in java. You follow the following steps:

  1. create a Webdriverwait with the timeout you want
  2. uses Wait.until( Desired condition ) Sometimes it can be interesting to wait not only for Elementexists but also for Elementisvisible, however it depends on your application.
public static IWebElement WaitUntilElementExists(this IWebDriver driver, By by, int timeout = 5)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
return wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(by));
}

0

One way to accomplish this is to use ExecutorService and Future.

Follow example of code:

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Boolean> handler = executor.submit(new Callable() {
            @Override
            public Boolean call() {
                return existe();
            }
        });

        try {
            // aqui você tem 1 minuto para o handler
            System.out.println(handler.get(1, TimeUnit.MINUTES));
        } catch (TimeoutException | InterruptedException | ExecutionException e) {
            handler.cancel(true);
        }
        executor.shutdownNow();

If you are using a java >= 8, you can decrease the code this way:

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Boolean> handler = executor.submit((Callable) () -> existe());

        try {
            // aqui você tem 1 minuto para o handler
            System.out.println(handler.get(1, TimeUnit.MINUTES));
        } catch (TimeoutException | InterruptedException | ExecutionException e) {
            handler.cancel(true);
        }
        executor.shutdownNow();

0


Based on the answer from Zesousa I was able to solve the problem by replacing wait.Until(...) for wait.Until(ExpectedConditions.visibilityOf(elemento)) without affecting other timeout.

But I found a solution following the recommendation of documentation of Selenium to search the existence of element:

findElement shall not be used to search for elements not present, use findElements (By) and instead state a response from zero-length.

Already to solve the problem of timeout I used a resource based on streser response

Final code:

public boolean elementoExiste(){
    // TimeOut implicito
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
    // Recomendação do Selenium
    Boolean existe = driver.findElements(elemento).size() > 0;
    return existe;
}

Obs: Elemento is a Webelement

Browser other questions tagged

You are not signed in. Login or sign up in order to post.