Подтвердить что ты не робот

Espresso соответствует первому элементу, найденному, когда многие из них находятся в иерархии

Я пытаюсь написать функцию эспрессо для соответствия первому элементу espresso find в соответствии с моей функцией, даже если найдено несколько совпадающих элементов.

Пример: У меня есть список с ячейками, которые содержат цену товара. Я хочу иметь возможность переключать валюту на канадские доллары и проверять цены на товары в CAD.

Я использую эту функцию:

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

Это вызывает исключение AmbiguousViewMatcherException.

В этом случае мне все равно, сколько или несколько ячеек отображает САПР, я просто хочу проверить, что он отображается. Есть ли способ сделать эспрессо пройти этот тест, как только он встретит объект, соответствующий параметрам?

4b9b3361

Ответ 1

Вы должны иметь возможность создать собственный совпадение, которое соответствует только первому элементу со следующим кодом:

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");
        }
    };
}

Ответ 2

Из того, что я понимаю, в вашем сценарии все цены должны быть в CAD после того, как вы переключили валюту. Так что просто захват первого элемента и его проверка также должны решить вашу проблему:

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

Ответ 3

Я создал этот помощник, если у вас много элементов с такими же характеристиками, как один и тот же идентификатор, и , если вы хотите не только первый элемент, но и хотите определенный элемент. Надеюсь, это поможет:

    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);
        }
    };
}

Пример:

У вас много кнопок с одинаковым идентификатором, указанным в библиотеке, которую вы используете, вы хотите выбрать вторую кнопку.

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