id | title |
---|---|
APIRef.Matchers |
Matchers |
Detox uses Matchers to find UI elements
in your app, Actions to emulate user interaction with those elements
and Expectations to verify values on those elements
.
Matchers find elements in your app that match one or more properties.
NOTE: Whenever possible we recommend to match elements by.id
, these are more resilient to layout restructuring and text/language changes
by.id
will match an id that is given to the view via testID
prop.
In a React Native component add testID like so:
<TouchableOpacity testID={'tap_me'}>
...
Then match with by.id
:
element(by.id('tap_me'));
For other cases, and only if you can't use by.id
there is a variety of options:
Find an element by text, useful for text fields, buttons.
element(by.text('Tap Me'));
Find an element by accessibilityLabel
on iOS, or by contentDescription
on Android.
element(by.label('Welcome'));
Find an element by native view type. View types differ between iOS and Android.
on iOS:
element(by.type('RCTImageView'));
on Android, provide the class canonical name:
element(by.type('android.widget.ImageView'));
Find an element with an accessibility trait. (iOS only)
element(by.traits(['button']));
element(by.id('uniqueId').and(by.text('some text')));
element(by.id('child').withAncestor(by.id('parent')));
element(by.id('parent').withDescendant(by.id('child')));
-
To find the view with the id
child
<View testID='grandparent' style={{padding: 8, backgroundColor: 'red', marginBottom: 10}}> <View testID='parent' style={{padding: 8, backgroundColor: 'green'}}> <View testID='child' style={{padding: 8, backgroundColor: 'blue'}}> <View testID='grandchild' style={{padding: 8, backgroundColor: 'purple'}} /> </View> </View> </View>
Use:
// any of the following will work element(by.id('child')); element(by.id('child').withAncestor(by.id('parent'))); element(by.id('child').withDescendant(by.id('grandchild')));
When a matcher matches multiple views, there are three possible solutions:
-
Use multiple matchers to narrow down the matched results.
-
Add unique identifiers (testIDs) to the view which need to matched.
A common use-case, is adding identifiers to list items. testIDs for FlatList items can be assigned dynamically, by passingindex
inrenderItem({item, index})
and using it in the component's render function.FlatList
renderItem
function:renderItem({item, index}) { return ( <CustomComponent index={index} ... /> ); }
CustomComponent
'srender
function:render() { return ( <View testID={'listitem' + this.props.index} ... /> ); }
-
Select a matched view from the matched view list using
atIndex
element(by.text('Product')).atIndex(2);
Usage of atIndex
is not recommended!, since the order of matched views can not be guaranteed by the system. Recyclable views in UITableView / UICollectionView / RecyclerView or any custom view may even change during scroll, while views are being recycled with new data.
React Native FlatList items are being traversed in different ways on the different platforms, causing atIndex
to return the opposite indexes on iOS than what it does on Android.
on iOS 11:
element(by.traits(['button']).and(by.label('Back')));
on iOS 10:
element(by.type('_UIModernBarButton').and(by.label('Back')));