Sunday, December 22, 2013

Mouse hover in Selenium WebDriver

In some web applications we need to mouse hover on one element to make visible of another element. In those cases we need to mouse over on first element before performing any action on second element.

For example, when we mouse hover on certain menus, the sub-menus appears. In such cases we need to use the following ways to hover on web elements:

  1. Using Actions class:
  2. We can use WebDriver's Actions class to perform hover action as below:
    Actions actions = new Actions(driver);
    WebElement mainMenu = driver.findElement(By.cssSelector("#headerMenu"));
    actions.moveToElement(mainMenu);
    
    WebElement subMenu = driver.findElement(By.cssSelector("#headerMenu .subMenu"));
    actions.moveToElement(subMenu);
    actions.click();
    
    actions.perform();
    
    Don't forget to call 'perform()' method. This action won't complete unless you call perform().

  3. Using JQuery:
  4. You can use JQuery selector with mouseover() function as below:
    String aJQueryString = "jQuery(\"#headerMenu\").mouseover()"; 
    WebElement element = findElementByJQuery(aJQueryString);
    
    For understanding "findElementByJQuery(aJQueryString)" method and use please go through my post "Finding web elements by executing JQuery script".


  5. Using Robot:
  6. You can use Robot class to find out location of the web element in the screen and then by hover on it as below:
    /**
     * Mouse overs on the element by its locator by
     * 
     * @param by
     *            a locator e.g. xpath, css, name, id, class name etc
     */
    public void mouseOverOnElementUsingRobot(By by) {
     try {
      Point coordinates = driver.findElement(by).getLocation();
      Robot robot = new Robot();
      robot.mouseMove(coordinates.getX(), coordinates.getY() + 60);
      /*
       * WebDriver provide document coordinates, where as Robot class is
       * based on Screen coordinates, so I have added +60 to compensate
       * the browser header. You can even adjust if needed.
       */
    
     } catch (AWTException e) {
      log.error("Failed to mouseover on the element '" + by + "'. " + e);
     }
    }
    

Drag and Drop in Selenium WebDriver

Now we can perform Drag and Drop actions in WebDriver using Actions class. Below is the code for this:
Actions builder = new Actions(driver);
builder.dragAndDrop(source, target);
Here 'source' is the source(from element) web element and 'target' is the target(to element) web element. 
Or
/**
 * Drags the web element fromWebElement and drop at web element
 * toWebElement
 * 
 * @param fromWebElement
 * @param toWebElement
 */
public void dragAndDrop(WebElement fromWebElement, WebElement toWebElement) {
 Actions builder = new Actions(driver);

 Action dragAndDrop = builder.clickAndHold(fromWebElement)
   .moveToElement(toWebElement).release(toWebElement).build();

 dragAndDrop.perform();
}
Please visit here for more details.

Using robot:
/**
 * Drags the web element fromWebElement and drop at web element
 * toWebElement
 * 
 * @param fromWebElement
 * @param toWebElement
 */
public void dragAndDrop(WebElement fromWebElement, WebElement toWebElement) {
 Point coordinates1 = fromWebElement.getLocation();
 Point coordinates2 = toWebElement.getLocation();

 Robot robot = new Robot();

 robot.mouseMove(coordinates1.getX(), coordinates1.getY());
 robot.mousePress(InputEvent.BUTTON1_MASK);
 robot.mouseMove(coordinates2.getX(), coordinates2.getY());
 robot.mouseRelease(InputEvent.BUTTON1_MASK);

}
For more details on mouse actions in Robot please visit here
For more tricks on drag and drop actions please visit my post Drag and Drop tricks in Selenium

Saturday, December 21, 2013

Format string for locators

There are many locators for web elements which are of same kind, only they vary with a small difference in index or string such as 
"//div[@id='one']/span[text()='jack']" and 
"//div[@id='one']/span[text()='john']"

For these web elements we should find a common locator with an input span text.
Let's take an example of a web element,
  1. Coffee
  2. Tea
  3. Milk
  4. Soup
  5. Soft Drinks
