Wait commands let you put tests on hold or pause for a few seconds or even days. Nowadays, Ajax-based websites are widely in used for their high data-exchanging speed. However, there will be variations in receiving each and every Ajax web service on a fully loaded page. To avoid such delays and to ignore exceptions such as ElementNotVisibleException
, it is highly recommended to use waits. To handle such delays on a web page, Selenium WebDriver makes use of both implicit and explicit waits.
An explicit wait waits for certain conditions to occur. It results in TimeoutError
only when the conditions fail to meet their target. In general, the usage of the explicit wait is highly recommended. Here's an example of an explicit wait:
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.presenceOfElementLocated(By.locatorType("path")));
In the example that follows, WebDriver waits for 20 seconds until the web element is found; if it is not, it will simply throw TimeoutException
:
@Test public void Test01() throws Exception { driver.get(baseUrl + "/"); try { waits().until(ExpectedConditions.presenceOfElementLocated(By.id("invalidID"))); } catch(Exception e){ System.out.println("Element Not Found"); } private WebDriverWait waits(){ return new WebDriverWait(driver, 20); }
A few of the useful tasks that you can perform using explicit waits are listed as follows:
NullPointerException
exception will be thrown whenever WebDriverWait
is declared globally on the PageObject design pattern. To avoid such risks, make use of the following snippet efficiently:public class classname{ private WebDriver driver; private final Wait<WebDriver> wait; public classname(WebDriver driver) { //constructor this.driver = driver; wait = new WebDriverWait(driver, 20); } } public void Test01() throws Exception { wait.until (ExpectedConditions.presenceOfElementLocated(By.locatorType("path"))); }
@Test public void Test01() throws Exception { driver.get(baseUrl + "/"); waitForID("value"); } public void waitForID(String id) { WebDriverWait wait = new WebDriverWait(driver, 10); wait.until (ExpectedConditions.presenceOfElementLocated(By.id(id))); }
In the preceding code, WaitForID
is a user-defined method, where the locator ID
can be customized with any locator types. ExpectedCondition
is one of the Selenium libraries containing a set of conditions that verify an element's availability through WebDriverWait
. The methods listed in the following screenshot includes all the expected conditions of Selenium:
The FluentWait
method uses a polling technique, that is, it will keep on polling every fixed interval for a particular element to appear. The FluentWait
method is more or less similar to explicit wait; however, FluentWait
holds additional features, such as polling intervals and ignore exceptions. In the following example, the polling takes place every two seconds with a timeout of 10 seconds, so every two seconds, it checks for the element to appear, until it reaches 10 seconds, and the overall polling count will be five. Through FluentWait
, the user can ignore any kind of exceptions, such as NoSuchElementException
. The code for the FluentWait
method is as follows:
@Test public void Test01() throws Exception { driver.get(baseUrl + "/"); fluentWait(By.locatorType("path")); } public WebElement fluentWait(final By locator) { FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(10, TimeUnit.SECONDS) .pollingEvery(2, TimeUnit.SECONDS) .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function<WebDriver, WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(locator); } }); return foo; };
The sleeper method is not an ideal approach to handle delays. The worst case of explicit wait is Thread.sleep
, which is a fixed delay and mostly used for debugging test cases when the internet speed is slow. It lets the user pause test execution for a certain time period even though the expected condition is met.
The general usage of the sleeper method instead of the explicit wait or fluentWait
is not appreciated. Here's the code for the sleeper method:
Thread.sleep(long millis);
Here, the sleeper is set to 3 seconds, that is, it lets you wait for 3 seconds to move forward to the next process:
Thread.sleep(3000); // waits for 3 secs
Unlike explicit wait, timeouts is an interface without any conditions that set a standard user-defined timeframe for a test to fail. The three types of timeouts are explained as follows:
implicitlyWait()
: An implicit wait waits for an element to appear or be displayed within a certain time period set by the user. In general, every timeout that occurs throughout the tests relies on the implicit wait. It lets you to poll the DOM for a specific time period until an element is found. An implicit wait acts as a master wait; however, the usage of the explicit wait or Fluent Wait is highly recommended since it has the ability to wait for dynamically loading Ajax elements that target a unique web element. The implicit wait is active from the start to the end of the test execution, that is, till the web page is closed. In the Selenium IDE, the wait defaults to 30 seconds. The following is the syntax for the implicit wait:driver.manage().timeouts().implicitlyWait(long, TimeUnit);
The following code snippet is one of the possible ways to define an implicit wait (it can be days, hours, microseconds, milliseconds, minutes, nanoseconds, or seconds):
driver.manage().timeouts().implicitlyWait(30, TimeUnit.DAYS); driver.manage().timeouts().implicitlyWait(30, TimeUnit.HOURS); driver.manage().timeouts().implicitlyWait(30, TimeUnit.MICROSECONDS); driver.manage().timeouts().implicitlyWait(30, TimeUnit.MILLISECONDS); driver.manage().timeouts().implicitlyWait(30, TimeUnit.MINUTES); driver.manage().timeouts().implicitlyWait(30, TimeUnit.NANOSECONDS); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
pageLoadTimeout()
: The pageLoad
timeout method waits for the entire page to be loaded within a specific time period. A timeout exception will be thrown whenever a page takes more than the expected time to load. The following is the syntax for this method:driver.manage().timeouts().pageLoadTimeout(long, TimeUnit);
In the example code snippet that follows, the pageLoad
timer is set to 30 seconds for a web page to load soon after launching a browser under test:
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
setScriptTimeout()
: The setScript
timeout method waits for asynchronous APIs (Ajax) to be loaded in a web page within a certain time period. The following is the syntax for this method:driver.manage().timeouts().setScriptTimeout(long, TimeUnit);
In the following example, the setScript
timer is set to 30 seconds to avoid unusual Ajax timeout breaks. The timeout error returns whenever Ajax calls fail to retrieve within the given time period. The example code snippet follows:
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
18.227.111.197