Превышен тайм-аут XXXms. Для асинхронных тестов и перехватов убедитесь, что вызывается «done()»

#reactjs #react-native #react-native-ios #react-native-router-flux #detox

#reactjs #react-native #react-native-ios #react-native-router-flux #детоксикация

Вопрос:

У меня действительно есть проблема с использованием detox , и я абсолютно понятия не имею, почему. Я знаю, что такого рода проблемы публиковались ранее, но, похоже, ни одна из них на самом деле не отвечает на мою проблему. Сначала я объясню это подробно, а затем опубликую некоторые коды и конфигурации.

Объяснение

Я хотел бы сначала попробовать функцию входа в мое приложение. У меня есть первый экран, где пользователь вводит свою команду и нажимает кнопку, чтобы перейти на другой экран для входа в систему. Я запрашиваю сервер, чтобы проверить, существует ли команда. Если команда ошибается, он получит сообщение об ошибке. Я хотел бы проверить, появляется ли это сообщение об ошибке.

При выполнении следующего теста отображается красное сообщение об ошибке, но тест заканчивается по истечении времени ожидания. На этом изображении показано, где заканчивается тест.

Этот образ

Код

Вот такой тест:

 describe('Login', () => {
  it('should show error message after bad team', async () => {
    await element(by.id('selectTeam_teamInput')).typeText('failingTeam');
    await element(by.id('selectTeam_domainInput')).replaceText('mydomain.cloud');
    await element(by.id('selectTeam_nextButton')).tap();
    await expect(element(by.id('selectTeam_errorMessage'))).toExist();
    await expect(element(by.id('selectTeam_errorMessage'))).toBeVisible();
  });
});
  

Вот представление ( goToLogin Метод запускает асинхронный вызов, который изменяет prop organisationInfosStatus на либо success , либо error . Когда это error , я показываю это сообщение об ошибке):

 <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
  <View>
    {this.props.organisationInfosStatus === 'error' amp;amp; (
      <View
        testID="selectTeam_errorMessage"
        style={{
          height: 24,
          marginBottom: 24,
          alignItems: 'center',
          justifyContent: 'center',
          borderWidth: 2,
          borderColor: 'white',
        }}
      >
        <Text style={{ color: theme.color.red.shade500, fontWeight: '500' }}>
          <Trad id="login.invalidTeam">Invalid team</Trad>
        </Text>
      </View>
    )}
    <View>
      <Text
        style={{
          marginHorizontal: 16,
          marginBottom: 24,
          fontSize: 18,
          lineHeight: 21,
          textAlign: 'center',
        }}
      >
        <Trad id="login.selectTeam">Please insert your team name</Trad>
      </Text>
      <View
        style={{
          paddingRight: 8,
          paddingLeft: 16,
          justifyContent: 'space-between',
          flexDirection: 'row',
          borderTopWidth: theme.border.width,
          borderBottomWidth: theme.border.width,
          borderColor: theme.color.grey.shade300,
        }}
      >
        <TextInput
          testID="selectTeam_teamInput"
          style={{ paddingVertical: 16, flex: 1 }}
          placeholder={TradSingleton.getTrad('login.organizationName')() || 'organization'}
          autoCapitalize="none"
          autoCorrect={false}
          onChangeText={teamName => this.setState({ teamName })}
          onSubmitEditing={this.goToLogin}
          returnKeyType="go"
          underlineColorAndroid="transparent"
          value={this.state.teamName}
        />
        <Text style={{ paddingVertical: 16 }}>.</Text>
        <View style={[{ flexDirection: 'row', justifyContent: 'space-between' }]}>
          <TextInput
            testID="selectTeam_domainInput"
            style={{
              paddingVertical: 16,
              marginRight: 8,
              minWidth: 50,
              maxWidth: 200,
            }}
            placeholder={TradSingleton.getTrad('login.domain')() || 'domain'}
            autoCapitalize="none"
            autoCorrect={false}
            onChangeText={domain => this.setState({ domain })}
            onSubmitEditing={this.goToLogin}
            returnKeyType="go"
            underlineColorAndroid="transparent"
            value={this.state.domain}
            keyboardType="email-address"
            ref="domainField"
          />
          <TouchableOpacity
            style={{
              backgroundColor: 'white',
              padding: 4,
              justifyContent: 'center',
              alignItems: 'center',
            }}
            onPress={() => {
              this.setState({ domain: '' });
              this.refs.domainField.focus();
            }}
            hitSlop={functions.hitSlop()}
          >
            <Icon
              icon={icon.get('close')}
              iconStyle={{ height: 12, width: 12, tintColor: theme.color.grey.shade500 }}
            />
          </TouchableOpacity>
        </View>
      </View>
      <Button
        onPress={this.goToLogin}
        testID="selectTeam_nextButton"
        containerStyle={[styleSheet.loginButton, { marginTop: 24 }]}
        disabled={this.state.loginButtonDisabled}
        textStyle={styleSheet.loginButtonText}
        tradId="utils.next"
      >
        Next
      </Button>
    </View>
  </View>
</TouchableWithoutFeedback>
  

Вот мой init.js :

 require('babel-polyfill');
const detox = require('detox');
const config = require('../package.json').detox;

before(async () => {
  await detox.init(config);
});

after(async () => {
  await detox.cleanup();
});
  

И, наконец, мой mocha.opts :

 --recursive
--timeout 20000
--bail
--file e2e/init.js
  

Я использую react-native-router-flux , но вот установщик разных версий:

 "react": "16.8.3",
"react-native": "^0.59.4",
"react-native-router-flux": "4.1.0-beta.5",
"react-navigation": "3.6.1",
"detox": "^12.1.3",
  

Другая информация

Перед обновлением до 0.59 я столкнулся 0.57.1 с той же проблемой. Была ли предыдущая версия или маршрутизатор 4.0.6 , та же проблема. Я пробовал с expect , с waitFor и таймаутом, та же проблема :/

Я также попробовал тот же тест с действительной командой, чтобы посмотреть, находит ли она в принципе следующее представление. Это заканчивается таймаутом точно так же.

Скажите мне, нужна ли вам дополнительная информация 🙂

Заранее спасибо!

Комментарии:

1. Я предполагаю, что вам может понадобиться убедиться, что done() вызван? Можете ли вы попробовать изменить свой тест на: it('should show error message after bad team', async (done) => { и вызвать done() в конце?

2. Да, тоже пробовал. Оно никогда не достигается. Похоже, что await expect(element(by.id('selectTeam_errorMessage'))).toExist(); приводит к бесконечному циклу, даже несмотря на то, что отображается сообщение

3. Как насчет ожидания ? waitFor(expect(element(by.id('selectTeam_errorMessage'))).toExist().withTimeout(2000);

4. Также пробовал. Та же проблема. await waitFor(element(by.id('selectTeam_errorMessage'))) .toExist() .withTimeout(2000); await waitFor(element(by.id('selectTeam_errorMessage'))) .toBeVisible() .withTimeout(2000); done(); Тест выглядел так. Время ожидания точно такое же