11import { spawn , ChildProcess } from "child_process" ;
2- import { resolve , delimiter , sep } from "path" ;
3- import { existsSync } from "fs" ;
2+ import { resolve , delimiter , sep , dirname } from "path" ;
3+ import { existsSync , copyFile , copyFileSync } from "fs" ;
44import { Platform , DeviceType , Status } from "./enums" ;
55import { IDevice , Device } from "./device" ;
66import {
@@ -36,12 +36,12 @@ export class AndroidController {
3636 return devices ;
3737 }
3838
39- public static getPhysicalDensity ( token : string ) {
40- return parseInt ( executeCommand ( AndroidController . ADB + " -s emulator-" + token + " shell wm density") . split ( ":" ) [ 1 ] ) * 0.01 ;
39+ public static getPhysicalDensity ( device : IDevice ) {
40+ return parseInt ( AndroidController . executeAdbCommand ( device , " shell wm density") . split ( ":" ) [ 1 ] ) * 0.01 ;
4141 }
4242
43- public static getPixelsOffset ( token : string ) {
44- return Math . floor ( OFFSET_DI_PIXELS * AndroidController . getPhysicalDensity ( token ) ) ;
43+ public static getPixelsOffset ( device : IDevice ) {
44+ return Math . floor ( OFFSET_DI_PIXELS * AndroidController . getPhysicalDensity ( device ) ) ;
4545 }
4646
4747 public static async startEmulator ( emulator : IDevice , options = "" , logPath = undefined ) : Promise < IDevice > {
@@ -61,8 +61,8 @@ export class AndroidController {
6161 emulator . startedAt = Date . now ( ) ;
6262 }
6363
64- const density = AndroidController . getPhysicalDensity ( emulator . token ) ;
65- const offsetPixels = AndroidController . getPixelsOffset ( emulator . token ) ;
64+ const density = AndroidController . getPhysicalDensity ( emulator ) ;
65+ const offsetPixels = AndroidController . getPixelsOffset ( emulator ) ;
6666 emulator . config = {
6767 density : density ,
6868 offsetPixels : offsetPixels ,
@@ -90,9 +90,8 @@ export class AndroidController {
9090 public static kill ( emulator : IDevice ) {
9191 let isAlive : boolean = true ;
9292 if ( emulator . type === DeviceType . EMULATOR ) {
93-
9493 if ( emulator . token ) {
95- executeCommand ( AndroidController . ADB + " -s " + DeviceType . EMULATOR + "-" + emulator . token + " emu kill" ) ;
94+ AndroidController . executeAdbCommand ( emulator , " emu kill" ) ;
9695 isAlive = false ;
9796 }
9897
@@ -208,11 +207,39 @@ export class AndroidController {
208207 AndroidController . executeAdbCommand ( device , `shell am force-stop ${ appId } ` ) ;
209208 }
210209
210+ public static async getScreenshot ( device : IDevice , dir , fileName ) {
211+ fileName = fileName . endsWith ( ".pne" ) ? fileName : `${ fileName } .png` ;
212+ const pathToScreenshotPng = `/sdcard/${ fileName } ` ;
213+ AndroidController . executeAdbCommand ( device , `shell screencap ${ pathToScreenshotPng } ` ) ;
214+ const fullFileName = resolve ( dir , fileName ) ;
215+ AndroidController . pullFile ( device , pathToScreenshotPng , fullFileName ) ;
216+ return fullFileName ;
217+ }
218+
219+ public static async recordVideo ( device : IDevice , dir , fileName , callback : ( ) => Promise < any > ) {
220+ new Promise ( async ( res , reject ) => {
221+ const videoFileName = `${ fileName } .mp4` ;
222+ const pathToVideo = resolve ( dir , res ) ;
223+ const devicePath = `/sdcard/${ videoFileName } ` ;
224+ const prefix = AndroidController . gettokenPrefix ( device . type ) ;
225+ const videoRecoringProcess = spawn ( AndroidController . ADB , [ '-s' , prefix + device . token , 'screenrecord' , devicePath ] ) ;
226+ callback ( ) . then ( ( result ) => {
227+ videoRecoringProcess . kill ( "SIGINT" ) ;
228+ AndroidController . pullFile ( device , devicePath , pathToVideo ) ;
229+ console . log ( result ) ;
230+ res ( pathToVideo ) ;
231+ } ) . catch ( ( error ) => {
232+ reject ( error ) ;
233+ } ) ;
234+ } ) ;
235+ }
236+
211237 public static getPackageId ( appFullName ) {
212238 return AndroidController . runAaptCommand ( appFullName , "package:" ) ;
213239 }
214-
215- public static pullFile ( device : IDevice , remotePath , destinationFolder ) {
240+
241+ public static pullFile ( device : IDevice , remotePath , destinationFile ) {
242+ const destinationFolder = dirname ( destinationFile ) ;
216243 // Verify remotePath
217244 const remoteBasePath = remotePath . substring ( 0 , remotePath . lastIndexOf ( "/" ) ) ;
218245 const sdcardFiles = AndroidController . executeAdbCommand ( device , " shell ls -la " + remoteBasePath ) ;
@@ -228,7 +255,7 @@ export class AndroidController {
228255 }
229256
230257 // Pull files
231- const output = AndroidController . executeAdbCommand ( device , "pull " + remotePath + " " + destinationFolder ) ;
258+ const output = AndroidController . executeAdbCommand ( device , "pull " + remotePath + " " + destinationFile ) ;
232259 console . log ( output ) ;
233260 const o = output . toLowerCase ( ) ;
234261 if ( ( o . includes ( "error" ) ) || ( o . includes ( "failed" ) ) || ( o . includes ( "does not exist" ) ) ) {
@@ -237,18 +264,18 @@ export class AndroidController {
237264 console . log ( "Error: " + output ) ;
238265 return undefined ;
239266 } else {
240- console . log ( remotePath + " transferred to " + destinationFolder ) ;
267+ console . log ( remotePath + " transferred to " + destinationFile ) ;
241268 }
242269
243- return destinationFolder ;
270+ return destinationFile ;
244271 }
245272
246- public static pushFile ( device : IDevice , localPath , remotePath ) {
273+ public static pushFile ( device : IDevice , fileName , deviceParh ) {
247274
248275 let output = AndroidController . executeAdbCommand ( device , "shell mount -o rw,remount -t rootfs /" ) ;
249276
250277 // Verify remotePath
251- const remoteBasePath = remotePath . substring ( 0 , remotePath . lastIndexOf ( "/" ) ) ;
278+ const remoteBasePath = deviceParh . substring ( 0 , deviceParh . lastIndexOf ( "/" ) ) ;
252279 const sdcardFiles = AndroidController . executeAdbCommand ( device , "shell ls -la " + remoteBasePath ) ;
253280 if ( sdcardFiles . includes ( "No such file or directory" ) ) {
254281 const error = remoteBasePath + " does not exist." ;
@@ -257,28 +284,25 @@ export class AndroidController {
257284 }
258285
259286 // Verify localPath
260- localPath = localPath . replace ( "/" , sep ) ;
261- localPath = localPath . replace ( "\\" , sep ) ;
262- const localFilePath = localPath ;
263- if ( ! existsSync ( localFilePath ) ) {
264- const error = localPath + " does not exist." ;
287+ fileName = fileName . replace ( "/" , sep ) . replace ( "\\" , sep ) ;
288+ if ( ! existsSync ( fileName ) ) {
289+ const error = fileName + " does not exist." ;
265290 console . log ( error ) ;
266291 return undefined ;
267292 }
268293
269294 // Push files
270- output = AndroidController . executeAdbCommand ( device , "push " + localFilePath + " " + remotePath ) ;
295+ output = AndroidController . executeAdbCommand ( device , "push " + fileName + " " + deviceParh ) ;
271296 console . log ( output ) ;
272297 if ( ( output . toLowerCase ( ) . includes ( "error" ) ) || ( output . toLowerCase ( ) . includes ( "failed" ) ) ) {
273- const error = "Failed to transfer " + localPath + " to " + remotePath ;
274- console . log ( error ) ;
275- console . log ( "Error: " + output ) ;
298+ console . log ( "Failed to transfer " + fileName + " to " + deviceParh ) ;
299+ console . log ( "Error: " , output ) ;
276300 return undefined ;
277301 } else {
278- console . log ( localPath + " transferred to " + remotePath ) ;
302+ console . log ( fileName + " transferred to " + deviceParh ) ;
279303 }
280304
281- return localFilePath ;
305+ return fileName ;
282306 }
283307
284308 private static getAaptPath ( ) {
0 commit comments