Create Espresso DataMatcher Selector for Appium

Hi. How to create Espresso DataMatcher Selector for Appium?
I have an app with ListView which is populated by ArrayAdapter. The item is a Cat.class. I want to click on element with text “Barsik” (in case if it is invisible).

public class MainActivity extends ListActivity {

private static final List<Cat> cats = new ArrayList<Cat>();

static {
    cats.add(new Cat("Vaska", "kote"));
    cats.add(new Cat("Murzik", "kotyara"));
    cats.add(new Cat("Murka", "коshka"));
    cats.add(new Cat("Barsik", "kotik"));  
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ArrayAdapter<Cat> adapter = new CatAdapter(this);
    setListAdapter(adapter);
}

private static class Cat {
    public final String name;
    public final String gender;

    public Cat(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }
}

private class CatAdapter extends ArrayAdapter<Cat> {

    public CatAdapter(Context context) {
        super(context, android.R.layout.simple_list_item_2, cats);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Cat cat = getItem(position);

        if (convertView == null) {
            convertView = LayoutInflater.from(getContext())
                    .inflate(android.R.layout.simple_list_item_2, null);
        }
        ((TextView) convertView.findViewById(android.R.id.text1))
                .setText(cat.name);
        ((TextView) convertView.findViewById(android.R.id.text2))
                .setText(cat.gender);
        return convertView;
    }
}

}

I tried with next method to click and it throws “org.openqa.selenium.InvalidSelectorException: Not a valid selector”:

public static void findElementInSimpleList(WebDriver driver) {

    WebElement list = driver.findElement(MobileBy.id("android:id/list"));
  
           String selector = new Json().toJson(
            ImmutableMap.of(
                    "name", "contains",
                    "args", ImmutableList.of(
                            ImmutableMap.of(
                                    "name", "isA",
                                    "args", "String.class"
                            ),
                            ImmutableMap.of(
                                    "name", "containsString",
                                    "args", "Barsik"
                            )
                    )));

    list.findElement(MobileBy.androidDataMatcher(selector)).click();

}

args should be a valid JSON, not a map. Check https://www.youtube.com/watch?v=gU9EEUV5n9U

There is no map, it is a valid JSON. This is in a log:

*** Element info: {Using=-android datamatcher, value={

  "name": "allOf",
  "args": [
    {
      "name": "contains",
      "args": {
        "name": "isA",
        "args": "String.class"
      }
    },
    {
      "name": "containsString",
      "args": "Barsik"
    }
  ]
} }

Exception is:

org.openqa.selenium.NoSuchElementException: Could not find element with strategy DATAMATCHER and selector

Maybe I’m using methods incorrectly? Plz, help…

Now the selector itself is valid. Espresso cannot find a matching element for it though

good answer… then how to find it with data matcher? Could you give an example for that case.


http://appium.io/docs/en/writing-running-appium/android/espresso-datamatcher-selector/

I have seen it already. But thanx for links. Can you please explain how I can create a selector with the strategy which is described in Medium " AdapterViews and Espresso" article for " your own data type".
How I can send to “-android datamatcher” the custom matcher with code:

    public static Matcher withName(Matcher nameMatcher){
    return new TypeSafeMatcher<Person>(){
        @Override
        public boolean matchesSafely(Person person) {
            return nameMatcher.matches(person.getName());
        }
        
        @Override
        public void describeTo(Description description) {
            ...
        }
    }
}

I might be wrong, but it is not possible to create a matcher based on an own data type using espresso driver. Only standard types might be used