9

I am trying to access a button from a specific view. The same view is displayed 6 times. This is the code I am using.

public void testTimeConfig(){
    onData(withDesc("description")).onChildView(withId(R.id.positive)).perform(click());
}

private static Matcher<Object> withDesc(String desc) {
    return allOf(is(instanceOf(String.class)), is(desc));
}

When I run, I get an error:

Error performing 'load adapter data' on view 'is assignable from class: class android.widget.AdapterView'.

Is this the best way to access a child view? If so, how?

EDIT

This is the code I am trying to use now.

   onView(allOf((withContentDescription("description")), hasSibling(withContentDescription("SettingsLayout")), hasSibling(withId(R.id.positive)))).perform(click());

and

   onView(allOf((withContentDescription("description")), hasSibling(withId(R.id.positive)))).perform(click());

With this Error:

   No views in hierarchy found matching

The xml

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/setAGoalTitle"
        android:layout_alignParentLeft="true"
        class="com.xxx"
        android:layout_marginTop="30dp"
        android:id="@+id/timeGoalWidget"
        app:goalLabel="@string/time_min_upper"
        app:icon="@drawable/ic_icn_summary_time"
        app:step="300"
        app:valueFormat="time"
        android:gravity="center_horizontal"
        android:layout_marginBottom="60dp"
        android:contentDescription="setAGoalTimeConfigurator"/>

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/timeGoalWidget"
        class="com.xxx"
        android:id="@+id/distanceGoalWidget"
        app:goalLabel="@string/distance_upper"
        app:icon="@drawable/ic_icn_summary_track"
        app:step="0.25"
        app:valueFormat="decimal_two"
        android:gravity="center_horizontal"
        android:contentDescription="setAGoalDistanceConfigurator"/>

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/timeGoalWidget"
        android:layout_alignLeft="@id/timeGoalWidget"
        class="com.xxx"
        android:id="@+id/paceGoalWidget"
        app:goalLabel="@string/pace_upper"
        app:icon="@drawable/ic_icn_summary_pace"
        app:valueFormat="time"
        app:step="10"
        android:gravity="center_horizontal"
        android:layout_marginBottom="60dp"
        android:contentDescription="setAGoalPaceConfigurator"/>


    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/distanceGoalWidget"
        android:layout_alignTop="@id/paceGoalWidget"
        class="com.xxx"
        android:id="@+id/speedGoalWidget"
        app:goalLabel="@string/speed_upper"
        app:icon="@drawable/ic_icn_summary_speed"
        app:step="0.5"
        app:valueFormat="decimal_two"
        android:gravity="center_horizontal"
        android:contentDescription="setAGoalSpeedConfigurator"/>


    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/paceGoalWidget"
        android:layout_alignLeft="@id/paceGoalWidget"
        class="com.xxx"
        android:id="@+id/inclineGoalWidget"
        app:goalLabel="@string/incline_percent_upper"
        app:icon="@drawable/ic_icn_summary_elevation"
        app:step="0.5"
        app:valueFormat="decimal_two"
        android:gravity="center_horizontal"
        android:contentDescription="setAGoalInclineConfigurator"/>


    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/speedGoalWidget"
        android:layout_alignTop="@id/inclineGoalWidget"
        class="com.xxx"
        android:id="@+id/caloriesGoalWidget"
        app:goalLabel="@string/calories_upper"
        app:icon="@drawable/ic_icn_summary_calories"
        app:step="10"
        app:valueFormat="decimal_zero"
        android:gravity="center_horizontal"
        android:contentDescription="setAGoalCaloriesConfigurator"/>


</RelativeLayout>

The view xml that is used 6 times.

<ImageButton
    android:id="@+id/increaseGoalButton"
    android:layout_height="@dimen/view_goal_setting_incrementor_button_height_width"
    android:layout_width="@dimen/view_goal_setting_incrementor_button_height_width"
    android:background="@drawable/button_goal_widget"
    android:gravity="center"
    android:src="@drawable/ic_plus"
    android:textSize="@dimen/view_goal_setting_incrementor_button_text_size"
    android:textColor="@color/goal_configuration_widget_button_text_color"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="1dp"
    android:contentDescription="@string/increase"/>

<ImageButton
    android:id="@+id/decreaseGoalButton"
    android:layout_height="@dimen/view_goal_setting_incrementor_button_height_width"
    android:layout_width="@dimen/view_goal_setting_incrementor_button_height_width"
    android:background="@drawable/button_goal_widget"
    android:gravity="center"
    android:src="@drawable/ic_minus"
    android:textSize="@dimen/view_goal_setting_incrementor_button_text_size"
    android:layout_alignParentRight="true"
    android:textColor="@color/goal_configuration_widget_button_text_color"
    android:layout_below="@id/increaseGoalButton"
    android:contentDescription="@string/decrease"/>

