While working on a project for a client the design team had a pretty specific requirement for how EditText need to appear. I tried to bend TextInputEditText and TextInputLayout to my will but it just wasn't happening. This lead me to create a custom text input view which could show errors, hints, supporting labels, and suffixes in exactly the right way. I even ended up subclassing EditText to get some of these features.

Unfortunately this makes writing Espresso tests a little harder, leading to some very long and ugly onView(...) and failing replaceText(...) calls. By diving into ViewActions I was able to make a few modifications to smooth over this whole situation.

I started with ReplaceTextAction, copying the source into my own ReplaceTextInputViewAction since my class is called (TextInputView.) There are really on two important methods here - getConstraints() and perform(). getConstraints() simply sets the requirements for the ViewAction to proceed, otherwise throwing an exception. perform() is where it actually does the action. This is where it can get exciting if you have a complicated custom view, but its important to have a nice clean interface to get/set the state of your View. Here is what I ended up with: