Animated Button block the Detox

烂漫一生 提交于 2019-12-05 12:54:09
Antoni4

From Detox documentation:

Endless looping animations

By default, Detox will wait until animations complete. If you have an endless looping animation, this may cause Detox to hang. In this case, consider turning off the animation synchronization or remove the endless loop in your E2E build with react-native-repackager.

https://github.com/wix/detox/blob/master/docs/Troubleshooting.Synchronization.md

General remarks

Infinite animations (looped animations) can make detox wait forever. Please consider turning looped animations off for testing. It's also a good practice to speed up all animations for testing.

https://github.com/wix/detox/blob/master/docs/More.AndroidSupportStatus.md

Detox provides disableSynchronization() - so you can temporarily disable synchronization to work around an animation and then turn it back on after the animation is gone. This however will not work for all cases. For example if you are using react-navigation and the on press button pushes new screen to the navigation stack the button is still going to continue animating in the background, blocking any further tests you are planning to run on the new screen.

So ideally you want to go with the other suggestion and disable these types of animations for your E2E tests. Here are 3 possible options to achieve this.

A:

Detox authors suggest using react-native-repackager for this. At the moment it only supports RN 0.51, so this might not be ideal for everyone. Please check supported version before using.

Currently supports only RN 0.51

B:

Set up React Native build environments. Based on an environment configuration variables you can then disable continues animations when building for E2E tests.

https://blog.carbonfive.com/2016/09/29/setting-up-react-native-build-environments-using-nativemodules/

C:

The easiest way I found is to use react-native-config. Here is also a good article on Managing Configuration in React Native with react-native-config, and another related question how-to-tell-detox-is-running-tests.

Install the package:

$ yarn add react-native-config

Link the library:

$ react-native link react-native-config

To test this solution I created 2 files, .env.production and .env.testing in the root React Native app directory. I am then using IS_ANIMATE config variable to toggle animation depending on the build environment. You need to add ENVFILE=.env.testing and ENVFILE=.env.production to your detox build config.

.env.production

ENV_TYPE=Production
IS_ANIMATE=1

.env.testing

ENV_TYPE=Testing
IS_ANIMATE=0

app.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)

example.spec.js

it('Animated Button', async () => {
  const buttonElement = element(by.id('button'));
  await expect(buttonElement).toBeVisible();
  await buttonElement.tap();
});

package.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"
    }
  }
}

The release build will hang: detox build --configuration ios.sim.release && detox test --configuration ios.sim.release

The test build will pass: detox build --configuration ios.sim.test && detox test --configuration ios.sim.test

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!