To verify that a web application really does what it is supposed to do, sometimes it is not enough to use the built in functions of Selenium. In some cases you don’t just want to know whether Text “xyz” exists or HTML-element-abc is present. You really want to know whether your website looks like you want it to. In most cases you don’t care if there are a few pixels that differ, so you don’t want an exact screenshot comparison but a fuzzy screenshot comparison.
The Selenium WebDriver offers a built in function to take screenshots. This example is from stackoverflow:
WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com/"); File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); // Now you can do whatever you need to do with it, for example copy somewhere FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
What Selenium doesn’t offer out of the box is a function to compare two screenshots in order to know whether something has changed or not. We wrote our own Java-Library to do this fuzzy screenshot comparison for us. We do not provide any support for this library, but feel free to download and use it as it is:
Download:
image-comparison-1.0.jar | 2015-06-23 |
Basic usage example:
import java.io.IOException; import org.frontendtest.components.ImageComparison; public class RunComparison { public static void main(String[] args) throws IOException { String imgOriginal = "original.jpg"; String imgToCompareWithOriginal = "new_screenshot.jpg"; String imgOutputDifferences = "new_screenshot_with_changes.jpg"; ImageComparison imageComparison = new ImageComparison(10,10,0.05); if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences)) System.out.println("Images are fuzzy-equal."); else System.out.println("Images are not fuzzy-equal."); } }What it does (simplified):
- 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!
Here are some examples of the comparison results:
We will compare these two images:
Here are the results:
E.g. comparing these images with square-size 30x30pix and a threshold of 5% (0.05) will tell you that the images are fuzzy-equal!
License:
The MIT License (MIT)
Copyright © 2015 Nils Schütte
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This library makes use of the Thumbnailator which is already included and also published under the MIT License.
the same steps i have followed and it is throwing exception as below,
Exception in thread “main” java.lang.NoClassDefFoundError: net/coobird/thumbnailator/Thumbnails
at org.frontendtest.components.ImageComparison.adaptImageSize(ImageComparison.java:105)
at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:36)
at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
at efWebDriver.ImageComparisionTest.main(ImageComparisionTest.java:38)
Caused by: java.lang.ClassNotFoundException: net.coobird.thumbnailator.Thumbnails
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 4 more
Hi Arjun, if you post your code or send a message with your code, I will have a look at it.
String imgOriginal = “expected.png”;
String imgToCompareWithOriginal = “Actual.png”;
String imgOutputDifferences = “diffImage.png”;
ImageComparison imageComparison = new ImageComparison(10,10,0.05);
if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences))
System.out.println(“Images are fuzzy-equal.”);
else
System.out.println(“Images are not fuzzy-equal.”);
I also got the same exception, please look in my code once, I will be very thankful.
package Day1;
import java.io.IOException;
import org.frontendtest.components.ImageComparison;
public class RunComparison {
public static void main(String[] args) throws IOException {
String imgOriginal = “D:\\JAVA\\Programs\\Helios\\src\\Image1.jpg”;
String imgToCompareWithOriginal = “D:\\JAVA\\Programs\\Helios\\src\\Image2.jpg”;
String imgOutputDifferences = “D:\\JAVA\\Programs\\Helios\\src\\new_screenshot_with_changes.jpg”;
ImageComparison imageComparison = new ImageComparison(10,10,0.05);
if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences))
System.out.println(“Images are fuzzy-equal.”);
else
System.out.println(“Images are not fuzzy-equal.”);
}
}
Even I’m getting same Error. Please solve this
i get the same error. Below is my code;
package rs.indoo.selenium.imagecomparison;
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 org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.frontendtest.components.ImageComparison;
public class Inspector {
public static void main(String[] args) throws IOException {
compareImages();
}
private static void compareImages() throws IOException {
String imgOriginal = “/home/barbaros/Desktop/original-300×170.jpg”;
String imgToCompareWithOriginal = “/home/barbaros/Desktop/new_screenshot-300×170.jpg”;
String imgOutputDifferences = “/home/barbaros/Desktop/original_diff.png”;
ImageComparison imageComparison = new ImageComparison(10, 10, 0.05);
if (imageComparison.fuzzyEqual(imgOriginal, imgToCompareWithOriginal,
imgOutputDifferences))
System.out.println(“Images are fuzzy-equal.”);
else
System.out.println(“Images are not fuzzy-equal.”);
}
}
me again, ok solved that problem. apparently you need to import the Thumbnailator library even through you claim it is included in image-comparison-1.0.jar. maybe not referenced correctly? anyways thanks for the great work.
Thanks for posting your work-around for this issue. I will look into it and post a solution as soon as I solved the bug.
Awesome, even i solved the problem , by downloading the Thumnailator jar and importing it.
Thanks for sharing ,,. it solved a heap of problems off my head
Can you please post your code here
link for the jar to be downloaded:
http://www.java2s.com/Code/Jar/t/Downloadthumbnailator042alljar.htm
import command:
import net.coobird.*;
Thanks nikhil kanojia. I have downloaded thumbnailator-0.4.4.jar from http://www.java2s.com/Code/Jar/t/Downloadthumbnailator044jar.htm
Excellent post …Really thanks.
great….
I got the same exception:Exception in thread “main” java.lang.NoClassDefFoundError: net/coobird/thumbnailator/Thumbnails
at org.frontendtest.components.ImageComparison.adaptImageSize(ImageComparison.java:105)
at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:36)
at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
at image_comparison.RunComparison.main(RunComparison.java:15)
Caused by: java.lang.ClassNotFoundException: net.coobird.thumbnailator.Thumbnails
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 4 more
The above exception mentioned by me is solved by using “thumbnailator-0.4.4.jar” in class path. The download URL is http://www.java2s.com/Code/Jar/t/Downloadthumbnailator044jar.htm
I’ve checked in your project at GitHub, added Maven and fixed some small issues with it: https://github.com/tholewebgods/image-comparison I could transfer the project to you (and then clone it) if you wish.
Hi ive tried using the class but getting javax.imageio.IIOException: Can’t read input file! when comparing.
Any idea why? 🙁
Fixed that, my path wasnt correct however now it just hangs when comparing images
Thank you very much.
Getting following exception:
ArrayIndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
at test.testcomponent.TestComponent.compareMediaFile(TestComponent.java:300)
at test.testcomponent.TestComponent.compareMediaFile(TestComponent.java:323)
at test.testcomponent.TestComponent.fetchMediaFile(TestComponent.java:468)
at test.testcomponent.CameraFrontTest.getTestResult(CameraFrontTest.java:85)
at result.automatic.AutomaticTester.executeFrontCamera(AutomaticTester.java:1258)
at result.automatic.AutomaticTester.runAutomaticTests(AutomaticTester.java:458)
at result.automatic.AutomaticTester.run(AutomaticTester.java:1460)
Hi I wanted to know if we wish to use this tool to compare specific parts of a screen shot how can we do it?.. (As in I want the Fre comparison on 2 images on certain parts of the image and not the complete image?)
Where can i get the Maven dependency for this?
Great work!