Swift UI Testing Access string in the TextField
Asked Answered
I

3

22

I am using the UI Test Case class integrated in Xcode and XCTest to test app UI. I want to test something like this:

app = XCUIApplication()
let textField = app.textFields["Apple"]
textField.typeText("text_user_typed_in")
XCTAssertEqual(textField.text, "text_user_typed_in")

I've tried the textField.value as! String method; it does not work. I've also tried using the new async method with expectationForPredicate(), and it will result in a timeout.

Any idea how to do this or validation of this kind is not possible with UI Test and I could only write black-box tests?

Incantation answered 18/11, 2015 at 22:27 Comment(1)
Thx @Charles A. for pointing out that the problem is the textField does not exist. I am confused because I call the typeText method and I can see that the text is being input into the textField.Incantation
F
43

I use this code and it works fine:

textField.typeText("value")
XCTAssertEqual(textField.value as! String, "value")

If you're doing something similar and it isn't functioning, I would check to make sure that your textField element actually exists:

XCTAssertTrue(textField.exists, "Text field doesn't exist")
textField.typeText("value")
XCTAssertEqual(textField.value as! String, "value", "Text field value is not correct")
Fivespot answered 18/11, 2015 at 22:35 Comment(7)
Yeah you are right. The textField does not exist. But I don't understand this: I call the typeText on textField and I can see that the text is being input into the textField.Incantation
Should I use the async method on this?Incantation
Is the initial text "Apple"? The default behavior is probably that the accessibility label of the field is its contents, so the query fails the second time you try and resolve an element.Fivespot
You should set an accessibility identifier on your text field, and look for it with that instead of "Apple" so it is consistent. Every time you access an element it attempts to resolve it again.Fivespot
I understand what you are saying, and I find a workaround with elementBoundByIndex(). Thx for the helpIncantation
@Incantation you should add your comment in answer section.Faggoting
@Incantation If you know the index of your textField, you can do something like this: let textField = XCUIApplication().textFields.element(boundBy: index). It would be easier to determine the text field index of a more specific element than the root XCUIApplication instance, of course.Fivespot
G
3

Swhift 4.2. You need to clear an existing value in textField and paste new value.

let app = XCUIApplication()
let textField = app.textFields["yourTextFieldValue"]
textField.tap()
textField.clearText(andReplaceWith: "VALUE")
XCTAssertEqual(textField.value as! String, "VALUE", "Text field value is not correct")

where clearText is a method of XCUIElement extension:

extension XCUIElement {
    func clearText(andReplaceWith newText:String? = nil) {
        tap()
        press(forDuration: 1.0)
        var select = XCUIApplication().menuItems["Select All"]

        if !select.exists {
            select = XCUIApplication().menuItems["Select"]
        }
        //For empty fields there will be no "Select All", so we need to check
        if select.waitForExistence(timeout: 0.5), select.exists {
            select.tap()
            typeText(String(XCUIKeyboardKey.delete.rawValue))
        } else {
            tap()
        }
        if let newVal = newText {
            typeText(newVal)
        }
    }
}
Gwen answered 31/1, 2019 at 8:6 Comment(0)
G
2

the following is working in Xcode 10.3 running on macOS 10.14.3, for iOS app running iOS 12.4:

XCTAssert( app.textFields["testTextField"].exists, "test text field doesn't exist" )
let tf = app.textFields["testTextField"]
tf.tap()    // must give text field keyboard focus!
tf.typeText("Hello!")
XCTAssert( tf.exists, "tf exists" )   // text field still exists
XCTAssertEqual( tf.value as! String, "Hello!", "text field has proper value" )
Grate answered 3/9, 2019 at 20:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.