Wednesday, June 15, 2016

CSV Reader utility

Goal: Read data from CSV file.and return a Map List

package common;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ReadCSVUtil {

private String fileName;

/**
* Constructor
* @param fileName
*/
public ReadCSVUtil(String fileName) {
this.fileName = fileName;
}
/**
* First value is your key and each row is your value.
* Size of Hashmap is = no of rows - 1(headers)
*
* @return this will return list of hashmap
*/
public List<HashMap<String, String>> run() {
List<HashMap<String, String>> mapList = new ArrayList<HashMap<String, String>>();
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
String[] keys;
br = new BufferedReader(new FileReader(this.fileName));
HashMap<String, String> map =null;
// Read first line from CSV file and use it as key
if ((line = br.readLine()) != null) {
keys = line.split(cvsSplitBy);
} else
return null;
// Read each line after first line and use it as values
while ((line = br.readLine()) != null) {
map = new HashMap<String, String>();
String[] values = line.split(cvsSplitBy);
for (int i = 0; i < keys.length; i++) {
// Store key and values to hash map
map.put(keys[i], values[i]);
}
// add hash map to list
mapList.add(map);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return mapList;
}

}

Tuesday, June 14, 2016

Image Comparison in Selenium using Thumbnailator

What it does (simplified): Used to compare two images.

First the two images that should be compared are divided in squares with the width and height,that you defined in the constructor. For every square in each image an average RGB-Value is calculated. If the average RGB-Values of the corresponding squares differ more than the threshold that you defined in the constructor (0.05 = 5%), the function fuzzyEqual(…) will return false.If you passed a path to save an image with the found differences a copy will be save at this path with \ all the differences marked with red squares.

Note: The sensitivity of the fuzzy-equal-test will be influenced by the defined threshold as well as the size of the squares!

How to Use:
  
  String imgOriginal = "F://ImageComparision//logo.png";
  String imgToCompareWithOriginal = "F://ImageComparision//screenshot.png";
  String imgOutputDifferences = "F://ImageComparision//new_screenshot_with_changes.png";
  
  ImageComparison imageComparison = new ImageComparison(10,10,0.05);
  if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences))
  System.out.println("Images are equal.");
  else
  System.out.println("Images are not equal.");

Jars files to add to buildpath : thumbnailator-0.4.8.jar - http://repo1.maven.org/maven2/net/coobird/thumbnailator/0.4.8/thumbnailator-0.4.8.jar

package common;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

import javax.imageio.ImageIO;

import net.coobird.thumbnailator.Thumbnails;
import com.sun.image.codec.jpeg.*;

public class ImageComparison {
    private BufferedImage imgOut = null;
    private int pixelPerBlockX;
    private int pixelPerBlockY;
    private double threshold;

    public ImageComparison(int pixelPerBlockX, int pixelPerBlockY,
   double threshold) {
this.pixelPerBlockX = pixelPerBlockX;
this.pixelPerBlockY = pixelPerBlockY;
this.threshold = threshold;
    }

    public boolean fuzzyEqual(String path1, String path2, String pathOut)
   throws IOException {
return fuzzyEqual(ImageIO.read(new File(path1)),
ImageIO.read(new File(path2)), pathOut);
    }

    public boolean fuzzyEqual(File file1, File file2, String pathOut)
   throws IOException {
return fuzzyEqual(ImageIO.read(file1), ImageIO.read(file2), pathOut);
    }

    public boolean fuzzyEqual(Image img1, Image img2, String pathOut)
   throws IOException {
return fuzzyEqual(imageToBufferedImage(img1),
imageToBufferedImage(img2), pathOut);
    }

