Java. Explicit and Implicit Wait. Testing Ajax Applications

42
Java. Explicit and Implicit Wait. Testing Ajax Applications IT Academy 24/03/2015
  • Upload

    -
  • Category

    Software

  • view

    412
  • download

    3

Transcript of Java. Explicit and Implicit Wait. Testing Ajax Applications

Java. Explicit and Implicit Wait. Testing Ajax

Applications

IT Academy

24/03/2015

Agenda▪ Implicit Wait▪ Explicit Wait▪ Taking a Screenshot▪ Ajax Applications▪ Testing Ajax Applications▪ Examples▪ Case studies

Explicit and Implicit Wait

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();

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( ));} }

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.

Explicit/Implicit Waitsimport 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");

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( ));

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( );} }

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!"); } } );

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);

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")));

Explicit WaitsWebElement 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.

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")));

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"));

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.

WebDriver Wait Commands

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"));

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);

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.

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")); }} );

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.

Waits Solutionlong 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;

}

Waits Solutionpublic 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;

}

Taking a Screenshot

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.

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 somewhereFileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

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( ); }

Taking a Screenshot@Testpublic void aTest( ) { driver.get("http://www.google.com.ua/"); // more test logic - test might pass or fail at this point }@Afterpublic 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:\\tmp\\screenshot.png")); driver.quit( ); } }

Taking a Screenshottry {

File scrnsht =

((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

FileUtils.copyFile(scrnsht, new File("e:\\google_page.png"));

} catch (Exception e) {

e.printStackTrace( );

}

Testing Ajax Applicationswith Selenium

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.

Testing Ajax Applications▪ http://www.w3schools.com/ajax/default.asp

Testing Ajax Applications

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.

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.

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.

Testing Ajax Applications▪ WaitTool handles the following tasks at the behind

scene.– nullifying implicitlyWait( );– executing WebDriverWait( ), and return element;– reset implicitlyWait( ) again.

Testing Ajax Applicationspublic 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)

Testing Ajax ApplicationsWebElement webElement = new WebDriverWait(driver, timeOutInSecond) .until(new ExpectedConditions<Boolean>( ) { @Overridew public Boolean apply(WebDriver d) { return isElementPresent(d, by);} } );// reset implicitlyWait( )driver.manage( ).timeouts( ) .implicitlyWait(10, TimeUnit.SECONDS);} catch(Exceptions e) { …

References▪ Explicit and Implicit Waits

http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp

▪ Selenium WebDriverhttp://docs.seleniumhq.org/docs/03_webdriver.jsp

▪ How to Handle Ajax call in Selenium Webdriver

http://agilesoftwaretesting.com/selenium-wait-for-ajax-the-right-way/