UI Testing Failure - Neither element nor any descendant has keyboard focus on secureTextField
Solution 1
This issue caused me a world of pain, but I've managed to figure out a proper solution. In the Simulator, make sure I/O -> Keyboard -> Connect hardware keyboard
is off.
Solution 2
Recently we found a hack to make solution from accepted answer persistent. To disable Simulator setting: I/O -> Keyboard -> Connect hardware keyboard
from command line one should write:
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0
It will not affect a simulator which is running - you need to restart simulator or start a new one to make that setting have its effect.
Solution 3
I have written a small extension (Swift) which works perfect for me. Here is the code:
extension XCTestCase {
func tapElementAndWaitForKeyboardToAppear(element: XCUIElement) {
let keyboard = XCUIApplication().keyboards.element
while (true) {
element.tap()
if keyboard.exists {
break;
}
NSRunLoop.currentRunLoop().runUntilDate(NSDate(timeIntervalSinceNow: 0.5))
}
}
}
The main idea is to keep tapping an element (text field) before the keyboard is presented.
Solution 4
Stanislav has the right idea.
In a team environment, you need something that will automatically work. I've come up with a fix here on my blog.
Basically you just paste:
UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()
Solution 5
Another cause of this error is if there is a parent view of the text field in which you are trying to enter text that is set as an accessibility element (view.isAccessibilityElement = true
). In this case, XCTest is not able to get a handle on the subview to enter the text and returns the error.
UI Testing Failure - Neither element nor any descendant has keyboard focus.
It isn't that no element has focus (as you can often see the keyboard up and blinking cursor in the UITextField), it is just that no element it can reach has focus. I ran into this when attempting to enter text in a UISearchBar. The search bar itself is not the text field, when setting it as an accessibility element, access to the underlying UITextField was blocked. To resolve this, searchBar.accessibilityIdentifier = "My Identifier"
was set on the UISearchBar
however the isAccessibilityElement
was not set to true
. After this, test code of the form:
app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")
Works
Related videos on Youtube
Bartłomiej Semańczyk
iOS developer and keen enthusiast of and its development. Focused on clean code everytime while coding. I like Git very much:-) Swift is the only right language to programming on iOS. Implementing only latest solutions from Apple. Do not support old things. Tests are required, not optional:) #SOreadytohelp
Updated on May 05, 2022Comments
-
Bartłomiej Semańczyk about 2 years
This is my case:
let passwordSecureTextField = app.secureTextFields["password"] passwordSecureTextField.tap() passwordSecureTextField.typeText("wrong_password") //here is an error
UI Testing Failure - Neither element nor any descendant has keyboard focus. Element:
What is wrong? This is working nice for normal
textFields
, but problem arise only withsecureTextFields
. Any workarounds?-
ma11hew28 about 8 years
-
aurilio over 5 yearsand the weird part is if i try like this it works XCUIApplication().webViews.secureTextFields["Password"].tap() XCUIApplication().webViews.secureTextFields["Password"].typeText("Welcome")
-
soumil over 4 yearsIt might be the case that you have set the accessibility identifier but you haven't set isAccessibilityElement = true
-
nteissler over 4 yearsI've added an answer to a similar question here: stackoverflow.com/a/59637897/2585413. My issue was that I had other UIWindows in existence with bad .windowLevel values
-
storoj over 3 yearsAn answer to a similar question: stackoverflow.com/a/65335238/1837959
-
-
Bartłomiej Semańczyk over 8 years
passwordSecureTextField
exists. I fixed the problem, but cleaning memory, and rewrite those lines again. Weird, but it worked. -
JOM over 8 yearsGood to hear it's fixed! I run into similar problem yesterday with beta 6 :)
-
Bartłomiej Semańczyk over 8 yearsbeta 6?:-) really? I have only 5:)
-
JOM over 8 yearsYou've been busy coding :) Beta 6 didn't record
tap
for me, took some time to figure it out. Good debug practise! -
Bartłomiej Semańczyk over 8 yearsMaybe you know the answer for this: stackoverflow.com/questions/32219015/… ?
-
Harry over 8 yearsIf you have an answer to this question, can you add it please. I've been having a similar problem where an element is behind the keyboard and all
tap
does is tap on the keyboard. -
JOM over 8 years@Harry you have a completely different question, so you should write a new question! Anyways, either first scroll item visible or close keyboard
-
Christian over 8 yearsResetting the simulator helped me, too. Interestingly the problem did only occur in the simulator while the same test (tap texfield followed by typing characters) ran fine on a device.
-
shmim over 8 yearsI believe this is the real answer. UI recording is very fussy, so there might be many reasons for a problem (typical Apple...), but I got the same error and this fixed it. What it means is that you have to poke the keys on the simulator, can't use the ones on your mac or recording will fail.
-
Stanislav Pankevich over 8 yearsThis has fixed the issue. But it is very poor workaround as we cannot apply it automatically for CI.
-
Stanislav Pankevich over 8 yearsThanks for sharing your solution. Unfortunately it is not working for me right now. I am having Xcode 7.2 (7C68), what you? See other solution that we found for CI: stackoverflow.com/questions/32184837/….
-
Stanislav Pankevich over 8 yearsThis definitely does not work for secure password text field.
-
Stanislav Pankevich over 8 yearsThis is not working for me right now. I am having Xcode 7.2 (7C68), what version do you have? This solution that we found for CI works for us: stackoverflow.com/a/34812979/598057.
-
Stanislav Pankevich over 8 yearsTo confirm it one more time: this helper works for you for secure password text field not just regular text field?
-
Oleksandr over 8 yearsYes, it works for both types of text field: regular and secure.
-
Rob about 8 yearsThis only fixes it if you only have one test. Soon as I wrote a second one, saw the same error.
-
Vish about 8 yearsFor me, disabling only one option didn't help; what worked was this answer: stackoverflow.com/a/37052122/682912
-
charlyatwork about 8 yearsIf you run your tests on CI (Jenkins etc.) You can set the following parameters in a script before running your tests. "defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0"
-
Vish almost 8 yearsFunnily enough, I got this error on a real device as well.
-
netshark1000 almost 8 yearsthis hasn't changed something.
-
AlexDenisov almost 8 years@netshark1000 that may be changed with the newer version of Xcode, I will check it.
-
Travis M. over 7 yearsThis worked for my secure password text field just fine. Good solution.
-
Laser Hawk over 7 yearsextremely helpful, I needed the opposite where keyboard is always enabled, but yeah this is great thanks. I ended up going with
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool true
, but its the same concept. -
Michael over 7 yearsThis doesn't solve the problem for me. I can clearly see the textfield obtaining focus, with the keyboard up, but the testing framework can never enter text using the typeText: method
-
Wagner Sales almost 7 yearsI created a script on build phases to do it. But I needed kill all simulators, so I did that:
killall "Simulator"; defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0;
-
user1122069 over 6 yearsProblem with this answer is that it uses a hardcoded delay. Instead, use the wait for expectations model with the keyboard element.
-
Corbin Miller over 6 yearsThe problem is if you have a large number of UI Tests that perform something like an initial login, this will add a huge overhead to your CI test run.
-
Shivam Pokhriyal over 5 yearsWhat is the difference between your code and the code asked in the question.
-
Mike Collins over 4 yearsRan into this after upgrading to Xcode 11. This worked for me. Have not upgraded CI to Xcode 11 so don't know if the defaults disabling bit will work.
-
Reinhard Männer over 4 yearsWorked for me on Xcode 11, but unchecking Connect hardware keyboard may not be enough. One has additionally to ensure that the software keyboard is really shown (I had actually the situation where no hardware keyboard was connected, and no software keyboard was shown, even if the textField had focus, and the cursor was blinking).
-
jherg over 4 yearsI ran into this on Xcode 11 as well. Fixes locally, but how can this be set in CI?
-
nr5 about 4 years@seeya where would you say to place the script? I tried placing it in the scheme of my test case for pre-actions in test and build options but no luck.
-
Simon McLoughlin almost 4 yearsThis doesn't seem to work anymore, has the key changed?? @AlexDenisov
-
Simon McLoughlin almost 4 years@WagnerSales doesn't seem to work anymore, do you know has the key changed?
-
bwobbones almost 4 yearsWorked for me, MAN I hate this aspect of XCode!
-
Hasaan Ali almost 4 yearsI have added a full script below which disables hardware keyboard for any selected simulator stackoverflow.com/a/62929963/1590911.
-
francybiga over 3 yearsI managed to fix this by performing
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool false
before running tests on a CI, but this doesn't work for "parallel testing", it seems that the "clones" Simulators doesn't inherit theConnectHardwareKeyboard
setting. Did anyone manage to make it work with parallel testing? -
Marco Boerner over 3 yearsFor some reason I need to toggle the
I/O > Keyboard > Connect Hardware Keyboard
option from off to on and then off again to make it work every time after restarting XCode and the simulator. -
Abdalrahman Shatou over 3 yearsWould break tests that require not putting the app in the background. But otherwise, works like a charm.
-
Awais about 3 yearsThankyou... This just saved few hours of debugging.
-
Przemyslaw Jablonski over 2 yearsHaven't thought of that, have an upvote!
-
Joseph about 2 yearsYou need to add some explanation to your answer
-
Shrikant Phadke almost 2 yearsExcellent. Tried 'app.secureTextFields["PasswordTextField"].press(forDuration: 1.1)' instead of 'app.secureTextFields["PasswordTextField"].doubleTap()' This problem occurs when editing multiple tetxfields