The locator for the above list items 'Soft Drinks' can be represented as below:
private final String DRINK_ITEM = "ul#drinks li:nth-of-type(5)";// using CSS selector
or
private final String DRINK_ITEM = "//ul[@id='drinks']/li[5]";// using Xpath
For finding 5th 'li' item we can directly use the above locator, but when we want to use 2nd 'li' item or some other item or all 'li' items at a time, then we need to represent the locator in a common way.
  • By direct use: 
For a list item,
WebElement element= driver.findElement(By.xpath(DRINK_ITEM));
element.doSomething();
Or, for all list items,
for (int i = 1; i < count; i++) {
 WebElement element = driver.findElement(By.xpath("//ul[@id='drinks']/li[" + i + "]"));
 element.doSomething();
}
  • By formatting the locator:
For a list item,
String drinkItem = String.format(DRINK_ITEM, 5);
WebElement element = driver.findElement(By.xpath(drinkItem));
element.doSomething();
For multiple list items,
for (int i = 1; i < count; i++) {
 String drinkItem = String.format(DRINK_ITEM, i);
 WebElement element = driver.findElement(By.xpath(drinkItem));
 element.doSomething();
}
If you are still not clear about how to use format string, please see the below examples:
private final String GRID_TABLE_VIEW = "div#panel2content div.table.%s";
private final String RESULT_TABLE_VIEW = "//div[@id='panel1content']//div[%d]/span[text()='%s']";
private final String SPACE_TOGGLE_MENU_OPTION = "ul#spacing_toggle li:nth-of-type(%d)";

String gridTableView = String.format(GRID_TABLE_VIEW, "filterByName");
String resultTableView = String.format(RESULT_TABLE_VIEW, 2, "bill");
String spaceToggleMenuOption = String.format(SPACE_TOGGLE_MENU_OPTION, 3);

/** It will print "div#panel2content div.table.filterByName" */
System.out.println(gridTableView);

/** It will print "//div[@id='panel1content']//div[2]/span[text()='bill']" */
System.out.println(resultTableView);

/** It will print "ul#spacing_toggle li:nth-of-type(3)" */
System.out.println(spaceToggleMenuOption);

Finding web elements by executing JQuery script

WebDriver provides findElement(By by) to find elements by selectors such as Xpath, CSS, name, id, class name etc. Similar way, we can use JQuery expression to select elements and traverse through the DOM tree. 
Here is a simple way to findout, 
For an input element with class 'spbtn' of a parent element with id 'myDiv', we can use the below code to find the web element:
String jQuerySelector = "'#myDiv input.spbtn'";
WebElement webElement = (WebElement) ((JavascriptExecutor) getDriver()).executeScript("return $(" + jQuerySelector+ ").get(0);");
In the other way, we can use the following code which uses a proper wait with optimized way to find out the element. The method throws NoSuchElementException exception if there is no element with this JQuery selector.
/**
 * Finds an element by executing the given jQuery statement
 * jQueryScript
 * 
 * @param jQueryScript
 *            a JQuery Script
 * @return WebElement that is described by that jQuery statement
 *         jQueryScript, if not found, returns null.
 */
public WebElement findElementByJQuery(final String jQueryScript) {
 WebElement element = null;

 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
   .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
   .pollingEvery(50, TimeUnit.MILLISECONDS)
   .ignoring(NoSuchElementException.class);
 try {
  element = wait.until(new Function<WebDriver, WebElement>() {
   @Override
   public WebElement apply(WebDriver d) {
    String script = "return " + jQueryScript + ".get(0);";
    JavascriptExecutor jse = (JavascriptExecutor) d;
    WebElement webElement = (WebElement) jse
      .executeScript(script);
    return webElement;
   }
  });
 } catch (Exception e) {
  log.error("Failed to find the element by executing JQuery script '"
    + jQueryScript + "'." + e);
 }
 return element;
}
Usage of the above method:
For an element with JQuery selector '#myDiv input.spbtn'
String aJQueryString = "jQuery(\"div.sorted\")";//To get the element
String aJQueryString = "jQuery(\"div.sorted\").parent()";//To get parent of the element
String aJQueryString = "jQuery(\"div.sorted\").mouseover()";//To mouseover on the element

WebElement element = findElementByJQuery(aJQueryString);
Similar way you can use other JQuery functions to work with web elements.

