babel-plugin-react-native-testid
raw JSON →A Babel plugin that automatically generates testID (and id) props for React Native components, designed to streamline automated testing with Detox, Appium, or similar frameworks. Current stable version is 0.2.1, released under an Apache-2.0 license, with no recent updates. Release cadence is low. Key differentiators: supports a multi-priority strategy for testID generation (manual props, meaningful attributes like title/placeholder, children text with i18n key extraction, fallback to component hierarchy), is highly configurable (attributes list, delimiter, ignore list, custom meaningful attributes), and ships TypeScript definitions. Alternatives like react-native-testid or babel-plugin-react-native-transform-testid offer simpler fixed-pattern approaches, whereas this plugin prioritizes semantic and stable IDs from props and i18n keys.
Common errors
error Error: Plugin/preset files are not allowed to export objects, only functions. (While processing: /path/to/node_modules/babel-plugin-react-native-testid/lib/index.js) ↓
error TypeError: Cannot read properties of undefined (reading 'node') ↓
error Require stack: - /path/to/project/babel.config.js ... Error: Cannot find module 'babel-plugin-react-native-testid' ↓
Warnings
breaking Version 0.2.0 changed default behavior: now adds both 'testID' and 'id' attributes, not just 'testID'. ↓
breaking Version 0.2.0 removed support for Node.js <10 (engine field update). ↓
deprecated The 'addId' option is deprecated as of 0.2.0; use the 'attributes' option instead. ↓
gotcha Plugin does NOT execute i18n translation functions; it extracts the raw translation key (e.g., 'auth.welcome' from t('auth.welcome')). This is intentional for stable IDs, but won't work if your i18n function uses dynamic keys or interplation. ↓
gotcha The plugin ignores elements listed in 'ignoreElements' (default includes View, Text, Image). This means those components will NEVER get auto-generated testID. If you need testID on them, remove them from the list. ↓
gotcha When children contain JSX expressions (e.g., <Text>{conditional ? 'A' : 'B'}</Text>), the plugin cannot extract a stable string and may fall back to hierarchy-based ID (e.g., 'Component-Text'). ↓
Install
npm install babel-plugin-react-native-testid yarn add babel-plugin-react-native-testid pnpm add babel-plugin-react-native-testid Imports
- default (plugin) wrong
// Wrong: trying to import as a module in app code import plugin from 'babel-plugin-react-native-testid'correct// In babel.config.js module.exports = { plugins: ['babel-plugin-react-native-testid'] } - Options type
import type { BabelPluginReactNativeTestIdOptions } from 'babel-plugin-react-native-testid'
Quickstart
// babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'babel-plugin-react-native-testid',
{
attributes: ['testID'], // Only add testID, not id
delimiter: '-',
ignoreElements: ['View', 'Text', 'Image'], // Skip these
meaningfulAttributes: ['title', 'placeholder', 'label', 'alt']
}
]
]
};
// Your React Native component
function LoginScreen() {
return (
<View>
<TextInput placeholder="Enter username" />
<Button title="Login" />
<Text>{t('auth.welcome')}</Text>
</View>
);
}
// Output will be:
// <TextInput placeholder="Enter username" testID="Enter username" />
// <Button title="Login" testID="Login" />
// <Text testID="auth.welcome">{t('auth.welcome')}</Text>