I have a tab layout with view pager .I am using Espresso for testing my android app. In my previous projects I use the tab title to perform click for selecting a tab Position like follows.
Espresso.onView(ViewMatchers.withText("MAP"))
.perform(ViewActions.click());
Right now I a have 114 tabs. So I can't use above method for randomly select these tabs for testing. Is there any way I can select tabs by its position. I already check other solutions but none of those helped me.
The Layout tab includes a selection tool for cells, rows, columns, and the entire table; tools to delete or insert rows and columns; tools to merge or divide cells; cell alignment and margin settings; the typography controls for Open Type fonts.
In Android TabLayout is a new element introduced in Design Support library. It provides horizontal layout to display tabs on the screen. We can display more screens in a single screen using tabs. We can quickly swipe between the tabs.
In this article, we will learn about how to add TabLayout with ViewPager in an app. TabLayout provides a horizontal layout to display tabs.
Both of the above answers are good. For me, after selecting the tab I also wanted to verify that it is the correct tab by matching with the title. Since, this post is about espresso testing, I will share the code snippet here as it may be helpful to someone.
fun matchCurrentTabTitle(tabTitle: String): Matcher<View> {
return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) {
description?.appendText("unable to match title of current selected tab with $tabTitle")
}
override fun matchesSafely(item: View?): Boolean {
val tabLayout = item as TabLayout
val tabAtIndex: TabLayout.Tab = tabLayout.getTabAt(tabLayout.selectedTabPosition)
?: throw PerformException.Builder()
.withCause(Throwable("No tab at index ${tabLayout.selectedTabPosition}"))
.build()
return tabAtIndex.text.toString().contains(tabTitle, true)
}
}
}
fun matchTabTitleAtPosition(tabTitle: String, tabIndex: Int): Matcher<View> {
return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) {
description?.appendText("unable to select tab at index $tabIndex and match title with $tabTitle")
}
override fun matchesSafely(item: View?): Boolean {
val tabLayout = item as TabLayout
val tabAtIndex: TabLayout.Tab = tabLayout.getTabAt(tabIndex)
?: throw PerformException.Builder()
.withCause(Throwable("No tab at index $tabIndex"))
.build()
return tabAtIndex.text.toString().contains(tabTitle, true)
}
}
}
Should be doable with a custom ViewAction
. Something like this:
fun selectTabAtPosition(tabIndex: Int): ViewAction {
return object : ViewAction {
override fun getDescription() = "with tab at index $tabIndex"
override fun getConstraints() = allOf(isDisplayed(), isAssignableFrom(TabLayout::class.java))
override fun perform(uiController: UiController, view: View) {
val tabLayout = view as TabLayout
val tabAtIndex: TabLayout.Tab = tabLayout.getTabAt(tabIndex)
?: throw PerformException.Builder()
.withCause(Throwable("No tab at index $tabIndex"))
.build()
tabAtIndex.select()
}
}
}
and the usage:
onView(withId(R.id.tab_layout)).perform(selectTabAtPosition(99))
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