Thursday, 13 June 2013

Easy Integration of Sikuli with existing framework of selenium

Nowadays Selenium is widely used tool for automating web application. In real life, products are enterprise application, so application would be an integration of  Silverlight ,Java applets,Raphael java script, canvas objects,Javascripts,Jquery. We could not expect everything to get identified with selenium and can face challenges in automating the few of the above mentioned UI with selenium.

Sikuli is one of the easiest tool to learn and can be used to automate anything using image recognition technique.
Here I am trying to share my experience about automating an enterprise application with integration of selenium and SIkuli.

I  was involved in automating the BPM product (business process modeling ),I have developed a framework in selenium to test this product .our functional team has developed around 1000+ tests using this framework.
Few months back our product development team has introduced new functionality of browser based modeling in which model can be developed in browser itself. This functionality was developed using canvas objects and Raphael javascripts.Automating this functionality was very important for us. Unfortunately selenium was unable to identify it. I tried all the options from selenium webdriver but all the efforts were in vain. Then We tried with different tools like Watir, Watij , AUTOIT and white to identify (business process modeling )BPM canvas objects but unfortunately these tools are also failed to get it automated.
                                                                                                                                                                                                                                            
While evaluating few other tools for BPM automation, I come across Sikuli (http://www.sikuli.org/), it’s an intelligent tool for recognizing the Canvas UI. It’s an open source tool.
It automates the UI using image recognition, and this image recognition technique was finest fit for us to identify Canvas objects and other modeler components from browser based modeler written in Raphael Java scripts.

Sikuli permits us to write the modularize tests in Java. Using this feature of sikuli, I  have integrated it in our selenium framework written in JAva
Sikulli team has provided neat and precise documentation about tool from basic to advance level, which guided us wherever we stuck up at any point while scripting with this tool.

As I mentioned earlier our functional team was expert  in writing the test using my existing framework written for selenium java. And I don’t want to expose them to new automation tool for automating one functionality from our huge product.so the main challenge for me was
ü  To integrate the sikuli with existing framework of selenium
ü  Developing the new keywords for sikuli , in a same way that I followed for selenium keywords,so that for our selenium test writer approach would remain same for writing the tests.
ü  With a detailed feasibility study of sikuli we observed that sikuli has its limitation and sikuli nowhere sits near selenium, so I decided to keep Sikuli’s use restricted to only for the UI which couldn’t get automate with selenium and remaining stuff with selenium.

How to integrate sikuli with existing framework of selenium ?
Sikuli provides sikuli-script.jar.you can download it from sikuli site  as recommended on the download page, Import this jar is your java application, once you have this jar in your java application.
You can invoke sikuli api’s in your selenium framework by creating Screen objects instance.

protected static Screen sikuliObject = new Screen();

Following is one of the simple way to call selenium and sikuli api alternatively as per the need of the test.

in following code ,Line 2 to 6 is of selenium code and line 11 to 13 is of sikuli code.

public void dragModelElementInCanvas(String modelElement, int x,int y) {
String elementToclick = "//a[contains(.,'"+ modelElement + "')]";
WebElement clickabelModelElement = seleniumDriver.findElement(By.xpath(elementToclick));
if (clickabelModelElement != null) {
 Actions action = new Actions(driver);
 action.clickAndHold(clickabelModelElement).perform();
 sleep();
//If you have been observed that selenium is not able to identify the component (e.g canvas)where you would like to above dragged element.
   System.out.println("moving mouse to the location " + x + " : " + y);
   sikuliObject.mouseMove(new Pattern(getAbsolutePath()).targetOffset(x, y));
   System.out.println("simulating mouse up");
 sikuliObject.mouseUp(Button.LEFT);
 action.release().perform();
  } else
   throw new KeywordException(
     "Timeout recieved while finding element with Xpath:"
       + clickabelModelElement);
 }
Important part here is for testwriter whomsever is using your framework will not have to bother which underline tool you are using to automate the stuff. For e.g in above code selenium testwriter will call the method dragModelElementInCanvas ,where he/she will not realize which tool has been used to achieve the task.

Above is the just the reference code that I have documented here for the one who will be getting started withselenium and sikuli’s integration. In real life we have developed many classes where we are using selenium and sikuli Hand to hand. Post your doubts if you are facing any specific issues while integrating selenium and sikuli.i would like to share my experience as we already overcome many challenges that we faced in integration of two automation tools in our existing framework of selenium.

Happy integration !!

Tuesday, 14 May 2013

Working on Iframes with selenium

While working with different automation team members, I have observed that people are facing lot of challenges when they start working on UI with multiple iframes.here I tried to document my personal experience about handling iframes with selenium.

If you are beginner in automating UI having frames/ iframes, then please make a note that selenium doesn’t recognize any object from a frame, unless you attach the selenium control to respective frame.
I have listed few scenarios where automated test can stuck :


Scenario 1:
How to attach the control to iframe with selenium webdriver :
        driver.switchTo().frame(frameID or any other unique attribute of frame);
Above code will take care of attaching to frame after that you can identify any objects from the frame using the same way you are identifying the objects from webpage.
                  driver.switchTo().defaultContent();

Scenario 2:
If I have two independent Iframe (FrameID1 and frameID2) how to work on these two frames
driver.switchTo().frame(frameID1);
<perform the operation on frame1>
:
:
:
<Now if you have to work on controls from frame2 then >
driver.switchTo().defaultContent();
driver.switchTo().frame(frameID2);

Scenario 3:
If I have childFrame inside the parentFrame how to work on child frame . Refer below HTML for detail understanding

<frame name="Frame1" id="parentFrameID">
        -----------
            <frame name="Frame2" id="childFrameID1">
        -----------
   
            </frame>
<frame name="Frame2" id="childFrameID2">
        -----------
   
            </frame>

 </frame>

In this case, you cannot directly attach to childFrameID,first switchTo parentFrame inside which childframeis is placed then look for required child frame.
            driver.switchTo().defaultContent();
            driver.switchTo().frame("parentFrameID");
            driver.switchTo().frame("childFrameID1");


How to switch from parent frame from one childframe ?
you cannot toggle directly between child frame just by switching from one child frame to another child frame, refer below code

            driver.switchTo().defaultContent();
            driver.switchTo().frame("parentFrameID");
            driver.switchTo().frame("childFrameID1");
            //now as you have to switch for a childframe2 then
            driver.switchTo().defaultContent();
            driver.switchTo().frame("parentFrameID");
            driver.switchTo().frame("childFrameID2");

You can also switch to child frame using its index
 
driver.switchTo().frame(indexoftheframe);
                         
index starts from ‘0’
  
Believe me, there are many more scenarios related to frames that supposed to be handle in this post but for now I want to keep it simple.
Please feel free to discuss if you are facing any other challenge which I haven’t mentioned here. we can surely extend this post to resolve your creepy  issues related to iframe with selenium.


Sunday, 21 April 2013

Video recording of failed test Scripts in selenium framework

Failure analysis is very crucial part for any automation team. We can automate the tests , we can automate the process of executing the tests once build is arrived for testing,but automation tester have to have spare some time in manually analyzing the report to make sure whether it’s a product issue or not. To make failure analysis job bit easy, here I tried to explain how to capture the screens on failures and how to do video recording of the test during execution.

What is main challenge in failure analysis ? 

If test is taking 3 minutes to get executed and failing somewhere at last set of lines, during failure analysis, complete test needs to be rerun to find where exactly it’s failing. Instead of that, this feature will help us, to quickly play the video. In fast track, we can reach to the step, where exactly it failed and can take corrective action before rerun.
Sometimes it also happens test gets failed due to some intermittent time out issues, and it became difficult to reproduce those issues in rerun. For such failures this video file will support us in analyzing the page or component taking more than expected time to get rendered.


How can I Capture the screen shots on test failures with selenuim ? 

Selenium is having a method which capture the screen shot, but this method need to be use smartly in framework to capture the screen shots only when the test gets failed.so by referring the screen shot test can be fixed
Attached code is an example how to capture the screen shots on failures. 
public class KeywordException extends RuntimeException {

 /**
  * Throw this exception if keyword is failing.
  * @param message
  */
 public static String callerClass;
 public static String callingMethodName;
 private static WebDriver driver = BasicTestContext.driv;
 public CaptureScreenShotOnException(String message) {
  super(message);

  File scrFile = ((TakesScreenshot) driver)
    .getScreenshotAs(OutputType.FILE);
  String screenShotPath = "C:\\screenshot\\" + callerClass + "_"
    + callingMethodName + "_"
    + getCurrentTimeStamp("yyyyMMMdd_hhmmss") + ".png";
  try {
   FileUtils.copyFile(scrFile, new File(screenShotPath));
   System.out.println("Saved screenshot: " + screenShotPath);
   System.out.println("Failed : " + callerClass + "_"
     + callingMethodName + " . REASON : "+message);
  } catch (IOException e1) {
   e1.printStackTrace();
  }
 }
}
 
How to use it in your test ?

public void setText(String value) {

            if (INF_Common_Utility.SyncForElement("xpath=" + getRootXpath()))
                  browser.type("xpath=" + getRootXpath(), value);
            else
                  throw new CaptureScreenShotOnException("Timeout recieved while finding element with Xpath: xpath=" + getRootXpath());
                 
      }
Capturing the Video on failures for the selenium tests:

You can evolve your automation framework by introducing a feature of recording the selenium test execution.Using this feature selenium test execution can be recorded as a video file.it will generate one video file for each failed tests.
 
 How can I implement it in my framework ?

To implement this feature, we used Monte Media Library .This library is having a class ScreenRecorder.this class provides the api for recording screencast of Selenium Tests in Java.
To play the recorded video: ScreenRecoder supports “AVI” format for recording the video. To play the video file generated in  “AVI” format, you need to install TSCC Codec (Techsmith Screen Capture Codec).
/**
       * This method will start the recording of the execution. recorded file will
       * get generated in the folder name as className_methodName. recording can
       * be started from any particular time.
       */

      public void startRecording() {

            RecordingClassName = Reflection.getCallerClass(2).getSimpleName();
            RecordingMethodName = new Throwable().fillInStackTrace()
                        .getStackTrace()[1].getMethodName();
            fileRecordingLocation = "c://screenshot//" + RecordingClassName + "_"
                        + RecordingMethodName;
            RecordedFile = new File(fileRecordingLocation);

            GraphicsConfiguration gc = GraphicsEnvironment//
                        .getLocalGraphicsEnvironment()//
                        .getDefaultScreenDevice()//
                        .getDefaultConfiguration();
            try {
                  ScreenRecorder = new ScreenRecorder(gc, null, new Format(
                              MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI),
                              new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey,
                                          ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
                                          CompressorNameKey,
                                          ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, DepthKey,
                                          (int) 24, FrameRateKey, Rational.valueOf(15),
                                          QualityKey, 1.0f, KeyFrameIntervalKey,
                                          (int) (15 * 60)), new Format(MediaTypeKey,
                                          MediaType.VIDEO, EncodingKey, "black",
                                          FrameRateKey, Rational.valueOf(30)), null,
                              RecordedFile);
                  ScreenRecorder.start();
            } catch (IOException e) {
                  e.printStackTrace();
            } catch (AWTException e) {
                  e.printStackTrace();
            }
      }

      /**
       * This method will stop the recording.
       */
      public void stopRecording() {
            if (ScreenRecorder != null) {
                  try {
                        ScreenRecorder.stop();
                  } catch (IOException e) {
                        e.printStackTrace();
                  }
            }
      }
