Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Espresso - Click checkbox if not checked

I have onView(withId(R.id.check_box)).perform(click()), but i only want to do this if the check box is not already checked. How can I do this in espresso?

like image 899
kyrax Avatar asked Jun 14 '16 18:06

kyrax


People also ask

How do I check if a checkbox is checked in espresso?

You can check this by: onView(withId(R. id. checkbox)).


2 Answers

I also wanted to toggle a checkbox/switch depending on it's previous state. At first, I tried this to toggle ON a checkbox that was OFF:

onView(withId(R.id.checkbox)).check(matches(isNotChecked())).perform(scrollTo(), click()); 

...and this to toggle OFF a checkbox that was ON:

onView(withId(R.id.checkbox)).check(matches(isChecked())).perform(scrollTo(), click()); 

However, this doesn't work, since Espresso will be looking for a specific toggle state before it performs the action. Sometimes, you don't know whether it's ON or OFF beforehand.

My solution is to use a custom ViewAction to turn OFF/ON any checkable object (Switch, Checkbox, etc.) that isn't dependent on previous state. So, if it's already ON, it'll stay ON. If it's OFF, it'll toggle ON. Here's the ViewAction:

public static ViewAction setChecked(final boolean checked) {     return new ViewAction() {         @Override         public BaseMatcher<View> getConstraints() {             return new BaseMatcher<View>() {                 @Override                 public boolean matches(Object item) {                     return isA(Checkable.class).matches(item);                 }                  @Override                 public void describeMismatch(Object item, Description mismatchDescription) {}                  @Override                 public void describeTo(Description description) {}             };         }          @Override         public String getDescription() {             return null;         }          @Override         public void perform(UiController uiController, View view) {             Checkable checkableView = (Checkable) view;             checkableView.setChecked(checked);         }     }; } 

And here's how you use it (in this example, when you want to toggle to ON):

onView(withId(R.id.toggle)).perform(scrollTo(), setChecked(true)); 
like image 77
0xMatthewGroves Avatar answered Oct 04 '22 12:10

0xMatthewGroves


Just as @FrostRocket suggested but written in Kotlin.

We define a custom action that can only performed on checkable items (as specified in constraints). So we safely cast the view to Checkable to access setCheckable method.

fun setChecked(checked: Boolean) = object : ViewAction {     val checkableViewMatcher = object : BaseMatcher<View>() {         override fun matches(item: Any?): Boolean = isA(Checkable::class.java).matches(item)         override fun describeTo(description: Description?) {             description?.appendText("is Checkable instance ")         }     }      override fun getConstraints(): BaseMatcher<View> = checkableViewMatcher     override fun getDescription(): String? = null     override fun perform(uiController: UiController?, view: View) {         val checkableView: Checkable = view as Checkable         checkableView.isChecked = checked     } } 
like image 26
Achraf Amil Avatar answered Oct 04 '22 12:10

Achraf Amil