"hide_keyboard" API call throwing an exception after updating to iOS 14.6

Phone model: iPhone X
OS: iOS 14.6
Appium version: 1.21.0
XCode version: 12.5

After updating to iOS 14.6, Appium started throwing an selenium.common.exceptions.InvalidElementStateException on attempt to hide keyword, i.e.:

if self._driver.is_keyboard_shown():
    self._driver.hide_keyboard()

I’m getting:

E selenium.common.exceptions.InvalidElementStateException: Message: Error Domain=com.facebook.WebDriverAgent Code=1 “Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.” UserInfo={NSLocalizedDescription=Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.}

Appium server log:

[HTTP] --> GET /wd/hub/session/df8b294c-95df-4254-b9c6-2b7d7a14ded6/appium/device/is_keyboard_shown
[HTTP] {}
[W3C (df8b294c)] Calling AppiumDriver.isKeyboardShown() with args: [“df8b294c-95df-4254-b9c6-2b7d7a14ded6”]
[XCUITest] Executing command ‘isKeyboardShown’
[BaseDriver] Waiting up to 0 ms for condition
[WD Proxy] Matched ‘/element’ to command name ‘findElement’
[WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8100/session/7701025B-0850-4E0C-8401-0D2D7343703E/element] with body: {“using”:“class name”,“value”:“XCUIElementTypeKeyboard”}
[WD Proxy] Got response with status 200: {“value”:{“ELEMENT”:“93000000-0000-0000-CE08-000000000000”,“element-6066-11e4-a52e-4f735466cecf”:“93000000-0000-0000-CE08-000000000000”},“sessionId”:“7701025B-0850-4E0C-8401-0D2D7343703E”}
[W3C (df8b294c)] Responding to client with driver.isKeyboardShown() result: true
[HTTP] <-- GET /wd/hub/session/df8b294c-95df-4254-b9c6-2b7d7a14ded6/appium/device/is_keyboard_shown 200 261 ms - 14
[HTTP]
[HTTP] --> POST /wd/hub/session/df8b294c-95df-4254-b9c6-2b7d7a14ded6/appium/device/hide_keyboard
[HTTP] {“strategy”:“tapOutside”}
[W3C (df8b294c)] Calling AppiumDriver.hideKeyboard() with args: [“tapOutside”,null,null,null,“df8b294c-95df-4254-b9c6-2b7d7a14ded6”]
[XCUITest] Executing command ‘hideKeyboard’
[WD Proxy] Proxying [POST /wda/keyboard/dismiss] to [POST http://127.0.0.1:8100/session/7701025B-0850-4E0C-8401-0D2D7343703E/wda/keyboard/dismiss] with body: {“keyNames”:[“done”]}
[WD Proxy] Got response with status 400: {“value”:{“error”:“invalid element state”,“message”:“Error Domain=com.facebook.WebDriverAgent Code=1 “Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.” UserInfo={NSLocalizedDescription=Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.}”,“traceback”:""},“sessionId”:“7701025B-0850-4E0C-8401-0D2D7343703E”}
[W3C] Matched W3C error code ‘invalid element state’ to InvalidElementStateError
[W3C (df8b294c)] Encountered internal error running command: InvalidElementStateError: Error Domain=com.facebook.WebDriverAgent Code=1 “Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.” UserInfo={NSLocalizedDescription=Did not know how to dismiss the keyboard. Try to dismiss it in the way supported by your application under test.}
[W3C (df8b294c)] at errorFromW3CJsonCode (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/lib/protocol/errors.js:780:25)
[W3C (df8b294c)] at ProxyRequestError.getActualError (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/lib/protocol/errors.js:663:14)
[W3C (df8b294c)] at JWProxy.command (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/lib/jsonwp-proxy/proxy.js:272:19)
[W3C (df8b294c)] at runMicrotasks ()
[W3C (df8b294c)] at processTicksAndRejections (internal/process/task_queues.js:85:5)
[HTTP] <-- POST /wd/hub/session/df8b294c-95df-4254-b9c6-2b7d7a14ded6/appium/device/hide_keyboard 400 3959 ms - 1322

Is there a way to fix this problem locally without making any workarounds (i.e. if exception caught, tap “Done” button on keyboard to hide it) or it’s strictly Appium problem?

The hide_keyboard method allows to explicitly provide the keyboard button name to tap in order to hide it. If there is no such button then the client code should apply the same strategy to hide it as a normal app user would do, for example swipe down on the upper top part of the screen.

1 Like

Thanks! Then will use this approach. I thought that hide_keyboard() method always hides keyboard without specifying any buttons name explicitly. Strange that it stoped working with default parameters only after updating to iOS 14.6