/**
* to delete the recorded file.if the test is passing then this method will delete the recorded file.
*/
      public void deleteRecordedFile() {
            if (RecordedFile != null) {
                  String[] children = RecordedFile.list();
                  for (int i = 0; i &lt; children.length; i++) {
                        new File(RecordedFile, children[i]).delete();
                        System.out.println("Deleted this " + RecordedFile + "//"
                                    + children[i]);
                  }

                  // The directory is now empty so delete it
                  RecordedFile.delete();
            }
      }

      /**
       * This method works similar to the org.testng.Assert.assertTrue and also
       * performs following actions: 
       * it takes the screenshot of the active screen if the assertion fails.
       * it also deletes the recorded vedio file if the test is passed. Call this
       * method only once, at the end of the test.
       *
       * @param condition
       * @param message
       */
      public void finalAssertTrue(boolean condition, String message) {
            stopRecording();
            if (condition)
                  deleteRecordedFile();
            _assertTrue(condition, message);
      }

How to use it in the test ?
public class MySeleniumTest extends BasicSeleniumTest {

 @TestDetails(author = "Bhushan Pawar", description = "Show the demo of video recording.")
 @Test
 public void testToGenerateVideoFile() {

  startRecording();

  /**
   * <> 

   * <> 

   * <>
   * 
   */
  finalAssertTrue(condition,
    "test is failed and I want to see the video file where exactly it failed !!");
 }

This way, Video recording feature will assist the one who is maintaining the tests  .
Happy Automation testing !