To find all elements with the given JQuery selector. This is similar to findElements(By by) of WebDriver.
/**
 * Find all the elements by executing the given jQuery statement
 * jQueryScript
 * 
 * @param jQueryScript
 *            a JQuery Script 
 * @return WebElement that is described by that jQuery statement
 *         jQueryScript, if not found, returns null.
 */
public List<WebElement> findElementsByJQuery(final String jQueryScript) {
 List<WebElement> elements = null;

 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
   .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
   .pollingEvery(50, TimeUnit.MILLISECONDS)
   .ignoring(NoSuchElementException.class);
 try {
  elements = wait.until(new Function<WebDriver, List<WebElement>>() {
   @Override
   public List<WebElement> apply(WebDriver d) {
    List<WebElement> webElements = new ArrayList<WebElement>();
    for (int i = 0;; i++) {
     String script = "return " + jQueryScript + ".get(" + i
       + ");";
     JavascriptExecutor jse = (JavascriptExecutor) d;
     WebElement webElement = (WebElement) jse
       .executeScript(script);
     if (webElement != null) {
      webElements.add(webElement);
     } else {
      break;
     }
    }
    return webElements;
   }
  });
 } catch (Exception e) {
  log.error("Failed to find the elements by executing JQuery script '"
    + jQueryScript + "'." + e);
 }
 return elements;
}

Tuesday, November 26, 2013

Get name of test method in teardown

Sometimes we need name of the test method that has just executed in the tear down method for various purposes such as:
  • If you take screenshot in tear down and want to give last executed method name as a part of screenshot name.
  • May be someone want to track something in the log with the test method information.
  • If you have different classes containing test methods and tear down method, and you want to use test method information in tear down method.
@AfterMethod
public void yourTearDownMethod(ITestResult result) {
  System.out.println("method name:" + result.getMethod().getMethodName();
}
Similar way, you can get other information about the test method by result.getMethod().getXXX()

Wednesday, September 04, 2013

Ant task for ReportNG report

This is same like testng report, and also it uses "testng" task to execute the tests, just the difference is we need to specify a listener to it in its "listener" attribute.
This task also executes all the tests with group "alltests" and places the report in the "reprots.reportng" directory specified in the ant property.
 

 
 
  
   
   
   
  
 
Here in my example i have used custom listener to customize the report in com.myorg.core.util.GenericReportNGListener class, you can use the default listener by setting useDefaultListeners="true" as attribute of above testng task. You can give title to your ReportNG report in the ant task like here i gave "All Page Tests". This title will be shown in the report.

A ReportNG report looks like as below:


 The overview of the report looks something like this:



Thursday, June 20, 2013

Ant task for generating XSLT report

Once you are executed the test by TestNG or TestNG with Group, you can invoke the following ant target to generate xslt report.
 

 
 
  
   
   
  
 
Note: To work this above code you should have the following 2 jars in your class path:
SaxonLiaison.jar and saxon-8.7.jar 
In my example i have used a custom style which is specified in the "xslt_style/testng-results.xsl" file. After executing this target you will find your xslt report in "index.html" file which is in the "reports.xslt" directory specified in the ant property.

The report generated by testng with xslt looks something like the below image:


Ant task to run all tests by the specified group name

Following ant task shows us how to run all testng tests those are specified with the group "alltests" in the test classes. We can actually do this by two ways. 

Type-I(from testng suite) 
The following target runs all the tests with group "alltests". In this case it will search for all the tests that are specified with group "alltests" and only for the tests/classes/packages specified in the testng.xml(test suite) only. After executing the tests it creates the testng report in the "reprots.testng" directory specified in ant property.
 

 
 
  
   
  
 
Type-II(directly from the classes) 
The following target runs all the tests with group "alltests". In this case it will search for all the tests that compiled and there in the "classes" directory specified in the ant property. After executing the tests it creates the testng report in the "reprots.testng" directory specified in ant property.
 

 
 
  
   
   
   
  
 
The report generated by testng looks like the below snapshot:


Saturday, May 11, 2013

Wait in Selenium WebDriver

There are many types of waits in selenium WebDriver.
  1. Thread.sleep()
  2. Implicit Wait
  3. WebDriver Wait
  4. Wait for the Ajax call
  5. Wait for the page to load
1. Thread.sleep()

Here we can't predict the exact required wait time. With this we may need to wait for some extra seconds which decreases performances. These extra seconds became more when we execute multiple tests which increases the overhead. This wait is not recommended and we should not use this in our test.

2. Implicit Wait

This is the wait provided by WebDriver which is used, in general, for waiting for an element. This is recommended and we can use it. For example,
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
When we use this statement, the WebDriver waits for the element(on which next action is performed) till 30 seconds if that is not available immediately. After the timeout period, if the element is not available, it throws NoSuchElementException.
Use of this at the beginning of each test is very profitable and a best practice.
3. WebDriver Wait

This wait waits for a condition. This is also recommended and we can use it. This checks the condition in every 500 milliseconds until it returns true or the timeout. For example,
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpath)));
Here the condition is "ExpectedConditions.presenceOfElementLocated(By.xpath(xpath))" and this condition is checked in every 500 milliseconds until it is timed out by the timeout specified in timeOutInSeconds.

