来自排毒文档:
无尽的循环动画
默认情况下,排毒会等到动画完成。如果您有无限循环动画,这可能会导致 Detox 挂起。在这种情况下,请考虑关闭动画同步或使用 react-native-repackager 删除 E2E 构建中的无限循环。
https://github.com/wix/detox/blob/master/docs/Troubleshooting.Synchronization.md#endless-looping-animations
一般说明
无限动画(循环动画)可以让排毒永远等待。请考虑关闭循环动画进行测试。加快所有动画以进行测试也是一个好习惯。
https://github.com/wix/detox/blob/master/docs/More.AndroidSupportStatus.md#general-remarks
Detox 提供disableSynchronization()
- 因此您可以暂时禁用同步以解决动画问题,然后在动画消失后将其重新打开。然而,这并不适用于所有情况。例如,如果您使用react-navigation并且按下按钮将新屏幕推送到导航堆栈,则该按钮仍将继续在后台动画,阻止您计划在新屏幕上运行的任何进一步测试。
因此,理想情况下,您希望采用其他建议并为您的 E2E 测试禁用这些类型的动画。这里有 3 个可能的选项来实现这一点。
A:
Detox 作者建议为此使用react-native-repackager。目前它只支持 RN 0.51,所以这可能并不适合所有人。使用前请检查支持的版本。
目前仅支持 RN 0.51
乙:
设置 React Native 构建环境。根据环境配置变量,您可以在构建 E2E 测试时禁用继续动画。
https://blog.carbonfive.com/2016/09/29/setting-up-react-native-build-environments-using-nativemodules/
C:
我发现最简单的方法是使用react-native-config。这里还有一篇关于使用 react-native-config在 React Native 中管理配置的好文章,以及另一个相关问题how-to-tell-detox-is-running-tests。
安装包:
$ yarn add react-native-config
链接库:
$ react-native 链接 react-native-config
为了测试这个解决方案,我创建了 2 个文件,.env.production
并.env.testing
在根 React Native 应用程序目录中。然后我使用IS_ANIMATE配置变量根据构建环境切换动画。您需要添加ENVFILE=.env.testing
和ENVFILE=.env.production
到您的 detox 构建配置。
.env.production
ENV_TYPE=Production
IS_ANIMATE=1
.env.testing
ENV_TYPE=Testing
IS_ANIMATE=0
应用程序.js
import Config from 'react-native-config'
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Alert,
Animated,
View,
TouchableOpacity,
Text
} from 'react-native'
class example extends Component {
constructor(props) {
super(props)
this.state = {
radius: new Animated.Value(1)
}
}
componentDidMount() {
// only enable animation for production
if (Config.IS_ANIMATE == true) {
this.cycleAnimation()
}
}
cycleAnimation() {
Animated.loop(
Animated.sequence([
Animated.timing(this.state.radius, {
toValue: 2,
duration: 500,
delay: 1000
}),
Animated.timing(this.state.radius, {
toValue: 1,
duration: 500
})
])
).start()
}
render() {
return (
<View testID='container' style={styles.container}>
<Text>{Config.ENV_TYPE}</Text>
<TouchableOpacity
testID='button'
onPress={() => Alert.alert("I was pressed")}
>
<Animated.View
style={[
styles.button,
{transform: [
{scale: this.state.radius},
]}
]}
>
<Text>START DIARY</Text>
</Animated.View>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
button: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 60,
width: 120,
height: 120,
backgroundColor: 'green'
},
text: {
padding: 5,
fontSize: 14
}
})
AppRegistry.registerComponent('example', () => example)
例子.spec.js
it('Animated Button', async () => {
const buttonElement = element(by.id('button'));
await expect(buttonElement).toBeVisible();
await buttonElement.tap();
});
包.json
"detox": {
"specs": "e2e",
"configurations": {
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"build": "ENVFILE=.env.production export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -project ios/example.xcodeproj -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 5s, iOS 10.3"
},
"ios.sim.test": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app",
"build": "ENVFILE=.env.testing xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build -arch x86_64",
"type": "ios.simulator",
"name": "iPhone 5s, iOS 10.3"
}
}
}
发布版本将挂起:detox build --configuration ios.sim.release && detox test --configuration ios.sim.release
测试构建将通过:detox build --configuration ios.sim.test && detox test --configuration ios.sim.test