Skip to content

Commit db39d66

Browse files
feat: Add 'mobile: keys' extension (#2156)
1 parent 6d647fe commit db39d66

File tree

7 files changed

+65
-5
lines changed

7 files changed

+65
-5
lines changed

docs/execute-methods.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,20 @@ Checks if the system on-screen keyboard is visible.
13701370

13711371
`true` if the keyboard is visible
13721372

1373+
### mobile: keys
1374+
1375+
Send keys to the given element or to the application under test.
1376+
This API is only supported since Xcode 15/iOS 17.
1377+
It is not supported on tvOS.
1378+
The API only works on iPad. On iOS calling it has no effect.
1379+
1380+
#### Arguments
1381+
1382+
Name | Type | Required | Description | Example
1383+
--- | --- | --- | --- | ---
1384+
elementId | string | no | Unique identifier of the element to send the keys to. If unset then keys are sent to the current application under test. | 21045BC8-013C-43BD-9B1E-4C6DC7AB0744
1385+
keys | array | yes | Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's [typeKey:modifierFlags: method](https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc) and on [XCUIKeyboardKey constants](https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)) or a dictionary with `key` and `modifierFlags` entries, if the key should also be entered with modifiers. | ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] or ['XCUIKeyboardKeyEscape'] |
1386+
13731387
### mobile: lock
13741388

13751389
Lock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.

lib/commands/keyboard.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,31 @@ export default {
3434
return false;
3535
}
3636
},
37+
38+
/**
39+
* Send keys to the given element or to the application under test.
40+
* This API is not supported on tvOS
41+
*
42+
* @since Xcode 15/iOS 17
43+
* @this {import('../driver').XCUITestDriver}
44+
* @param {(Key|string)[]} keys Array of keys to type.
45+
* Each item could either be a string, that represents a key itself (see
46+
* https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc
47+
* and https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)
48+
* or a dictionary, if the key should also be entered with modifiers.
49+
* @param {string?} [elementId=null] uuid of the element to send keys to.
50+
* If the element is not provided then the keys will be sent to the current application.
51+
*/
52+
async mobileKeys(keys, elementId = null) {
53+
const url = `/wda/element/${elementId || 0}/keyboardInput`;
54+
return await this.proxyCommand(url, 'POST', { keys });
55+
},
3756
};
3857

3958
/**
4059
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
4160
*/
61+
62+
/**
63+
* @typedef {import('./types').KeyboardKey} Key
64+
*/

lib/commands/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,18 @@ export interface Viewport {
550550
*/
551551
height: number;
552552
}
553+
554+
export interface KeyboardKey {
555+
/**
556+
* Represents a key to type (see
557+
* https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc
558+
* and https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)
559+
*/
560+
key: string;
561+
/**
562+
* Set of modifier flags
563+
* (https://developer.apple.com/documentation/xctest/xcuikeymodifierflags?language=objc)
564+
* to use when typing the key.
565+
*/
566+
modifierFlags?: number;
567+
}

lib/driver.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,7 @@ class XCUITestDriver extends BaseDriver {
20322032
hideKeyboard = commands.keyboardExtensions.hideKeyboard;
20332033
mobileHideKeyboard = commands.keyboardExtensions.mobileHideKeyboard;
20342034
isKeyboardShown = commands.keyboardExtensions.isKeyboardShown;
2035+
mobileKeys = commands.keyboardExtensions.mobileKeys;
20352036

20362037
/*--------------+
20372038
| LOCALIZATION |

lib/execute-method-map.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ export const executeMethodMap = {
442442
'mobile: calibrateWebToRealCoordinatesTranslation': {
443443
command: 'mobileCalibrateWebToRealCoordinatesTranslation',
444444
},
445+
'mobile: keys': {
446+
command: 'mobileKeys',
447+
params: {
448+
required: ['keys'],
449+
optional: ['elementId'],
450+
},
451+
},
445452
'mobile: deepLink': {
446453
command: 'mobileDeepLink',
447454
params: {

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"appium-ios-device": "^2.5.4",
7474
"appium-ios-simulator": "^5.3.3",
7575
"appium-remote-debugger": "^10.0.0",
76-
"appium-webdriveragent": "^5.11.0",
76+
"appium-webdriveragent": "^5.12.2",
7777
"appium-xcode": "^5.1.4",
7878
"async-lock": "^1.4.0",
7979
"asyncbox": "^2.9.4",

0 commit comments

Comments
 (0)