2015-09-03 13 views
16

Sto provando a scrivere una funzione espresso in modo che corrisponda al primo elemento espresso in base alla mia funzione, anche quando vengono trovati più articoli corrispondenti.Espresso corrisponde al primo elemento trovato quando molti sono in gerarchia

Es: Ho una vista elenco con celle che contengono il prezzo dell'articolo. Voglio essere in grado di convertire la valuta in dollari canadesi e verificare che i prezzi degli articoli siano in CAD.

sto usando questa funzione:

onView(anyOf(withId(R.id.product_price), withText(endsWith("CAD")))) 
     .check(matches(
       isDisplayed())); 

Questo getta l'AmbiguousViewMatcherException.

In questo caso, non mi interessa quante o poche celle visualizzino CAD, voglio solo verificare che sia visualizzato. C'è modo di far passare il caffè espresso questo test non appena incontra un oggetto che soddisfa i parametri?

risposta

18

Si dovrebbe essere in grado di creare un matcher personalizzato che corrisponde solo al primo elemento con il seguente codice:

private <T> Matcher<T> first(final Matcher<T> matcher) { 
    return new BaseMatcher<T>() { 
     boolean isFirst = true; 

     @Override 
     public boolean matches(final Object item) { 
      if (isFirst && matcher.matches(item)) { 
       isFirst = false; 
       return true; 
      } 

      return false; 
     } 

     @Override 
     public void describeTo(final Description description) { 
      description.appendText("should return first matching item"); 
     } 
    }; 
} 
1

Da quello che ho capito, nello scenario tutti i prezzi dovrebbero essere in CAD dopo aver acceso la moneta. Quindi, solo afferrando il primo oggetto e verificare che dovrebbe risolvere il problema troppo:

onData(anything()) 
     .atPosition(0) 
     .onChildView(allOf(withId(R.id.product_price), withText(endsWith("CAD")))) 
     .check(matches(isDisplayed())); 
2

Ho creato questo matcher nel caso in cui si dispone di molti elementi con stesse caratteristiche come lo stesso ID, e se non vuole solo il primo elemento ma invece vogliono un elemento specifico . Spero che questo aiuti:

private static Matcher<View> getElementFromMatchAtPosition(final Matcher<View> matcher, final int position) { 
    return new BaseMatcher<View>() { 
     int counter = 0; 
     @Override 
     public boolean matches(final Object item) { 
      if (matcher.matches(item)) { 
       if(counter == position) { 
        counter++; 
        return true; 
       } 
       counter++; 
      } 
      return false; 
     } 

     @Override 
     public void describeTo(final Description description) { 
      description.appendText("Element at hierarchy position "+position); 
     } 
    }; 
} 

Esempio:

Hai molte pulsanti con lo stesso ID dato da una libreria che si sta utilizzando, si consiglia di scegliere il secondo pulsante.

ViewInteraction colorButton = onView(
      allOf(
        getElementFromMatchAtPosition(allOf(withId(R.id.color)), 2), 
        isDisplayed())); 
    colorButton.perform(click());