    public boolean fuzzyEqual(BufferedImage img1, BufferedImage img2,
   String pathOut) throws IOException {
boolean fuzzyEqual = true;
img2 = adaptImageSize(img1, img2);

imgOut = imageToBufferedImage(img2);
Graphics2D outImgGraphics = imgOut.createGraphics();
outImgGraphics.setColor(Color.RED);

int subImageHeight;
int subImageWidth;
// String debug;

int blocksx = (int) Math.ceil((float) img1.getWidth()
/ (float) pixelPerBlockX);
int blocksy = (int) Math.ceil((float) img1.getHeight()
/ (float) pixelPerBlockY);

for (int y = 0; y < blocksy; y++) {
   // debug = "";
   for (int x = 0; x < blocksx; x++) {
subImageWidth = calcPixSpan(pixelPerBlockX, x, img1.getWidth());
subImageHeight = calcPixSpan(pixelPerBlockY, y,
img1.getHeight());
/*
* System.out.println(" Real Width:" + img1.getWidth() +
* " Real Height:" + img1.getHeight() + " X-Start:" + x
* pixelPerBlockX + " Y-Start:" + y * pixelPerBlockY +
* " sub width:" + subImageWidth + " sub height:" +
* subImageHeight); System.out.println(" Real Width:" +
* img2.getWidth() + " Real Height:" + img2.getHeight() +
* " X-Start:" + x pixelPerBlockX + " Y-Start:" + y *
* pixelPerBlockY + " sub width:" + subImageWidth +
* " sub height:" + subImageHeight);
*/
HashMap<String, Integer> avgRgb1 = getAverageRgb(img1
.getSubimage(x * pixelPerBlockX, y * pixelPerBlockY,
subImageWidth, subImageHeight));
HashMap<String, Integer> avgRgb2 = getAverageRgb(img2
.getSubimage(x * pixelPerBlockX, y * pixelPerBlockY,
subImageWidth, subImageHeight));
// debug = debug
// + String.format(Locale.ENGLISH, "%1.2f",
// calculateRgbDiff(avgRgb1, avgRgb2)) + " | ";
if (calculateRgbDiff(avgRgb1, avgRgb2) > threshold) {
   outImgGraphics.drawRect(x * pixelPerBlockX, y
   * pixelPerBlockY, pixelPerBlockX - 1,
   pixelPerBlockY - 1);
   fuzzyEqual = false;
}
   }
   // System.out.println(debug);
}
if (pathOut != null && !pathOut.isEmpty())
   saveImage(imgOut, pathOut);
return fuzzyEqual;
    }

    private int calcPixSpan(int pixelPerBlock, int n, int overallSpan) {
if (pixelPerBlock * (n + 1) > overallSpan)
   return overallSpan % pixelPerBlock;
else
   return pixelPerBlock;
    }

    private BufferedImage adaptImageSize(BufferedImage img1, BufferedImage img2)
   throws IOException {
int scalePixelWidth;
int scalePixelHeight;
/*
* System.out.println("1 Real Width:" + img1.getWidth() +
* " Real Height:" + img1.getHeight());
* System.out.println("2 Real Width:" + img2.getWidth() +
* " Real Height:" + img2.getHeight());
*/

if (((float) img2.getWidth() / (float) img1.getWidth()) < ((float) img2
.getHeight() / (float) img1.getHeight())) {
   scalePixelWidth = img1.getWidth();
   scalePixelHeight = (int) (img2.getHeight() * Math.ceil((float) img1
   .getWidth() / (float) img2.getWidth()));
   System.out.println("If : Scale Width:" + scalePixelWidth
   + " Scale Height:" + scalePixelHeight);
} else {
   scalePixelHeight = img1.getHeight();
   scalePixelWidth = (int) (img2.getWidth() * Math.ceil((float) img1
   .getHeight() / (float) img2.getHeight()));
   System.out.println("Else: Scale Width:" + scalePixelWidth
   + " Scale Height:" + scalePixelHeight);
}
/*
* System.out.println("1 Real Width:" + img1.getWidth() +
* " Real Height:" + img1.getHeight());
* System.out.println("2 Real Width:" +
* Thumbnails.of(img2).size(scalePixelWidth, scalePixelHeight)
* .asBufferedImage().getWidth() + " Real Height:" +
* Thumbnails.of(img2).size(scalePixelWidth, scalePixelHeight)
* .asBufferedImage().getHeight());
*/
return Thumbnails.of(img2).size(scalePixelWidth, scalePixelHeight)
.asBufferedImage();
    }