WebDriver wait is an explicit wait. You can refer here for more about implicit and explicit waits.


4. Wait for the AJAX call to complete

This is also recommended and very useful when we need to wait for some elements on the web page which is updating upon ajax calls.
You can refer the my post "Wait For Ajax call" for how to use this.

5. Wait for page to load

This is also recommended and very useful when you need to wait for a web page to load completely.
You can refer the my post "Wait for Page to load" for how to use this.

Friday, May 10, 2013

Wait for AJAX call to complete in WebDriver

Sometimes in our web application only part of the web page gets loaded upon certain actions, at that time actually an ajax call happens and depending upon the ajax response the page part loads. So in this case we need to wait till the ajax call is completed to test anything on that part of the webpage, if you don't want to do that by waiting for a specific element to be available. Below is the code that waits till the ajax calls completed:
/**
 * Waits until there are no more active ajax connection and until the
 * specified timeoutInSeconds is timeout
 * 
 * @param timeoutInSeconds
 */
public void waitForAjax(long timeoutInSeconds) {
 log.info("Checking active ajax calls by calling jquery.active");
 try {
  if (driver instanceof JavascriptExecutor) {
   JavascriptExecutor jsDriver = (JavascriptExecutor) driver;

   for (int i = 0; i < timeoutInSeconds; i++) {
    Object numberOfAjaxConnections = jsDriver
      .executeScript("return jQuery.active");
    // return should be a number
    if (numberOfAjaxConnections instanceof Long) {
     Long n = (Long) numberOfAjaxConnections;
     log.info("Number of active jquery ajax calls: " + n);
     if (n.longValue() == 0L)
      break;
    }
    Thread.sleep(1000);// 1 second sleep
   }
  } else {
   log.error("Web driver: " + driver
     + " cannot execute javascript");
  }
 } catch (Exception e) {
  log.error("Failed to wait for ajax response: " + e);
 }
}
In this code snippet we are checking the number of active Ajax connections by executing the javascript code jQuery.active then depending upon the result we are waiting for the ajax calls to complete until the timeout specified in timeoutInSeconds paameter

Wait for page to load in WebDriver

Unlike Selenium RC(selenium 1) have waitForPageToLoad method to wait until the page to load, WebDriver(selenium 2) doesn't have any method in the API to wait until the page to load. Here is a way to wait until the page elements load properly.
/**
 * Waits for a page to load for timeOutInSeconds number of
 * seconds.
 * 
 * @param timeOutInSeconds
 */
public void waitForPageToLoad(long timeOutInSeconds) {
 ExpectedCondition expectation = new ExpectedCondition() {
  public Boolean apply(WebDriver driver) {
   return ((JavascriptExecutor) driver).executeScript(
     "return document.readyState").equals("complete");
  }
 };
 try {
  log.info("Waiting for page to load...");
  WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
  wait.until(expectation);
 } catch (Throwable error) {
  log.error("Timeout waiting for Page Load Request to complete after "
    + timeOutInSeconds + " seconds");
  Assert.assertFalse(true,
    "Timeout waiting for Page Load Request to complete.");
 }
}
Here we are checking for the "complete" loading state of the web page by JavascriptExecutor and until that we are waiting till the timeout period specified in timeOutInSeconds parameter.

Friday, April 05, 2013

Logging application log to a log file(by File Appender)

