Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a specific Tab position in Tab Layout using Espresso testing

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.

like image 551
Vinayak B Avatar asked Apr 03 '18 09:04

Vinayak B


People also ask

What you can find in the tab layout?

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.

What is a tab layout?

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.

Which layout is used to implement horizontal 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.


2 Answers

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)
    }
  }
}
like image 68
Abdul Rahman Avatar answered Oct 28 '22 10:10

Abdul Rahman


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))
like image 34
Be_Negative Avatar answered Oct 28 '22 10:10

Be_Negative