    private double calculateRgbDiff(HashMap<String, Integer> avgRgb1,
   HashMap<String, Integer> avgRgb2) {
double maxDifference = 255 * 3;
double difference = Math.abs(avgRgb1.get("r") - avgRgb2.get("r"))
+ Math.abs(avgRgb1.get("g") - avgRgb2.get("g"))
+ Math.abs(avgRgb1.get("b") - avgRgb2.get("b"));

return difference / maxDifference;
    }

    private HashMap<String, Integer> getAverageRgb(BufferedImage img) {
Raster currentRaster = img.getData();
HashMap<String, Integer> averageRgb = new HashMap<String, Integer>();
averageRgb.put("r", 0);
averageRgb.put("g", 0);
averageRgb.put("b", 0);

for (int y = 0; y < img.getHeight(); y++) {
   for (int x = 0; x < img.getWidth(); x++) {
averageRgb.put("r",
averageRgb.get("r") + currentRaster.getSample(x, y, 0));
averageRgb.put("g",
averageRgb.get("g") + currentRaster.getSample(x, y, 1));
averageRgb.put("b",
averageRgb.get("b") + currentRaster.getSample(x, y, 2));

   }
}

averageRgb.put("r",
averageRgb.get("r") / (img.getHeight() * img.getWidth()));
averageRgb.put("g",
averageRgb.get("g") / (img.getHeight() * img.getWidth()));
averageRgb.put("b",
averageRgb.get("b") / (img.getHeight() * img.getWidth()));

return averageRgb;
    }

    private BufferedImage imageToBufferedImage(Image img) {
BufferedImage bi = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(img, null, null);
return bi;
    }

    private void saveImage(Image img, String filename) {
BufferedImage bi = imageToBufferedImage(img);
FileOutputStream out = null;
try {
   out = new FileOutputStream(filename);
} catch (java.io.FileNotFoundException io) {
   System.out.println("File Not Found");
}
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
param.setQuality(0.8f, false);
encoder.setJPEGEncodeParam(param);
try {
   encoder.encode(bi);
   out.close();
} catch (java.io.IOException io) {
   System.out.println("IOException");
}
    }

}


Courtesy:  http://www.frontendtest.org/blog/screenshot-comparison/

A Video Recorder for your Selenium FW using Monte

Screen recorder for web tests on webdriver by means of java.

Usage:
1) initialize web driver
     WebDriver driver = new FirefoxDriver();
     driver.get("http://automated-testing.info");
2) capture video
     initScreen(Path to save video);
     startVideoCapturing();
3) Stop Video recording
     stopVideoCapturing();
4) Quit web driver
     driver.quit();
Jars files to add to buildpath : monte-cc.jar, jai_core.jar, jmf.jar

Note: Monte java library is used to implement it http://www.randelshofer.ch/monte/


package common;
import org.monte.media.Format;
import org.monte.media.FormatKeys.*;
import org.monte.media.math.Rational;
import org.monte.screenrecorder.ScreenRecorder;
import java.awt.AWTException;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
import static org.monte.media.FormatKeys.*;
import static org.monte.media.VideoFormatKeys.*;

public class VideoCapture {
    public static ScreenRecorder screenLogger = null;

    /**
     * initializes a graphic configurations
     */
    public static void initScreen(String pathToFile) {
// get the graphics configuration of the current screen
GraphicsConfiguration gc = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();

// set screen recorder configuration
try {
   screenLogger = 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,
   24, FrameRateKey, Rational.valueOf(15), QualityKey,
   1.0f, KeyFrameIntervalKey, 15 * 60), new Format(
   MediaTypeKey, MediaType.VIDEO, EncodingKey,
   "black", FrameRateKey, Rational.valueOf(30)), null,
   new File(pathToFile));
} catch (IOException ioe) {
   ioe.printStackTrace();
} catch (AWTException awte) {
   awte.printStackTrace();
}
    }

    /**
     * starts the screen recorder
     */
    public static void startVideoCapturing() {
try {
   screenLogger.start();
} catch (IOException ioe) {
   ioe.printStackTrace();
}
    }

    /**
     * stops the screen recorder
     */
    public static void stopVideoCapturing() {
try {
   screenLogger.stop();
} catch (Exception e) {
   e.printStackTrace();
}
    }

}