How can I ask the Selenium-WebDriver to wait for few seconds in Java?

JavaSeleniumSelenium WebdriverWebdriver

Java Problem Overview


I'm working on a Java Selenium-WebDriver. I added

driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

and

WebElement textbox = driver.findElement(By.id("textbox"));

because my Applications takes few seconds to load the User Interface. So I set 2 seconds implicitwait. but I got unable to locate element textbox

Then I add Thread.sleep(2000);

Now it works fine. Which one is a better way?

Java Solutions


Solution 1 - Java

Well, there are two types of wait: explicit and implicit wait. The idea of explicit wait is

WebDriverWait.until(condition-that-finds-the-element);

The concept of implicit wait is

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

You can get difference in details here.

In such situations I'd prefer using explicit wait (fluentWait in particular):

public WebElement fluentWait(final By locator) {
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(30, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);

    WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    });

    return  foo;
};

fluentWait function returns your found web element. From the documentation on fluentWait: An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page. Details you can get here

Usage of fluentWait in your case be the following:

WebElement textbox = fluentWait(By.id("textbox"));

This approach IMHO better as you do not know exactly how much time to wait and in polling interval you can set arbitrary timevalue which element presence will be verified through . Regards.

Solution 2 - Java

This thread is a bit older, but thought I'd post what I currently do (work in progress).

Though I'm still hitting situations where the system is under heavy load and when I click a submit button (e.g., login.jsp), all three conditions (see below) return true but the next page (e.g., home.jsp) hasn't started loading yet.

This is a generic wait method that takes a list of ExpectedConditions.

public boolean waitForPageLoad(int waitTimeInSec, ExpectedCondition<Boolean>... conditions) {
    boolean isLoaded = false;
    Wait<WebDriver> wait = new FluentWait<>(driver)
            .withTimeout(waitTimeInSec, TimeUnit.SECONDS)
            .ignoring(StaleElementReferenceException.class)
            .pollingEvery(2, TimeUnit.SECONDS);
    for (ExpectedCondition<Boolean> condition : conditions) {
        isLoaded = wait.until(condition);
        if (isLoaded == false) {
            //Stop checking on first condition returning false.
            break;
        }
    }
    return isLoaded;
}

I have defined various reusable ExpectedConditions (three are below). In this example, the three expected conditions include document.readyState = 'complete', no "wait_dialog" present, and no 'spinners' (elements indicating async data is being requested).

Only the first one can be generically applied to all web pages.

/**
 * Returns 'true' if the value of the 'window.document.readyState' via
 * JavaScript is 'complete'
 */
public static final ExpectedCondition<Boolean> EXPECT_DOC_READY_STATE = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        String script = "if (typeof window != 'undefined' && window.document) { return window.document.readyState; } else { return 'notready'; }";
        Boolean result;
        try {
            result = ((JavascriptExecutor) driver).executeScript(script).equals("complete");
        } catch (Exception ex) {
            result = Boolean.FALSE;
        }
        return result;
    }
};
/**
 * Returns 'true' if there is no 'wait_dialog' element present on the page.
 */
public static final ExpectedCondition<Boolean> EXPECT_NOT_WAITING = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        Boolean loaded = true;
        try {
            WebElement wait = driver.findElement(By.id("F"));
            if (wait.isDisplayed()) {
                loaded = false;
            }
        } catch (StaleElementReferenceException serex) {
            loaded = false;
        } catch (NoSuchElementException nseex) {
            loaded = true;
        } catch (Exception ex) {
            loaded = false;
            System.out.println("EXPECTED_NOT_WAITING: UNEXPECTED EXCEPTION: " + ex.getMessage());
        }
        return loaded;
    }
};
/**
 * Returns true if there are no elements with the 'spinner' class name.
 */
