Selenium Wait
In this tutorial, we will understand how we can avoid synchronization issues while executing the test script in a selenium WebDriver.
Before going further in this tutorial, first, we will understand that what is Synchronization issue?
Synchronization Issue:
Whenever WebDriver try to act on the web element, but the web element is not loaded in the UI,
In such cases, the web driver throws NoSuchElementException and stops the entire execution because of the synchronization issue.
To avoid synchronization issue, we go for the Wait Statements in selenium WebDriver.
"A process of matching application speed with automation tool speed is known as Synchronization Wait in selenium WebDriver."
There are two wait statements available in selenium WebDriver, and they are as following:
- Implicit Wait
- Explicit Wait
Now, the question arises when we use Wait Statement?
- We use the wait statement, whenever the user performs any click operation on button and link.
- We should mandatorily use the wait statement because click operation is always navigating to another page.
- Using the Selenium Wait statements, our test script will wait for the web elements to load for a certain period before continuing with the next step.
Implicit Wait:
- Implicitly wait is always wait for an entire HTML document to load in UI.
- In other words, implicitly wait will be used to set maximum life span time for the driver object.
- Technically, implicitly wait for monitoring or polling the entire HTML document, while loading the page, if the page is getting loaded before maximum duration.
- It releases the driver control to the next line instead of waiting the entire maximum time.
- If we inserted implicitly wait before get() method, that wait would be applicable for all the actions done by the web driver or driver object.
Syntax for implicit wait:
driver.manage().timeouts().implicitlyWait(TimeOut,TimeUnit.SECONDS);
Let see one example where will see how implicit wait will work.
package testpackage; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class Wait_statement { public static void main(String[] args) throws InterruptedException { // System Property for gecko Driver System.setProperty("webdriver.gecko.driver","C:\\Users\\JTP\\Downloads\\geckodriver-v0.25.0-win64\\geckodriver.exe"); // create an object for FirefoxDriver class. WebDriver driver=new FirefoxDriver(); //maximixe the window size driver.manage().window().maximize(); //delete all cookies driver.manage().deleteAllCookies(); //wait for dynamic element appear in UI driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); //navigate to the url driver.get("https://www.google.com/");
Explanation of the code:-
- In the above code, I gave an implicit wait value at 30 seconds, which means that the maximum wait time is 30 seconds to load the element.
- If the element is not loaded within the maximum time, then the wait statement throws an exception, which is TimeoutException.
Note: The main disadvantage of an implicit wait is that the implicit wait can't be used for the Ajax element (dynamic).
And the performance cause issue is not caught while using implicit wait.
Explicit Wait:
- The Explicit wait always waits for an expected element to appear in UI.
- Technically, the explicit wait check for the expected element appears; within the maximum duration, it releases driver control to the next line instead of waiting complete 20 sec.
- The explicit wait will play a significant role in the Ajax application because it will be used for a dynamic element to be load in UI.
The explicit wait can be achieved in two ways, which is as follows,
- WebDriver wait
- Fluent wait
Let us discuss one by one to give you a complete understanding of explicit wait:
WebDriver wait:
WebDriver wait is used when we need to build the customize wait methods based on the conditions.
The Syntax for an explicit wait:
WebDriverWait wait = WebDriverWait(WebDriverReference,TimeOut);
To declare the WebDriver wait, we will use the ExpectedConditions. Some of the most commonly used expected conditions are as follows-
Expected conditions | Description | Commands |
visibilityOf() | It is used for checking that an element, known to be present on the DOM of a page, is visible. |
visibilityOf(WebElement element): ExpectedCondition |
visibilityOfAllElements() | It is used to check that all the elements present on the web page, and also match the locators are visible. |
visibilityOfAllElements(WebElement elements):ExpectedCondition
|
visibilityOfAllElementsLocatedBy() | It used to check the elements present on the web page that match the locator are visible. |
visibilityOfAllElementsLocatedBy(By locator):ExpectedCondition
|
visibilityOfElementLocated() | It is used to check that an element is present on the DOM of a page and visible also. |
visibilityOfElementLocated(By locator):
ExpectedCondition |
elementSelectionStateToBe() | It is used to check if the given element is selected. |
elementSelectionStateToBe(WebElement element,boolean
selected): ExpectedCondition |
elementToBeClickable() | It is used to check an element is visible, and enabled such that you can click it. |
elementToBeClickable(WebElement element):
ExpectedCondition |
elementToBeSelected() | It is used to check if the given element is selected. |
elementToBeSelected(WebElement element):
ExpectedCondition |
frameToBeAvaliableAndSwitchToIt() | It is used to check whether the given frame is available to switch. |
frameToBeAvaliableAndSwitchToIt(By locator):
ExpectedCondition |
invisibilityOfTheElementLocated() | This method is used to check that an element is either invisible or not, and present on the DOM |
invisibilityOfTheElementLocated(By locator):
ExpectedCondition |
invisibilityOfElementWithText() | It is used to check that an element with the text is either invisible or not and present on the Dom. |
invisibilityOfElementWithText(By locator,String
text): ExpectedCondition |
presenceOfAllElementsLocatedBy() | It is used to check that there is at least one element present on the web page. |
presenceOfAllElementsLocatedBy(By locator):ExpectedCondition
|
presenceOfElementLocated() | This method is used to check that an element is present on the DOM of a web page. |
presenceOfElementLocated(By locator):
ExpectedCondition |
textToBePresentInElement() | It is used to check if the given text is present in the specified element. |
textToBePresentInElement(WebElement element,String
text): ExpectedCondition |
textToBePresentInElementLocated() | It is used to check, if the given text is present in the element that matches the given locator. |
textToBePresentInElementLocated(By locator,String
text): ExpectedCondition |
textToBePresentInElementValue() | It is used to check, if the given text is present in the specified elements value attribute. |
textToBePresentInElementValue((By locator,String
text): ExpectedCondition |
titleIs() | This method is used to check the title of a page. |
titlels(String title): ExpectedContition |
titleContains() | This method is used to check that the title contains a case-sensitive substring. |
titlesContains(String title):
ExpectedContition |
urlToBe() | It is used for the URL of the current page to be a specific URL. |
urlToBe(String url): ExpectedContition |
Let see one example where will see how WebDriver wait will work,
package testpackage; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; public class Wait_statement { public static void main(String[] args) throws InterruptedException { //System Property for gecko Driver System.setProperty("webdriver.chrome.driver", "C:\\Users\\JTP\\Downloads\\chromedriver_win32 (1)\\chromedriver.exe"); //create driver class object WebDriver driver = new ChromeDriver(); //maximize the window size driver.manage().window().maximize(); //delete all the cookies driver.manage().deleteAllCookies(); //launch Chrome and navigate to the url driver.get("https://mail.rediff.com/cgi-bin/login.cgi"); //wait for dynamic element appear in UI WebDriverWait wait =new WebDriverWait(driver,20); //check the expected conditions for email text box wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("login"))); System.out.println("email text box is visible"); driver.findElement(By.name("login")).sendKeys("[email protected]"); //check the expected conditions for password text box wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("password"))); System.out.println("password text box is visible"); driver.findElement(By.id("password")).sendKeys("admin@12"); //identify the go button driver.findElement(By.name("proceed")).click(); //close the browser driver.close(); } }
Explanation of the above code:-
In the above example, I used the Rediff login credentials and located them using id and name locators.
And, I am providing the WebDriver wait here, and also given the visibility of element located with the help of locators. And asked the driver to wait for 20 seconds until the expected condition is satisfied.
If expected conditions are satisfied, it will move to the next step, and pass the value for an email and the password text boxes.
After executing the above test script, first, the Chrome driver will be launched the Google Chrome browser, and it will navigate to the login page of rediff.com and pass the values which are mentioned in the above code.
The main advantage of using explicit wait is that we do not need to set the WebDriver wait for a timeout of a particular value we can change it, based on our requirement
But while using the implicitly wait, if we have defined 10 seconds of wait, it will apply to all the elements on the webpage, and it cannot be modified.
Let us see the difference between implicit and explicit wait in selenium web driver-
Implicit Wait v/s Explicit Wait:
Implicit Wait | Explicit Wait |
The Implicit wait is always waiting for the entire Html document to load in UI. | The Explicit wait always waits for an expected element to appear in UI. |
The Implicit wait is used to set the maximum time for the driver object. | An Explicit wait check for the expected element for every 500 mills second. |
In Implicit wait, we do not require any Expected Condition for the element to be located. | In explicit wait, we need the Expected conditions (visibilityOfElementLocated(), elementToBeClickable(),titleIs(),urlToBe())etc for the element to be located. |
The Implicit wait cannot wait for the ajax element (dynamic), so it cannot be used in the ajax application. | The Explicit wait plays a significant role in the ajax application because it will be used for a dynamic element to be load in UI. |
Fluent Wait:
The fluent wait is the extended wait of an explicitly wait.
It is precisely similar to the WebDriver wait, but, it can check for the expected element based on the user-defined time.
It is used to find the web element repeatedly at regular intervals of time until the timeout or until the object gets found.
Note: Both WebDriver and fluent wait classes implement wait interface.
Syntax for fluent wait:
Wait wait= new FluentWait(WebDriver reference) .withTimeout(timeout,SECONDS) .PollingEvery(timeout,SECONDS) .ignoring(Exception.class);
The above syntax is deprecated in Selenium v3.11 and above versions.
So we will use the below syntax for fluent wait:
Wait wait = new FluentWait(WebDriver reference) .withTimeout(Duration.ofSeconds(SECONDS)) .pollingEvery(Duration.ofSeconds(SECONDS)) .ignoring(Exception.class);
Where,
withTimeOut: -sets how long to wait for the evaluated condition to be true.
pollingEvery: - setting up a repeat cycle with the time frame to verify/check the status at the regular interval of time.
ignoring: - ignore is used to specific types of exceptions while waiting for a condition.
Let us see one sample text script where we will use the fluent wait and see how it works,
For our testing purpose, we will see one scenario where an element is loaded at different intervals of time. The element might be load within 10 seconds, 30 seconds, or even more than that.
In such a case, the fluent wait is the ideal wait to use, so we will try to find the element at a different frequency.
package testpackage; import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.Function; import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; public class fluent_wait { public static void main(String[] args) throws InterruptedException { // System Property for gecko Driver System.setProperty("webdriver.chrome.driver", "C:\\Users\\JTP\\Downloads\\chromedriver_win32 (1)\\chromedriver.exe"); //create driver class object WebDriver driver = new ChromeDriver(); //maximize the window size driver.manage().window().maximize(); //delete all the cookie driver.manage().deleteAllCookies(); // launch Chrome and navigate to the url driver.get("https://the-internet.herokuapp.com/dynamic_loading/1"); //identify the start button driver.findElement(By.xpath("//button[contains(text(),'Start')]")).click(); //Wait for 30 seconds to load an element on the page,and check for its presence once every 3 seconds Waitwait = new FluentWait (driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(3)) .ignoring(NoSuchElementException.class); WebElement wb = wait.until(new Function () { public WebElement apply(WebDriver driver) { if(driver.findElement(By.xpath("//div[@id='finish']//h4")).isDisplayed()) { return driver.findElement(By.xpath("//div[@id='finish']//h4")); } else { return null; } } }); //print the value of the text System.out.println(driver.findElement(By.xpath("//div[@id='finish']//h4")).getText()); //quit the browser driver.quit(); } }
Explanation of the above code:-
In the above text script, we are taking the-internet.herokuapp.com website, and then go to the dynamic loading page, where we click on example 1: Element on page that is hidden, and click on the start button, it will print Hello world! on the screen.
And we will set the polling frequency to 3 seconds, and the maximum time is 30 seconds, which implies that we will check for the element on the web page every 3 seconds for the maximum time of 30 seconds.
The Fluent wait is not used for real-time scenarios as such, but generally, it will ask for the interview purpose.
Thread Wait: (java)
- Thread wait also called the hardcoded wait (fixed time) because it always waits for a set amount of time.
- Thread wait is not used for real-time selenium test script because it always depends on the wait, which is given by the user, or it still waits for user-defined time, even though the page is getting loaded earlier.
- Thread wait increases the time of automation execution.
Syntax:
Thread.sleep(millseconds);
e.g.:Thread.sleep(2000);
Where,
- Thread is a class.
- Sleep is a method.