0

I have validation code which sets the error of the EditText when it doesn't satisfy the requirements.

field.setError(errorMessage);

This puts a little red circle with an exclamation point over the field, and when I touch the field, it displays my error message in a black box. Great!

Now I want calabash to verify that the field failed validation. For the moment at least I'm not concerned about the specific error message - I just want to know that an error message is displayed (or I would be happy to settle for the exclamation point, but since I can't find it using query in console, I suspect that would be harder).

This query:

query("android.widget.PopupWindow$PopupViewContainer")

finds the error message window if it is present.

But it's only present if the field with the error has focus. And I only set the error when the field loses focus. That should be OK - my step can enter text into the field, leave the field, and come back. When I do these things manually, the error message window is displayed. What I have not yet been able to do is to write a step which does these things and reliably displays the error message window. I have tried

query("EditText id:'#{field_id}'", {:setText => bad_text})
touch(query("* id:'#{another_field_id}'")[0])
touch(query("* id:'#{field_id}'")[0])

and

query("EditText id:'#{field_id}'", {:setText => bad_text})
system("#{default_device.adb_command} shell input keyevent KEYCODE_TAB")
touch(query("* id:'#{field_id}'")[0])

and both of these behave correctly for the first EditText, but fail to show the error message window for subsequent EditTexts. Why? What's the right way to do this?

alannichols
  • 1,496
  • 1
  • 10
  • 20
Carl Manaster
  • 39,912
  • 17
  • 102
  • 155

1 Answers1

1

There are multiple things with your calabash commands that could cause your tests to fail.

1) Do not use touch(query(...

# bad
touch(query("q"))
# good
touch("q")

2) Do not use 'setText' to simulate entering text

# bad
query("EditText", {:setText => 'bad_text'})
# good
enter_text("EditText", 'bad_text')

3) Do not use any input events

Input events like system("#{default_device.adb_command} shell input keyevent KEYCODE_TAB") are impossible for the user to perform on most devices, as very few Android devices have a physical keyboard. Use press_user_action_button to simulate the user pressing the input key appearing instead of the enter key.

Tobias
  • 678
  • 4
  • 9
  • Thank you! This did the trick, specifically enter_text instead of set_text. Can you point to a resource which explains why to use one instead of the other? – Carl Manaster Mar 19 '15 at 16:40
  • 1
    Using the 'setText approach' is just invoking the method setText on the matches of the query. This wont invoke any callbacks. Using `keyboard_enter_text` is the way to input text. – Tobias Mar 20 '15 at 11:01
  • That makes sense, but I still have trouble understanding why it worked on the first field on the screen. Thanks. – Carl Manaster Mar 20 '15 at 15:16