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...
A ViewPager allows to show multiple fragments in an activity that can be navigated by either fliping left or right. A ViewPager needs to be feed of either Views or Fragments by using a PagerAdapter.
Though dialog fragments have UI elements, their layout is populated in a separate window, rather than in the activity itself. For this reason, use FragmentScenario.launch () to test dialog fragments. // Assumes that "MyDialogFragment" extends the DialogFragment class.
A FragmentManager manages Fragments in Android, specifically, it handles transactions between fragments. A transaction is a way to add, replace, or remove fragments. getPageTitle (int pos): (optional) Similar to getItem () this methods returns the title of the page at index pos.
When the FragmentScenario class recreates the fragment under test, the fragment returns to the lifecycle state that it was in before it was destroyed. To trigger UI actions in your fragment under test, use Espresso view matchers to interact with elements in your view: ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With