7
PopupWindow$PopupViewContainer(@xxxxxxxx)
--ListPopupWindow$DropDownListView(@yyyyyyyy)
  --RelativeLayout(@zzzzzzz)
    ImageView
    TextView
  --RelativeLayout(@aaaaaaaa)
    ImageView
    TextView
  --RelativeLayout(@aaaaaaaa)
    ImageView
    TextView

I want to know how to access the the TextView in RelativeLayout 2 using espresso android automation, as @id is not present and values are assigned dynamically.

The above is the dropdown list and I want to click second choice.

e.g like when we search item in any search box we get list populated. And I want to click the second one in the list populated. All the element id's are dynamic.

Shehary
  • 9,926
  • 10
  • 42
  • 71
StackTrace
  • 221
  • 5
  • 12

3 Answers3

9

I was struggling with this issue and I found that you need to use a combination of withText to select the view and an option called RootMatchers.isPlatformPopup() which will try and find the matching text within views such as the autocomplete view and it is actually designed for this purpose.

It should look something like;

onView(withText("matching text"))
.inRoot(RootMatchers.isPlatformPopup())
.perform(click());
arj
  • 91
  • 1
  • 3
6

You maybe be able to just do

onData(anything())
    .atPosition(1)
    .perform(click());

However, that assumes only one adapter view. If you have others, you'll need to somehow pick out that ListPopupWindow$DropDownListView.

I know you said all IDs are dynamic, but is there some ancestor view which you could pick out by ID? If so, you could do something like

onData(anything())
    .inAdapterView(isDescendantOfA(withId(someAncestorId)))
    .atPosition(1)
    .perform(click());

As a last resort, we could match on class name, but it would be a bit fragile:

onData(anything())
    .inAdapterView(withClassName(equalTo(
        "android.widget.ListPopupWindow$DropDownListView")))
    .atPosition(1)
    .perform(click());
Daniel Lubarov
  • 7,796
  • 1
  • 37
  • 56
  • 1
    Yes every id is dynamic in popup and when I see the Tree View(in android Studio) for this popup it is not displaying in MainSearchActivity but its the different Action in tree view as PopupWindow:@xxxxxxxx. Now when I try above code it is throwing error "android.support.test.espresso.NoMatchingViewException" as PopupWindow is not in main activity it is not referring the layout in popup Window but referring from MainSearchActivity. I want to set focus to popupwindow when I execute above code, it should refer popupwindow layout instead of MainActivityWindow. – StackTrace Apr 07 '15 at 01:13
  • Any resolution to this? I am having issues with multiple spinners. – JPM Aug 08 '17 at 22:30
  • @JPM you should use `inAdapterView`, but which matcher you pass it depends on what your view hierarchy looks like. Do your matchers have different IDs? Pass it `withId`. Different initial selections? Pass it `withSpinnerText`. Different parent containers (with different IDs)? Pass it `isDescendantOfA`. – Daniel Lubarov Aug 09 '17 at 18:30
1

A combination of both previous answers seems to work for me:

Espresso.onData(Matchers.anything())
        .inRoot(RootMatchers.isPlatformPopup())
        .atPosition(1)
        .perform(ViewActions.click())