How to use this.adb.pull method in Appium Android Driver

Best JavaScript code snippet using appium-android-driver

android-controller.js

Source:android-controller.js Github

copy

Full Screen

...385 function (cb) {386 this.adb.broadcastProcessEnd(intentToBroadcast, this.appProcess, cb);387 }.bind(this),388 function (cb) {389 this.adb.pull(ecOnDevicePath, localfile, cb);390 }.bind(this),391 function (cb) {392 fs.readFile(localfile, function (err, data) {393 if (err) return cb(err);394 b64data = new Buffer(data).toString('base64');395 cb();396 });397 }.bind(this),398 ],399 function (err) {400 if (fs.existsSync(localfile)) fs.unlinkSync(localfile);401 if (err) return cb(err);402 cb(null, {403 status: status.codes.Success.code404 , value: b64data405 });406 });407};408androidController.pullFile = function (remotePath, cb) {409 var localFile = temp.path({prefix: 'appium', suffix: '.tmp'});410 var b64data = "";411 async.series([412 function (cb) {413 this.adb.pull(remotePath, localFile, cb);414 }.bind(this),415 function (cb) {416 fs.readFile(localFile, function (err, data) {417 if (err) return cb(err);418 b64data = new Buffer(data).toString('base64');419 cb();420 });421 }.bind(this),422 ],423 function (err) {424 if (fs.existsSync(localFile)) fs.unlinkSync(localFile);425 if (err) return cb(err);426 cb(null, {427 status: status.codes.Success.code428 , value: b64data429 });430 });431};432androidController.pushFile = function (base64Data, remotePath, cb) {433 var localFile = temp.path({prefix: 'appium', suffix: '.tmp'});434 mkdirp.sync(path.dirname(localFile));435 async.series([436 function (cb) {437 var content = new Buffer(base64Data, 'base64');438 var fd = fs.openSync(localFile, 'w');439 fs.writeSync(fd, content, 0, content.length, 0);440 fs.closeSync(fd);441 // adb push creates folders and overwrites existing files.442 this.adb.push(localFile, remotePath, cb);443 }.bind(this),444 ],445 function (err) {446 if (fs.existsSync(localFile)) fs.unlinkSync(localFile);447 if (err) return cb(err);448 cb(null, {449 status: status.codes.Success.code450 });451 });452};453androidController.pullFolder = function (remotePath, cb) {454 var localFolder = temp.path({prefix: 'appium'});455 var bufferOnSuccess = function (buffer) {456 logger.debug("Converting in-memory zip file to base64 encoded string");457 var data = buffer.toString('base64');458 logger.debug("Returning in-memory zip file as base54 encoded string");459 cb(null, {status: status.codes.Success.code, value: data});460 };461 var bufferOnFail = function (err) {462 cb(new Error(err));463 };464 this.adb.pull(remotePath, localFolder, function (err) {465 if (err) return cb(new Error(err));466 var zip = new AdmZip();467 zip.addLocalFolder(localFolder);468 zip.toBuffer(bufferOnSuccess, bufferOnFail);469 });470};471androidController.getScreenshot = function (cb) {472 var localfile = temp.path({prefix: 'appium', suffix: '.png'});473 var b64data = "";474 async.series([475 function (cb) {476 var png = "/data/local/tmp/screenshot.png";477 var cmd = ['"/system/bin/rm', png + ';', '/system/bin/screencap -p',478 png, '"'].join(' ');479 this.adb.shell(cmd, cb);480 }.bind(this),481 function (cb) {482 if (fs.existsSync(localfile)) fs.unlinkSync(localfile);483 this.adb.pull('/data/local/tmp/screenshot.png', localfile, cb);484 }.bind(this),485 function (cb) {486 fs.readFile(localfile, function (err, data) {487 if (err) return cb(err);488 b64data = new Buffer(data).toString('base64');489 cb();490 });491 },492 function (cb) {493 fs.unlink(localfile, function (err) {494 if (err) return cb(err);495 cb();496 });497 }...

Full Screen

Full Screen

index.js

Source:index.js Github

copy

Full Screen

1/**2 * AndroidAutomataion3 * Simple nodejs library for Andorid automation4 *5 * Requires uiautomator and Android SDK6 *7 * @author: Andrei Nedobylskii (admin@twister-vl.ru)8 */9const utils = require('util');10const exec = utils.promisify(require('child_process').exec);11const fs = require('fs');12const xpath = require('xpath')13 , dom = require('xmldom').DOMParser14const aaUtils = require('./utils');15class AndroidAutomation {16 /**17 * Keys codes18 * @type {{KEYCODE_ALT_RIGHT: string, KEYCODE_SYM: string, KEYCODE_AT: string, KEYCODE_DPAD_UP: string, KEYCODE_MINUS: string, KEYCODE_ENVELOPE: string, KEYCODE_COMMA: string, KEYCODE_DPAD_DOWN: string, KEYCODE_EQUALS: string, KEYCODE_Y: string, KEYCODE_DPAD_LEFT: string, KEYCODE_Z: string, KEYCODE_W: string, KEYCODE_X: string, KEYCODE_U: string, KEYCODE_UNKNOWN: string, KEYCODE_V: string, KEYCODE_S: string, KEYCODE_T: string, KEYCODE_SHIFT_LEFT: string, TAG_LAST_KEYCODE: string, KEYCODE_VOLUME_UP: string, KEYCODE_LEFT_BRACKET: string, KEYCODE_PLUS: string, KEYCODE_BACKSLASH: string, KEYCODE_CLEAR: string, KEYCODE_ENDCALL: string, KEYCODE_GRAVE: string, KEYCODE_HEADSETHOOK: string, KEYCODE_POWER: string, KEYCODE_POUND: string, KEYCODE_DPAD_CENTER: string, KEYCODE_NUM: string, KEYCODE_EXPLORER: string, KEYCODE_SLASH: string, KEYCODE_BACK: string, KEYCODE_1: string, KEYCODE_2: string, KEYCODE_SHIFT_RIGHT: string, KEYCODE_SEMICOLON: string, KEYCODE_0: string, KEYCODE_DEL: string, KEYCODE_CALL: string, KEYCODE_NOTIFICATION: string, KEYCODE_VOLUME_DOWN: string, KEYCODE_RIGHT_BRACKET: string, KEYCODE_SPACE: string, KEYCODE_I: string, KEYCODE_STAR: string, KEYCODE_J: string, KEYCODE_G: string, KEYCODE_PERIOD: string, KEYCODE_H: string, KEYCODE_E: string, KEYCODE_F: string, KEYCODE_C: string, KEYCODE_D: string, KEYCODE_Q: string, KEYCODE_R: string, KEYCODE_O: string, KEYCODE_P: string, KEYCODE_M: string, KEYCODE_ENTER: string, KEYCODE_N: string, KEYCODE_K: string, KEYCODE_L: string, KEYCODE_SOFT_RIGHT: string, KEYCODE_9: string, KEYCODE_APOSTROPHE: string, KEYCODE_MENU: string, KEYCODE_TAB: string, KEYCODE_7: string, KEYCODE_FOCUS: string, KEYCODE_HOME: string, KEYCODE_8: string, KEYCODE_ALT_LEFT: string, KEYCODE_5: string, KEYCODE_6: string, KEYCODE_CAMERA: string, KEYCODE_3: string, KEYCODE_SEARCH: string, KEYCODE_4: string, KEYCODE_A: string, KEYCODE_B: string, KEYCODE_DPAD_RIGHT: string}}19 */20 KEY_CODE = aaUtils.KEY_CODES;21 /**22 * Simple async wait23 * @type {(function(*=): Promise<unknown>)|*}24 */25 wait = aaUtils.wait;26 constructor(options) {27 options = {...options, sdkPath: process.env.ANDROID_SDK_ROOT, tempPath: '.'}28 this.sdkPath = options.sdkPath;29 this.adb = `${this.sdkPath}/platform-tools/adb`;30 this.tempPath = options.tempPath;31 }32 /**33 * Download screenshot34 * @param {string} path35 * @returns {Promise<string>}36 */37 async donwloadScreenshot(path = this.tempPath + '/screenshot.png') {38 let screenResult = await exec(`${this.adb} shell screencap -p /data/local/tmp/app.png`);39 //console.log(screenResult);40 let downloadScreenResult = await exec(`${this.adb} pull /data/local/tmp/app.png ${path}`);41 //console.log(downloadScreenResult);42 return path;43 }44 /**45 * Download UIX to specefied path46 * @param {string} path47 * @returns {Promise<string>}48 */49 async downloadUIX(path = this.tempPath + '/currentUI.uix') {50 let screenResult = await exec(`${this.adb} shell uiautomator dump /data/local/tmp/app.uix`);51 //console.log(screenResult);52 let downloadScreenResult = await exec(`${this.adb} pull /data/local/tmp/app.uix ${path}`);53 return path;54 }55 /**56 * Get UIX XML57 * @returns {Promise<string>}58 */59 async getUIX() {60 let uixPath = await this.downloadUIX();61 return fs.readFileSync(uixPath).toString();62 }63 /**64 * XPath selector to UI elements65 * @param {string} selector66 * @returns {Promise<*[SelectorResult]>}67 */68 async $(selector) {69 let uixString = await this.getUIX();70 let doc = new dom().parseFromString(uixString);71 // console.log(doc);72 let nodes = xpath.select(selector, doc);73 // console.log(nodes);74 let selectorResults = [];75 for (let selectorResult of nodes) {76 selectorResults.push(new SelectorResult(this, selectorResult))77 }78 /*if(selectorResults.length === 1){79 selectorResults = selectorResults[0];80 //selectorResults[0] = selectorResults[0];81 }*/82 return selectorResults;83 }84 /**85 * Click (tap) on screen86 * @param {number} x87 * @param {number} y88 * @returns {Promise<void>}89 */90 async tapTouch(x, y) {91 let tapResult = await exec(`${this.adb} shell input tap ${x} ${y}`);92 }93 /**94 * Write text to form95 * @param {string} text96 * @returns {Promise<void>}97 */98 async writeText(text) {99 let tapResult = await exec(`${this.adb} shell input text '${JSON.stringify(text)}'`);100 }101 /**102 * Send key event103 * @param {string|number} keyCode Key code from KEY_CODES104 * @returns {Promise<void>}105 */106 async key(keyCode) {107 let tapResult = await exec(`${this.adb} shell input keyevent ${keyCode}`);108 }109 /**110 * Wait for selector available111 * @param {string} selector112 * @returns {Promise<SelectorResult[]>}113 */114 async waitForSelector(selector) {115 let selectorResult;116 while (true) {117 selectorResult = await this.$(selector);118 if(selectorResult.length !== 0) {119 return selectorResult;120 }121 await aaUtils.wait();122 }123 }124 /**125 * Run app by package id126 * @param packageId127 * @param intent128 * @returns {Promise<void>}129 */130 async runApp(packageId, intent = 'android.intent.category.LAUNCHER') {131 let runResult = await exec(`${this.adb} shell monkey -p ${packageId} -c ${intent} 1`);132 }133 /**134 * Force stop app by package id135 * @param packageId136 * @returns {Promise<void>}137 */138 async forceStop(packageId) {139 let stopResult = await exec(`${this.adb} shell am force-stop ${packageId}`);140 }141}142/**143 * Element selector result144 */145class SelectorResult {146 constructor(androidAutomation, selectorResult) {147 this.androidAutomation = androidAutomation;148 this.selectorResult = selectorResult;149 //Element attributes150 this.attributes = {};151 for (let i = 0; i < this.selectorResult.attributes.length; i++) {152 let attribute = this.selectorResult.attributes[i];153 this.attributes[attribute.name] = attribute.value;154 }155 //Short version for attributes156 this.attr = this.attributes;157 //Parsed element boundaries158 this.bounds = aaUtils.parseBounds(this.attr['bounds']);159 }160 /**161 * Click on element162 * @returns {Promise<void>}163 */164 async click(timeout = 0) {165 let x = Math.round((this.bounds[0][0] + this.bounds[1][0]) / 2);166 let y = Math.round((this.bounds[0][1] + this.bounds[1][1]) / 2);167 await this.androidAutomation.tapTouch(x, y);168 if(timeout > 0) {169 await aaUtils.wait(500);170 }171 }172}...

Full Screen

Full Screen

startAliVerify.js

Source:startAliVerify.js Github

copy

Full Screen

1const {2 execSync,3 exec4} = require('child_process');5const getPixels = require('get-pixels');6const path = require('path');7//const adb = "/Users/bigdata/Library/Android/sdk/platform-tools/adb -s emulator-5554";8function avg(arr){9 let totals = 0;10 arr.forEach(item => {11 totals+=item;12 })13 return totals/arr.length;14}15class AliVerify {16 constructor(devicename) {17 18 this.screen = devicename;19 this.adb = "adb -s "+ devicename;20 21 }22 clearOldToken() {23 global.aliSessionId = "";24 }25 /**26 * swipeToCircle - 移动到圈圈内27 *28 * @return {type} description29 */30 swipeToCircle(sPoint, ePoint) {31 let pressX = sPoint[0];32 let pressY = sPoint[1];33 let pressX1 = ePoint[0];34 let pressY1 = ePoint[1];35 let dur = 500;36 let adbCommand = `${this.adb} shell input swipe ${pressX} ${pressY} ${pressX1} ${pressY1} ${dur}`;37 exec(adbCommand, (err) => {38 if(err){39 return console.log(err);40 }41 });42 }43 /**44 * capture - 截屏45 *46 * @return {type} description47 */48 capture() {49 // console.log('屏幕截图开始',`adb shell /system/bin/screencap -p /sdcard/screenshot.png`);50 return new Promise((resolve, reject) => {51 let command = `${this.adb} shell /system/bin/screencap -p /sdcard/${this.screen}.png`;52 console.log(command);53 require('child_process').exec(command, (err) => {54 if(err){55 return reject(err);56 }57 // console.log('屏幕截图完成')58 // console.log('拉取屏幕截图到电脑','adb pull /sdcard/screenshot.png /Users/junliang/server/www/maotaiServer/temp/');59 command = `${this.adb} pull /sdcard/${this.screen}.png ./temp/`60 console.log(command);61 require('child_process').exec(command, (err) => {62 if(err){63 return reject(err);64 }65 return resolve(true);66 });67 }); 68 })69 70 71 // console.log('拉取完成');72 }73 /**74 * openAliUI - 远程打开阿里验证UI75 *76 * @return {type} description77 */78 openAliUI() {79 console.log('start to open ali ui')80 let pressX = 126;81 let pressY = 98;82 let dur = 10;83 let adbCommand = `${this.adb} shell input tap ${pressX} ${pressY}`;84 console.log(adbCommand);85 exec(adbCommand, (err) => {86 if(err){87 return console.log(err);88 }89 });90 }91 calcPos(callback) {92 let sPoint = [0, 0],93 ePoint = [0, 0];94 let startPointX = [];95 let startPointY = [];96 let endPointX = [];97 let endPointY = [];98 let getPixTime = (+new Date());99 getPixels(path.resolve(__dirname, `../temp/${this.screen}.png`), (err, pixels) => {100 console.log('获取图像耗时', (+new Date() - getPixTime) + "ms");101 if (err) {102 console.log(err);103 callback([sPoint, ePoint]);104 }105 let width = pixels.shape[0];106 let height = pixels.shape[1];107 console.log('image size', width, height);108 let startTime = +new Date();109 for (let i = 0; i < width; i = i + 4) {110 for (let j = height / 3; j < height; j = j + 4) {111 let R = pixels.get(i, j, 0),112 G = pixels.get(i, j, 1),113 B = pixels.get(i, j, 2);114 if (R == 235 && G == 2 && B == 41) {115 // start pos;116 sPoint = [i, j];117 startPointX.push(i);118 startPointY.push(j);119 }120 if (R == 46 && G == 171 && B == 255) {121 // end pos122 ePoint = [i , j]123 endPointX.push(i);124 endPointY.push(j);125 }126 }127 }128 console.log(sPoint, ePoint, (+new Date() - startTime) + "ms");129 if(130 startPointX.length > 0131 &&132 startPointY.length > 0133 &&134 endPointX.length > 0135 &&136 endPointY.length > 0137 ){138 sPoint = [avg(startPointX), avg(startPointY)]139 ePoint = [avg(endPointX), avg(endPointY)]140 }141 callback([sPoint, ePoint]);142 })143 }144 /**145 * connectSidFromHard - 从硬件设备获取SID146 *147 * @return {type} description148 */149 connectSidFromHard(devicename) {150 151 // return new Promise((resolve, reject) => {152 this.openAliUI();153 return this.captureAndCalcPos();154 // })155 }156 /**157 * captureAndCalcPos - 重新截屏158 * 防止截屏的时候并没有加载完成阿里组件的情况159 *160 * @return {type} description161 */162 captureAndCalcPos() {163 // 开始截屏164 return new Promise((resolve, reject) => {165 setTimeout(() => {166 this.capture()167 .then((opened) => {168 this.calcPos(Points => {169 if (170 Points[0][0] == 0 ||171 Points[0][1] == 0 ||172 Points[1][0] == 0 ||173 Points[1][1] == 0174 ) {175 console.log('restart to find image');176 this.captureAndCalcPos();177 }else{178 this.swipeToCircle(Points[0], Points[1]);179 return resolve(true); 180 }181 182 });183 }).catch(e => {184 this.captureAndCalcPos();185 });186 187 }, 1000); 188 })189 }190}...

Full Screen

Full Screen

controllers.js

Source:controllers.js Github

copy

Full Screen

...42 });43 const remoteFile = `${ADB.ANDROID_TMP_DIR}/screenshot.png`;44 const cmd = `/system/bin/rm ${remoteFile}; /system/bin/screencap -p ${remoteFile}`;45 yield this.adb.shell(cmd);46 yield this.adb.pull(remoteFile, swapFilePath);47 var base64 = null;48 try {49 let data = fs.readFileSync(swapFilePath);50 base64 = new Buffer(data).toString('base64');51 } catch (e) {52 throw new errors.NoSuchWindow();53 }54 _.rimraf(swapFilePath);55 return base64;56};57controllers.get = function * (url) {58 const cmd = `am start -a android.intent.action.VIEW -d ${url}`;59 yield this.adb.shell(cmd);60 return null;...

Full Screen

Full Screen

ADBLogcatRecording.js

Source:ADBLogcatRecording.js Github

copy

Full Screen

...51 }52 }53 async doSave(artifactPath) {54 if (this.hasRecordedFile) {55 await this.adb.pull(this.deviceId, this.pathToLogOnDevice, artifactPath);56 await this.adb.rm(this.deviceId, this.pathToLogOnDevice);57 } else {58 log.debug(`Skipping saving artifact because the recording has not started: ${artifactPath}`);59 }60 }61 async doDiscard() {62 if (this.hasRecordedFile) {63 await this.adb.rm(this.deviceId, this.pathToLogOnDevice);64 } else {65 log.debug(`Skipping discarding artifact due to a not started recording: ${this.pathToLogOnDevice}`);66 }67 }68 async _assertLogIsCreated() {69 const size = await this.adb.getFileSize(this.deviceId, this.pathToLogOnDevice);...

Full Screen

Full Screen

ADBScreenrecorderArtifact.js

Source:ADBScreenrecorderArtifact.js Github

copy

Full Screen

...31 }32 }33 async doSave(artifactPath) {34 await this._waitWhileVideoIsBusy;35 await this.adb.pull(this.deviceId, this.pathToVideoOnDevice, artifactPath);36 await this.adb.rm(this.deviceId, this.pathToVideoOnDevice);37 }38 async doDiscard() {39 await this._waitWhileVideoIsBusy;40 await this.adb.rm(this.deviceId, this.pathToVideoOnDevice);41 }42 async _assertVideoIsBeingRecorded() {43 const size = await this.adb.getFileSize(this.deviceId, this.pathToVideoOnDevice);44 if (size < 1) {45 throw new DetoxRuntimeError({46 message: `The video is not being recorded on device (${this.deviceId}) at path: ${this.pathToVideoOnDevice}`,47 });48 }49 }...

Full Screen

Full Screen

coverage.js

Source:coverage.js Github

copy

Full Screen

...14 try {15 // ensure the ec we're pulling is newly created as a result of the intent.16 await this.adb.rimraf(ecOnDevicePath);17 await this.adb.broadcastProcessEnd(intentToBroadcast, this.appProcess);18 await this.adb.pull(ecOnDevicePath, localFile);19 let data = await fs.readFile(localFile);20 b64data = new Buffer(data).toString('base64');21 await unlinkFile(localFile);22 } catch (err) {23 log.debug(`Error ending test coverage: ${err.message}`);24 }25 return b64data;26};27Object.assign(extensions, commands, helpers);28export { commands, helpers };...

Full Screen

Full Screen

AndroidInstrumentsRecording.js

Source:AndroidInstrumentsRecording.js Github

copy

Full Screen

...7 this.deviceId = deviceId;8 }9 async doSave(artifactPath) {10 await super.doSave(artifactPath);11 await this.adb.pull(this.deviceId, this.temporaryRecordingPath, artifactPath);12 await this.adb.rm(this.deviceId, this.temporaryRecordingPath, true);13 }14 async doDiscard() {15 await this.adb.rm(this.deviceId, this.temporaryRecordingPath, true);16 }17}...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var adb = require('appium-adb');2var path = require('path');3var fs = require('fs');4var ADB = adb.ADB;5var adb = new ADB();6var pullPath = path.resolve(__dirname, 'test');7var fromPath = '/sdcard/test.txt';8adb.pull(fromPath, pullPath, function(err) {9 if(err) {10 console.error(err);11 } else {12 console.log('File copied');13 }14});15var adb = require('appium-adb');16var path = require('path');17var fs = require('fs');18var ADB = adb.ADB;19var adb = new ADB();20var pullPath = path.resolve(__dirname, 'test');21var fromPath = '/sdcard/test.txt';22adb.pull(fromPath, pullPath, function(err) {23 if(err) {24 console.error(err);25 } else {26 console.log('File copied');27 }28});29var adb = require('appium-adb');30var path = require('path');31var fs = require('fs');32var ADB = adb.ADB;33var adb = new ADB();34var pullPath = path.resolve(__dirname, 'test');35var fromPath = '/sdcard/test.txt';36adb.pull(fromPath, pullPath, function(err) {37 if(err) {38 console.error(err);39 } else {40 console.log('File copied');41 }42});

