Espresso: return boolean if view exists

I am trying to check to see if a view is displayed with Espresso. Here is some pseudo code to show what I am trying:

if (!Espresso.onView(withId(R.id.someID)).check(doesNotExist()){
   // then do something
 } else {
   // do nothing, or what have you
 }

But my problem is .check(doesNotExist()) does not return boolean. It is just an assertion. With UiAutomator I was able to just do something like so:

  • Sending files using POST with HttpURLConnection
  • How to get current GoogleMap zoom level?
  • Where is the source code of Android Architecture Components?
  • Divider for vertical LinearLayout?
  • Fragments overlapping each other
  • Caused by: android.os.NetworkOnMainThreadException
  •  if (UiAutomator.getbyId(SomeId).exists){
          .....
       }
    

    I found this; check line 46. Still can’t find out how to use it.

    Related posts:

    Use RxAndroid or RxKotlin when programming in Kotlin for Android?
    Android: How do I display an updating clock in a TextView
    How to send post parameters dynamically (or in loop) in OKHTTP 3.x in android?
    Measuring text width to be drawn on Canvas ( Android )
    Programmatically change the width of the Button in android
    Android - show animated status bar icon
  • CSS Media Queries on Nexus 7, display resolution not working in code
  • Making part of a string bold in textview
  • Dropping event due to window no focus
  • What is standard resolution of android tablet?
  • How to open Gmail Compose when a button is clicked in Android App?
  • Android - delayed clicks in ListView
  • 5 Solutions collect form web for “Espresso: return boolean if view exists”

    We need that functionality and I ended up implementing it below:

    https://github.com/marcosdiez/espresso_clone

    if(onView(withText("click OK to Continue")).exists()){ 
        doSomething(); 
    } else { 
       doSomethingElse(); 
    }
    

    I hope it is useful for you.

    Conditional logic in tests is undesirable. With that in mind, Espresso’s API was designed to guide the test author away from it (by being explicit with test actions and assertions).

    Having said that, you can still achieve the above by implementing your own ViewAction and capturing the isDisplayed check (inside the perform method) into an AtomicBoolean.

    Another less elegant option – catch the exception that gets thrown by failed check:

        try {
            onView(withText("my button")).check(matches(isDisplayed()));
            //view is displayed logic
        } catch (NoMatchingViewException e) {
            //view not displayed logic
        }
    

    You check with the below code also. If view is displayed it will click else it will pass on.

    onView(withText("OK")).withFailureHandler(new FailureHandler() {
            @Override
            public void handle(Throwable error, Matcher<View> viewMatcher){
            }
        }).check(matches(isDisplayed())).perform(customClick());
    

    I think to mimic UIAutomator you can do this:
    (Though, I suggest rethinking your approach to have no conditions.)

    ViewInteraction view = onView(withBlah(...)); // supports .inRoot(...) as well
    if (exists(view)) {
         view.perform(...);
    }
    
    @CheckResult
    public static boolean exists(ViewInteraction interaction) {
        try {
            interaction.perform(new ViewAction() {
                @Override public Matcher<View> getConstraints() {
                    return any(View.class);
                }
                @Override public String getDescription() {
                    return "check for existence";
                }
                @Override public void perform(UiController uiController, View view) {
                    // no op, if this is run, then the execution will continue after .perform(...)
                }
            });
            return true;
        } catch (AmbiguousViewMatcherException ex) {
            // if there's any interaction later with the same matcher, that'll fail anyway
            return true; // we found more than one
        } catch (NoMatchingViewException ex) {
            return false;
        } catch (NoMatchingRootException ex) {
            // optional depending on what you think "exists" means
            return false;
        }
    }
    

    Also exists without branching can be implemented really simple:

    onView(withBlah()).check(exists()); // the opposite of doesNotExist()
    
    public static ViewAssertion exists() {
        return matches(anything());
    }
    

    Though most of the time it’s worth checking for matches(isDisplayed()) anyway.

    Based on the answer by Dhiren Mudgil, I ended up writing the following method:

    public static boolean viewIsDisplayed(int viewId)
    {
        final boolean[] isDisplayed = {true};
        onView(withId(viewId)).withFailureHandler(new FailureHandler()
        {
            @Override
            public void handle(Throwable error, Matcher<View> viewMatcher)
            {
                isDisplayed[0] = false;
            }
        }).check(matches(isDisplayed()));
        return isDisplayed[0];
    }
    

    I’m using this to help determine which View in a ViewFlipper is currently displayed.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.