Search code examples
androidautocompletetextviewandroid-espressotesting-support-library

Testing AutoCompleteTextView with Espresso


I am using Espresso to test an app with several AutoCompleteTextViews. For one particular test, the autocomplete popup appears, but I want to just ignore it and move to the next TextView. How can I do this? My ideas are to either simulate a "Back" press or simulate a tap in the popup.

Update:

I am attempting the following to click on the autocomplete popup:

onView(withId(R.id.brand_text))
        .perform(scrollTo(), typeText(card.getBrand()));
onData(allOf(is(instanceOf(String.class)), is(card.getBrand())))
        .inRoot(isPlatformPopup())
        .perform(click());
onView(withId(R.id.brand_text))
        .check(matches(withText(card.getBrand())));

Now the problem is that in some cases, the text entered doesn't have any autocomplete matches so no popup appears. How do I conditionally perform the click depending on whether or not a view is matched?


Solution

  • My solution was to add a UiDevice object from UI Automator to my test:

     UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    

    Then I call UiDevice.pressEnter() to advance to the next TextView.

    device.pressEnter();
    

    The problem encountered is that this doesn't work as expected out of the box. I also added a View.OnKeyListener to each AutoCompleteTextView to handle the Enter key event. For now I add a listener to each view and explicitly state which view requests focus on an Enter key event.

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // ...
    
        brandText.setOnKeyListener(new View.OnKeyListener() { 
            @Override 
            public boolean onKey(View v, int keyCode, KeyEvent event) { 
                if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) { 
                    yearText.requestFocus(); 
                    return true; 
                } 
    
                return false; 
            } 
        });
    
        //...
    }
    

    This isn't ideal. Eventually I plan to generalize this, possibly with a custom component which inherits from AutoCompleteTextView which handles the Enter key as I expect. It will send focus to the "next" view.