UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

129 lines 5.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getScreenshot = getScreenshot; exports.getElementScreenshot = getElementScreenshot; exports.getViewportScreenshot = getViewportScreenshot; const asyncbox_1 = require("asyncbox"); const lodash_1 = __importDefault(require("lodash")); const driver_1 = require("appium/driver"); const support_1 = require("appium/support"); /** * Takes a screenshot of the current screen. * * @returns Base64-encoded screenshot data */ async function getScreenshot() { if (this.isWebContext()) { const webScreenshotMode = (await this.settings.getSettings()).webScreenshotMode; switch (lodash_1.default.toLower(webScreenshotMode)) { case 'page': case 'viewport': return await this.remote.captureScreenshot({ coordinateSystem: lodash_1.default.capitalize(webScreenshotMode), }); case 'native': case undefined: case null: break; default: this.log.warn(`The webScreenshotMode setting value '${webScreenshotMode}' is not known. ` + `Supported values are: page, viewport and native. Falling back to the native mode.`); break; } } const getScreenshotFromWDA = async () => { this.log.debug(`Taking screenshot with WDA`); const data = await this.proxyCommand('/screenshot', 'GET'); if (!lodash_1.default.isString(data)) { throw new Error(`Unable to take screenshot. WDA returned '${JSON.stringify(data)}'`); } return data; }; // if we've specified an mjpeg server, use that if (this.mjpegStream) { this.log.info(`mjpeg video stream provided, returning latest frame as screenshot`); const data = await this.mjpegStream.lastChunkPNGBase64(); if (data) { return data; } this.log.warn('Tried to get screenshot from active MJPEG stream, but there ' + 'was no data yet. Falling back to regular screenshot methods.'); } try { return await getScreenshotFromWDA(); } catch (err) { this.log.warn(`Error getting screenshot: ${err.message}`); } // simulator attempt if (this.isSimulator()) { this.log.info(`Falling back to 'simctl io screenshot' API`); const payload = await this.device.simctl.getScreenshot(); if (!payload) { throw new driver_1.errors.UnableToCaptureScreen(); } return payload; } // Retry for real devices only. Fail fast on Simulator if simctl does not work as expected return await (0, asyncbox_1.retryInterval)(2, 1000, getScreenshotFromWDA); } /** * Takes a screenshot of a specific element. * * @param el - Element to capture * @returns Base64-encoded screenshot data */ async function getElementScreenshot(el) { el = support_1.util.unwrapElement(el); if (this.isWebContext()) { const atomsElement = this.getAtomsElement(el); const { width, height } = await this.executeAtom('get_size', [atomsElement]); if (!width || !height) { throw new driver_1.errors.UnableToCaptureScreen('Cannot take a screenshot of a zero-size element'); } const { x, y } = await this.executeAtom('get_top_left_coordinates', [atomsElement]); return await this.remote.captureScreenshot({ rect: { x, y, width, height } }); } const data = await this.proxyCommand(`/element/${el}/screenshot`, 'GET'); if (!lodash_1.default.isString(data)) { throw new driver_1.errors.UnableToCaptureScreen(`Unable to take an element screenshot. WDA returned: ${JSON.stringify(data)}`); } return data; } /** * Takes a screenshot of the current viewport. * * @returns Base64-encoded screenshot data */ async function getViewportScreenshot() { if (this.isWebContext()) { return await this.remote.captureScreenshot(); } const screenshot = await this.getScreenshot(); // if we don't have a status bar, there's nothing to crop, so we can avoid // extra calls and return straight away if ((await this.getStatusBarHeight()) === 0) { return screenshot; } const sharp = support_1.imageUtil.requireSharp(); const { width, height } = await sharp(Buffer.from(screenshot, 'base64')).metadata(); if (!width || !height) { throw new driver_1.errors.UnableToCaptureScreen('The device screenshot is empty'); } this.log.debug(`Screenshot dimensions: ${width}x${height}`); const region = await this.getViewportRect(); if (region.width + region.left > width) { this.log.info('Viewport region exceeds screenshot width, adjusting region to fit'); region.width = width - region.left; } if (region.height + region.top > height) { this.log.info('Viewport region exceeds screenshot height, adjusting region to fit'); region.height = height - region.top; } this.log.debug(`Calculated viewport rect: ${JSON.stringify(region)}`); return await support_1.imageUtil.cropBase64Image(screenshot, region); } //# sourceMappingURL=screenshots.js.map