Android espresso accessing EditText in adapter in first row - android

I am using Espresso for testing my app. I have a listview with some data in it. I want to check the value of an edittext in the first line.
I tried:
onData(withId(R.id.editTextKommissioniert)).inAdapterView(withId(R.id.jflArticleList_ListView)).atPosition(0).check(matches(withText("60.0")));
But I always get this exception:
android.support.test.espresso.AmbiguousViewMatcherException: 'with id:
at.stockserv:id/editTextKommissioniert' matches multiple views in the
hierarchy.
What can I do, to access the first line in my adapter?

Try below approach , Working for me
onData(anything()).inAdapterView(withId(R.id.jflArticleList_ListView))
.atPosition(0).onChildView(withId(R.id.edt_id)).check(matches(withText("60.0")));

Related

data binding to list size is not working?

I have an android app that shows a screen to the user to enter data if a List is empty, otherwise it shows the List in a recyclerview.
When the app first starts this works fine. The data must be read from an online database so the empty list text shows until the data is loaded and then the list shows. If I delete the entries from the database using the app the List size goes to zero, but the empty list does not show, the Recyclerview remains visible (but empty sine the List is empty.
The binding for the empty textview is:
android:visibility="#{list.size() == 0 ? View.VISIBLE : View.GONE}"
and for the recyclerview is:
android:visibility="#{list.size() == 0 ? View.GONE : View.VISIBLE}"
The List is bound using:
binding.setList(mList) ;
As I said the startup of the app works so I don't understand why having the list go to empty does not also work.
Any pointers would be much appreciated.
It seems like you are not triggering the "binding update" after deleting items from database. Anyway you could approach it differently, using let's say LiveData<Boolean> or ObservableBoolean that would say wheter list is empty or not, your binding expression would not change.
The advantage of using LiveData or Observable<T>with dataBinding is that everytime you change the value of these it is "propagated" to the view automatically - so you dont need to do this binding.setList(mList); each time view should update. There is also ObservableArrayList, binding that instead of regular List might work too, but I haven't tried that.
see using observables with databinding
By the way the LiveData + databinding works even better if you place your LiveData into a ViewModel and bind from xml to that.

Espresso, clicking on a item at position

I'm trying to click on a item at a specific position in a grid view.
onData(instanceOf(MyClass.class))
.inAdapterView(withId(R.id.my_view))
.atPosition(R.integer.my_id)
.perform(click());
but I'm getting this java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
I'm queuing the responses using MockWebServer, even after the UI is on screen with all the list item, I'm getting this error, I'm not sure why.
Also, I want to get the content of the specific item.
Well, I think that's because you're matching class which is only one, not a specific adapter with values.
Please consider this post:
The matcher passed as argument to onData() must match the value as
returned by Adapter.getItem(). So the first version doesn't match,
because of the wrong type being used. It should be:
onData(is(instanceOf(IconRowAdapter.IconRow.class)))
What also can be a pitfall is using equalTo on different kinds of
CharSequences. String is a CharSequence, but if IconRow.getText()
returns CharSequence instead of String, then this can also be
Spannable, Editable, etc in which case equalTo wouldn't match. So if
IconRow.getText() return anything but String, make sure to convert it
into a String before comparison.
This post was taken from How to use Espresso to test item in adapter at a specific position
Your question lacks of code of tested class, so I cannot give you direct answer. I can only recommend to read StackOverflow link above.
Hope it help
You may need to "drill down" a little deeper into the view hierarchy to get to the item in the cell. Put an additional method call before the ".perform" using the id of the item in the grid cell
onChildView(withId(R.id.???)).perform(click());
Use the id of the view that the user would click on.

Espresso - check if the TextView exists in the ListView

I want to check displaying of Save €XX in the list. Save €XX is a TextView that can be VISIBLE or INVISIBLE. I use JUnit 4 and Espresso 2.2.1.
I tried to check it like this:
onView(withText(startsWith("Save"))).check(matches(isDisplayed()));
but always get an error:
android.support.test.espresso.AmbiguousViewMatcherException: 'with text: a string starting with "Save"' matches multiple views in the hierarchy.
Is there a way to if the TextView exists in the ListView with Espresso?
UPDATE
I also tried to use onData:
onData(hasToString(startsWith("Save")))
.inAdapterView(withId(R.id.suggestion_list_view)).atPosition(0)
.check(matches(isDisplayed()));
but it seems that onData works with data layer but not the view layer. Therefore, I receive the error:
java.lang.RuntimeException: No data found matching: with toString() a string starting with "Save" contained values: <[Data: ...]>
After several tries, I found the way.
In this case, we should use a combined approach and work with both data and view layers. We access the ListView by ID and choose the first item. Then check it for the 'Save' text.
onData(anything())
.inAdapterView(withId(R.id.list_view))
.atPosition(0)
.onChildView(withId(R.id.suggestion_saving))
.check(matches(withText(startsWith("Save"))));
Works like a charm. Enjoy!

Testing ViewPager with multiple fragments using android espresso

I am trying to test my app which uses ViewPager. Each page contains fragments but these fragments are not always visible. I want to check visibility of a fragment in the currently visible page.
onView(withId(R.id.container_weather))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
But the problem is that espresso looks are all the pages not just the current page and I get the following error:
android.support.test.espresso.AmbiguousViewMatcherException: 'with id: eu.airpatrol.android:id/container_weather' matches multiple views in the hierarchy...
I had the same problem, however using the condition isCompletelyDisplayed() solved this problem as it only takes into account the on-screen views.
So, something like this should work:
onView(allOf(withId(R.id.container_weather), isCompletelyDisplayed()))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
Note: isDisplayed() works too in some cases but it also takes views off-screen into account and won't work if the ViewPager has any other page pr fragment loaded with the same view id.
Your tests are failing because of multiple elements with the same id. You can combine conditions using allOf(...). Then use isDisplayed() to check that matched view is visible on the screen. Below example can work:
onView(allOf(
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
withId(R.id.container_weather)))
.check(matches(isDisplayed()));
Ran into this exact same problem. I was fortunate because the view hierarchies in my ViewPager can be easily identified by their siblings, so I was able to solve this using the hasSibling matcher, like so:
onView(
allOf(
hasSibling(withId(R.id.some_sibling)),
withId(R.id.field_to_test)
)
).perform(replaceText("123"));
Not a perfect solution as it can be slightly brittle, but in my case I think it was an acceptable compromise.
I had similar problem, where I was reusing the button layout and it was giving me a matches multiple views in the hierarchy exception.
So the easy work around I did was to create 2 different screens and have 2 different methods with different text.
Withdraw Screen:
public WithdrawScreen clickWithdraw() {
onView(allOf(withId(R.id.save_button), withText("Withdraw")))
.perform(click());
return this;
}
Deposit Screen:
public DepositScreen clickDeposit() {
onView(allOf(withId(R.id.save_button), withText("Deposit")))
.perform(click());
return this;
}
and in my tests, I create a new instance of both screens and call the above methods based on screen reference which is a bit easy to test for.
WithdrawScreen withdrawInstance = new WithdrawScreen();
withdrawInstance.clickWithdraw();
DepositScreen depositInstance = new DepositScreen();
depositInstance.clickDeposit();
The point was they were using same id - R.id.save_button for button and I was replacing text of button based on visibility of the fragment we are on.
Hope it helps.

getting logcat error as cannot be casted

I want to generate a listview from sqlite database but the
LOGCAT shows error.
What does this below error mean?
09-23 12:01:20.354: E/AndroidRuntime(3682): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.abhishekp.listproduct/com.abhishekp.listproduct.List}: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.widget.ListView
Its Happen only because of..two possibilities.
1) If you are using TextView in xml file...
and try to initialize it with.
TextView tv=(ListView)findViewbyId(R.id.textView);
and if it is right then change it with
TextView tv=(TextView)findViewbyId(R.id.textView);
2) May be you are trying to put id of listView instead of text view.
like
TextView tv=(TextView)findViewbyId(R.id.listView);
if it is then should change
TextView tv=(TextView )findViewbyId(R.id.textView );
And if it is all good then try to clean your project and rebuild it...
Thanks!!
From your logcat its clearly showing that you are trying to cast your TextView in ListView. Check you may have declared your TextView i.e.
TextView tv=(ListView)findViewbyId(R.id.textView);
or may be you are referring the id of your ListView in your java file.
TextView tv=(ListView)findViewbyId(R.id.listView); //id defined is of listview
Eclipse tends to mess up your resources every now and then. This leads to some odd behavior such as strings and images being swapped all over your app, and more commonly classCastException(s), which happen when Eclipse switches your Views' ids around.
Just clean your project.It will work fine.

Categories

Resources