UI Testing Failure - Neither element nor any descendant has keyboard focus on secureTextField

40,825

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

Share:
40,825

Related videos on Youtube

Bartłomiej Semańczyk
Author by

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, 2022

Comments

  • Bartłomiej Semańczyk
    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 with secureTextFields. Any workarounds?

    • ma11hew28
      ma11hew28 about 8 years
    • aurilio
      aurilio over 5 years
      and the weird part is if i try like this it works XCUIApplication().webViews.secureTextFields["Password"].tap(‌​) XCUIApplication().webViews.secureTextFields["Password"].type‌​Text("Welcome")
    • soumil
      soumil over 4 years
      It might be the case that you have set the accessibility identifier but you haven't set isAccessibilityElement = true
    • nteissler
      nteissler over 4 years
      I'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
      storoj over 3 years
      An answer to a similar question: stackoverflow.com/a/65335238/1837959
  • Bartłomiej Semańczyk
    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
    JOM over 8 years
    Good to hear it's fixed! I run into similar problem yesterday with beta 6 :)
  • Bartłomiej Semańczyk
    Bartłomiej Semańczyk over 8 years
    beta 6?:-) really? I have only 5:)
  • JOM
    JOM over 8 years
    You'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
    Bartłomiej Semańczyk over 8 years
    Maybe you know the answer for this: stackoverflow.com/questions/32219015/… ?
  • Harry
    Harry over 8 years
    If 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
    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
    Christian over 8 years
    Resetting 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
    shmim over 8 years
    I 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
    Stanislav Pankevich over 8 years
    This has fixed the issue. But it is very poor workaround as we cannot apply it automatically for CI.
  • Stanislav Pankevich
    Stanislav Pankevich over 8 years
    Thanks 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
    Stanislav Pankevich over 8 years
    This definitely does not work for secure password text field.
  • Stanislav Pankevich
    Stanislav Pankevich over 8 years
    This 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
    Stanislav Pankevich over 8 years
    To confirm it one more time: this helper works for you for secure password text field not just regular text field?
  • Oleksandr
    Oleksandr over 8 years
    Yes, it works for both types of text field: regular and secure.
  • Rob
    Rob about 8 years
    This only fixes it if you only have one test. Soon as I wrote a second one, saw the same error.
  • Vish
    Vish about 8 years
    For me, disabling only one option didn't help; what worked was this answer: stackoverflow.com/a/37052122/682912
  • charlyatwork
    charlyatwork about 8 years
    If 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
    Vish almost 8 years
    Funnily enough, I got this error on a real device as well.
  • netshark1000
    netshark1000 almost 8 years
    this hasn't changed something.
  • AlexDenisov
    AlexDenisov almost 8 years
    @netshark1000 that may be changed with the newer version of Xcode, I will check it.
  • Travis M.
    Travis M. over 7 years
    This worked for my secure password text field just fine. Good solution.
  • Laser Hawk
    Laser Hawk over 7 years
    extremely 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
    Michael over 7 years
    This 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
    Wagner Sales almost 7 years
    I 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
    user1122069 over 6 years
    Problem with this answer is that it uses a hardcoded delay. Instead, use the wait for expectations model with the keyboard element.
  • Corbin Miller
    Corbin Miller over 6 years
    The 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
    Shivam Pokhriyal over 5 years
    What is the difference between your code and the code asked in the question.
  • Mike Collins
    Mike Collins over 4 years
    Ran 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
    Reinhard Männer over 4 years
    Worked 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
    jherg over 4 years
    I ran into this on Xcode 11 as well. Fixes locally, but how can this be set in CI?
  • nr5
    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
    Simon McLoughlin almost 4 years
    This doesn't seem to work anymore, has the key changed?? @AlexDenisov
  • Simon McLoughlin
    Simon McLoughlin almost 4 years
    @WagnerSales doesn't seem to work anymore, do you know has the key changed?
  • bwobbones
    bwobbones almost 4 years
    Worked for me, MAN I hate this aspect of XCode!
  • Hasaan Ali
    Hasaan Ali almost 4 years
    I have added a full script below which disables hardware keyboard for any selected simulator stackoverflow.com/a/62929963/1590911.
  • francybiga
    francybiga over 3 years
    I 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 the ConnectHardwareKeyboard setting. Did anyone manage to make it work with parallel testing?
  • Marco Boerner
    Marco Boerner over 3 years
    For 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
    Abdalrahman Shatou over 3 years
    Would break tests that require not putting the app in the background. But otherwise, works like a charm.
  • Awais
    Awais about 3 years
    Thankyou... This just saved few hours of debugging.
  • Przemyslaw Jablonski
    Przemyslaw Jablonski over 2 years
    Haven't thought of that, have an upvote!
  • Joseph
    Joseph about 2 years
    You need to add some explanation to your answer
  • Shrikant Phadke
    Shrikant Phadke almost 2 years
    Excellent. Tried 'app.secureTextFields["PasswordTextField"].press(forDuration‌​: 1.1)' instead of 'app.secureTextFields["PasswordTextField"].doubleTap()' This problem occurs when editing multiple tetxfields