8

This question already has an answer here:

Webdriver does not provide direct any function to image verification, but we can verify images by taking two screenshots of the whole web page using TakeScreenshot WebDriver function, one at script creation time and another at execution time.

I have created a sample script in which first I captured a Google home page screen shot and saved (input.jpg) into my project, another screen shot (output.jpg) captured on the same page at test execution time and saved into the project. I want to compare both the images if they are not same then test script will fail.

How should I apply logic in image verification using selenium?

marked as duplicate by c32hedge, Milin Patel, alecxe Aug 25 '17 at 4:40

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • I don't understand the question. Are you asking how to compare screenshots? – user246 Apr 27 '16 at 14:22
  • 2
    I have created a sample script in which first I captured a Google home page screen shot and saved (GoogleInput.jpg) into my project, Another screen shot “GoogleOutput.jpg” captured of same page at test executing time and saved into project. I want to compare both images if they are not same then test script will fail. then how can I do this using Selnium – Bharat Mane Apr 27 '16 at 14:31
  • 1
    Selenium does not provide a way to compare images. You will need some other mechanism to do that. This does not mean you cannot use Selenium for your project; rather, it means you will need to use Selenium to capture the images and something other than Selenium to compare the images. – user246 Apr 27 '16 at 14:55
  • 2
    Be careful taking this route. There are entire companies that dedicate themselves to solving this problem for automation. One of the biggest ones that I know of is Applitools. They write quite a bit about the solutions they use without getting into their gritty implementation details. So you could likely learn a lot by exploring how they and other companies approach their solutions – Julian Dec 2 '16 at 23:59
  • 3
    They have a whole ecosystem around their product. If you do start comparing images you'll begin to realize that different browsers will render html in subtly different ways. To a human, two images will look identical, to a computer, however, text being rendered might be smoothed with a different algorithm which may result in pixels not matching. This is a common problem with image verification from screenshots. This problem can also exist within the same browser but for different versions or on different operating systems too. This is one of the problems companies have set out to solve. – Julian Dec 3 '16 at 21:42
7

Selenium is a software library to locate elements on web page and interact with them. To deal with images, you need to use different library. Selenium can provide screenshots (images) but you need to use something else to work with such images.

As a programmer, you need to master more than a single library, and learn to use right tool for the job.

4

Use Sikulix API. Sikuli is a library that will help you compare two images or recognize images when they are displayed on your screen. After the said image is displayed, you can click on the recognized image.

Download Link

Go for the download link.

  1. Download sikulix-setup-1.1.0.jar
  2. Run the jar file.
  3. Choose below option / or go for whichever option is best suited for you.

enter image description here

  1. Click on Setup Now
  2. Let the setup complete and you will find a file named - sikulixapi.jar. This jar has to be included in your classpath.

Sample Code:

Screen screen = new Screen();
//set a timeout for waiting for the image
screen.setAutoWaitTimeout(30000); //default is 10 seconds
//wait for an image to get displayed on the screen and then click on it
screen.wait(new Pattern("img/image.PNG")).click();
//wait for an image with exact match
screen.wait(new Pattern("img/image.PNG").exact()).click();
  • Is match based on image file name or based on image content? – dzieciou Apr 28 '16 at 4:48
  • Its based on image content. Sikuli calculates the match ratio, so if the match crosses a threshold (say 0.7), then its a match. If we want an exact match, then we have to specify so. – LittlePanda Apr 28 '16 at 4:50
2

You can calculate hash of images and then compare the hashes for equality. SO has a question on calculating hash

2

One option for verifying images is to use Applitools + Selenium. It seems to be gaining in popularity among the Selenium crowd as it's not just able to do image comparison but also do layout comparisons. I haven't used it myself but it's on my TODO list.

From the looks of it, they have a decent tutorial where you can choose your environment (Selenium) and language and it will show you how to install the dependencies and give you some sample code to run a test.

I've seen it pop up quite a bit in collaboration with Sauce Labs, here's a blog post with some Java example code.

2

One non-selenium tool we use (we use the paid version) is GhostInspector which has several options for screenshots including comparing by % difference and by css selectors to target areas.

enter image description here

2

If you use Selenium/Webdriver with Javascript, there are some libraries to compare screenshots:

  1. Resemble.JS => Compare two images and find the difference. Resemble.js can be used for any image analysis and comparison requirement you might have in the browser.

  2. TemplateMatching.JS => Image search: Find another image (e. g. a button) inside a bigger image (e. g. a screenshot)

  • Thanks @timfredo, This one is the good example of image verification. Do you have an example/code for the same - How this can be used with Selenium? – Bharat Mane Jan 6 '17 at 9:51
  • To use the Javascript libraries you need to control Selenium via Javascript/Node.JS and/or use it with PhantomJS. Unfortunately that is pretty tricky to set up. Alternatively maybe Kantu, a screenshot-based web testing tool, can be an option. – timfredo Jan 6 '17 at 9:59
1

Check this code might work

import java.awt.image.BufferedImage;
 import java.awt.image.DataBuffer;
 import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 import javax.imageio.ImageIO;
 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.testng.Assert;
 import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.Test;

 public class ImageComparison {

      public WebDriver driver;
      private String baseUrl;

      @BeforeSuite
      public void setUp() throws Exception {
         driver = new FirefoxDriver();
         baseUrl = "https://www.google.co.in/";
         driver.navigate().to(baseUrl);
         driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);      
      }

      @AfterSuite
      public void tearDown() throws Exception {
         driver.quit();    
      }

      @Test
      public void testImageComparison() throws IOException, InterruptedException {         
         File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
         Thread.sleep(3000);
         FileUtils.copyFile(screenshot, new File("GoogleOutput.jpg"));

         File fileInput = new File("GoogleInput.jpg");
         File fileOutPut = new File("GoogleOutput.jpg");

         BufferedImage bufferfileInput = ImageIO.read(fileInput);
         DataBuffer bufferfileInput = bufferfileInput.getData().getDataBuffer();
         int sizefileInput = bufferfileInput.getSize();                     
         BufferedImage bufferfileOutPut = ImageIO.read(fileOutPut);
         DataBuffer datafileOutPut = bufferfileOutPut.getData().getDataBuffer();
         int sizefileOutPut = datafileOutPut.getSize();
         Boolean matchFlag = true;
         if(sizefileInput == sizefileOutPut) {                         
            for(int i=0; i<sizefileInput; i++) {
                  if(bufferfileInput.getElem(i) != datafileOutPut.getElem(i)) {
                        matchFlag = false;
                        break;
                  }
             }
         }
         else {                           
            matchFlag = false;
         Assert.assertTrue(matchFlag, "Images are not same");    
      }
 }
  • Please format your code. – user246 Apr 27 '16 at 14:58
  • 2
    @amit Can you explain why this method is used - BufferedImage bufferfileInput = ImageIO.read(fileInput); DataBuffer bufferfileInput = bufferfileInput.getData().getDataBuffer(); Why are you using 'BufferedImage' in your script?? – Bharat Mane Apr 28 '16 at 9:41
  • I have always used BufferedImages to store and manipulate the images in memory. For images comparison in Java I always use this. – amitsahu86 Dec 10 '18 at 10:30
1

You cannot do that with just Selenium, as @Peter-Masiar mentioned, but you can look at the Structural Similarity method. Additional link. My company has been using this method quite a lot for testing.

0

Combine the Selenium screenshots with the ImageMagick library or write your own image-compare functions. ImageMagick works from most programming-languages, but you can always just run it from the command line and parse the output.

Not the answer you're looking for? Browse other questions tagged or ask your own question.