48

I'm attempting to update an EditText as part of an Espresso test with:

onView(allOf(withClassName(endsWith("EditText")), withText(is("Test")))).perform(clearText())
                                                                        .perform(click())
                                                                        .perform(typeText("Another test"));

However I receive the following error:

com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: No views in hierarchy found matching: (with class name: a string ending with "EditText" and with text: is "Test")

By breaking down the test line I can see that this occurs after performing clearText(), so I assume that the matchers are being re-run prior to each perform and fail the prior to the second action. Although this makes sense, it leaves me somewhat confused as to how to update the EditText using Espresso. How should I do this?

Note that I cannot use a resource ID or similar in this scenario and have to use the combination as shown above to identify the correct view.

5 Answers5

53

You can use the replaceText method.

onView(allOf(withClassName(endsWith("EditText")), withText(is("Test"))))
    .perform(replaceText("Another test"));
Benoit Duffez
  • 11,839
  • 12
  • 77
  • 125
Abhinav Manchanda
  • 6,546
  • 3
  • 39
  • 46
  • replaceText() function works! That saved me. Seems that typeText() has some problems with input keyboard. – herbertD Dec 10 '15 at 06:44
28

Three things to try:

1. You can run performs in succession.

onView(...)
    .perform(clearText(), typeText("Some Text"));

2. There is a recorded issue on the Espresso page which was marked as invalid (but is still very much a bug). A workaround for this is to pause the test in-between performs.

public void test01(){
    onView(...).perform(clearText(), typeText("Some Text"));
    pauseTestFor(500);
    onView(...).perform(clearText(), typeText("Some Text"));
}

private void pauseTestFor(long milliseconds) {
    try {
        Thread.sleep(milliseconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

3. Are you absolutely sure that your EditText contains the text, "Test"?

James Davis
  • 301
  • 4
  • 7
4

To set value in EditText with Espresso simple like this

onView(withId(R.id.yourIdEditText)).perform(typeText("Your Text"))

  • 1
    OP states that "Note that I cannot use a resource ID or similar in this scenario and have to use the combination as shown above to identify the correct view." ... – Bö macht Blau Apr 23 '20 at 05:56
2

I was having a similar issue and solved it using the containsString matcher and Class.getSimpleName(). Like this:

onView(withClassName(containsString(PDFViewPagerIVZoom.class.getSimpleName()))).check(matches(isDisplayed()));

You can see the full code here

voghDev
  • 5,641
  • 2
  • 37
  • 41
1

You could try two things. First I would try to use

onView(withId(<id>).perform... 

This way you would always have access to the EditText field even when other EditText fields are on the screen.

If that's not an option, you could split up your perform calls.

onView(allOf(withClassName(endsWith("EditText")),withText(is("Test")))).perform(clearText());
onView(withClassName(endsWith("EditText"))).perform(click());
onView(withClassName(endsWith("EditText"))).perform(typeText("Another Test");
Maxwell
  • 6,532
  • 4
  • 37
  • 55
  • 1
    Thanks for the response. Unfortunately there are multiple EditTexts in the activity, programatically generated without IDs, so neither of these suggestions will work. –  May 21 '14 at 20:55
  • I see. Perhaps you could set a tag to each EditText you create and find the view based on that tag. The tag may only be used for testing, but it would at least give you something to differentiate the EditText fields. Then again, that may violate the condition you mention at the end of your question (I overlooked that part before I answered). – Maxwell May 21 '14 at 21:18