appium: ID locator strategy not working for `resource-id` elements generated by React Native 0.64
The problem
ID locator strategy not working for resource-id
elements generated by React Native 0.64 using testID
.
Environment
- Appium version (or git revision) that exhibits the issue: Appium Desktop 1.19.1, Appium CLI 1.21.0
- Last Appium version that did not exhibit the issue (if applicable): NA
- Desktop OS/version used to run Appium: MacOS Big Sur 11.2
- Node.js version (unless using Appium.app|exe): v14.16.1
- Npm or Yarn package manager: NA
- Mobile platform/version under test: Android
- Real device or emulator/simulator: Real device
- Appium CLI or Appium.app|exe: Both
- React Native: 0.64.0
Details
Since https://github.com/facebook/react-native/pull/29610 has been merged, we can now use testID
which is exposed via a view’s resource-id
. However, it is impossible to locate these elements using their ID, both in Appium Desktop and Appium CLI. The elements are simply not found, even though they appear as id
in Appium Desktop.
Link to Appium logs
[MJSONWP (71a501f7)] Calling AppiumDriver.findElements() with args: ["id","backButton","71a501f7-6dca-4900-9031-28783ce7577b"]
[BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, css selector, -android uiautomator
[BaseDriver] Waiting up to 0 ms for condition
[WD Proxy] Matched '/elements' to command name 'findElements'
[WD Proxy] Proxying [POST /elements] to [POST http://127.0.0.1:8200/wd/hub/session/347565f6-94ae-4cd5-922f-9af19084f0da/elements] with body: {"strategy":"id","selector":"backButton","context":"","multiple":true}
[WD Proxy] Got response with status 200: {"sessionId":"347565f6-94ae-4cd5-922f-9af19084f0da","value":[]}
[MJSONWP (71a501f7)] Responding to client with driver.findElements() result: []
[HTTP] <-- POST /wd/hub/session/71a501f7-6dca-4900-9031-28783ce7577b/elements 200 51 ms - 74
Code To Reproduce Issue
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* Generated with the TypeScript template
* https://github.com/react-native-community/react-native-template-typescript
*
* @format
*/
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
TouchableOpacity
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
const Section: React.FC<{
title: string;
}> = ({ children, title }) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
};
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<TouchableOpacity
accessible={true}
accessibilityLabel="Go back"
accessibilityHint="Navigates to the previous screen"
testID="backButton"
>
<Text >Go Back</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 21
Update: A better selector is:
//*[@resource-id="Some_Element_ID"]
. It has behaved very well and selects for just the element I want vs. usingcontains
like in my response above.I’m faceing the same problem. But when I use
new UiSelector().resourceId("the_simple_id")
it works. Both of use${pkgName}:id/${resId}
and Android UiAutomator2 selector are ugly way. It breaks the cross-platform ability. So, are there any better way? I think it’s a bug that relates to appium.If I use
com.testiddemo:id/backButton
astestID
it works! I can find the element searching forcom.testiddemo:id/backButton
using theid
locator strategy.Another workaround that seems to work: using
xpath
This is just a general agreement across Android resources identification that ensures ids are unique. Ofc, nothing forces you to follow it.