javaseleniumashotvisual-testing

Ashot screenshot does not correctly crop the element from screenshot


I am trying to open this url and take the screenshot of the Keep browsing button which looks like the below image using Ashot library.

enter image description here

Here is my dependencies on pom.xml:

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>

    <dependency>
      <groupId>ru.yandex.qatools.ashot</groupId>
      <artifactId>ashot</artifactId>
      <version>1.5.4</version>
    </dependency>
  </dependencies>

And here is my code:

public class Main {

  public static void main(String[] args) throws InterruptedException, IOException {
    System.setProperty("webdriver.chrome.driver", "C:\\selenium-driver\\chromedriver.exe");
    WebDriver driver = new ChromeDriver();
    String baseUrl = "https://www.immoweb.be/en/search/house/for-sale?countries=BE&page=1&orderBy=relevance";
    driver.get(baseUrl);
    Thread.sleep(3000);


    WebElement element = driver.findElement(By.xpath("//*[@id='uc-btn-accept-banner']"));
    Screenshot screenshot = new AShot().coordsProvider(new WebDriverCoordsProvider())
        .takeScreenshot(driver, element);

    File actualFile = new File("C:\\baseImage\\dashboardActual.png");
    ImageIO.write(screenshot.getImage(), "png", actualFile);

    driver.close();

 
  }
}

But when i executes the code, the taken screenshot not correct.

Here is my screenshot:

enter image description here

Update: After reading this question, i added the shootingStartegy which also was not helpful:

Screenshot screenshot =
    new AShot()
        .shootingStrategy(ShootingStrategies.viewportPasting(100))
        .coordsProvider(new WebDriverCoordsProvider())
        .takeScreenshot(driver, element);

Solution

  • I think, AShot library doesn't have enough documentation. However, you do not need AShot to take screenshot of an element but you need it for making a comparision between two different images. Here is my suggested solution:

      public static String URL = "https://www.immoweb.be/en/search/house/for-sale?countries=BE&page=1&orderBy=relevance";
      // Notice that the ELEMENT_ID  might change as the website is dynamic
      public static String ELEMENT_ID = "//article[@id='classified_9408324']";
      public static String BUTTON_ID =  "//*[@id='uc-btn-accept-banner']";
      public static int DELAY_IN_MILLI_SECONDS = 5000;
    
        System.setProperty("webdriver.chrome.driver", "C:\\selenium-driver\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        
        driver.manage().window().maximize();
        
        driver.get(URL);
        Thread.sleep(DELAY_IN_MILLI_SECONDS);
        
        driver.findElement(By.xpath(BUTTON_ID)).click();
        
        WebElement element = driver.findElement(By.xpath(ELEMENT_ID));
        
        File actualFile = element.getScreenshotAs(OutputType.FILE);
        BufferedImage  actualImage = ImageIO.read(actualFile);
        FileUtils.copyFile(actualFile, new File("C:\\baseImage\\dashboardActual.png"));
        
        File expectedFile = new File("C:\\baseImage\\6.png");
        BufferedImage  expectedImage = ImageIO.read(expectedFile);
        
        // Compare two images for visual testing
        ImageDiff diff = new ImageDiffer().makeDiff(actualImage, expectedImage);
        BufferedImage diffImage = diff.getMarkedImage();
        
        File diffFile = new File("C:\\baseImage\\Diff.png");
        ImageIO.write(diffImage, "jpg", diffFile);
        
        Assert.assertFalse("Images are not equal",diff.hasDiff());
        
        driver.close();
    

    So, to make it short, the following line, which works by Selenium, can take the screenshot of element and you can use it as the Base-Image for your visual testing:

    WebElement element = driver.findElement(By.xpath(ELEMENT_ID));
    
    File actualFile = element.getScreenshotAs(OutputType.FILE);
    BufferedImage  actualImage = ImageIO.read(actualFile);
    FileUtils.copyFile(actualFile, new File("C:\\baseImage\\dashboardActual.png"));
    

    And here is the image:

    enter image description here