public static final ExpectedCondition<Boolean> EXPECT_NO_SPINNERS = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        Boolean loaded = true;
        try {
        List<WebElement> spinners = driver.findElements(By.className("spinner"));
        for (WebElement spinner : spinners) {
            if (spinner.isDisplayed()) {
                loaded = false;
                break;
            }
        }
        }catch (Exception ex) {
            loaded = false;
        }
        return loaded;
    }
};

Depending on the page, I may use one or all of them:

waitForPageLoad(timeoutInSec,
            EXPECT_DOC_READY_STATE,
            EXPECT_NOT_WAITING,
            EXPECT_NO_SPINNERS
    );

There are also predefined ExpectedConditions in the following class: org.openqa.selenium.support.ui.ExpectedConditions

Solution 3 - Java

If using webdriverJs (node.js),

driver.findElement(webdriver.By.name('btnCalculate')).click().then(function() {
    driver.sleep(5000);
});

The code above makes browser wait for 5 seconds after clicking the button.

Solution 4 - Java

Using Thread.sleep(2000); is an unconditional wait. If your test loads faster you will still have to wait. So in principle using implicitlyWait is the better solution.

However, I don't see why implicitlyWait does not work in your case. Did you measure if the findElement actually takes two seconds before throwing an exception. If so, can you try to use WebDriver's conditional wait as described in this answer?

Solution 5 - Java

I like to use custom conditions. Here's some code in Python:

def conditions(driver):
    flag = True
    ticker = driver.find_elements_by_id("textbox")
    if not ticker:
        flag = False
    return flag

... click something to load ...
self.wait = WebDriverWait(driver, timeout)
self.wait.until(conditions)

Whenever you need to wait, you can do it explicitly by checking existance of a certain element (such element may vary from page to page). find_elements_by_id returns list - empty or not, you have just to check.

Solution 6 - Java

click appears to be blocking? - here's another way to wait if you're using WebDriverJS:

driver.findElement(webdriver.By.name('mybutton')).click().then(function(){
  driver.getPageSource().then(function(source) {
    console.log(source);
  });
});

The code above waits after the button is clicked for the next page to load and then grabs the source of the next page.

Solution 7 - Java

Implicitly wait and Thread.sleep Both are used for synchronization only..but the difference is we can use Implicitly wait for entire program but Thread.sleep will works for that single code only..Here my suggestion is use Implicitly wait once in the program when every time your Webpage will get refreshed means use Thread.sleep at that time..it will much Better :)

Here is My Code :

package beckyOwnProjects;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;

public class Flip {

	public static void main(String[] args) throws InterruptedException {
		WebDriver driver=new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(2, TimeUnit.MINUTES);
		driver.get("https://www.flipkart.com");
	WebElement ele=driver.findElement(By.cssSelector(".menu-text.fk-inline-block"));
	Actions act=new Actions(driver);
	Thread.sleep(5000);
	act.moveToElement(ele).perform();
	}

}

Solution 8 - Java

Use Actions -

> The user-facing API for emulating complex user gestures.

See Actions#pause method.

Solution 9 - Java

Sometimes implicit wait seems to get overridden and wait time is cut short. [@eugene.polschikov] had good documentation on the whys. I have found in my testing and coding with Selenium 2 that implicit waits are good but occasionally you have to wait explicitly.

It is better to avoid directly calling for a thread to sleep, but sometimes there isn't a good way around it. However, there are other Selenium provided wait options that help. waitForPageToLoad and waitForFrameToLoad have proved especially useful.

Solution 10 - Java

Sometimes implicit wait fails, saying that an element exists but it really doesn't.

The solution is to avoid using driver.findElement and to replace it with a custom method that uses an Explicit Wait implicitly. For example:

import org.openqa.selenium.NoSuchElementException;


public WebElement element(By locator){
    Integer timeoutLimitSeconds = 20;
    WebDriverWait wait = new WebDriverWait(driver, timeoutLimitSeconds);
    try {
        wait.until(ExpectedConditions.presenceOfElementLocated(locator));
    }
    catch(TimeoutException e){
        throw new NoSuchElementException(locator.toString());
    }
    WebElement element = driver.findElement(locator);
    return element;
}

