2

I have to check if there is any UITextField is empty or contains any value using XCUITest or XCTest. I was checking on many places and found textField.Value can be used to find out the result. But for me the problem is textField.value returns placeholder as value and hence it fails to detect empty field as empty.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Rishi Chaurasia
  • 520
  • 4
  • 18

4 Answers4

2

I ran into this recently and as pointed out by @adamjansch for UITextField the XCUIElement will return the placeholder value if it is set and there is no text in the text field.

Given that, I ended up doing something like this:

let query = app.scrollViews.otherElements
let textField = query.textFields["textFieldIdentifier"]

if textField.value != nil,
   let aValue = textField.value as? String,
   let placeholderValue = textField.placeholderValue,
   aValue != placeholderValue

{
   // Do something with the text field; it has a value
   // so perhaps it needs to be cleared before a new
   // value is input.
   textField.buttons["Clear text"].tap()
}
else
{
    ...
}
-1

You have two cases to figure out wheter the textfield is empty. First one - Use standart bool value of yourTextField.text == nil and second check for the instance to have string of "" -> This should for instance occur when user would write some text and then delete it...

So in code:

// The second condition will occur only if the text is not nil, so 
// it is okay to unwrap it like it.
 XCTAssertTrue(textField.text == nil || textField.text!.isEmpty)
Dominik Bucher
  • 2,120
  • 2
  • 16
  • 25
  • 3
    This answer cannot work (for iOS at least). A text field in an iOS UI test is not accessed through a UITextField object, so the properties `text` and `text.isEmpty` will not be available. Instead access to a text field is through an XCUIElement object, and the only way to get the text is through the `value` property. However, that value is populated if either the main text *or* the placeholder text is set, hence the OP's problem. – adamjansch Apr 28 '20 at 15:12
  • Do you try it before write this, you cannot use `textField.text` in iOS UI Test as adamjansch said. – Zhou Haibo Apr 25 '22 at 04:53
  • Can someone else please write me that it won't work please? – Dominik Bucher May 02 '22 at 12:23
  • @DominikBucher Let me know how my answer doesn't work for you and I'll be happy to update it. – adamjansch May 09 '22 at 07:33
  • I upvoted your answer, however I demand more answers – Dominik Bucher May 09 '22 at 07:54
-1

There is a workaround for your problem. If you dont want to get the placeholder

  • First click on the textfield

    textField.tap()
    
  • Get the value from the textfield element

    let pageTitle = textField.value as? String
    var titleLength = pageTitle?.characters.count
    XCTAssertTrue(titleLength==0, "Title is empty")
    
Mahmud Riad
  • 1,169
  • 1
  • 8
  • 19
  • You miss checking for nil in the titleLenght property. – Dominik Bucher Dec 22 '17 at 11:40
  • @DominikBucher i am checking the string count. if count is 0 then it is definitely empty or nill. Why downvote it dear. – Mahmud Riad Dec 22 '17 at 11:42
  • Okay dear. Since your answer is almost complete wrong, I will tell you the wrong aspects: 1. For swift 4 - `characters` property of String is deprecated 2. You are comparing nillable, so the assert will fail when the titleLenght is nil (Which is right assumption here) 3. Because of this, you are not covering all the cases. 4. TextField.value is complete nonsense because it returns instance of UITextField again, not the actual string, therefore there are just functions `value(for key:)` which are not safe to call. – Dominik Bucher Dec 22 '17 at 11:49
  • Since OP gets the placeholder value from so to avoid it i just suggest to tap on that field first so that he can avoid getting the placeholder text. OP can decide what idea suits for him best. And there is no tag that it should be on swift 4 or not. OP can change into desired api on what he is working. – Mahmud Riad Dec 22 '17 at 12:02
-1

There is a solution which should work (apart from in one situation*). XCUIElement has a property placeholderValue, which should contain the text field's placeholder text. So try this:

let textfield = XCUIApplication().textFields["textFieldIdentifier"]

if let textFieldText = textField.value as? String,
   textFieldText.isEmpty == false,
   textFieldText != textField.placeholderValue {
    // Do the thing that requires the text field *not* to be empty
}

* The one scenario where this won't work is if the text entered in the text field is the same as the placeholder's text. Then we're in Failsville.

However, as this is a UITest, I would think you should have some control over what gets entered into this text field.

adamjansch
  • 1,170
  • 11
  • 22