Skip to content

Commit 7a8f3b7

Browse files
authored
feat(android): add hideKeyboardStrategy option to AndroidDevice and implement hideKeyboard method (#1037)
* feat(android): add hideKeyboardStrategy option to AndroidDevice and implement hideKeyboard method * feat(android): enhance keyboard handling with autoDismissKeyboard and hideKeyboardStrategy options in AndroidDevice tests * fix(android): rename hideKeyboardStrategy to keyboardDismissStrategy for consistency in AndroidDevice implementation and documentation
1 parent b6694fa commit 7a8f3b7

File tree

5 files changed

+416
-2
lines changed

5 files changed

+416
-2
lines changed

apps/site/docs/en/integrate-with-android.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ The AndroidDevice constructor supports the following parameters:
107107
- `deviceId: string` - The device id
108108
- `opts?: AndroidDeviceOpt` - Optional, the options for the AndroidDevice
109109
- `autoDismissKeyboard?: boolean` - Optional, whether to dismiss the keyboard after inputting. (Default: true)
110+
- `keyboardDismissStrategy?: 'esc-first' | 'back-first'` - Optional, the strategy to dismiss the keyboard. 'esc-first' tries ESC key first, then back key if needed. 'back-first' tries back key first, then ESC key if needed. (Default: 'esc-first')
110111
- `androidAdbPath?: string` - Optional, the path to the adb executable.
111112
- `remoteAdbHost?: string` - Optional, the remote adb host.
112113
- `remoteAdbPort?: number` - Optional, the remote adb port.

apps/site/docs/zh/integrate-with-android.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ AndroidDevice 的构造函数支持以下参数:
107107
- `deviceId: string` - 设备 id
108108
- `opts?: AndroidDeviceOpt` - 可选参数,用于初始化 AndroidDevice 的配置
109109
- `autoDismissKeyboard?: boolean` - 可选参数,是否在输入文本后自动关闭键盘。默认值为 true。
110+
- `keyboardDismissStrategy?: 'esc-first' | 'back-first'` - 可选参数,关闭键盘的策略。'esc-first' 优先尝试 ESC 键,如果键盘仍存在则尝试返回键。'back-first' 优先尝试返回键,如果键盘仍存在则尝试 ESC 键。默认值为 'esc-first'。
110111
- `androidAdbPath?: string` - 可选参数,用于指定 adb 可执行文件的路径。
111112
- `remoteAdbHost?: string` - 可选参数,用于指定远程 adb 主机。
112113
- `remoteAdbPort?: number` - 可选参数,用于指定远程 adb 端口。

packages/android/src/page/index.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ ${Object.keys(size)
685685
}
686686

687687
if (isAutoDismissKeyboard === true) {
688-
await adb.hideKeyboard();
688+
await this.hideKeyboard(options);
689689
}
690690
}
691691

@@ -925,4 +925,66 @@ ${Object.keys(size)
925925
async getElementInfoByXpath(xpath: string): Promise<ElementInfo> {
926926
throw new Error('Not implemented');
927927
}
928+
929+
async hideKeyboard(
930+
options?: AndroidDeviceInputOpt,
931+
timeoutMs = 1000,
932+
): Promise<boolean> {
933+
const adb = await this.getAdb();
934+
const keyboardDismissStrategy =
935+
options?.keyboardDismissStrategy ??
936+
this.options?.keyboardDismissStrategy ??
937+
'esc-first';
938+
939+
// Check if keyboard is shown
940+
const keyboardStatus = await adb.isSoftKeyboardPresent();
941+
const isKeyboardShown =
942+
typeof keyboardStatus === 'boolean'
943+
? keyboardStatus
944+
: keyboardStatus?.isKeyboardShown;
945+
946+
if (!isKeyboardShown) {
947+
debugPage('Keyboard has no UI; no closing necessary');
948+
return false;
949+
}
950+
951+
// Determine key codes order based on strategy
952+
const keyCodes =
953+
keyboardDismissStrategy === 'back-first'
954+
? [4, 111] // KEYCODE_BACK, KEYCODE_ESCAPE
955+
: [111, 4]; // KEYCODE_ESCAPE, KEYCODE_BACK
956+
957+
// Try each key code with waiting
958+
for (const keyCode of keyCodes) {
959+
await adb.keyevent(keyCode);
960+
961+
// Wait for keyboard to be hidden with timeout
962+
const startTime = Date.now();
963+
const intervalMs = 100;
964+
965+
while (Date.now() - startTime < timeoutMs) {
966+
await sleep(intervalMs);
967+
968+
const currentStatus = await adb.isSoftKeyboardPresent();
969+
const isStillShown =
970+
typeof currentStatus === 'boolean'
971+
? currentStatus
972+
: currentStatus?.isKeyboardShown;
973+
974+
if (!isStillShown) {
975+
debugPage(`Keyboard hidden successfully with keycode ${keyCode}`);
976+
return true;
977+
}
978+
}
979+
980+
debugPage(
981+
`Keyboard still shown after keycode ${keyCode}, trying next key`,
982+
);
983+
}
984+
985+
console.warn(
986+
'Warning: Failed to hide the software keyboard after trying both ESC and BACK keys',
987+
);
988+
return false;
989+
}
928990
}

0 commit comments

Comments
 (0)