Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use espresso with custom EditText

Here is part of my layout:

<com.rey.material.widget.EditText
            android:id="@+id/tagEditorSettings"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_marginStart="10dp"
            android:layout_toEndOf="@+id/circularProgressbar"
            android:hint="@string/tag_name_tag_settings"
            android:inputType="text"
            android:textSize="18sp"
            app:et_dividerColor="@color/my_primary"
            app:et_dividerHeight="1dp"
            app:et_inputId="@+id/name_input"
            app:et_labelEnable="true"
            app:et_labelTextSize="14sp"
            app:et_supportLines="1" />

and my testing code:

onView(withId(R.id.tagEditorSettings))
                .perform(click()).perform(clearText());

And when I try to run it I get such error:

Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints: (is displayed on the screen to the user and is assignable from class: class android.widget.EditText)

As I understand the problem is with "is assignable from class: class android.widget.EditText", but could someone please advice, how I can fix it and use in my case?

like image 324
JohnA Avatar asked Nov 21 '17 11:11

JohnA


People also ask

How to test a textview with espresso?

Here’s how to test this with Espresso: The first step is to look for a property that helps to find the button. The button in the SimpleActivity has a unique R.id, as expected. Now to perform the click: The TextView with the text to verify has a unique R.id too: Now to verify the content text:

What is espresso framework for UI testing?

UI Testing with Espresso. Espresso framework is an… | by Anshul Jain | AndroidPub | Medium Espresso framework is an instrumentation Testing framework made available by Google for the ease of UI Testing. UI Testing becomes more relevant as our code base grows.

How do I set up espresso framework on Android?

Setting up the espresso framework in Android Navigate to app > Gradle Script > build.gradle (Module:app), add the following lines of code, and sync the project. defaultConfig { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }

What is the espresso API?

The Espresso API encourages test authors to think in terms of what a user might do while interacting with the application - locating UI elements and interacting with them.


2 Answers

Issue: com.rey.material.widget.EditText is extended from Framelayout and clearText uses ReplaceTextAction as

  public static ViewAction clearText() {
      return actionWithAssertions(new ReplaceTextAction(""));
  }

where ReplaceTextAction enforces the view, a type of EditText as

allOf(isDisplayed(), isAssignableFrom(EditText.class));
//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since rey...EdiText is not a subclass of EditText hence the error


Solution : create your own ViewAction as

public static ViewAction clearTextInCustomView(){
            return new ViewAction() {
                @SuppressWarnings("unchecked")
                @Override
                public Matcher<View> getConstraints() {
                    return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
//                                            ^^^^^^^^^^^^^^^^^^^ 
// To check that the found view is type of com.rey.material.widget.EditText or it's subclass
                }

                @Override
                public void perform(UiController uiController, View view) {
                    ((com.rey.material.widget.EditText) view).setText("");
                }

                @Override
                public String getDescription() {
                    return "clear text";
                }
            };
    }

And later you can do

onView(withId(R.id.tagEditorSettings))
                .perform(click()).perform(clearTextInCustomView());
like image 184
Pavneet_Singh Avatar answered Sep 22 '22 10:09

Pavneet_Singh


this custom EditText extends from FrameLayout. That's why it's complaining that the target is not assignable from class android.widget.EditText.

But, this custom EditText has some methods like setText to set the text in the contained EditText which is defined as:

protected android.widget.EditText mInputView;

and this one is an EditText from the android.widget package.

You can crate a custom ViewAction to access this public methods:

public static ViewAction setTextEditText(final Matcher<View> matcher,
   final String newText) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
        }

        @Override
        public String getDescription() {
            return "Update the text from the custom EditText";
        }

        @Override
        public void perform(final UiController uiController, final View view) {
            ((com.rey.material.widget.EditText) view).setText(newText);
        }
    };
}

Then, you can execute the custom ViewAction:

onView(withId(R.id.tagEditorSettings)).setTextEditText(null);
like image 33
jeprubio Avatar answered Sep 19 '22 10:09

jeprubio