Full Screen

Using AI Code Generation

copy

Full Screen

1var Appium = require('appium');2var AndroidDriver = Appium.AndroidDriver;3var ADB = Appium.ADB;4var driver = new AndroidDriver();5var adb = driver.adb;6var src = "/sdcard/Download/abc.txt";7var dest = "/Users/xyz/Desktop/abc.txt";8adb.pull(src, dest, function(err, stdout){9 if(err){10 console.log(err);11 }12 else{13 console.log(stdout);14 }15});

Full Screen

Using AI Code Generation

copy

Full Screen

1var adb = require('appium-adb');2var driver = new adb.ADB();3var srcPath = "/data/data/com.android.browser/databases/webview.db";4var dstPath = "C:\\Users\\xyz\\Downloads\\webview.db";5driver.pull(srcPath, dstPath, function(err, stdout){6if(err){7console.log("Error pulling file from device");8console.log(err);9}10else{11console.log("File copied successfully");12}13});

Full Screen

Using AI Code Generation

copy

Full Screen

1var driver = new AndroidDriver();2driver.adb.pull(source, destination);3pull: function (remotePath, localPath) {4 return this.adb.pull(remotePath, localPath);5 }6pull: function (remotePath, localPath) {7 return this.exec( "pull" , [remotePath, localPath]);8 }9adbExec: function (cmd, args , cb ) {10 var cmd = this .getAdbWithArgs().concat(cmd);11 if (args) {12 cmd = cmd.concat(args);13 }14 this .exec(cmd, { maxBuffer: 524288 }, function (err, stdout, stderr) {15 if (err) return cb(err, stdout, stderr);16 cb( null , stdout, stderr);17 });18 }19exec: function (cmd, args , cb ) {20 var cmd = this .getAdbWithArgs().concat(cmd);21 if (args) {22 cmd = cmd.concat(args);23 }24 this .exec(cmd, { maxBuffer: 524288 }, function (err, stdout, stderr) {25 if (err) return cb(err, stdout, stderr);26 cb( null , stdout, stderr);27 });28 }29exec: function (cmd, opts , cb ) {30 if (typeof opts === "function" ) {31 cb = opts;32 opts = {};33 }34 opts = _.defaults(opts, {35 });36 logger.debug( "Executing:

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Android Driver automation tests on LambdaTest cloud grid

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

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful