Skip to content

Commit 0344a46

Browse files
Zdravko BranzovZdravko Branzov
Zdravko Branzov
authored and
Zdravko Branzov
committed
feature: add the ability to run adb shell commands
1 parent a997bd7 commit 0344a46

File tree

6 files changed

+85
-10
lines changed

6 files changed

+85
-10
lines changed

lib/appium-driver.d.ts

+16
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,20 @@ export declare class AppiumDriver {
269269
* This is convenient to use for some gestures on the screen
270270
*/
271271
getScreenViewPort(): IRectangle;
272+
/**
273+
* Android ONLY! Input key event via ADB.
274+
* @param keyEvent The event number
275+
*/
276+
adbKeyEvent(keyEvent: number): Promise<void>;
277+
/**
278+
* Android ONLY! Send text via ADB.
279+
* @param text The string to send
280+
*/
281+
adbSendText(text: string): Promise<void>;
282+
/**
283+
* Android ONLY! Execute shell command via ADB.
284+
* @param command The command name
285+
* @param args Additional arguments
286+
*/
287+
adbShellCommand(command: string, args: Array<any>): Promise<void>;
272288
}

lib/appium-driver.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import {
3333
getStorage,
3434
encodeImageToBase64,
3535
ensureReportsDirExists,
36-
checkImageLogType
36+
checkImageLogType,
37+
adbShellCommand
3738
} from "./utils";
3839

3940
import { INsCapabilities } from "./interfaces/ns-capabilities";
@@ -1022,4 +1023,29 @@ export class AppiumDriver {
10221023
}
10231024
}
10241025
}
1026+
1027+
/**
1028+
* Android ONLY! Input key event via ADB.
1029+
* @param keyEvent The event number
1030+
*/
1031+
public async adbKeyEvent(keyEvent: number) {
1032+
await this.adbShellCommand("input", ["keyevent", keyEvent]);
1033+
}
1034+
1035+
/**
1036+
* Android ONLY! Send text via ADB.
1037+
* @param text The string to send
1038+
*/
1039+
public async adbSendText(text: string) {
1040+
await this.adbShellCommand("input", ["text", text]);
1041+
}
1042+
1043+
/**
1044+
* Android ONLY! Execute shell command via ADB.
1045+
* @param command The command name
1046+
* @param args Additional arguments
1047+
*/
1048+
public async adbShellCommand(command: string, args: Array<any>) {
1049+
await adbShellCommand(this._driver, command, args);
1050+
}
10251051
}

lib/ui-element.d.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ export declare class UIElement {
128128
* Send keys to field or other UI component
129129
* @param text
130130
* @param shouldClearText, default value is true
131+
* @param useAdb, default value is false. Usable for Android ONLY !
131132
*/
132-
sendKeys(text: string, shouldClearText?: boolean): Promise<void>;
133+
sendKeys(text: string, shouldClearText?: boolean, useAdb?: boolean): Promise<void>;
133134
/**
134135
* Type text to field or other UI component
135136
* @param text
@@ -142,9 +143,14 @@ export declare class UIElement {
142143
*/
143144
pressKeycode(keyCode: number): Promise<void>;
144145
/**
145-
* Clears text form ui element
146+
* Clears text from ui element
146147
*/
147148
clearText(): Promise<void>;
149+
/**
150+
* Clears text from ui element with ADB. Android ONLY !
151+
* @param charactersCount Characters count to delete. (Optional - default value 10)
152+
*/
153+
adbDeleteText(charactersCount?: number): Promise<void>;
148154
log(): Promise<void>;
149155
refetch(): Promise<any>;
150156
/**

lib/ui-element.ts

+28-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Point } from "./point";
22
import { Direction } from "./direction";
33
import { INsCapabilities } from "./interfaces/ns-capabilities";
44
import { AutomationName } from "./automation-name";
5-
import { calculateOffset } from "./utils";
5+
import { calculateOffset, adbShellCommand } from "./utils";
66
import { AndroidKeyEvent } from "mobile-devices-controller";
77

88
export class UIElement {
@@ -382,12 +382,21 @@ export class UIElement {
382382
* Send keys to field or other UI component
383383
* @param text
384384
* @param shouldClearText, default value is true
385+
* @param useAdb, default value is false. Usable for Android ONLY !
385386
*/
386-
public async sendKeys(text: string, shouldClearText: boolean = true) {
387-
if (shouldClearText) {
388-
await this.clearText();
387+
public async sendKeys(text: string, shouldClearText: boolean = true, useAdb: boolean = false) {
388+
if (useAdb && this._args.isAndroid) {
389+
if (shouldClearText) {
390+
await this.adbDeleteText();
391+
}
392+
await this.click();
393+
await adbShellCommand(this._driver, "input", ["text", text]);
394+
} else {
395+
if (shouldClearText) {
396+
await this.clearText();
397+
}
398+
await this._element.sendKeys(text);
389399
}
390-
await this._element.sendKeys(text);
391400
}
392401

393402
/**
@@ -407,17 +416,29 @@ export class UIElement {
407416
* @param key code
408417
*/
409418
public async pressKeycode(keyCode: number) {
410-
await this._driver.pressKeycode(keyCode);
419+
await this._driver.pressKeyCode(keyCode);
411420
}
412421

413422
/**
414-
* Clears text form ui element
423+
* Clears text from ui element
415424
*/
416425
public async clearText() {
417426
await this.click();
418427
await this._element.clear();
419428
}
420429

430+
/**
431+
* Clears text from ui element with ADB. Android ONLY !
432+
* @param charactersCount Characters count to delete. (Optional - default value 10)
433+
*/
434+
public async adbDeleteText(charactersCount: number = 10) {
435+
await this.click();
436+
for (let index = 0; index < charactersCount; index++) {
437+
// Keyevent 67 Delete (backspace)
438+
await adbShellCommand(this._driver, "input", ["keyevent", 67]);
439+
}
440+
}
441+
421442
public async log() {
422443
const el = await this.element();
423444
console.dir(el);

lib/utils.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export declare function logWarn(info: any, obj?: any): void;
5151
export declare function logError(info: any, obj?: any): void;
5252
export declare function log(message: any, verbose: any): void;
5353
export declare const logColorized: (bgColor: ConsoleColor, frontColor: ConsoleColor, info: any) => void;
54+
export declare function adbShellCommand(wd: any, command: string, args: Array<any>): Promise<void>;
5455
declare enum ConsoleColor {
5556
Reset = "\u001B[0m",
5657
Bright = "\u001B[1m",

lib/utils.ts

+5
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,11 @@ export const logColorized = (bgColor: ConsoleColor, frontColor: ConsoleColor, in
687687
console.log(`${ConsoleColor.BgYellow}${ConsoleColor.FgBlack}%s${ConsoleColor.Reset}`, info);
688688
}
689689

690+
691+
export async function adbShellCommand(wd: any, command: string, args: Array<any>) {
692+
await wd.execute('mobile: shell', {"command": command, "args": args});
693+
}
694+
690695
enum ConsoleColor {
691696
Reset = "\x1b[0m",
692697
Bright = "\x1b[1m",

0 commit comments

Comments
 (0)