<LinearLayout
    android:id="@+id/goalWidgetValueContainer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_toLeftOf="@id/increaseGoalButton"
    android:layout_centerVertical="true"
    android:gravity="center_vertical|right"
    android:layout_marginRight="@dimen/view_goal_setting_value_margin_right" >

    <TextView
        android:id="@+id/goalValueTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textColor="@color/goal_configuration_widget_value_text_color"
        android:textSize="@dimen/view_goal_setting_value_text_size"
        android:lineSpacingExtra="-10sp"
        app:typeface="proxima_bold"
        android:text="999:00"/>

    <TextView
        android:id="@+id/goalValueLabelTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="right"
        android:textSize="@dimen/view_goal_setting_value_label_text_size"
        android:textColor="@color/goal_configuration_widget_value_text_color"
        android:includeFontPadding="false"
        android:lineSpacingExtra="10sp"
        android:text="@string/incline_percent_upper"/>

</LinearLayout>

It is the ImageView with id increaseGoalButton that I am trying to click.

Community
  • 1
  • 1
Chad Bingham
  • 32,650
  • 19
  • 86
  • 115

3 Answers3

27

Based on your last comment you should use onView() instead of onData(). I think you'll be able to click the button using hasSibling() - example

onView(allOf(withId(R.id.positive), hasSibling(withDesc(someString))))
    .perform(click());

or examples without your custom matcher (sibling view has text):

onView(allOf(withId(R.id.positive), hasSibling(withText(someString))))
    .perform(click());

or (sibling view has content description):

onView(allOf(withId(R.id.positive), hasSibling(withContentDescription(someString))))
    .perform(click());

EDITED:

OK, I'd try these two variants:

onView(allOf(withId(R.id.increaseGoalButton), isDescendantOfA(withId(R.id.timeGoalWidget))))
    .perform(click());

or

onView(allOf(withId(R.id.increaseGoalButton), withParent(withId(R.id.timeGoalWidget))))
    .perform(click());
denys
  • 6,834
  • 3
  • 37
  • 36
  • These three examples are all the same – Chad Bingham Dec 31 '13 at 15:26
  • There are 3 cases: 1st with custom matcher, 2nd for a view with text and 3rd for a view with content description. Does any of them work for you? – denys Dec 31 '13 at 16:04
  • Sorry, I was looking at them on my phone and all I got was `onView(allOf(withId(R.id.positive)` so they all looked the same. I will play around with this and see if it works – Chad Bingham Dec 31 '13 at 16:18
  • +1 for mentioning `hasSbiling()`. Do you know if it matters if the view is inside a `RelativeLayout`, inside the parent `RelativeLayout`? So it is two children deep? – Chad Bingham Dec 31 '13 at 17:31
  • Take a look at source code for `hasSibling()` matcher - [link](https://code.google.com/p/android-test-kit/source/browse/espresso/lib/src/main/java/com/google/android/apps/common/testing/ui/espresso/matcher/ViewMatchers.java#199). Seems that they must be in the same parent. Can you also post your layout xml file, since it's hard to judge without it. – denys Jan 01 '14 at 13:32
  • Ok I posted the xml. Take a look. Sorry for the delay. I had to edit it so I am not showing sensitive information. – Chad Bingham Jan 02 '14 at 16:58
  • Is the `com.xxx` needed? – Chad Bingham Jan 02 '14 at 20:32
  • No, I just took it from your example. You should replace it with your real package name which you changed to com.xxx in above xml code. – denys Jan 02 '14 at 20:37
  • Right. I am wondering if the com.package is need at all. Right now I am just using `R.id`. without the `com.xx` – Chad Bingham Jan 02 '14 at 20:40
  • `hasParent` did not work. isDescendantOfA` does. Thanks. – Chad Bingham Jan 02 '14 at 21:50
  • `hasParent` does not exist. There is a `withParent` method instead. – lacton Sep 23 '14 at 14:04
  • +1 for `onView(allOf(withId(R.id.increaseGoalButton), isDescendantOfA(withId(R.id.timeGoalWidget)))) .perform(click());` – Ruwanka De Silva Jul 11 '17 at 07:55
1

None of your content descriptions match the string "description" that's why it doesn't find anything.

Bebop_
  • 645
  • 2
  • 6
  • 9
0

Assuming the button id is R.id.positive, and the id is unique in the current activity view, you can simply use:

onView(withId(R.id.positive)).perform(click());
skyleecm
  • 437
  • 2
  • 4