UNPKG

babel-plugin-react-native-testid

Version:

babel plugin for react native testid attributes

210 lines (163 loc) 5.84 kB
# babel-plugin-react-native-testid 一个智能的Babel插件,为React Native组件自动生成testID属性,支持多种优先级策略,特别适用于自动化测试(如Detox)。 ## 特性 - 🎯 **智能优先级策略**: 按照预定义的优先级自动生成testID - 🌐 **多语言支持**: 智能提取i18n翻译键作为testID - 📱 **React Native优化**: 专为React Native组件设计 - ⚙️ **高度可配置**: 支持自定义属性、分隔符和忽略元素 - 🔄 **向后兼容**: 保持与原有testID的兼容性 ## testID生成优先级(从高到低) ### 1. 【最高优先级】手动指定的testID **原则**: 保留人工干预的最高权力。如果组件已有testID或id,插件不会覆盖。 ```jsx // 输入 <Button testID="custom-login-button">登录</Button> <Button id="custom-id">登录</Button> // 输出 (保持不变) <Button testID="custom-login-button">登录</Button> <Button id="custom-id">登录</Button> ``` ### 2. 【核心】从有意义的属性中提取 **原则**: 组件的功能通常由其props定义。 ```jsx // 输入 <TextInput placeholder="请输入用户名" /> <Button title="登录">Click</Button> <Icon name="settings" /> // 输出 <TextInput placeholder="请输入用户名" testID="请输入用户名" id="请输入用户名" /> <Button title="登录" testID="登录" id="登录">Click</Button> <Icon name="settings" testID="icon-settings" id="icon-settings" /> ``` **支持的有意义属性**: - `title` - 标题 - `placeholder` - 占位符 - `label` - 标签 - `alt` - 替代文本 - `name` - 名称(会添加组件类型前缀) - `id` - 标识符 - `key` - 键值 - `accessibilityLabel` - 无障碍标签 ### 3. 【核心】从组件内容中提取(智能处理多语言) **原则**: 组件的内容(children)是其最直观的语义。 #### 静态文本 ```jsx // 输入 <Button>登录</Button> // 输出 <Button testID="登录" id="登录">登录</Button> ``` #### 国际化(i18n)文本 **关键优化**: 插件不执行t函数,而是直接提取翻译Key,这个Key是稳定且极具语义的。 ```jsx // 输入 <Text>{t('user.profile.nickname')}</Text> <Button>{i18n.t('common.save')}</Button> // 输出 <Text testID="user.profile.nickname" id="user.profile.nickname">{t('user.profile.nickname')}</Text> <Button testID="common.save" id="common.save">{i18n.t('common.save')}</Button> ``` ### 4. 【最低优先级】回退到基于组件名的层级结构 **原则**: 作为保底方案,确保所有元素至少有一个可用的ID。 ```jsx // 输入 function ProfileScreen() { return ( <View> <Button /> </View> ); } // 输出 function ProfileScreen() { return ( <View> <Button testID="ProfileScreen-Button" id="ProfileScreen-Button" /> </View> ); } ``` ## 安装 ```bash npm install babel-plugin-react-native-testid --save-dev # 或 yarn add babel-plugin-react-native-testid --dev ``` ## 使用方法 ### 基本配置 在你的`.babelrc`或`babel.config.js`中添加插件: ```json { "plugins": ["babel-plugin-react-native-testid"] } ``` **默认情况下,插件会同时添加`testID`和`id`属性。** ### 高级配置 ```javascript // babel.config.js module.exports = { plugins: [ [ 'babel-plugin-react-native-testid', { // 要添加的属性名称 attributes: ['testID'], // 层级分隔符 delimiter: '-', // 忽略的元素(不会生成testID) ignoreElements: ['View', 'Text', 'Image'], // 有意义的属性 meaningfulAttributes: ['title', 'placeholder', 'label', 'customLabel'] } ] ] }; ``` ### 配置选项 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `attributes` | `string[]` | `['testID', 'id']` | 要添加的属性名称 | | `delimiter` | `string` | `'-'` | 层级分隔符 | | `ignoreElements` | `string[]` | `['View', 'Text', 'Image', ...]` | 忽略的元素列表 | | `meaningfulAttributes` | `string[]` | `['title', 'placeholder', ...]` | 有意义的属性列表 | ## 实际应用示例 ### Detox测试 ```javascript // 测试代码 await element(by.id('请输入用户名')).typeText('testuser'); await element(by.id('user.profile.nickname')).tap(); await element(by.id('登录')).tap(); ``` ### 多语言应用 ```jsx // 组件代码 function LoginScreen() { return ( <View> <TextInput placeholder={t('login.username.placeholder')} /> <TextInput placeholder={t('login.password.placeholder')} /> <Button>{t('login.submit')}</Button> </View> ); } // 生成的testID和id // testID="login.username.placeholder" id="login.username.placeholder" // testID="login.password.placeholder" id="login.password.placeholder" // testID="login.submit" id="login.submit" ``` ## 与您的XML输出对比 根据您提供的XML视图层次结构,这个插件可以帮助生成更有意义的testID: ```xml <!-- 当前: 缺少testID --> <RCTView alpha="1.0" class="RCTView" focused="false" height="30" id="EnhancedTouchable-Component" label="登录" visibility="visible" width="62" x="198" y="0"> <RCTTextView alpha="1.0" class="RCTTextView" focused="false" height="21" id="ReText-RNText" label="登录" visibility="visible" width="30" x="16" y="4" /> </RCTView> <!-- 使用插件后: 自动生成有意义的testID --> <RCTView testID="登录" alpha="1.0" class="RCTView" focused="false" height="30" id="EnhancedTouchable-Component" label="登录" visibility="visible" width="62" x="198" y="0"> <RCTTextView testID="登录" alpha="1.0" class="RCTTextView" focused="false" height="21" id="ReText-RNText" label="登录" visibility="visible" width="30" x="16" y="4" /> </RCTView> ``` ## 许可证 MIT ## 贡献 欢迎提交Issue和Pull Request!