agoda-com / Kakao

This repo is no longer supported. Please visit a https://github.com/KakaoCup/Kakao
Apache License 2.0
1.11k stars 102 forks source link

AmbiguousViewMatcherException with recycler views #227

Closed vkosovskii closed 4 years ago

vkosovskii commented 4 years ago

Steps to reproduce:

On the ViewPager I have three RecyclerViews and when I just try to check "rvAppsList.isVisible()" test failed and shows an error: androidx.test.espresso.AmbiguousViewMatcherException: '(with id: com.malwarebytes.antimalware.cloud:id/rvAppsList)' matches multiple views in the hierarchy. Problem views are marked with 'MATCHES' below.

Create a recycler view:

// Apps list
    val rvAppsList = KRecyclerView({
        withId(R.id.rvAppsList)
    }, itemTypeBuilder = {
        itemType(YourAppsScreen::ListItems)
    })

    class ListItems(parent: Matcher<View>) : KRecyclerItem<ListItems>(parent) {
        val ivAppIcon = KImageView(parent) { withId(R.id.iv_app_icon) }
        val tvAppName = KTextView(parent) { withId(R.id.tv_app_name) }
        val tvAppPackageName = KTextView(parent) { withId(R.id.tv_app_package_name) }
        val tvAppLastUpdate = KTextView(parent) { withId(R.id.tv_app_last_update) }
    }

Failing on the step "isVisible"

private fun isMyLabelIsVisible(): Boolean {
        return try {
            yourAppsScreen.rvList.isVisible()
            true
        } catch (e: AssertionFailedError) {
            false
        } catch (e: NoMatchingViewException) {
            false
        }
    }

Observed Results:

androidx.test.espresso.AmbiguousViewMatcherException: '(with id: com.malwarebytes.antimalware.cloud:id/rvAppsList)' matches multiple views in the hierarchy.
Problem views are marked with '****MATCHES****' below.

View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1920, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@745332f, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+-->ViewStub{id=16908682, res-name=action_mode_bar_stub, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@3694d3c, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
+-->FrameLayout{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@1c65ac5, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}
|
+--->FitWindowsFrameLayout{id=2131361837, res-name=action_bar_root, visibility=VISIBLE, width=1080, height=1794, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@b7bd34b, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
Unlimity commented 4 years ago

Hi and thanks for reaching out. Although, the recycler views in your ViewPager are not displayed, pager works in a fashion that keeps at least 3 pages active, which means the non-displayed recyclers are present within the view hierarchy, thus the ambiguous match exception. The easiest thing to do is to match the actively displayed recycler in your case:

val rvAppList = KRecyclerView({
    withId(R.id.rvAppList)
    isDisplayed() // or isCompletelyDisplayed()
}, ...

I hope that helps 👍

vkosovskii commented 4 years ago

Yes! Thanks a lot!! isCompletelyDisplayed() completely solved my problem.