Thursday, March 13, 2014

Screen Recording (Video) of Webdriver test scripts

There are many paid tools which provides the feature of screen recording the test scripts. I just came up across the “Monte Media Library” java based library developed by Werner Randelshofer.

The below are the steps to capture screen cast/ Video recording of selenium/webdriver test script execution.

Step to implement Monte Media library to Selenium/Webdriver test scripts.

  1. Download “MonteScreenRecorder.jar” from link http://www.randelshofer.ch/monte/
  2. Add this jar file to your selenium/webdriver eclipse project.
  3. This jar file contain “ScreenRecorder” class, we need to create this class object by following way.


GraphicsConfiguration gc = GraphicsEnvironment

      .getLocalGraphicsEnvironment()

      .getDefaultScreenDevice()

      .getDefaultConfiguration();





ScreenRecorder  screenRecorder = new ScreenRecorder(gc, 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, 24, FrameRateKey, Rational.valueOf(15), QualityKey, 1.0f, KeyFrameIntervalKey, 15 * 60), new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, "black", FrameRateKey, Rational.valueOf(30)),null);
 
4. Need to call screenRecorder.start() methods at starting of your test scripts and "screenRecorder.stop() at the end of execution.

5. If we need to save video file in desire location, then we need to override “createMovieFile” function of “ScreenRecorder” class class for creating a new folder and file. For this we need to create another class like “SpecializedScreenRecorder” and extend “ScreenRecorder” class as below:

package com.test;
import java.awt.AWTException;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.monte.media.Format;
import org.monte.media.Registry;
import org.monte.screenrecorder.ScreenRecorder;
public class SpecializedScreenRecorder extends ScreenRecorder {
    private String name;
    public SpecializedScreenRecorder(GraphicsConfiguration cfg,
           Rectangle captureArea, Format fileFormat, Format screenFormat,
           Format mouseFormat, Format audioFormat, File movieFolder,
           String name) throws IOException, AWTException {
         super(cfg, captureArea, fileFormat, screenFormat, mouseFormat,
                  audioFormat, movieFolder);
         this.name = name;
    }
    @Override
    protected File createMovieFile(Format fileFormat) throws IOException {
          if (!movieFolder.exists()) {
                movieFolder.mkdirs();
          } else if (!movieFolder.isDirectory()) {
                throw new IOException("\"" + movieFolder + "\" is not a directory.");
          }
                           
          SimpleDateFormat dateFormat = new SimpleDateFormat(
                   "yyyy-MM-dd HH.mm.ss");
                         
          return new File(movieFolder, name + "-" + dateFormat.format(new Date()) + "."
                  + Registry.getInstance().getExtension(fileFormat));
    }
 }

6. Now we need to create object of  “SpecializedScreenRecorder” instead of creating “Screen” class object.

package com.demo;
import org.monte.screenrecorder.ScreenRecorder;
import org.monte.media.Format;
import org.monte.media.math.Rational;
import static org.monte.media.AudioFormatKeys.*;
import static org.monte.media.VideoFormatKeys.*;
import org.openqa.selenium.By;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.util.Date;
import org.openqa.selenium.WebDriver;
//import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
//import org.sikuli.script.App;
import org.sikuli.script.FindFailed;
import org.sikuli.script.Pattern;
import org.sikuli.script.Screen;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.thoughtworks.selenium.SeleneseTestBase;

public class TestBaseSikuli extends SeleneseTestBase{
   
    public static WebDriver driver;
     private ScreenRecorder screenRecorder;
    Screen screen = new Screen(); //Create and initialise an instance of Screen object 
    //public static String URL_var;
    public boolean isImagePresent(Pattern pattern){
        boolean status = false;
        screen = new Screen();
        try {
            screen.find(pattern);
            status = true;
        } catch (FindFailed e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return status;
    }
    public void clearField() throws Exception
    {
    Robot robot = new Robot();

    robot.keyPress(KeyEvent.VK_CONTROL);
    robot.keyPress(KeyEvent.VK_A);
    robot.keyRelease(KeyEvent.VK_CONTROL);
    robot.keyPress(KeyEvent.VK_BACK_SLASH);
    }
     public void startRecording() throws Exception
     {
                          
         File file = new File("D:\\Videos");
        
         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
         int width = screenSize.width;
         int height = screenSize.height;
                       
         Rectangle captureSize = new Rectangle(0,0, width, height);
                       
       GraphicsConfiguration gc = GraphicsEnvironment
          .getLocalGraphicsEnvironment()
          .getDefaultScreenDevice()
          .getDefaultConfiguration();
      this.screenRecorder = new SpecializedScreenRecorder(gc, captureSize,
          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, 24, FrameRateKey, Rational.valueOf(15),
               QualityKey, 1.0f,
               KeyFrameIntervalKey, 15 * 60),
          new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, "black",
               FrameRateKey, Rational.valueOf(30)),
          null, file, "MyVideo");
     this.screenRecorder.start();
     }
     public void stopRecording() throws Exception
     {
       this.screenRecorder.stop();
     }
@BeforeTest()
public void setupBeforeTest() throws Exception{
    TestBaseSikuli  videoReord = new TestBaseSikuli();
    videoReord.startRecording();      
    /*String path=System.getProperty("user.dir") +File.separator + "Browsers"+ File.separator +"chromedriver.exe";
    System.out.println(path);
    System.setProperty("webdriver.chrome.driver", path);
      driver = new ChromeDriver();*/
    driver = new FirefoxDriver();
    System.out.println("Driver started " +driver);
    String URL = "http://www.yatra.com/";
    System.out.println("GetURL " +URL);
    long start = System.currentTimeMillis(); //locate element load time
    driver.get(URL);
    driver.manage().window().maximize();
    long finish = System.currentTimeMillis();
    long TotalTime = finish - start;
    System.out.println("Total Time for page load - "+TotalTime);
    videoReord.stopRecording();
}
@Test()
public void FlightHotelBooking() throws Exception {
    TestBaseSikuli  videoReord = new TestBaseSikuli();
    videoReord.startRecording();
            driver.findElement(By.xpath("//*[@id='menu_flights-hotels']/a")).click();
            File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(scrFile, new File("c:\\error\\sample.png"));
           
            Pattern FlightHotel = new Pattern("C:\\Screenshots\\FlightHotel.png"); 
            if(isImagePresent(FlightHotel)){
                System.out.println("Element exists" +FlightHotel);
            }
            else{
                System.out.println("Element" +FlightHotel+ "doesnot exists");
            }
           
            driver.findElement(By.xpath("//*[@id='frescoHeader']/div/a")).click();
            videoReord.stopRecording();
}
@AfterTest()
public void kill() throws Exception{
   
    driver.close(); //closing the driver and killing all open processes
    driver.quit();
    System.out.println("Browser Killed");
}

}

Create a File class object and pass path where you want to save your video
   File file = new File("D:\\Videos");
Create dimension of your screen to capture video, create an object for default screen.

   Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
   int width = screenSize.width;
   int height = screenSize.height;
   Rectangle captureSize = new Rectangle(0,0, width, height);
Now Create object of “SpecializedScreenRecorder” and pass Rectangle object, File object, and file name as a last argument and rest are same.
Run the test, the video will be generated & stored/saved in the desired location mentioned.