To log your application log to a log file by using log4j, you have to go through the following steps:
  1. Download latest jar of log4j.jar and add it to your project classpath.
  2. Create a log4j.properties file inside your source directory to define properties of your logger.
  3. To log your application log to a log file, you need to add the following code in the log4j.properties
  4.  
    #################################################################
    #####     Application Logs to be printed in the log file    #####
    #################################################################
     
    log4j.rootLogger= WARN, FILE_APPENDER
    
    # test appender  daily rolling logs format
    log4j.appender.FILE_APPENDER=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.FILE_APPENDER.File=logs/autoLog.log
    log4j.appender.FILE_APPENDER.DatePattern='.'yyyy-MM-dd
    log4j.appender.FILE_APPENDER.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE_APPENDER.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p (%F:%M:%L) - %m%n
    
    # test appender  daily rolling logs for packages
    log4j.logger.com.myorg=DEBUG
    log4j.logger.com.myorg.core.util=FILE_APPENDER
    log4j.logger.com.myorg.core.page=FILE_APPENDER
    
  5. To know the usage of logger see the below code:
    //In ConfigUtil.java
    private static Logger log = Logger.getLogger(ConfigUtil.class);
    // The below line is called inside static block
    log.info("Properties file loaded at '" + configLoc + "'");
    
    //In BasePage.java
    protected static Logger log = Logger.getLogger(BasePage.class);
    // The below line is called inside setTimeout() method
    log.info("The timeout value is set to " + timeoutSeconds + " seconds.");
    
    //In DriverManager.java
    private static Logger log = Logger.getLogger(DriverManager.class);
    // The below line is called inside static block
    log.info("Driver location is set to '" + driverLoc + "'");
    
  6. You will get your application log in the log file(which you have specified in your log4j.properties, in this example i have specified "logs/autoLog.log" file) as shown in the below sample:
     
    2013-09-05 12:36:04  INFO (ConfigUtil.java::39) - Properties file loaded at '/Users/aksahu/MySpace/Web_Workspace/KnowledgeBase/config/config.properties'
    2013-09-05 12:36:04  INFO (BasePage.java:setTimeout:155) - The timeout value is set to 60 seconds.
    2013-09-05 12:36:04  INFO (DriverManager.java::54) - Driver location is set to '/Users/aksahu/MySpace/Web_Workspace/CoreDriver/drivers/'
    2013-09-05 12:36:04  INFO (DriverManager.java:getDriver:85) - initializing 'chrome' driver...
    2013-09-05 12:36:15  INFO (BasePage.java:windowMaximize:101) - Maximizing the browser window.
    2013-09-05 12:36:17  INFO (BasePage.java:openUrl:86) - Openning the url 'http://knowledgebase-wiki.appspot.com/' in the browser...
    2013-09-05 12:36:23  INFO (BasePage.java:waitForPageToLoad:956) - Waiting for page to load...
    2013-09-05 12:36:23  INFO (BasePage.java:typeByID:195) - Entering text 'java' to the element specified by id 'searchField'
    2013-09-05 12:36:23  INFO (BasePage.java:clickByID:258) - Clicking on the element specified by id 'resultDiv0'
    2013-09-05 12:36:23  INFO (BasePage.java:waitForElementLocatedByXpath:848) - Waiting for the element specified by xpath '//a[contains(text(),'[Go to page]')]'
    2013-09-05 12:36:23  INFO (BasePage.java:clickByXpath:238) - Clicking on the element specified by xpath '//a[contains(text(),'[Go to page]')]'
    2013-09-05 12:36:24  INFO (BasePage.java:waitForPageToLoad:956) - Waiting for page to load...
    2013-09-05 12:36:24  INFO (BasePage.java:isTextPresent:807) - Checking for the text 'Installing Java' in the page
    2013-09-05 12:36:24  INFO (BasePage.java:isTextPresent:807) - Checking for the text 'java' in the page
    2013-09-05 12:36:24  INFO (BasePage.java:quitBrowser:582) - Closing all the instances of the browser 'chrome'
    

Logging application log in the Console(by Console Appender)

