0

Example screenshot of not centered hackernews header: attempt to take a screenshot of hackernews headerI am trying to take a screenshot of a DOM element with Selenium (nodejs). I know this is not supported in Selenium, so my approach has been to take a fullscreen screenshot and then crop the image with the elements dimensions.

My issue is that the x and y location returned by element.getRect() are not lining up with the cropping of the image. I have also tried executing js (element.getClientBoundingRect()) in the browser.

I have tried using easyimage or sharp to crop the images but something about my dimensions are wrong. I have also tried resizing the image to the viewport width and height with no luck. Any help would be appreciated.

There are multiple similar questions on stack overflow, but no working approaches / solutions for a node environment.

const easyimg = require('easyimage')
const webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    until = webdriver.until;

const driver = new webdriver.Builder()
    .forBrowser('firefox')
    .build();

webdriver.WebDriver.prototype.saveScreenshot = async function (path, elem) {
    const data = elem ? await elem.takeScreenshot() : await driver.takeScreenshot()
    const base64Data = data.replace(/^data:image\/png;base64,/, "")
    const error = fs.writeFileSync(`${path}.png`, base64Data, 'base64')
    if (error) {
        console.error(error)
    }
}

(async () => {

await driver.get(url)
await driver.saveScreenshot('./images')

const cropInFile = async function (size, location, srcFile) {
    await easyimg.crop({
        src: srcFile,
        dst: srcFile,
        cropwidth: size.width,
        cropheight: size.height,
        x: location.x,
        y: location.y,
        gravity: 'NorthWest'
    }
};

 const { height, width, x, y } = await driver.executeScript(`return document.querySelector('${selector}').getBoundingClientRect()`)
 const size = {height, width}
 const location = {x, y}
 await cropInFile(size, location, `./images/name.png`)
})()
Alec Davidson
  • 175
  • 1
  • 3
  • 12
  • Javascript is supported in Selenium through the browser. Headless or otherwise – Paula Livingstone May 22 '19 at 20:03
  • @PaulaLivingstone, not relevant to my question. I specified that taking a screenshot of an element with selenium is not supported like it may be with other browser automation frameworks like puppeteer. – Alec Davidson May 22 '19 at 20:08
  • Possible duplicate of [How to capture the screenshot of a specific element rather than entire page using Selenium Webdriver?](https://stackoverflow.com/questions/13832322/how-to-capture-the-screenshot-of-a-specific-element-rather-than-entire-page-usin) – JeffC May 22 '19 at 21:37
  • 1
    why don't you just call WebElement's takeScreenshot() method? – Corey Goldberg May 22 '19 at 22:36
  • @CoreyGoldberg, not supported in most browsers / drivers and falling back to the fullscreen is not an option in this case. – Alec Davidson May 23 '19 at 00:14
  • @JeffC, none of those solutions worked for me. – Alec Davidson May 23 '19 at 13:45
  • element screenshots are in the webdriver spec and I thought most browsers/drivers were now spec compliant. – Corey Goldberg May 23 '19 at 13:46
  • You are asking us to guess on how to fix your code without actually seeing it. Post an [mcve]... the code you are using and the actual site (or at least a sample site) so we can see the results and how they aren't working. – JeffC May 23 '19 at 14:02
  • @JeffC updated with example code – Alec Davidson May 23 '19 at 14:19

0 Answers0