Testing ViewPager with multiple fragments using the android endgame

I am trying to test my application that uses ViewPager . Each page contains fragments, but these fragments are not always visible. I want to check the visibility of a fragment on the current visible page.

 onView(withId(R.id.container_weather)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))); 

But the problem is that the espresso looks all the pages of not only the current page, and I get the following error:

android.support.test.espresso.AmbiguousViewMatcherException: 'with id: eu.airpatrol.android:id/container_weather' corresponds to several views in the hierarchy ...

+4
source share
4 answers

Your tests do not work due to multiple elements with the same identifier. You can combine conditions using allOf(...) . Then use isDisplayed() to verify that the matching view is displayed on the screen. The following is an example:

 onView(allOf( withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), withId(R.id.container_weather))) .check(matches(isDisplayed())); 
+5
source

Ran into this same problem. I was lucky because the view hierarchies in my ViewPager can be easily identified by their siblings, so I was able to solve this problem with the hasSibling routine, for example:

 onView( allOf( hasSibling(withId(R.id.some_sibling)), withId(R.id.field_to_test) ) ).perform(replaceText("123")); 

Not an ideal solution, as it can be a little fragile, but in my case, I think this is an acceptable compromise.

+1
source

I had the same problem, but when using the isCompletelyDisplayed() condition, this problem was resolved, since it only takes into account screen representations.

So something like this should work:

 onView(allOf(withId(R.id.container_weather), isCompletelyDisplayed())) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))); 

Note: isDisplayed() also works in some cases, but also takes into account off-screen views and will not work if the ViewPager has another fragment of the pr page loaded with the same identifier.

+1
source

I had a similar problem when I reused the button layout and it gave me some matches in a hierarchy exception.

So the easy work around me was to create two different screens and two different methods with different text.

  • Cancel 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 the screen link, which is a little easy to verify.

 WithdrawScreen withdrawInstance = new WithdrawScreen(); withdrawInstance.clickWithdraw(); DepositScreen depositInstance = new DepositScreen(); depositInstance.clickDeposit(); 

The bottom line is that they used the same identifier - R.id.save_button for the button, and I changed the button text based on the visibility of the fragment in which we are.

Hope this helps.

0
source

All Articles