diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 47989c2..07ef718 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,7 +20,7 @@ Create a feature branch and start improving:
% git checkout -b my-feature-branch
```
-HEAD-based development is prefered, which means all changes are applied
+HEAD-based development is preferred, which means all changes are applied
directly on top of master.
### Step 3: Commit
diff --git a/README.md b/README.md
index 0242478..cce3c1c 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Selenium Shutterbug is a utility library written in Java for making screenshots
## Code Example
-Screenhot of the page with scrolling (for Chrome to make screenshot of the whole page but not viewport only):
+Screenshot of the page with scrolling (for Chrome to make screenshot of the whole page but not viewport only):
```
Shutterbug.shootPage(driver, ScrollStrategy.BOTH_DIRECTIONS).save("C:\\testing\\screenshots\\");
```
diff --git a/pom.xml b/pom.xml
index c444585..a91e6bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,11 @@
commons-io
2.6
+
+ org.projectlombok
+ lombok
+ 1.18.8
+
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/core/ElementSnapshot.java b/src/main/java/com/assertthat/selenium_shutterbug/core/ElementSnapshot.java
index 1e343bb..0687d79 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/core/ElementSnapshot.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/core/ElementSnapshot.java
@@ -9,7 +9,6 @@
import com.assertthat.selenium_shutterbug.utils.web.Coordinates;
import com.assertthat.selenium_shutterbug.utils.web.ElementOutsideViewportException;
import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/core/PageSnapshot.java b/src/main/java/com/assertthat/selenium_shutterbug/core/PageSnapshot.java
index be8e3b6..f291712 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/core/PageSnapshot.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/core/PageSnapshot.java
@@ -5,9 +5,9 @@
package com.assertthat.selenium_shutterbug.core;
-import com.assertthat.selenium_shutterbug.utils.web.ElementOutsideViewportException;
import com.assertthat.selenium_shutterbug.utils.image.ImageProcessor;
import com.assertthat.selenium_shutterbug.utils.web.Coordinates;
+import com.assertthat.selenium_shutterbug.utils.web.ElementOutsideViewportException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/core/Snapshot.java b/src/main/java/com/assertthat/selenium_shutterbug/core/Snapshot.java
index 81de24c..0479533 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/core/Snapshot.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/core/Snapshot.java
@@ -69,7 +69,7 @@ public T withTitle(String title) {
* @return instance of type Snapshot
*/
public T withThumbnail(String path, String name, double scale) {
- File thumbnailFile = new File(path.toString(), name);
+ File thumbnailFile = new File(path, name);
if(!Files.exists(Paths.get(path))) {
thumbnailFile.mkdirs();
}
@@ -90,15 +90,12 @@ public T withThumbnail(String path, String name, double scale) {
* @return instance of type Snapshot
*/
public T withCroppedThumbnail(String path, String name, double scale, double cropWidth, double cropHeight) {
- File thumbnailFile = new File(path.toString(), name);
- if(!Files.exists(Paths.get(path))) {
- thumbnailFile.mkdirs();
- }
+ File thumbnailFile = getFile(path, name);
thumbnailImage=ImageProcessor.cropAndScale(image,scale, cropWidth, cropHeight);
FileUtil.writeImage(thumbnailImage, EXTENSION, thumbnailFile);
return self();
}
-
+
/**
* Generate cropped thumbnail of the original screenshot.
* Will save different thumbnails depends on when it was called in the chain.
@@ -111,15 +108,27 @@ public T withCroppedThumbnail(String path, String name, double scale, double cr
* @return instance of type Snapshot
*/
public T withCroppedThumbnail(String path, String name, double scale, int maxWidth, int maxHeight) {
- File thumbnailFile = new File(path.toString(), name);
- if(!Files.exists(Paths.get(path))) {
- thumbnailFile.mkdirs();
- }
+ File thumbnailFile = getFile(path, name);
thumbnailImage=ImageProcessor.cropAndScale(image,scale, maxWidth, maxHeight);
FileUtil.writeImage(thumbnailImage, EXTENSION, thumbnailFile);
return self();
}
-
+
+ /**
+ * Generate file for cropped thumbnail of the original screenshot.
+ *
+ * @param path to save thumbnail image to
+ * @param name of the resulting image
+ * @return instance of type File
+ */
+ private File getFile(String path, String name) {
+ File thumbnailFile = new File(path, name);
+ if (!Files.exists(Paths.get(path))) {
+ thumbnailFile.mkdirs();
+ }
+ return thumbnailFile;
+ }
+
/**
* Generate cropped thumbnail of the original screenshot.
* Will save different thumbnails depends on when it was called in the chain.
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/file/FileUtil.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/file/FileUtil.java
index 024a465..320b11b 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/file/FileUtil.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/file/FileUtil.java
@@ -24,7 +24,7 @@ public static String getJsScript(String filePath) {
try {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
if (is == null) {
- // This is needed to load the files in an OSGI enviroment when enclosed in a bundle
+ // This is needed to load the files in an OSGI environment when enclosed in a bundle
is = FileUtil.class.getClassLoader().getResourceAsStream(filePath);
}
// if the input stream is still null, this will avoid a non descriptive null pointer exception
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/file/UnableSaveSnapshotException.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/file/UnableSaveSnapshotException.java
index dd7a7cc..9faeca0 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/file/UnableSaveSnapshotException.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/file/UnableSaveSnapshotException.java
@@ -5,8 +5,6 @@
package com.assertthat.selenium_shutterbug.utils.file;
-import org.openqa.selenium.WebDriverException;
-
/**
* Created by Glib_Briia on 17/06/2016.
*/
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessor.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessor.java
index 19ca528..35656fc 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessor.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessor.java
@@ -5,13 +5,18 @@
package com.assertthat.selenium_shutterbug.utils.image;
-import com.assertthat.selenium_shutterbug.utils.file.FileUtil;
+import com.assertthat.selenium_shutterbug.utils.image.model.ImageData;
import com.assertthat.selenium_shutterbug.utils.web.Coordinates;
import java.awt.*;
import java.awt.color.ColorSpace;
-import java.awt.image.*;
-import java.io.File;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.ColorModel;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+import java.awt.image.PixelGrabber;
/**
* Created by Glib_Briia on 17/06/2016.
@@ -19,7 +24,7 @@
public class ImageProcessor {
private static final int ARCH_SIZE = 10;
- private static float[] matrix = new float[49];
+ private static final float[] matrix = new float[49];
private static double pixelError = Double.MAX_VALUE;
static {
@@ -57,27 +62,21 @@ public static BufferedImage getElement(BufferedImage sourceImage, Coordinates co
public static BufferedImage blurArea(BufferedImage sourceImage, Coordinates coords) {
BufferedImage blurredImage = blur(sourceImage.getSubimage(coords.getX(), coords.getY(), coords.getWidth(), coords.getHeight()));
- BufferedImage combined = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = combined.createGraphics();
- g.drawImage(sourceImage, 0, 0, null);
- g.drawImage(blurredImage, coords.getX(), coords.getY(), null);
- g.dispose();
- return combined;
+ return getBufferedImage(sourceImage, coords, blurredImage, sourceImage);
}
public static BufferedImage monochromeArea(BufferedImage sourceImage, Coordinates coords) {
BufferedImage monochromedImage = convertToGrayAndWhite(sourceImage.getSubimage(coords.getX(), coords.getY(), coords.getWidth(), coords.getHeight()));
- BufferedImage combined = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = combined.createGraphics();
- g.drawImage(sourceImage, 0, 0, null);
- g.drawImage(monochromedImage, coords.getX(), coords.getY(), null);
- g.dispose();
- return combined;
+ return getBufferedImage(sourceImage, coords, monochromedImage, sourceImage);
}
public static BufferedImage blurExceptArea(BufferedImage sourceImage, Coordinates coords) {
BufferedImage subImage = sourceImage.getSubimage(coords.getX(), coords.getY(), coords.getWidth(), coords.getHeight());
BufferedImage blurredImage = blur(sourceImage);
+ return getBufferedImage(sourceImage, coords, subImage, blurredImage);
+ }
+
+ private static BufferedImage getBufferedImage(BufferedImage sourceImage, Coordinates coords, BufferedImage subImage, BufferedImage blurredImage) {
BufferedImage combined = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = combined.createGraphics();
g.drawImage(blurredImage, 0, 0, null);
@@ -87,8 +86,7 @@ public static BufferedImage blurExceptArea(BufferedImage sourceImage, Coordinate
}
public static BufferedImage cropAround(BufferedImage sourceImage, Coordinates coords, int offsetX, int offsetY) {
- BufferedImage subImage = sourceImage.getSubimage(coords.getX()-offsetX, coords.getY()-offsetY, coords.getWidth()+offsetX*2, coords.getHeight()+offsetY*2);
- return subImage;
+ return sourceImage.getSubimage(coords.getX() - offsetX, coords.getY() - offsetY, coords.getWidth() + offsetX * 2, coords.getHeight() + offsetY * 2);
}
public static BufferedImage addTitle(BufferedImage sourceImage, String title, Color color, Font textFont) {
@@ -108,156 +106,99 @@ public static BufferedImage convertToGrayAndWhite(BufferedImage sourceImage) {
}
public static boolean imagesAreEquals(BufferedImage image1, BufferedImage image2, double deviation) {
- int width1 = image1.getWidth(null);
- int width2 = image2.getWidth(null);
- int height1 = image1.getHeight(null);
- int height2 = image2.getHeight(null);
- if ((width1 != width2) || (height1 != height2)) {
- throw new UnableToCompareImagesException("Images dimensions mismatch: image1 - " + width1 + "x" + height1 + "; image2 - " + width2 + "x" + height2);
+ ImageData image1Data = new ImageData(image1);
+ ImageData image2Data = new ImageData(image2);
+ if (image1Data.notEqualsDimensions(image2Data)) {
+ throw new UnableToCompareImagesException("Images dimensions mismatch: image1 - " + image1Data.getWidth() + "x" + image1Data.getHeight() + "; image2 - " + image2Data.getWidth() + "x" + image2Data.getHeight());
}
- long diff = 0;
- for (int y = 0; y < height1; y++) {
- for (int x = 0; x < width1; x++) {
- int rgb1 = image1.getRGB(x, y);
- int rgb2 = image2.getRGB(x, y);
- int r1 = (rgb1 >> 16) & 0xff;
- int g1 = (rgb1 >> 8) & 0xff;
- int b1 = (rgb1) & 0xff;
- int r2 = (rgb2 >> 16) & 0xff;
- int g2 = (rgb2 >> 8) & 0xff;
- int b2 = (rgb2) & 0xff;
- diff += Math.abs(r1 - r2);
- diff += Math.abs(g1 - g2);
- diff += Math.abs(b1 - b2);
- }
- }
- double n = width1 * height1 * 3;
- double p = diff / n / 255.0;
- return p == 0 || p <= deviation;
+ return image1Data.equalsEachPixels(image2Data, deviation);
}
/**
* Extends the functionality of imagesAreEqualsWithDiff, but creates a third BufferedImage and applies pixel manipulation to it.
- * @param image1 The first image to compare
- * @param image2 The second image to compare
+ *
+ * @param image1 The first image to compare
+ * @param image2 The second image to compare
* @param pathFileName The output path filename for the third image, if null then is ignored
- * @param deviation The upper limit of the pixel deviation for the test
+ * @param deviation The upper limit of the pixel deviation for the test
* @return If the test passes
*/
public static boolean imagesAreEqualsWithDiff(BufferedImage image1, BufferedImage image2, String pathFileName, double deviation) {
- BufferedImage output = new BufferedImage(image1.getWidth(), image1.getHeight(), BufferedImage.TYPE_INT_RGB);
-
- int width1 = image1.getWidth(null);
- int width2 = image2.getWidth(null);
- int height1 = image1.getHeight(null);
- int height2 = image2.getHeight(null);
- if ((width1 != width2) || (height1 != height2)) {
- throw new UnableToCompareImagesException("Images dimensions mismatch: image1 - " + width1 + "x" + height1 + "; image2 - " + width2 + "x" + height2);
+ ImageData image1Data = new ImageData(image1);
+ ImageData image2Data = new ImageData(image2);
+ if (image1Data.notEqualsDimensions(image2Data)) {
+ throw new UnableToCompareImagesException("Images dimensions mismatch: image1 - " + image1Data.getWidth() + "x" + image1Data.getHeight() + "; image2 - " + image2Data.getWidth() + "x" + image2Data.getHeight());
}
- long diff = 0;
- long recordedDiff = 0; // Records the difference so it can be compared, saves having to do three if statements
- for (int y = 0; y < height1; y++) {
- for (int x = 0; x < width1; x++) {
- recordedDiff = diff;
-
- // Grab RGB values of both images, then bit shift and bitwise AND to break them down into R, G and B
- int rgb1 = image1.getRGB(x, y);
- int rgb2 = image2.getRGB(x, y);
- int r1 = (rgb1 >> 16) & 0xff;
- int g1 = (rgb1 >> 8) & 0xff;
- int b1 = (rgb1) & 0xff;
- int r2 = (rgb2 >> 16) & 0xff;
- int g2 = (rgb2 >> 8) & 0xff;
- int b2 = (rgb2) & 0xff;
- diff += Math.abs(r1 - r2);
- diff += Math.abs(g1 - g2);
- diff += Math.abs(b1 - b2);
-
- // If difference > recorded difference, change pixel to red. If zero, set to image 1's original pixel
- if(diff > recordedDiff)
- output.setRGB(x,y,new Color(255,0,0).getRGB() & rgb1); // Dark red = original position, Light red is moved to
- else
- output.setRGB(x,y,rgb1);
- }
- }
- int colourSpaceBytes = 3; // RGB is 24 bit, or 3 bytes
- double totalPixels = width1 * height1 * colourSpaceBytes;
- pixelError = diff / totalPixels / 255.0;
-
- // Write the image as png, with the filename based on the path provided
- if(pixelError > 0)
- FileUtil.writeImage(output,"png",new File(pathFileName+".png"));
- return pixelError == 0 || pixelError <= deviation;
+ return image1Data.equalsEachPixelsWithCreateDifferencesImage(image2Data, deviation, pathFileName);
}
public static BufferedImage scale(BufferedImage source, double ratio) {
- return cropAndScale(source, ratio, 1.0,1.0);
+ return cropAndScale(source, ratio, 1.0, 1.0);
}
-
- public static BufferedImage cropAndScale(BufferedImage source,double ratio, double cropWidth, double cropHeight) {
+
+ public static BufferedImage cropAndScale(BufferedImage source, double ratio, double cropWidth, double cropHeight) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
- BufferedImage scaledImage = getCompatibleImage(w, h, source);
- Graphics2D resultGraphics = scaledImage.createGraphics();
- resultGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
- RenderingHints.VALUE_INTERPOLATION_BICUBIC);
- resultGraphics.drawImage(source, 0, 0, w, h, null);
- resultGraphics.dispose();
- return scaledImage.getSubimage(0, 0, (int)(w*cropWidth),(int)(h*cropHeight));
+ BufferedImage scaledImage = createAndDrawImage(source, w, h);
+ return scaledImage.getSubimage(0, 0, (int) (w * cropWidth), (int) (h * cropHeight));
}
-
- public static BufferedImage cropAndScale(BufferedImage source,double ratio, int maxWidth, int maxHeight) {
+
+ public static BufferedImage cropAndScale(BufferedImage source, double ratio, int maxWidth, int maxHeight) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
+ BufferedImage scaledImage = createAndDrawImage(source, w, h);
+ if (maxWidth != -1 && w > maxWidth) {
+ w = maxWidth;
+ }
+ if (maxHeight != -1 && h > maxHeight) {
+ h = maxHeight;
+ }
+ return scaledImage.getSubimage(0, 0, w, h);
+ }
+
+ private static BufferedImage createAndDrawImage(BufferedImage source, int w, int h) {
BufferedImage scaledImage = getCompatibleImage(w, h, source);
Graphics2D resultGraphics = scaledImage.createGraphics();
resultGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
resultGraphics.drawImage(source, 0, 0, w, h, null);
resultGraphics.dispose();
- if(maxWidth != -1 && w > maxWidth){
- w = maxWidth;
- }
- if(maxHeight != -1 && h > maxHeight){
- h = maxHeight;
- }
- return scaledImage.getSubimage(0, 0, w,h);
+ return scaledImage;
}
-
-
+
private static BufferedImage getCompatibleImage(int w, int h, BufferedImage source) {
- BufferedImage bimage = null;
- try{
+ BufferedImage bImage = null;
+ try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
- bimage = gc.createCompatibleImage(w,h);
+ bImage = gc.createCompatibleImage(w, h);
} catch (HeadlessException e) {
// The system does not have a screen
}
- if (bimage == null) {
+ if (bImage == null) {
boolean hasAlpha = hasAlpha(source);
int type = BufferedImage.TYPE_INT_RGB;
if (hasAlpha) {
type = BufferedImage.TYPE_INT_ARGB;
}
- bimage = new BufferedImage(w, h, type);
+ bImage = new BufferedImage(w, h, type);
}
- return bimage;
+ return bImage;
}
public static boolean hasAlpha(Image image) {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
- BufferedImage bimage = (BufferedImage)image;
- return bimage.getColorModel().hasAlpha();
+ BufferedImage bImage = (BufferedImage) image;
+ return bImage.getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pg.grabPixels();
- } catch (InterruptedException e) {
+ } catch (InterruptedException ignored) {
}
// Get the image's color model
ColorModel cm = pg.getColorModel();
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/image/UnableToCompareImagesException.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/UnableToCompareImagesException.java
index 204ab54..490f520 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/image/UnableToCompareImagesException.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/UnableToCompareImagesException.java
@@ -9,6 +9,7 @@
* Created by Glib_Briia on 25/06/2016.
*/
public class UnableToCompareImagesException extends RuntimeException {
+
public UnableToCompareImagesException() {
super();
}
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/image/model/ImageData.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/model/ImageData.java
new file mode 100644
index 0000000..211f914
--- /dev/null
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/image/model/ImageData.java
@@ -0,0 +1,90 @@
+package com.assertthat.selenium_shutterbug.utils.image.model;
+
+import com.assertthat.selenium_shutterbug.utils.file.FileUtil;
+import lombok.Getter;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+@Getter
+public class ImageData {
+ private final int RED_RGB = new Color(255, 0, 0).getRGB();
+ private final BufferedImage image;
+ private final int width;
+ private final int height;
+
+ public ImageData(BufferedImage image) {
+ this.image = image;
+ this.width = image.getWidth(null);
+ this.height = image.getHeight(null);
+ }
+
+ public boolean notEqualsDimensions(ImageData imageData) {
+ return !equalsDimensions(imageData);
+ }
+
+ private boolean equalsDimensions(ImageData imageData) {
+ return this.width == imageData.width && this.height == imageData.height;
+ }
+
+ public boolean equalsEachPixelsWithCreateDifferencesImage(ImageData imageData, double deviation, String pathDifferenceImageFileName) {
+ return equalsEachPixelsWithCreateDifferencesImage(imageData.getImage(), deviation, pathDifferenceImageFileName);
+ }
+
+ private boolean equalsEachPixelsWithCreateDifferencesImage(BufferedImage image, double deviation, String pathDifferenceImageFileName) {
+ createDifferencesImage(image, pathDifferenceImageFileName);
+ return equalsEachPixels(image, deviation);
+ }
+
+ private void createDifferencesImage(BufferedImage image, String pathDifferenceImageFileName) {
+ BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int rgb1 = this.getImage().getRGB(x, y);
+ int rgb2 = image.getRGB(x, y);
+
+ // If difference > recorded difference, change pixel to red. If zero, set to image 1's original pixel
+ if (rgb1 != rgb2)
+ output.setRGB(x, y, RED_RGB & rgb1); // Dark red = original position, Light red is moved to
+ else
+ output.setRGB(x, y, rgb1);
+ }
+ }
+
+ FileUtil.writeImage(output, "png", new File(pathDifferenceImageFileName + ".png"));
+ }
+
+ public boolean equalsEachPixels(ImageData imageData, double deviation) {
+ return equalsEachPixels(imageData.getImage(), deviation);
+ }
+
+ private boolean equalsEachPixels(BufferedImage image, double deviation) {
+ double p = calculatePixelsDifference(image);
+
+ return p == 0 || p <= deviation;
+ }
+
+ private double calculatePixelsDifference(BufferedImage image) {
+ long diff = 0;
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int rgb1 = this.getImage().getRGB(x, y);
+ int rgb2 = image.getRGB(x, y);
+ int r1 = (rgb1 >> 16) & 0xff;
+ int g1 = (rgb1 >> 8) & 0xff;
+ int b1 = (rgb1) & 0xff;
+ int r2 = (rgb2 >> 16) & 0xff;
+ int g2 = (rgb2 >> 8) & 0xff;
+ int b2 = (rgb2) & 0xff;
+ diff += Math.abs(r1 - r2);
+ diff += Math.abs(g1 - g2);
+ diff += Math.abs(b1 - b2);
+ }
+ }
+ double n = width * height * 3;
+
+ return diff / n / 255.0;
+ }
+}
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Browser.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Browser.java
index 2b8289b..21b2634 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Browser.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Browser.java
@@ -8,8 +8,12 @@
import com.assertthat.selenium_shutterbug.utils.file.FileUtil;
import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.Dimension;
-import org.openqa.selenium.*;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
+import org.openqa.selenium.TakesScreenshot;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.HttpCommandExecutor;
@@ -35,17 +39,17 @@
*/
public class Browser {
- public static final String RELATIVE_COORDS_JS = "js/relative-element-coords.js";
- public static final String MAX_DOC_WIDTH_JS = "js/max-document-width.js";
- public static final String MAX_DOC_HEIGHT_JS = "js/max-document-height.js";
- public static final String VIEWPORT_HEIGHT_JS = "js/viewport-height.js";
- public static final String VIEWPORT_WIDTH_JS = "js/viewport-width.js";
- public static final String SCROLL_TO_JS = "js/scroll-to.js";
- public static final String SCROLL_INTO_VIEW_JS = "js/scroll-element-into-view.js";
- public static final String CURRENT_SCROLL_Y_JS = "js/get-current-scrollY.js";
- public static final String CURRENT_SCROLL_X_JS = "js/get-current-scrollX.js";
- public static final String DEVICE_PIXEL_RATIO = "js/get-device-pixel-ratio.js";
- public static final String ALL_METRICS = "js/all-metrics.js";
+ private static final String RELATIVE_COORDS_JS = "js/relative-element-coords.js";
+ private static final String MAX_DOC_WIDTH_JS = "js/max-document-width.js";
+ private static final String MAX_DOC_HEIGHT_JS = "js/max-document-height.js";
+ private static final String VIEWPORT_HEIGHT_JS = "js/viewport-height.js";
+ private static final String VIEWPORT_WIDTH_JS = "js/viewport-width.js";
+ private static final String SCROLL_TO_JS = "js/scroll-to.js";
+ private static final String SCROLL_INTO_VIEW_JS = "js/scroll-element-into-view.js";
+ private static final String CURRENT_SCROLL_Y_JS = "js/get-current-scrollY.js";
+ private static final String CURRENT_SCROLL_X_JS = "js/get-current-scrollX.js";
+ private static final String DEVICE_PIXEL_RATIO = "js/get-device-pixel-ratio.js";
+ private static final String ALL_METRICS = "js/all-metrics.js";
private WebDriver driver;
private int docHeight = -1;
@@ -57,9 +61,9 @@ public class Browser {
public Browser(WebDriver driver, boolean useDevicePixelRatio) {
this.driver = driver;
- if(useDevicePixelRatio) {
+ if (useDevicePixelRatio) {
Object devicePixelRatio = executeJsScript(DEVICE_PIXEL_RATIO);
- this.devicePixelRatio = devicePixelRatio instanceof Double? (Double)devicePixelRatio: (Long)devicePixelRatio*1.0;
+ this.devicePixelRatio = devicePixelRatio instanceof Double ? (Double) devicePixelRatio : (Long) devicePixelRatio * 1.0;
}
}
@@ -67,15 +71,15 @@ public Double getDevicePixelRatio() {
return devicePixelRatio;
}
- public static void wait(int milis) {
+ public static void wait(int ms) {
try {
- Thread.sleep(milis);
+ Thread.sleep(ms);
} catch (InterruptedException e) {
throw new UnableTakeSnapshotException(e);
}
}
- public void setScrollTimeout(int scrollTimeout){
+ public void setScrollTimeout(int scrollTimeout) {
this.scrollTimeout = scrollTimeout;
}
@@ -86,19 +90,21 @@ public BufferedImage takeScreenshot() {
} catch (IOException e) {
throw new UnableTakeSnapshotException(e);
} finally {
- // add this to clean up leaving this file in the temporary directory forever...
- if (srcFile.exists()) {
- srcFile.delete();
- }
- }
+ // add this to clean up leaving this file in the temporary directory forever...
+ if (srcFile.exists()) {
+ srcFile.delete();
+ }
+ }
}
- /**Using different screenshot strategy dependently on driver:
+ /**
+ * Using different screenshot strategy dependently on driver:
* for chrome - chrome command will be used
* for others - their default screenshot methods
+ *
* @return BufferedImage resulting image
- * */
+ */
public BufferedImage takeScreenshotEntirePage() {
if (driver instanceof EventFiringWebDriver) {
driver = ((EventFiringWebDriver) this.driver).getWrappedDriver();
@@ -116,20 +122,20 @@ public BufferedImage takeScreenshotEntirePage() {
public BufferedImage takeScreenshotEntirePageDefault() {
final int _docWidth = this.getDocWidth();
- final int _docHeight = this.getDocHeight();
- BufferedImage combinedImage = new BufferedImage(_docWidth, _docHeight, BufferedImage.TYPE_INT_ARGB);
+ final int _docHeight = this.getDocHeight();
+ BufferedImage combinedImage = new BufferedImage(_docWidth, _docHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = combinedImage.createGraphics();
int _viewportWidth = this.getViewportWidth();
int _viewportHeight = this.getViewportHeight();
final int scrollBarMaxWidth = 40; // this is probably too high, but better to be safe than sorry
- if (_viewportWidth < _docWidth || (_viewportHeight < _docHeight && _viewportWidth - scrollBarMaxWidth < _docWidth))
- _viewportHeight-=scrollBarMaxWidth; // some space for a scrollbar
+ if (_viewportWidth < _docWidth || (_viewportHeight < _docHeight && _viewportWidth - scrollBarMaxWidth < _docWidth))
+ _viewportHeight -= scrollBarMaxWidth; // some space for a scrollbar // TODO viewportHeight and scrollVarMaxWidth?
if (_viewportHeight < _docHeight)
- _viewportWidth-=scrollBarMaxWidth; // some space for a scrollbar
+ _viewportWidth -= scrollBarMaxWidth; // some space for a scrollbar
- int horizontalIterations = (int) Math.ceil(((double) _docWidth) / _viewportWidth);
- int verticalIterations = (int) Math.ceil(((double) _docHeight) / _viewportHeight);
+ int horizontalIterations = (int) Math.ceil(((double) _docWidth) / _viewportWidth);
+ int verticalIterations = (int) Math.ceil(((double) _docHeight) / _viewportHeight);
outer_loop:
for (int j = 0; j < verticalIterations; j++) {
this.scrollTo(0, j * _viewportHeight);
@@ -138,7 +144,7 @@ public BufferedImage takeScreenshotEntirePageDefault() {
wait(scrollTimeout);
Image image = takeScreenshot();
g.drawImage(image, this.getCurrentScrollX(), this.getCurrentScrollY(), null);
- if(_docWidth == image.getWidth(null) && _docHeight == image.getHeight(null)){
+ if (_docWidth == image.getWidth(null) && _docHeight == image.getHeight(null)) {
break outer_loop;
}
}
@@ -150,7 +156,7 @@ public BufferedImage takeScreenshotEntirePageDefault() {
public BufferedImage takeScreenshotEntirePageUsingChromeCommand() {
//should use devicePixelRatio by default as chrome command executor makes screenshot account for that
Object devicePixelRatio = executeJsScript(DEVICE_PIXEL_RATIO);
- this.devicePixelRatio = devicePixelRatio instanceof Double? (Double)devicePixelRatio: (Long)devicePixelRatio*1.0;
+ this.devicePixelRatio = devicePixelRatio instanceof Double ? (Double) devicePixelRatio : (Long) devicePixelRatio * 1.0;
try {
CommandInfo cmd = new CommandInfo("/session/:sessionId/chromium/send_command_and_get_result", HttpMethod.POST);
@@ -186,31 +192,36 @@ public WebDriver getUnderlyingDriver() {
}
public int getCurrentScrollX() {
- return (int)(((Long) executeJsScript(Browser.CURRENT_SCROLL_X_JS))*devicePixelRatio);
+ return (int) (((Long) executeJsScript(Browser.CURRENT_SCROLL_X_JS)) * devicePixelRatio);
}
public int getCurrentScrollY() {
- return (int)(((Long) executeJsScript(Browser.CURRENT_SCROLL_Y_JS))*devicePixelRatio);
+ return (int) (((Long) executeJsScript(Browser.CURRENT_SCROLL_Y_JS)) * devicePixelRatio);
}
public int getDocWidth() {
- return docWidth != -1 ? docWidth : (int)(((Long) executeJsScript(MAX_DOC_WIDTH_JS))*devicePixelRatio);
+ if (docWidth == -1) docWidth = (int) (((Long) executeJsScript(MAX_DOC_WIDTH_JS)) * devicePixelRatio);
+ return docWidth;
}
public int getDocHeight() {
- return docHeight != -1 ? docHeight : (int)(((Long) executeJsScript(MAX_DOC_HEIGHT_JS))*devicePixelRatio);
+ if (docHeight == -1) docHeight = (int) (((Long) executeJsScript(MAX_DOC_HEIGHT_JS)) * devicePixelRatio);
+ return docHeight;
}
public int getViewportWidth() {
- return viewportWidth != -1 ? viewportWidth : (int)(((Long) executeJsScript(VIEWPORT_WIDTH_JS))*devicePixelRatio);
+ if (viewportWidth == -1) viewportWidth = (int) (((Long) executeJsScript(VIEWPORT_WIDTH_JS)) * devicePixelRatio);
+ return viewportWidth;
}
public int getViewportHeight() {
- return viewportHeight != -1 ? viewportHeight : (int)(((Long) executeJsScript(VIEWPORT_HEIGHT_JS)).intValue()*devicePixelRatio);
+ if (viewportHeight == -1)
+ viewportHeight = (int) (((Long) executeJsScript(VIEWPORT_HEIGHT_JS)) * devicePixelRatio);
+ return viewportHeight;
}
public Coordinates getBoundingClientRect(WebElement element) {
- String script = FileUtil.getJsScript(RELATIVE_COORDS_JS);
+ FileUtil.getJsScript(RELATIVE_COORDS_JS);
ArrayList list = (ArrayList) executeJsScript(RELATIVE_COORDS_JS, element);
Point start = new Point(Integer.parseInt(list.get(0)), Integer.parseInt(list.get(1)));
Dimension size = new Dimension(Integer.parseInt(list.get(2)), Integer.parseInt(list.get(3)));
@@ -222,7 +233,7 @@ public void scrollToElement(WebElement element) {
}
public void scrollTo(int x, int y) {
- executeJsScript(SCROLL_TO_JS, x/devicePixelRatio, y/devicePixelRatio);
+ executeJsScript(SCROLL_TO_JS, x / devicePixelRatio, y / devicePixelRatio);
}
public Object executeJsScript(String filePath, Object... arg) {
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Coordinates.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Coordinates.java
index 5d17f9b..1295e32 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Coordinates.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/Coordinates.java
@@ -14,10 +14,10 @@
*/
public class Coordinates {
- private int width;
- private int height;
- private int x;
- private int y;
+ private final int width;
+ private final int height;
+ private final int x;
+ private final int y;
public Coordinates(WebElement element, Double devicePixelRatio) {
Point point = element.getLocation();
diff --git a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/ElementOutsideViewportException.java b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/ElementOutsideViewportException.java
index e980f99..82b05c7 100644
--- a/src/main/java/com/assertthat/selenium_shutterbug/utils/web/ElementOutsideViewportException.java
+++ b/src/main/java/com/assertthat/selenium_shutterbug/utils/web/ElementOutsideViewportException.java
@@ -4,6 +4,7 @@
* Created by Glib_Briia on 10/07/2016.
*/
public class ElementOutsideViewportException extends RuntimeException {
+
public ElementOutsideViewportException() {
super();
}
diff --git a/src/main/resources/js/all-metrics.js b/src/main/resources/js/all-metrics.js
index f0ddafe..e9c87b4 100644
--- a/src/main/resources/js/all-metrics.js
+++ b/src/main/resources/js/all-metrics.js
@@ -1,3 +1,5 @@
-({width: Math.max(window.innerWidth,document.body.scrollWidth,document.documentElement.scrollWidth)|0,
-height: Math.max(window.innerHeight,document.body.scrollHeight,document.documentElement.scrollHeight)|0,
-deviceScaleFactor: window.devicePixelRatio || 1,mobile: typeof window.orientation !== 'undefined'})
+({
+ width: Math.max(window.innerWidth, document.body.scrollWidth, document.documentElement.scrollWidth) | 0,
+ height: Math.max(window.innerHeight, document.body.scrollHeight, document.documentElement.scrollHeight) | 0,
+ deviceScaleFactor: window.devicePixelRatio || 1, mobile: typeof window.orientation !== 'undefined'
+});
diff --git a/src/main/resources/js/relative-element-coords.js b/src/main/resources/js/relative-element-coords.js
index 42770d8..67d74f2 100644
--- a/src/main/resources/js/relative-element-coords.js
+++ b/src/main/resources/js/relative-element-coords.js
@@ -1,2 +1,2 @@
-var rect = arguments[0].getBoundingClientRect();
-return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]
\ No newline at end of file
+var rect = arguments[0].getBoundingClientRect();
+return ['' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height)];
\ No newline at end of file
diff --git a/src/test/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessorTest.java b/src/test/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessorTest.java
index 9f46121..5515f3e 100644
--- a/src/test/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessorTest.java
+++ b/src/test/java/com/assertthat/selenium_shutterbug/utils/image/ImageProcessorTest.java
@@ -19,7 +19,6 @@
import com.assertthat.selenium_shutterbug.utils.web.Coordinates;
import org.junit.Ignore;
import org.junit.Test;
-import org.openqa.selenium.*;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
@@ -28,7 +27,7 @@
import java.awt.image.BufferedImage;
import java.io.IOException;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertTrue;
/**
* Created by Glib_Briia, Inha Briia on 26/06/2016.