Testing keyboard shortcuts on iOS device

I am trying to work on some tests for an iPad app to verify the keyboard shortcuts that activate some tools (without starting or being able to start the native keyboard of the iPad).

Does anyone know if this is possible and if so, can you share how?

Try https://github.com/appium/appium-xcuitest-driver/blob/master/docs/execute-methods.md#mobile-keys

1 Like


That worked but only for simple commands.

When I tried space + shift it didn’t work using:

driver.execute_script("mobile: keys", {"keys": [{"key": " ", "modifierFlags": "XCUIKeyboardKeyShift"}]})

It activates the space related tool but not the space + shift related tool.

The documentation there should probably be updated. The modifierFlags value must be an integer of the following type:

typedef NS_OPTIONS(NSUInteger, XCUIKeyModifierFlags) {
    XCUIKeyModifierNone       = 0,
    XCUIKeyModifierCapsLock   = (1UL << 0),
    XCUIKeyModifierShift      = (1UL << 1),
    XCUIKeyModifierControl    = (1UL << 2),
    XCUIKeyModifierOption     = (1UL << 3),
    XCUIKeyModifierCommand    = (1UL << 4),
    XCUIKeyModifierFunction   = (1UL << 5),
    // These values align with UIKeyModifierFlags and CGEventFlags.
    XCUIKeyModifierAlphaShift = XCUIKeyModifierCapsLock,
    XCUIKeyModifierAlternate  = XCUIKeyModifierOption,

This basically means if you want to press Space with Shift depressed then set the key argument to "XCUIKeyboardKeySpace" and modifierFlags to 1 << 1


The “1 << 1”, “1 << 2” values were confusing indeed.

Thank you very much for sharing! It works!

This worked for a couple of days but now it seems that the modifier is not recognized anymore. :confused:

This is not helpful. Please provide the server log

I need to press CMD + Z, I’m using:
self.driver.execute_script(“mobile: keys”, {“keys”: [{“key”: “z”, “modifierFlags”: “1 << 4”}]})
and it activates the tool corresponding to Z, instead of CMD + Z.

[XCUITestDriver@6072 (e9b3a076)] Calling AppiumDriver.execute() with args: [“mobile: keys”,[{“keys”:[{“key”:“z”,“modifierFlags”:“1 << 4”}]}],“e9b3a076-3ffd-43e8-85e2-5b2bf8ef3c24”]
[XCUITestDriver@6072 (e9b3a076)] Executing command ‘execute’
[XCUITestDriver@6072 (e9b3a076)] Proxying to WDA with an unknown route: POST /wda/element/0/keyboardInput
[XCUITestDriver@6072 (e9b3a076)] Proxying [POST /wda/element/0/keyboardInput] to [POST] with body: {“keys”:[{“key”:“z”,“modifierFlags”:“1 << 4”}]}
[XCUITestDriver@6072 (e9b3a076)] Got response with status 200: {“value”:null,“sessionId”:“FA5A0468-65DE-4795-9D3F-78F6CF9AEB7A”}
[XCUITestDriver@6072 (e9b3a076)] Responding to client with driver.execute() result: null

Are you sure you read https://github.com/appium/appium-xcuitest-driver/blob/master/docs/reference/execute-methods.md#mobile-keys properly? modifierFlags arg must not be a string

1 Like

Oh, my bad.
I must’ve updated by mistake.
Thank you and sorry for bothering you again!