There are additional reasons to avoid implicit wait other than sporadic, occasional failures (see this link).

You can use this "element" method in the same way as driver.findElement. For Example:

    driver.get("http://yoursite.html");
    element(By.cssSelector("h1.logo")).click();

If you really want to just wait a few seconds for troubleshooting or some other rare occasion, you can create a pause method similar to what selenium IDE offers:

    public void pause(Integer milliseconds){
    try {
        TimeUnit.MILLISECONDS.sleep(milliseconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Solution 11 - Java

Answer : wait for few seconds before element visibility using Selenium WebDriver go through below methods.

implicitlyWait() : WebDriver instance wait until full page load. You muse use 30 to 60 seconds to wait full page load.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

ExplicitlyWait WebDriverWait() : WebDriver instance wait until full page load.

WebDriverWait wait = new WebDriverWait(driver, 60);
		
wait.until(ExpectedConditions.visibilityOf(textbox));
		
driver.findElement(By.id("Year")).sendKeys(allKeys);

Note : Please use ExplicitlyWait WebDriverWait() to handle any particular WebElement.

Solution 12 - Java

I prefer the following code to wait for 2 seconds.

for(int i=0; i<2 && driver.findElements(By.id("textbox")).size()==0 ; i++){
   Thread.sleep(1000);
}

Solution 13 - Java

Implicit Wait: During Implicit wait if the Web Driver cannot find it immediately because of its availability, the WebDriver will wait for mentioned time and it will not try to find the element again during the specified time period. Once the specified time is over, it will try to search the element once again the last time before throwing exception. The default setting is zero. Once we set a time, the Web Driver waits for the period of the WebDriver object instance.

Explicit Wait: There can be instance when a particular element takes more than a minute to load. In that case you definitely not like to set a huge time to Implicit wait, as if you do this your browser will going to wait for the same time for every element. To avoid that situation you can simply put a separate time on the required element only. By following this your browser implicit wait time would be short for every element and it would be large for specific element.

Solution 14 - Java

Thread.sleep(1000);

is the worse: being a static wait, it will make test script slower.

driver.manage().timeouts.implicitlyWait(10,TimeUnit.SECONDS);

this is a dynamic wait

  • it is valid till webdriver existence or has a scope till driver lifetime
  • we can implicit wait also.

Finally, what I suggest is

WebDriverWait wait = new WebDriverWait(driver,20);
wait.until(ExpectedConditions.<different canned or predefined conditions are there>);

with some predefined conditions:

isAlertPresent();
elementToBeSelected();
visibilityOfElementLocated();
visibilityOfAllElementLocatedBy();
frameToBeAvailableAndSwitchToIt();
  • It is also dynamic wait
  • in this the wait will only be in seconds
  • we have to use explicit wait for a particular web element on which we want to use.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGnikView Question on Stackoverflow
Solution 1 - Javaeugene.polschikovView Answer on Stackoverflow
Solution 2 - JavaJeff VincentView Answer on Stackoverflow
Solution 3 - JavaAnupView Answer on Stackoverflow
Solution 4 - JavaValentinView Answer on Stackoverflow
Solution 5 - JavasimnoView Answer on Stackoverflow
Solution 6 - JavaDionView Answer on Stackoverflow
Solution 7 - JavaBeckham VinothView Answer on Stackoverflow
Solution 8 - JavaDzmitry SankouskiView Answer on Stackoverflow
Solution 9 - JavaBadgerAndKView Answer on Stackoverflow
Solution 10 - JavaJohnP2View Answer on Stackoverflow
Solution 11 - Javasandeep shewaleView Answer on Stackoverflow
Solution 12 - JavaGangadharView Answer on Stackoverflow
Solution 13 - JavaAbhishek SinghView Answer on Stackoverflow
Solution 14 - JavaShobhitView Answer on Stackoverflow