Xcode UI test fails to edit multiple UITextFields

I have a UI with multiple UITextFields that I want to test by clearing their contents and typing new values. However, only the first field can be changed in a UI test; subsequent fields can be cleared (if their clear button is enabled), but they can't be typed into (using XCUIElement.typeText()), because the test Failed to synthesize event: Neither element nor any descendant has keyboard focus. How can I edit multiple text fields in a UI test function?

The ViewController:

class ViewController: UIViewController {

    @IBOutlet weak var field1: UITextField!
    @IBOutlet weak var field2: UITextField!

    @IBAction func submit(_ sender: Any) {
        let actionVC = UIAlertController(title: "You did it!",
                                         message: "\(field1.text ?? ""), \(field2.text ?? "")",
                                         preferredStyle: .alert)
        actionVC.addAction(UIAlertAction(title: "Awesome!", style: .default, handler: nil))
        present(actionVC, animated: true, completion: nil)
    }

}

The test:

class TextFieldTesterUITests: XCTestCase {

    func testReplaceTextInMultipleTextFields() throws {
        let app = XCUIApplication()
        app.launch()

        let field1TextField = app.textFields["Field 1"]
        field1TextField.tap()
        app.buttons["Clear text"].tap()
        field1TextField.typeText("Oh")

        let field2TextField = app.textFields["Field 2"]
        field2TextField.tap()
        app.buttons["Clear text"].tap() // <-- 
        field2TextField.typeText("Susanna")

        app.staticTexts["Button"].tap()

        app.alerts["You did it!"].scrollViews.otherElements.buttons["Awesome!"].tap()
    }

}

The error:

Failed to synthesize event: Neither element nor any descendant has keyboard focus. Event dispatch snapshot: TextField, placeholderValue: 'Field 2', value: Field 2

Element debug description:

Attributes: TextField, {{16.0, 413.7}, {358.0, 34.0}}, placeholderValue: 'Field 2'

Element subtree:

 →TextField, 0x600001816d80, {{16.0, 413.7}, {358.0, 34.0}}, placeholderValue: 'Field 2'

Path to element:

 →Application, 0x6000018164c0, pid: 3755, label: 'TextFieldTester'

  ↳Window (Main), 0x600001816ca0, {{0.0, 0.0}, {390.0, 844.0}}

   ↳Other, 0x600001817560, {{0.0, 0.0}, {390.0, 844.0}}

    ↳Other, 0x600001817640, {{0.0, 0.0}, {390.0, 844.0}}

     ↳Other, 0x600001817800, {{0.0, 0.0}, {390.0, 844.0}}

      ↳Other, 0x6000018178e0, {{16.0, 379.7}, {358.0, 98.0}}

       ↳TextField, 0x600001816d80, {{16.0, 413.7}, {358.0, 34.0}}, placeholderValue: 'Field 2', value: Field 2

Query chain:

 →Find: Target Application 'net.poikilecreations.TextFieldTester'

  Output: {

    Application, pid: 3755, label: 'TextFieldTester'

  }

  ↪︎Find: Descendants matching type TextField

    Output: {

      TextField, {{16.0, 379.7}, {358.0, 34.0}}, placeholderValue: 'Field 1', value: Oh

      TextField, {{16.0, 413.7}, {358.0, 34.0}}, placeholderValue: 'Field 2'

    }

    ↪︎Find: Elements matching predicate '"Field 2" IN identifiers'

      Output: {

        TextField, {{16.0, 413.7}, {358.0, 34.0}}, placeholderValue: 'Field 2'

      }

I've posted this demonstration app on GitHub.

I've just confirmed that this error does not occur in iOS 14.3 or 15.0 beta simulators; it seems to be isolated to iOS 14.5.

It's helpful to make sure that element is exist. You can use waitForElementExistence. This will solve your problem.