Espresso 在回收站视图中单击两个项目

Espresso click two items in recycler view

我想以这种方式对回收站视图的两个不同项目执行两次点击:

onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            1, 
            longClick()
        )
    )
onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            2,
            longClick()
        )
    )

但我发现只有第二次点击位置 2 的项目才真正执行。
我还尝试了另一种变体:

onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            1,
            longClick()
        ),        
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            2,
            longClick()
        )
    )

但结果是一样的 - 只执行了第二次点击。 所以,问题是,我缺少什么以及如何正确实施这种情况?
感谢您的帮助!

更新。 似乎 initialTouchMode 标志不起作用。我用 initialTouchMode = true:

初始化我的 activity 测试规则
@get:Rule
var activityTestRule = ActivityTestRule(
        ListActivity::class.java,
        true,
        false
)

然后在每个 @Test 方法中我调用 activityTestRule.launchActivity(Intent(Intent.ACTION_MAIN)) 然后我点击。我发现,只有第一次点击不起作用,但第二次和第三次点击有效。那么,造成这种行为的原因是什么?

我找到问题的原因了。我的回收视图项目中有布局内部视图。这个视图实现了加载一些降价文本的 WebView。加载需要一些时间,所以我的点击是在视图真正呈现之前执行的。这是使测试工作的代码示例:

onView(withId(R.id.recycler_view))
                .perform(
                        waitForMillis(1500),//wait until markdown views loaded
                        actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(1, longClick()),
                        actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(2, longClick())
                )

其中 waitForMillis() 是自定义操作

fun waitForMillis(millis: Long): ViewAction? {
    return object : ViewAction {
        override fun getConstraints(): Matcher<View> {
            return isDisplayed()
        }

        override fun getDescription(): String {
            return "Wait for $millis milliseconds."
        }

        override fun perform(uiController: UiController, view: View) {
            uiController.loopMainThreadForAtLeast(millis)
        }
    }
}

这个解决方案有缺点。为确保在单击之前渲染视图,您需要设置固定时间,这可能会比渲染真正需要的时间更长。所以最好的解决方案是自定义匹配器,但我现在没有现成的例子。