-1

i'm trying to take a screenshot for any specific element on the safari browser - by appium+webdriverio+browserStack.

appium version : 1.15.0

here are the error logs :

Calling AppiumDriver.getElementScreenshot() with args: ["5028","e154c6f0-73b9-4306-b661-d3206aa7ba8e"] [debug] [XCUITest] Executing command 'getElementScreenshot' [debug] [RemoteDebugger] Executing atom 'getElementScreenshot' [debug] [MJSONWP (e154c6f0)] Encountered internal error running command: Error: Unable to load Atom 'getElementScreenshot' from file '/usr/local/.browserstack/appium_1.14.0_bstack/node_modules/appium-remote-debugger/atoms/getElementScreenshot.js' [debug] [MJSONWP (e154c6f0)] at getAtoms (/usr/local/.browserstack/appium_1.14.0_bstack/node_modules/appium-remote-debugger/lib/atoms.js:17:13) 2019-11-21 06:44:37:879 - [HTTP] <-- GET

Please help, is there anything I'm doing wrong? Please suggest as i want to take a screenshot of specific webElement by appium on safari browser

josh
  • 49
  • 8

1 Answers1

0

Afaik there is currently no way of taking a screenshot of a specific web element (via web selectors) with only webdriverio and appium. While webdriverio provides an element.saveScreenshot function, it does not seem to work on mobile with appium.

The way that I work around it is to take a screenshot of the whole page with browser.saveScreenshot(filepath) (make sure to switch to native context for this) and then crop it to the elements rect with an image library (sharp, in my case).

My util functions look like this:

import fs from 'fs';
import path from 'path';
import sharp from 'sharp';

export function takeScreenshot(element) {
  const timestamp = moment().format('YYYYMMDD-HHmmss.SSS');
  if (fs.existsSync('reports/screenshots/')) {
    const filePath = path.join('reports/screenshots/', timestamp + '.png');
    WebView.switchToContext(CONTEXT_REF.NATIVE);
    browser.saveScreenshot(filePath);
    WebView.switchToContext(CONTEXT_REF.WEBVIEW);

    if (element) {
      const size = getRealSize(element);
      const location = getRealLocation(element);
      const outputPath = path.join('reports/screenshots/', element.selector + timestamp + '.png');
      sharp(filePath).extract({ width: size.width, height: size.height, left: location.x, top: location.y }).toFile(outputPath)
        .then(function () {
          fs.unlinkSync(filePath);
          fs.renameSync(outputPath, filePath);
        })
        .catch(function (err) {
          console.log(err);
        });
    }
  }
}

export function getPixelRatio() {
  return browser.capabilities.pixelRatio ? browser.capabilities.pixelRatio : 1;
}

export function getRealLocation(element) {
  const location = element.getLocation();
  return {
    x: Math.round(location.x * getPixelRatio()),
    y: Math.round(location.y * getPixelRatio())
  }
}

export function getRealSize(element) {
  const size = element.getSize();
  return {
    width: Math.round(size.width * getPixelRatio()),
    height: Math.round(size.height * getPixelRatio())
  }
}

Justin H.
  • 103
  • 1
  • 8