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 < 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 !