To log your application log in the console by using log4j, you have to go through the following steps:
  1. Download latest jar of log4j.jar and add it to your project classpath.
  2. Create a log4j.properties file inside your source directory to define properties of your logger.
  3. To log your application log in the console, you need to add the following code in the log4j.properties
  4.  
    ################################################################
    #####     Application Logs to be printed in the console    #####
    ################################################################
     
    log4j.rootLogger= WARN, CONSOLE_APPENDER
    
    # console appender format
    log4j.appender.CONSOLE_APPENDER=org.apache.log4j.ConsoleAppender
    log4j.appender.CONSOLE_APPENDER.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE_APPENDER.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p (%F:%M:%L) - %m%n
    
    # console appender for packages
    log4j.logger.com.myorg=DEBUG
    log4j.logger.com.myorg.core.util=CONSOLE_APPENDER
    log4j.logger.com.myorg.core.page=CONSOLE_APPENDER
    
  5. To know the usage of logger see the below code:
    //In ConfigUtil.java
    private static Logger log = Logger.getLogger(ConfigUtil.class);
    // The below line is called inside static block
    log.info("Properties file loaded at '" + configLoc + "'");
    
    //In BasePage.java
    protected static Logger log = Logger.getLogger(BasePage.class);
    // The below line is called inside setTimeout() method
    log.info("The timeout value is set to " + timeoutSeconds + " seconds.");
    
    //In DriverManager.java
    private static Logger log = Logger.getLogger(DriverManager.class);
    // The below line is called inside static block
    log.info("Driver location is set to '" + driverLoc + "'");
    
  6. You will get your application log as shown in the below example:
     
    [TestNG] Running:
      /private/var/folders/cl/34rlg3ns31g8w4jktmpkc2440000gn/T/testng-eclipse--1656210619/testng-customsuite.xml
    
    2013-09-05 12:58:03  INFO (ConfigUtil.java::39) - Properties file loaded at '/Users/ashwin/MySpace/Web_Workspace/KnowledgeBase/config/config.properties'
    2013-09-05 12:58:03  INFO (BasePage.java:setTimeout:155) - The timeout value is set to 60 seconds.
    2013-09-05 12:58:03  INFO (DriverManager.java::54) - Driver location is set to '/Users/ashwin/MySpace/Web_Workspace/CoreDriver/drivers/'
    2013-09-05 12:58:03  INFO (DriverManager.java:getDriver:85) - initializing 'chrome' driver...
    2013-09-05 12:58:09  INFO (BasePage.java:windowMaximize:101) - Maximizing the browser window.
    2013-09-05 12:58:12  INFO (BasePage.java:openUrl:86) - Openning the url 'http://knowledgebase-wiki.appspot.com/' in the browser...
    2013-09-05 12:58:18  INFO (BasePage.java:waitForPageToLoad:956) - Waiting for page to load...
    2013-09-05 12:58:18  INFO (BasePage.java:typeByID:195) - Entering text 'java' to the element specified by id 'searchField'
    2013-09-05 12:58:19  INFO (BasePage.java:clickByID:258) - Clicking on the element specified by id 'resultDiv0'
    2013-09-05 12:58:19  INFO (BasePage.java:waitForElementLocatedByXpath:848) - Waiting for the element specified by xpath '//a[contains(text(),'[Go to page]')]'
    2013-09-05 12:58:19  INFO (BasePage.java:clickByXpath:238) - Clicking on the element specified by xpath '//a[contains(text(),'[Go to page]')]'
    2013-09-05 12:58:19  INFO (BasePage.java:waitForPageToLoad:956) - Waiting for page to load...
    2013-09-05 12:58:19  INFO (BasePage.java:isTextPresent:807) - Checking for the text 'Installing Java' in the page
    2013-09-05 12:58:19  INFO (BasePage.java:isTextPresent:807) - Checking for the text 'java' in the page
    2013-09-05 12:58:19  INFO (BasePage.java:quitBrowser:582) - Closing all the instances of the browser 'chrome'
    PASSED: testJavaModule
            Verifies the Java Module form Knowledge base
    
    ===============================================
        Default test
        Tests run: 1, Failures: 0, Skips: 0
    ===============================================
    

Tuesday, March 05, 2013

Getting started with WebDriver (Selenium 2)

