Espresso AutoCompleteTextView 点击

Espresso AutoCompleteTextView click

所以我最近开始在我现有的 Android 项目之一中使用 Espresso。

一切都很顺利,直到我在我的程序中找到 AutoCompleteTextView。我似乎不明白如何正确单击自动完成列表中的第一件事。实际上,我什至不确定在这种情况下使用 onView() 还是 onData()

所以我终于弄明白了,多亏了之前的问题: Testing autocomplete textview using espresso tool

我只是 post 我的版本,供将来可能使用它的人使用。

    onData(instanceOf("Whatever your arrayadapter contains".class)).inRoot(RootMatchers.withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView())))).perform(ViewActions.click());

我想我找到了比接受的答案更简洁的方法!

onData(equalTo("ITEM")).inRoot(RootMatchers.isPlatformPopup()).perform(click());

细分:

  • onData(x) 这将在下拉列表中找到呈现与 x 匹配的数据对象的视图。数据由 Adaptor 提供给 AutoCompleteTextView,因此它可以是 Adaptor 提供的任何类型的对象,它可能不会是视图。为此,您需要使用标准的 hamcrest 核心匹配器(equalToinstanceOf 等...)而不是(withTextwithId 等... ).尝试找到这是什么对象以及如何匹配它可能会很痛苦,但没有更简洁的方法:适配器中有很多项目,一些视图甚至还不在层次结构中,所以 onView 无法工作! onData 将确保加载与您的数据匹配的视图。签出 here (this what onData returns) and here(这会加载匹配数据)
  • inRoot(RootMatchers.isPlatformPopup()) 结果下拉菜单在另一个 window 上,而不是默认的 window 你的 activity 运行。所以我们必须指定我们想要搜索 window。接受的答案使用 RootMatchers.withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView()))) 似乎匹配任何非默认答案的 window。

无论如何HTH别人。

由于某些我不知道的原因,AStupidNoob 的解决方案不起作用。所以我又找到了一个:

onView(withText("Spinner Item"))
            .inRoot(RootMatchers.isPlatformPopup())
            .perform(click());

A​​utoCompleteTextView 本身

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/textInputLayout2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="12dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    app:layout_constraintEnd_toStartOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <AutoCompleteTextView
        android:id="@+id/product"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:completionThreshold="1"
        android:hint="@string/product"
        android:singleLine="true"
        android:textSize="16sp" />

</com.google.android.material.textfield.TextInputLayout>

根据 AStupidNoob 2017 年 7 月 28 日的回答...

要单击下拉列表的特定行号,您可以使用:

onData(anything())
    .atPosition(2)
    .inRoot(RootMatchers.isPlatformPopup())
    .perform(click());

要点击下拉列表特定行号中的特定项目,您可以使用:

onData(anything())
    .atPosition(2)
    .inRoot(RootMatchers.isPlatformPopup())
    .onChildView(withId(R.id.button_on_layout))
    .perform(click());

对于仍然 运行 解决这个问题的任何人,尽管尝试了上面接受的解决方案,但在我发现的 github issue 的帮助下,我设法让它工作。作为参考,我使用的是 Robolectric 4.6,我相信这可能是我需要与非仪器化测试不同的解决方案的原因。

我想出的解决方案(验证项目是否出现在 AutoCompleteTextView 弹出窗口中是:

fun testAutoCompleteTextViewEntry() {
  onView(withId(R.id.editText_search))
    .perform(typeTextIntoFocusedView("x"), showDropDown())
  onView(withText("xyz"))
   .inRoot(RootMatchers.isPlatformPopup())
   .check(matches(isDisplayed()))
}

// Somewhere else in your code
fun showDropDown(): ViewAction =
   object : ViewAction {
     override fun getDescription(): String = "Shows the dropdown menu of an AutoCompleteTextView"

     override fun getConstraints(): Matcher<View> = allOf(
       isEnabled(), isAssignableFrom(AutoCompleteTextView::class.java)
     )

     override fun perform(uiController: UiController, view: View) {
       val autoCompleteTextView = view as AutoCompleteTextView
       autoCompleteTextView.showDropDown()
       uiController.loopMainThreadUntilIdle()
     }
}