4. Explicit/Implicit Waits
▪ Explicit and Implicit Waits
– Waiting is having the automated task execution elapse a
certain amount of time before continuing with the next
step.
▪ Explicit Waits
– An explicit waits is code you define to wait for a certain
condition to occur before proceeding further in the code.
– The worst case of this is Thread.sleep();
5. Explicit/Implicit Waits
@Test
public void testSearchTC() throws Exception {
driver.get("https://www.google.com.ua/");
driver.findElement(By.id("gbqfq")).clear();
driver.findElement(By.id("gbqfq")).sendKeys("selenium ide");
driver.findElement(By.id("gbqfb")).click();
Thread.sleep(1000);
driver.findElement(By
.xpath("//ol[@id='rso']/div/li[2]/div/h3/a/em")).click();
assertEquals("Selenium IDE is a Firefox plugin … for any
kind of resiliency.", driver.findElement(By
.xpath("//div[@id='mainContent']/p[2]")).getText());
} }
6. Explicit/Implicit Waits
▪ Implicit Waits
– An implicit wait is to tell WebDriver to poll the DOM for a
certain amount of time when trying to find an element or
elements if they are not immediately available.
– The default setting is 0.
– Once set, the implicit wait is set for the life of the
WebDriver object instance.
7. Explicit/Implicit Waits
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.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Selenium2Example {
public static void main(String[] args) {
// Create a new instance of the Firefox driver
WebDriver driver = new FirefoxDriver();
// And now use this to visit Google
driver.get("http://www.google.com");
8. Explicit/Implicit Waits
// Alternatively the same thing can be done like this
// driver.navigate().to("http://www.google.com");
// Find the text input element by its name
WebElement element = driver.findElement(By.name("q"));
// Enter something to search for
element.sendKeys("Cheese!");
element.submit();
// Check the title of the page
System.out.println("Page title is: " + driver.getTitle());
9. Explicit/Implicit Waits
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
(new WebDriverWait(driver, 10)).until(new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().toLowerCase().startsWith("cheese!");
} } );
// Should see: "cheese! - Google Search"
System.out.println("Page title is: " + driver.getTitle());
// Close the browser
driver.quit();
} }
10. WebDriverWait
▪ Anonymous classes enable you to make your code more
concise.
▪ They enable you to declare and instantiate a class at the same
time.
▪ They are like local classes except that they do not have a
name.
▪ Use them if you need to use a local class only once.
(new WebDriverWait(driver, 10)).until(new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().toLowerCase().startsWith("cheese!");
} } );
11. WebDriverWait
▪ This is equivalent to:
class MyExpectedCondition
extends ExpectedCondition<Boolean> {
public Boolean apply(WebDriver d) {
return d.getTitle( ).toLowerCase( ).startsWith("cheese!");
}
}
MyExpectedCondition my = new MyExpectedCondition();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(my);
12. Explicit Waits
▪ There are some convenience methods provided that help you
write code that will wait only as long as required.
▪ WebDriverWait in combination with ExpectedCondition is
one way this can be accomplished.
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement =
(new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(
By.id("myDynamicElement")));
13. Explicit Waits
WebElement myDynamicElement =
(new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(
By.id("myDynamicElement")));
▪ This waits up to 10 seconds before throwing a
TimeoutException or if it finds the element will return it in 0 –
10 seconds.
▪ WebDriverWait by default calls the ExpectedCondition every
500 milliseconds until it returns successfully.
▪ A successful return is for ExpectedCondition type is Boolean
return true or not null return value for all other
ExpectedCondition types.
14. Explicit Waits
▪ Java to have convienence methods so you don’t have to code
an ExpectedCondition class yourself or create your own
utility package for them.
▪ Element is Clickable – it is Displayed and Enabled
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element =
wait.until(ExpectedConditions.elementToBeClickable(
By.id("someid")));
15. Implicit Waits
▪ An implicit wait is to tell WebDriver to poll the DOM for a
certain amount of time when trying to find an element or
elements if they are not immediately available. The default
setting is 0.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10,
TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement =
driver.findElement(By.id("myDynamicElement"));
16. WebDriver Wait Commands
▪ Listing out the different WebDriver Wait statements that can
be useful for an effective scripting and can avoid using the
Thread.sleep() comamnds.
18. WebDriver Wait
▪ implicitlyWait
▪ The ImplicitWait will tell the webDriver to poll the DOM for a
certain duration when trying to find the element, this will be
useful when certain elements on the webpage will not be
available immediately and needs some time to load.
▪ By default it ill take the value to 0, for the life of the WebDriver
object instance through out the test script.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10,
TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement =
driver.findElement(By.id("myDynamicElement"));
19. WebDriver Wait. Timeout
▪ pageLoadTimeout
– Sets the amount of time to wait for a page load to
complete before throwing an error.
– If the timeout is negative, page loads can be indefinite.
driver.manage().timeouts().pageLoadTimeout(100, SECONDS);
▪ setScriptTimeout
– Sets the amount of time to wait for an asynchronous script
to finish execution before throwing an error.
– If the timeout is negative, then the script will be allowed to
run indefinitely.
driver.manage().timeouts().setScriptTimeout(100,SECONDS);
20. WebDriver Wait
▪ FluentWait
▪ 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.
21. WebDriver Wait
// Waiting 30 seconds for an element to be present on the
// page, checking for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver,
WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
} );
22. WebDriver Wait Commands
▪ ExpectedConditions
▪ Would include determining if a web page has loaded or that
an element is visible.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element =
wait.until(ExpectedConditions.elementToBeClickable(
By.id("someid")));
▪ WebDriverWait will be used as we used in the Expected
conditions code snippet as above.
▪ Sleeper is something same as the Thread.sleep() method.
23. Waits Solution
long implicitlyWaitTimeout = 10;
public long getImplicitlyWaitTimeout() {
return implicitlyWaitTimeout;
}
public WebDriver getWebDriver() {
driver = new FirefoxDriver();
driver.manage().timeouts()
.implicitlyWait(getImplicitlyWaitTimeout(),
TimeUnit.SECONDS);
driver.manage().window().maximize();
return driver;
}
24. Waits Solution
public WebElement getWebElement(String name) {
WebElement webElement = new WebDriverWait(
getWebDriver(),
getImplicitlyWaitTimeout())
.until(ExpectedConditions
.visibilityOfElementLocated(By.name(name));
if (webElement == null) {
throw new RuntimeException("My Error");
}
return webElement;
}
26. Taking a Screenshot
▪ Most of the time we think to Capture Screenshot in WebDriver
when some kind of error or exception surfaces while practicing
testing, to resolve the same WebDriver has provided us one
interface TakesScreenshot for capturing the screenshot of
web application and This interface provides one method
names as getScreenshotAs() to capture screenshot in
instance of driver.
▪ This getScreenshotAs() method takes argument of type
OutputType.File or OutputType.BASE64 or
Output.BYTES.
27. Taking a Screenshot
▪ We have taken the screenshot with the help of
getScreenshotsAs() method and and now its time to
copy this file somewhere in our file system.
▪ So for this purpose we further use copyFile() method of
the FileUtils class from the
org.apache.commons.io.FileUtils class.
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com.ua/");
File scrFile =
((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// For example copy somewhere
FileUtils.copyFile(scrFile, new File("c:tmpscreenshot.png"));
28. Taking a Screenshot
▪ Take the screenshot in the @After test tear down method,
which is run after every test.
▪ This way you will always get a screenshot for both passed and
failed tests.
public class TestSample {
WebDriver driver;
@Before
public void setUp() {
// Start new webdriver session, for eg using firefox
driver = new FirefoxDriver();
}
29. Taking a Screenshot
@Test
public void aTest() {
driver.get("http://www.google.com.ua/");
// more test logic - test might pass or fail at this point }
@After
public void tearDown() {
// take the screenshot at the end of every test
File scrFile =
((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
FileUtils.copyFile(scrFile, new File("c:tmpscreenshot.png"));
driver.quit(); } }
30. Taking a Screenshot
try {
File scrnsht =
((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrnsht, new File("e:google_page.png"));
} catch (Exception e) {
e.printStackTrace();
}
32. Testing Ajax Applications
▪ Many web applications contain AJAX calls.
– AJAX calls don’t refresh the whole page, only a certain part
of a page is refreshed.
– When an AJAX call is made, while the page is waiting for a
response from the server, a waiting icon appears on the
page to inform the user, the page is waiting for
information, this could be either a rotating circle, or a
loading horizontal bar, etc.
▪ WebDriver is clever enough to wait for the whole page to load
before doing any action and without the user having to
specify a wait for page to load.
– However, in case of AJAX calls, because the whole page is
not refreshed, WebDriver has no way of knowing
something is happening.
35. Testing Ajax Applications
▪ In AJAX driven web applications, data is retrieved from server
without refreshing the page.
– Using and Wait commands will not work as the page is not
actually refreshed.
– Pausing the test execution for a certain period of time is
also not a good approach as web element might appear
later or earlier than the stipulated period depending on
the system’s responsiveness, load or other uncontrolled
factors of the moment, leading to test failures.
▪ The best approach would be to wait for the needed element in
a dynamic period and then continue the execution as soon as
the element is found.
36. Testing Ajax Applications
▪ This is done using waitFor commands, as
waitForElementPresent or waitForVisible, which wait
dynamically, checking for the desired condition every second
and continuing to the next command in the script as soon as
the condition is met.
▪ The best practice is to set implicitlyWait() at the
beginning of each test, and use WebDriverWait() for
waiting an element, or AJAX element to load.
37. Testing Ajax Applications
▪ However, implicitlyWait() and WebDriverWait() do
not work well together in the same test.
▪ You would have to nullify implicitlyWait() before calling
WebDriverWait because implicitlyWait() also sets the
"driver.findElement()" wait time.
▪ For Example, develop WaitTool. It solves the complexity of
ImplicitWait and WebDriverWait, and provides easy methods
to use.
38. Testing Ajax Applications
▪ WaitTool handles the following tasks at the behind scene.
– nullifying implicitlyWait();
– executing WebDriverWait(), and return element;
– reset implicitlyWait() again.
39. Testing Ajax Applications
public static void waitForElementPresent(WebDriver driver,
final By by, int timeOutInSecond) {
try {
// nullify implicitlyWait()
driver.manage().timeouts()
.implicitlyWait(0, TimeUnit.SECONDS);
// Create web element
WebElement webElement =
new WebDriverWait(driver, timeOutInSecond)