Skip to content

React Native Locators

Note: This issue is mostly not relevant starting from react-native@0.65.x. See React Native changelog.

Let’s say we have a React Native component like this:

<Button testID="someButton">My button</Button>

If you run:

I.tap('~someButton');

it works on iOS (XCUITest), but on Android UIAutomator2 you may get:

Touch actions like "tap" need at least some kind of position information like "element", "x" or "y" options, you've none given.

This happens because React Native puts testID into the View tag on Android, and UIAutomator cannot use view tags directly.

One common workaround is using testID for iOS and accessibilityLabel for Android, but accessibilityLabel is user-facing accessibility text and usually should not be overloaded for test-only needs.

A better option is to use the Espresso driver on Android.

Enable Espresso in Appium config:

{
helpers: {
Appium: {
app: '/path/to/apk.apk',
platform: 'Android',
desiredCapabilities: {
automationName: 'Espresso',
platformVersion: '9',
deviceName: 'Android Emulator'
}
}
}
}

Then use platform-specific locator:

I.tap({ android: '//*[@view-tag="someButton"]', ios: '~someButton' });

You can wrap it in a helper function:

function tid(id) {
return {
android: `//*[@view-tag="${id}"]`,
ios: `~${id}`,
};
}

Now tests are cleaner:

I.tap(tid('someButton'));

If your React Native app includes a WebView, web locators are available inside that context, including ARIA locators such as:

I.click({ aria: 'Sign in' });