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

Unable to click on a view inside a recyclerview viewholder #163

Closed lewiemortier closed 4 years ago

lewiemortier commented 4 years ago

Steps to reproduce:

  1. Add a screen with a recyclerview
  2. Add a viewholder with a button to the recyclerview
  3. In the tests, go to the screen
  4. Get the first item inside the recyclerview
  5. Click on the button of the first item inside the recyclerview

Observed Results:

Expected Results:

Relevant Code:

class ScreenA : Screen<ScreenA>() {

    val recycler by lazy {
        KRecyclerView({
            this.withId(R.id.recyclerview)
        }, {
            itemType(::ViewHolder)
        })
    }

    class ViewHolder(parent: Matcher<View>) : KRecyclerItem<ViewHolder>(parent) {
        val title = KView(parent) { withId(R.id.title) }
        val moreOptions = KView { withId(R.id.more)  }
    }
}
Screen.onScreen<ScreenA> {
    recycler.firstChild<ScreenA.ViewHolder> { 
        moreOptions.click()
    }
}
Unlimity commented 4 years ago

Hi! You forgot to pass parent to your moreOptions view. Here's how it should be declared:

val moreOptions = KView(parent) { withId(R.id.more) }
Vacxe commented 4 years ago

@lewiemortier let us know please does it solve the issue?

lewiemortier commented 4 years ago

Adding the parent to the view inside the recyclerview item did not work for me. The click is still happening on the middle of the viewholder instead of on the button which is displayed on the bottom right of the viewholder.

Obviously we don't want to pass any coordinates to the click method as those coordinates will differ depending on the device this test is running on

We're using version 2.1.0 of the library

Unlimity commented 4 years ago

Can you provide your layout then, please? If espresso clicks at the center of the holder, it believes that the center of the button is at that point as well.

lewiemortier commented 4 years ago

The provided layout looks like this

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
        android:contentDescription="@string/search_result_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/spListSelectorActivated"
        android:minHeight="@dimen/row_height_72"
        android:paddingBottom="@dimen/padding_medium"
        android:paddingTop="@dimen/padding_medium"
        android:paddingStart="@dimen/padding_medium"
        android:paddingEnd="@dimen/padding_medium"
        tools:background="@android:color/darker_gray">

    <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/icon"
            android:layout_width="@dimen/content_picker_search_preview"
            android:layout_height="@dimen/content_picker_search_preview"
            android:layout_marginEnd="@dimen/padding_medium"
            android:layout_centerVertical="true"/>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_toEndOf="@id/icon"
            android:layout_toStartOf="@id/ib_more">

        <TextView
                android:id="@+id/title"
                style="@style/SP.Text.Primary"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxLines="2"
                android:textSize="16sp"
                android:layout_marginBottom="8dp" />

        <FrameLayout
                android:id="@+id/layout_tags"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:minHeight="20dp"
                android:layout_marginBottom="8dp"/>

        <TextView
                android:id="@+id/id_snippet"
                style="@style/SP.Text.Primary"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="2"
                android:ellipsize="end"/>

    </LinearLayout>

    <ImageView
            android:id="@+id/more"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_marginStart="@dimen/padding_medium"
            android:rotation="90"
            app:srcCompat="@drawable/ic_more_vert_white_24dp"/>

</RelativeLayout>

In the UI test we're trying to click on the mroe button. We've temporarily worked around the issue by using the following code snippet:

fun clickChildViewWithId(id: Int): ViewAction {
        return object : ViewAction {
            override fun getConstraints(): Matcher<View>? {
                return null
            }

            override fun getDescription(): String {
                return "Click on a child view with specified id."
            }

            override fun perform(uiController: UiController, view: View) {
                val v = view.findViewById<ImageView>(id)
                v.performClick()
            }
        }
    }
Unlimity commented 4 years ago

Hello again! I don't see any obvious issue with your layout, but I suggest you to debug it with LayoutInspector and check the boundaries of your ImageView. Your workaround just triggers the click callback and do not simulate the real click from user.

anton46 commented 4 years ago

@lewiemortier seems like the middle layout blocking the click event

 <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_toEndOf="@id/icon"
            android:layout_toStartOf="@id/ib_more">
...

If you see the id of android:layout_toStartOf="@id/ib_more" different to the more button id which should be android:id="@+id/more". I dont know if this would work but I think worth to try.

Unlimity commented 4 years ago

Closing this issue due to no activity