How to use this.getScreenshotDataWithAdbShell method in Appium Android Driver

Best JavaScript code snippet using appium-android-driver

Run Appium Android Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

actions.js

Source: actions.js Github

copy
1import androidHelpers from '../android-helpers';
2import { fs, util, tempDir} from 'appium-support';
3import path from 'path';
4import log from '../logger';
5import B from 'bluebird';
6import jimp from 'jimp';
7import { exec } from 'teen_process';
8
9const swipeStepsPerSec = 28;
10const dragStepsPerSec = 40;
11
12let commands = {}, helpers = {}, extensions = {};
13
14commands.keyevent = async function keyevent (keycode, metastate = null) {
15  // TODO deprecate keyevent; currently wd only implements keyevent
16  log.warn('keyevent will be deprecated use pressKeyCode');
17  return await this.pressKeyCode(keycode, metastate);
18};
19
20commands.pressKeyCode = async function pressKeyCode (keycode, metastate = null) {
21  return await this.bootstrap.sendAction('pressKeyCode', {keycode, metastate});
22};
23
24commands.longPressKeyCode = async function longPressKeyCode (keycode, metastate = null) {
25  return await this.bootstrap.sendAction('longPressKeyCode', {keycode, metastate});
26};
27
28commands.getOrientation = async function getOrientation () {
29  let params = {
30    naturalOrientation: !!this.opts.androidNaturalOrientation,
31  };
32  let orientation = await this.bootstrap.sendAction('orientation', params);
33  return orientation.toUpperCase();
34};
35
36commands.setOrientation = async function setOrientation (orientation) {
37  orientation = orientation.toUpperCase();
38  let params = {
39    orientation,
40    naturalOrientation: !!this.opts.androidNaturalOrientation,
41  };
42  return await this.bootstrap.sendAction('orientation', params);
43};
44
45commands.fakeFlick = async function fakeFlick (xSpeed, ySpeed) {
46  return await this.bootstrap.sendAction('flick', {xSpeed, ySpeed});
47};
48
49commands.fakeFlickElement = async function fakeFlickElement (elementId, xoffset, yoffset, speed) {
50  let params = {xoffset, yoffset, speed, elementId};
51  return await this.bootstrap.sendAction('element:flick', params);
52};
53
54commands.swipe = async function swipe (startX, startY, endX, endY, duration, touchCount, elId) {
55  if (startX === 'null') {
56    startX = 0.5;
57  }
58  if (startY === 'null') {
59    startY = 0.5;
60  }
61  let swipeOpts = {startX, startY, endX, endY,
62                   steps: Math.round(duration * swipeStepsPerSec)};
63  // going the long way and checking for undefined and null since
64  // we can't be assured `elId` is a string and not an int
65  if (util.hasValue(elId)) {
66    swipeOpts.elementId = elId;
67  }
68  return await this.doSwipe(swipeOpts);
69};
70
71commands.doSwipe = async function doSwipe (swipeOpts) {
72  if (util.hasValue(swipeOpts.elementId)) {
73    return await this.bootstrap.sendAction('element:swipe', swipeOpts);
74  } else {
75    return await this.bootstrap.sendAction('swipe', swipeOpts);
76  }
77};
78
79commands.pinchClose = async function pinchClose (startX, startY, endX, endY, duration, percent, steps, elId) {
80  let pinchOpts = {
81    direction: 'in',
82    elementId: elId,
83    percent,
84    steps
85  };
86  return await this.bootstrap.sendAction('element:pinch', pinchOpts);
87};
88
89commands.pinchOpen = async function pinchOpen (startX, startY, endX, endY, duration, percent, steps, elId) {
90  let pinchOpts = {direction: 'out', elementId: elId, percent, steps};
91  return await this.bootstrap.sendAction('element:pinch', pinchOpts);
92};
93
94commands.flick = async function flick (element, xSpeed, ySpeed, xOffset, yOffset, speed) {
95  if (element) {
96    await this.fakeFlickElement(element, xOffset, yOffset, speed);
97  } else {
98    await this.fakeFlick(xSpeed, ySpeed);
99  }
100};
101
102commands.drag = async function drag (startX, startY, endX, endY, duration, touchCount, elementId, destElId) {
103  let dragOpts = {
104    elementId, destElId, startX, startY, endX, endY,
105    steps: Math.round(duration * dragStepsPerSec)
106  };
107  return await this.doDrag(dragOpts);
108
109};
110
111commands.doDrag = async function doDrag (dragOpts) {
112  if (util.hasValue(dragOpts.elementId)) {
113    return await this.bootstrap.sendAction('element:drag', dragOpts);
114  } else {
115    return await this.bootstrap.sendAction('drag', dragOpts);
116  }
117};
118
119commands.lock = async function lock (seconds) {
120  await this.adb.lock();
121  if (isNaN(seconds)) {
122    return;
123  }
124
125  const floatSeconds = parseFloat(seconds);
126  if (floatSeconds <= 0) {
127    return;
128  }
129  await B.delay(1000 * floatSeconds);
130  await this.unlock();
131};
132
133commands.isLocked = async function isLocked () {
134  return await this.adb.isScreenLocked();
135};
136
137commands.unlock = async function unlock () {
138  return await androidHelpers.unlock(this, this.adb, this.caps);
139};
140
141commands.openNotifications = async function openNotifications () {
142  return await this.bootstrap.sendAction('openNotification');
143};
144
145commands.setLocation = async function setLocation (latitude, longitude) {
146  return await this.adb.sendTelnetCommand(`geo fix ${longitude} ${latitude}`);
147};
148
149commands.fingerprint = async function fingerprint (fingerprintId) {
150  if (!this.isEmulator()) {
151    log.errorAndThrow('fingerprint method is only available for emulators');
152  }
153  await this.adb.fingerprint(fingerprintId);
154};
155
156commands.sendSMS = async function sendSMS (phoneNumber, message) {
157  if (!this.isEmulator()) {
158    log.errorAndThrow('sendSMS method is only available for emulators');
159  }
160  await this.adb.sendSMS(phoneNumber, message);
161};
162
163commands.gsmCall = async function gsmCall (phoneNumber, action) {
164  if (!this.isEmulator()) {
165    log.errorAndThrow('gsmCall method is only available for emulators');
166  }
167  await this.adb.gsmCall(phoneNumber, action);
168};
169
170commands.gsmSignal = async function gsmSignal (signalStrengh) {
171  if (!this.isEmulator()) {
172    log.errorAndThrow('gsmSignal method is only available for emulators');
173  }
174  await this.adb.gsmSignal(signalStrengh);
175};
176
177commands.gsmVoice = async function gsmVoice (state) {
178  if (!this.isEmulator()) {
179    log.errorAndThrow('gsmVoice method is only available for emulators');
180  }
181  await this.adb.gsmVoice(state);
182};
183
184commands.powerAC = async function powerAC (state) {
185  if (!this.isEmulator()) {
186    log.errorAndThrow('powerAC method is only available for emulators');
187  }
188  await this.adb.powerAC(state);
189};
190
191commands.powerCapacity = async function powerCapacity (batteryPercent) {
192  if (!this.isEmulator()) {
193    log.errorAndThrow('powerCapacity method is only available for emulators');
194  }
195  await this.adb.powerCapacity(batteryPercent);
196};
197
198commands.networkSpeed = async function networkSpeed (networkSpeed) {
199  if (!this.isEmulator()) {
200    log.errorAndThrow('networkSpeed method is only available for emulators');
201  }
202  await this.adb.networkSpeed(networkSpeed);
203};
204
205/**
206 * Emulate sensors values on the connected emulator.
207 *
208 * @typedef {Object} Sensor
209 * @property {string} sensorType - sensor type declared in adb.SENSORS
210 * @property {string} value - value to set to the sensor
211 *
212 * @param {Object} Sensor
213 * @throws {Error} - If sensorType is not defined
214 * @throws {Error} - If value for the se sor is not defined
215 * @throws {Error} - If deviceType is not an emulator
216 */
217commands.sensorSet = async function sensorSet (sensor = {}) {
218  const {sensorType, value} = sensor;
219  if (!util.hasValue(sensorType)) {
220    log.errorAndThrow(`'sensorType' argument is required`);
221  }
222  if (!util.hasValue(value)) {
223    log.errorAndThrow(`'value' argument is required`);
224  }
225  if (!this.isEmulator()) {
226    log.errorAndThrow('sensorSet method is only available for emulators');
227  }
228  await this.adb.sensorSet(sensorType, value);
229};
230
231helpers.getScreenshotDataWithAdbShell = async function getScreenshotDataWithAdbShell (adb, opts) {
232  const localFile = await tempDir.path({prefix: 'appium', suffix: '.png'});
233  if (await fs.exists(localFile)) {
234    await fs.unlink(localFile);
235  }
236  try {
237    const pngDir = opts.androidScreenshotPath || '/data/local/tmp/';
238    const png = path.posix.resolve(pngDir, 'screenshot.png');
239    const cmd = ['/system/bin/rm', `${png};`, '/system/bin/screencap', '-p', png];
240    await adb.shell(cmd);
241    if (!await adb.fileSize(png)) {
242      throw new Error('The size of the taken screenshot equals to zero.');
243    }
244    await adb.pull(png, localFile);
245    return await jimp.read(localFile);
246  } finally {
247    if (await fs.exists(localFile)) {
248      await fs.unlink(localFile);
249    }
250  }
251};
252
253helpers.getScreenshotDataWithAdbExecOut = async function getScreenshotDataWithAdbExecOut (adb) {
254  let {stdout, stderr, code} = await exec(adb.executable.path,
255                                    adb.executable.defaultArgs
256                                      .concat(['exec-out', '/system/bin/screencap', '-p']),
257                                    {encoding: 'binary', isBuffer: true});
258  // if there is an error, throw
259  if (code || stderr.length) {
260    throw new Error(`Screenshot returned error, code: '${code}', stderr: '${stderr.toString()}'`);
261  }
262  // if we don't get anything at all, throw
263  if (!stdout.length) {
264    throw new Error('Screenshot returned no data');
265  }
266
267  return await jimp.read(stdout);
268};
269
270commands.getScreenshot = async function getScreenshot () {
271  const apiLevel = await this.adb.getApiLevel();
272  let image = null;
273  if (apiLevel > 20) {
274    try {
275      // This screenshoting approach is way faster, since it requires less external commands
276      // to be executed. Unfortunately, exec-out option is only supported by newer Android/SDK versions (5.0 and later)
277      image = await this.getScreenshotDataWithAdbExecOut(this.adb);
278    } catch (e) {
279      log.info(`Cannot get screenshot data with 'adb exec-out' because of '${e.message}'. ` +
280               `Defaulting to 'adb shell' call`);
281    }
282  }
283  if (!image) {
284    try {
285      image = await this.getScreenshotDataWithAdbShell(this.adb, this.opts);
286    } catch (e) {
287      const err = `Cannot get screenshot data because of '${e.message}'. ` +
288                  `Make sure the 'LayoutParams.FLAG_SECURE' is not set for ` +
289                  `the current view`;
290      log.errorAndThrow(err);
291    }
292  }
293  if (apiLevel < 23) {
294    // Android bug 8433742 - rotate screenshot if screen is rotated
295    let screenOrientation = await this.adb.getScreenOrientation();
296    try {
297      image = await image.rotate(-90 * screenOrientation);
298    } catch (err) {
299      log.warn(`Could not rotate screenshot due to error: ${err}`);
300    }
301  }
302  const getBuffer = B.promisify(image.getBuffer, {context: image});
303  const imgBuffer = await getBuffer(jimp.MIME_PNG);
304  return imgBuffer.toString('base64');
305};
306
307Object.assign(extensions, commands, helpers);
308export { commands, helpers };
309export default extensions;
310
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Appium Android Driver on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)