WebDriver is a automation testing tool for automating testing web applications. It provides tester friendly API which is easy to explore and understand. This tool is not tied to any particular framework such as JUnit or TestNG. It can be used with simple "main" method or any of the unit testing framework such as JUnit or TestNG.

Required downloads: 
  • Download from here the latest version of selenium-server-standalone-x.y.z.jar where x, y and z are digits specifying the version of jar while created by the developers. 
  • Download respective drivers for your browser. Such as FirefoxDriver for Firefox, ChromeDriver for Chrome, InternetExplorerDriver for Internet Explorer and so on.
Quick steps: 
  1. Create a new java project in your favorite IDE 
  2. Add the downloaded jar file into your project build-path. 
  3. Make sure the browser you are selecting to run is installed in your machine.
  4. Copy and paste the following example to execute your first example on WebDriver.
Example Test:

In my example below i have chosen Firefox browser. Here i have not used any framework to execute my test, i have used simple "main" method to execute. The example is self explanatory by its comments.


package com.example.tests;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class GoogleTest {

 public static void main(String[] args) {

  // I have chosen Firefox browser to execute my script
  WebDriver driver = new FirefoxDriver();

  // Go to the Google home page
  driver.get("https://www.google.co.in/");
  
  // Maximize the browser window
  driver.manage().window().maximize();

  // Enter the query string "Cheese"
  WebElement query = driver.findElement(By.name("q"));

  // Type 'aksahu blog' in the search field
  query.sendKeys("aksahu blog");
  driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

  // Click on the 'A. K. Sahu's Blog' link
  WebElement blog = driver.findElement(By.linkText("A. K. Sahu's Blog"));
  blog.click();
  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

  // Quit the browser
  driver.quit();
 }
}

Thursday, February 14, 2013

Ant task for generating Cobertura report

The post describes how to use coburtura in the ant task. First of all you must tell ant about the Cobertura Ant tasks using a taskdef statement. The best practice is to place this before any target statements.
 
 
  
  
   
   
   
   
   
  
 

 
 
We must specify for Cobertura which class files to instrument by passing in ant filesets. You need to specify the directory location in "todir" to place the instrumented classes. You can exclude classes by using "excludeclasses" tag or using "ignore". Specify the name of the coverage data file to use in the "datafile" attribute. The default file is "cobertura.ser".

Cobertura-Instrument Task:
 
 
  
   
   
  
 

Running tests(Here i used TestNG to run tests):
The following components are the most important to get cobertura code coverage to work with testng.
This is a static variable that contains the location of the datafile. If the datafile moves, this lets the JVM know that the datafile has moved and is not in the current(or present) working directory.


Adding the instrumented classes before the actual classes guarantees that cobertura source code gets used first. This is required because we want to use the cobertura instrumented code instead of the regular compiled code, however we keep both versions just in case there's an issue with instrumentation.

Creating a reference id that contains just the cobertura.jar is important to guarantee that there is no NoClassDefFound exception with cobertura. When executing test units, the only dependency cobertura requires is the cobertura.jar file. All the other files are necessary for instrumentation, reporting and merging of tasks.
  
 
  
  
  
  
  
  
  
 

Cobertura-Report Task:
For generating cobertura report we need to use "cobertura-report" tag with the source file director specified in "srcdir" and destination report directory in "destdir" attribute.
 
 
 
  
   
   
   
   
   
   
   
  

  
  
 

The report generated by the cobertura looks like as the below snapshot:


Ant task to print all the test environment information

Below are the list of ant properties that gives the information about test environment. For example, if you want to know which java version is used, we can use "ant.java.version" property in the "echo" tag to print in the ant console. Similarly, for 

ant version - ant.version 
current project name - ant.project.name 
current user name - user.name 
current user directory - user.dir 

Below is the ant code to do this:
 
 
 
  
  
  
  
  
 
You will get the following message in your console:
Buildfile: /Users/aksahu/MySpace/Web_Workspace/AutoTest/build.xml
info:
     [echo] Java Version : 1.6
     [echo] Ant Version : Apache Ant version 1.7.1 compiled on June 27 2008
     [echo] Project Name : autoTest
     [echo] User Name : aksahu
     [echo] Project Location : /Users/aksahu/MySpace/Web_Workspace/AutoTest
BUILD SUCCESSFUL
Total time: 753 milliseconds