web-dev-qa-db-fra.com

Espresso - Cliquez par texte en mode liste

J'essaie de cliquer sur un texte dans une liste avec Espresso. Je sais qu'ils ont ce guide , mais je ne vois pas comment faire fonctionner ce travail en recherchant du texte. C'est ce que j'ai essayé

Espresso.onData(Matchers.allOf(Matchers.is(Matchers.instanceOf(ListView.class)), Matchers.hasToString(Matchers.startsWith("ASDF")))).perform(ViewActions.click());

Comme prévu, cela n'a pas fonctionné. L'erreur dit pas de vue dans la hiérarchie. Est-ce que quelqu'un sait comment sélectionner une chaîne? ("ASDF" dans ce cas) Merci d'avance.

Mise à jour due à @haffax

J'ai reçu une erreur:

com.google.Android.apps.common.testing.ui.espresso.AmbiguousViewMatcherException: 'est assignable à partir de la classe: la classe Android.widget.AdapterView' correspond à plusieurs vues dans la hiérarchie.

Deuxième erreur

Avec ce code

onData(hasToString(startsWith("ASDF"))).inAdapterView(withContentDescription("MapList")).perform(click());

Je reçois cette erreur

com.google.Android.apps.common.testing.ui.espresso.PerformException: erreur lors de l'exécution de "données de l'adaptateur de chargement" à la vue "avec une description de contenu:" MapList "".

Causée par: Java.lang.RuntimeException: aucune donnée trouvée ne correspond à: asString (une chaîne commençant par "ASDF") 


Solution

onData (n'importe quoi ()). inAdapterView (avecContentDescription ("desc")). atPosition (x) .perform (click ())

33
Chad Bingham

Le problème est que vous essayez de faire correspondre la vue liste elle-même avec instanceOf(ListView.class) en tant qu'argument pour onData(). onData() requiert un contrôleur de données qui corresponde aux données adaptées de la ListView, pas à la ListView elle-même, ni à la View que Adapter.getView() renvoie, mais aux données réelles.

Si vous avez quelque chose comme ça dans votre code de production:

ListView listView = (ListView)findViewById(R.id.myListView);
ArrayAdapter<MyDataClass> adapter = getAdapterFromSomewhere();
listView.setAdapter(adapter);

Ensuite, l'argument Matcher de Espresso.onData() devrait correspondre à l'instance désirée de MyDataClass. Donc, quelque chose comme ceci devrait fonctionner:

onData(hasToString(startsWith("ASDF"))).perform(click());

(Vous pouvez utiliser un autre Matcher en utilisant une méthode de org.hamcrest.Matchers)

Si votre activité comporte plusieurs vues d'adaptateur, vous pouvez appeler ViewMatchers.inAdapterView() avec un matcher de vue spécifiant le type AdapterView comme suit:

onData(hasToString(startsWith("ASDF")))
    .inAdapterView(withId(R.id.myListView))
    .perform(click());
39
haffax

Si l'adaptateur a une classe de modèle personnalisée, par exemple Item:

public static Matcher<Object> withItemValue(final String value) {
        return new BoundedMatcher<Object, Item>(Item.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has value " + value);
            }

            @Override
            public boolean matchesSafely(Item item) {
                return item.getName().toUpperCase().equals(String.valueOf(value));
            }
        };
    }

Puis appelez le suivant:

onData(withItemValue("DRINK1")).inAdapterView(withId(R.id.menu_item_grid)).perform(click());
2
Veer
onData(hasEntry(equalTo(ListViewActivity.ROW_TEXT),is("List item: 25")))
        .onChildView(withId(R.id.rowTextView)).perform(click());

Cela fonctionne mieux pour moi avec les données de texte en ligne.

0
anuja jain