Friday 6 September 2019

Selenium: Capture DOM Elements Image

I have an API to capture the image of a particular element in DOM and return them. For that, I have a list of WebElements which needs to be captured into a single webpage. For that same, I have found the solution here which works fine if an element is visible on the screen (no need to scroll down to see it).

driver.get(urltoconnect);
WebElement ele = getElement();

// Get entire page screenshot
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage  fullImg = ImageIO.read(screenshot);

// Get the location of element on the page
Point point = ele.getLocation();

// Get width and height of the element
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();

// Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(), eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);

// Copy the element screenshot to disk
File screenshotLocation = new File("C:\\images\\GoogleLogo_screenshot.png");
FileUtils.copyFile(screenshot, screenshotLocation);

But the cases where I need to scroll down to see element results in java.awt.image.RasterFormatException: (y + height) is outside of Raster. So I have added this.

What I have tried

//All Results in java.awt.image.RasterFormatException: (y + height) is outside of Raster

//scroll the page until the mentioned element is visible on the current page.
js.executeScript("arguments[0].scrollIntoView();",element); 

//This will scroll down the page by 450 pixel vertical      
js.executeScript("window.scrollBy(0,450)");

//AShot
Screenshot fpScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(400)).takeScreenshot(driver);
ImageIO.write(fpScreenshot.getImage(),"png",new File("image.png"));


Question is how can I capture the Image of particular elements where some elements need to be scrolled. Please note that I have multiple elements with there By.id, By.name, By.xpath for multiple sources so I can't set fullImg.getSubimage(x,y,w,h) by y+100 or something as this might work for one webpage but not for others. Any Help will be appreciated.

System.setProperty("webdriver.chrome.driver", "F:\\chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://www.testing-whiz.com/demoscripts/basic-element.html");
WebElement ele = getElement();

// Get entire page screenshot
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage  fullImg = ImageIO.read(screenshot);

// Get the location of element on the page
Point point = ele.getLocation();

// Get width and height of the element
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();

// Crop the entire page screenshot to get only element screenshot
try {
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(), eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);
}catch (Exception e) {
    js.executeScript("window.scrollBy(0,450)");
    //point.getY() = 732            //From console y = 492.8000183105469 after scroll https://stackoverflow.com/a/38767558/10961238
    //raster.getHeight() = 613
    BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(), eleWidth, eleHeight);
    ImageIO.write(eleScreenshot, "png", screenshot);
}

// Copy the element screenshot to disk
File screenshotLocation = new File("F:\\Images\\1.png");
FileUtils.copyFile(screenshot, screenshotLocation);

  • Backend: Spring Boot (Java 11)
  • Frontend: Angular


from Selenium: Capture DOM Elements Image

No comments:

Post a Comment