If we observe that an element becomes visible not immediately but after certain time we can set estimated implicit wait time so that before throwing NoSuchElementException, WebDriver must wait that much time.
If wait time set to x ms and elements become visible in x-1 ms then WebDriver will not wait x ms , it will stop polling at x-1 as element found at x-1 ms.
By default the implicit wait time is set to 0 ms.
Implicitly wait is applied globally, that is if driver is interacting with 100 elements, then implicit wait is applicable to all the 100 elements.
To understand implicit wait go through the different questions and corresponding answers.
Q1) Create a HTML page say 'implicit_example1.html' that shows a button in 9000 ms. Write a Selenium script that do not set any implicit wait and look for the button. Show the fail result.
Ans) implicit_example1.html contains a Java script method that sleep for 9000 ms after page opens in browser and then create a button. Selenium script looks for this button as soon as the page is opened. As the button appears later test fails.
implicit_example1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function implicit() {
document.write('<p>Sleeping for 9000 milli seconds');
await sleep(9000);
document.write('<p>wake up, adding a button<br>');
var btn = document.createElement("BUTTON"); // Create a <button> element
btn.innerHTML = "CLICK ME"; // Insert text
document.body.appendChild(btn); // Append <button> to <body>
}
implicit()
</script>
</body>
</html>
Selenium script:
@Test(description = "html page adds a button after 9000 ms. implicit wait is set to 1000 ms")
public void find_button_before_it_appears_fail_test() {
WebDriver driver = getChromeDriver();
//set implicit wait 1000 ms
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(1000));
driver.get("file:///" + System.getProperty("user.dir") + "/html/wait/implicit/implicit_example1.html");
driver.manage().window().maximize();
//fail as html will not have this button until 9000 ms
int n=driver.findElements(By.xpath("//button[text()='CLICK ME']")).size();
Assert.assertEquals(n,1);
}
Result:
Q2) Using above 'implicit_example1.html' create a Selenium script that set implicit wait 9001 ms and then starts looking for the button. Show the pass result
Ans) As page makes the button visible in 9000 ms and script looks for it after 9001 ms that makes it very clear that driver will be able to find the element and test will pass.
Selenium script:
@Test(description = "html page adds a button after 9000 ms. implicit wait is set to 9001 ms")
public void find_button_before_it_appears_pass_test() {
WebDriver driver = getChromeDriver();
//set implicit wait 9001 ms > wait set in html
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(9001));
driver.get("file:///" + System.getProperty("user.dir") + "/html/wait/implicit/implicit_example1.html");
driver.manage().window().maximize();
int n = driver.findElements(By.xpath("//button[text()='CLICK ME']")).size();
Assert.assertEquals(n, 1);
}
Result:
Q3) Prove that if implicit wait is set to x ms and element is available in x-1 ms then the actual wit time by driver will be x-1 ms and not x ms.
Ans) Modify implicit_example1.html by changing sleep time to 1000 ms. Set implicit wait time to 9000 ms. Below script proves that element is found in less ≤ 1000 ms not in 9000 ms:
Selenium script:
@Test(description = "html page adds a button after 1000 ms. implicit wait is set to 9000 ms. " +
"In minimum how much time script can find element? 1000 ms")
public void driver_do_not_wait_anymore_if_element_found_earlier_pass_test() {
Long startTime = 0L;
Long endTime = 0l;
WebDriver driver = getChromeDriver();
//set implicit wait 9000 ms
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(9000));
driver.get("file:///" + System.getProperty("user.dir") + "/html/wait/implicit/implicit_example1.html");
driver.manage().window().maximize();
startTime=(new Date()).getTime();
int n = driver.findElements(By.xpath("//button[text()='CLICK ME']")).size();
endTime=(new Date()).getTime();
System.out.println("Time elapsed: "+calculateElapsedExecutionTime("HH:mm:ss.SS",startTime,endTime));
Assert.assertEquals(n, 1);
}