使用 react-navigation 和 react-native-fluid-transitions 进行端到端排毒测试 - 预计 .toBeVisible 失败

Detox e2e testing with react-navigation and react-native-fluid-transitions - expect .toBeVisible failing

我有一个 detox e2e 测试来测试从我的应用程序启动到登录的流程。

我的应用程序以初始屏幕启动。然后它加载我的 StackNavigator,它的第一个元素是来自 react-native-fluid-transitions 库的 FluidNavigator .

测试失败并出现无法通过我对我的元素的断言的错误:

    Failed: [Error: Error: An assertion failed.

    Exception with Assertion: {
      "Assertion Criteria":  "assertWithMatcher:matcherForSufficientlyVisible(>=0.750000)",
      "Element Matcher":  "((!(kindOfClass('RCTScrollView')) && (respondsToSelector(accessibilityIdentifier) && accessibilityID('signInOrRegisterPage'))) || (((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && parentThatMatches(kindOfClass('RCTScrollView'))) && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && parentThatMatches((respondsToSelector(accessibilityIdentifier) && accessibilityID('signInOrRegisterPage'))))))"
    }


    Error Trace: [
      {
        "Description":  "Assertion with matcher [M] failed: UI element [E] failed to match the following matcher(s): [S]",
        "Description Glossary":    {
          "M":  "matcherForSufficientlyVisible(>=0.750000)",
          "E":  "<RCTView:0x7fb63252a270; AX=N; AX.id='signInOrRegisterPage'; AX.label='Welcome to the CompCare Member App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>",
          "S":  "matcherForSufficientlyVisible(>=0.750000)"
        },
        "Error Domain":  "com.google.earlgrey.ElementInteractionErrorDomain",
        "Error Code":  "3",
        "File Name":  "GREYAssertions.m",
        "Function Name":  "+[GREYAssertions grey_createAssertionWithMatcher:]_block_invoke",
        "Line":  "75"
      }
    ]

这是我的端到端测试:

describe('Login with Pin', () => {
  beforeEach(async () => {
    await device.reloadReactNative();
  });

  it('should show the Sign In Or Register page', async () => {
    await expect(element(by.id('signInOrRegisterPage'))).toBeVisible();
  });

  it('should show the register button and the sign in button', async () => {
    await expect(element(by.id('btnRegisterForApp'))).toBeVisible();
    await expect(element(by.id('btnSignIn'))).toBeVisible();
  });

  it('should navigate to the sign in page', async () => {
    await element(by.id('btnSignIn')).tap();
    await expect(element(by.id('signInPage'))).toBeVisible();
  });

  it('should show the pin input keypad', async () => {
    await expect(element(by.id('pinInputKeypad'))).toBeVisible();
  });

  it('should show the dashboard after entering a series of digits', async () => {
    await element(by.id('testInput1')).tap();
    await element(by.id('testInput9')).tap();
    await element(by.id('testInput6')).tap();
    await element(by.id('testInput0')).tap();
    //await expect(element(by.id('dashboard'))).toBeVisible();
  });
})

我试过使用排毒 await device.disableSynchronization(); 然后使用 await waitFor(element(by.id('signInOrRegisterPage'))).toBeVisible().withTimeout(2000);。那也没用。

以下是我的更多代码,希望对您有所帮助:

App.js

import React, { Component } from 'react';
import SplashScreen from 'react-native-splash-screen';
import { View } from 'react-native';

import StackNavigator from './components/StackNavigator';

export default class App extends Component {

  componentDidMount() {
    SplashScreen.hide();
  }

  render() {
    return (
        <StackNavigator />
    );
  }
}

我的基础 StackNavigator.js

const StackNavigator = createStackNavigator(
  {
    FluidTransitionNavigator: {
      screen: FluidTransitionNavigator
    },
    Dashboard: {
      screen: Dashboard
    }
  },
  {
    initialRouteName: 'FluidTransitionNavigator',
    headerMode: 'float',
    navigationOptions: (props) => ({
      header: renderHeader(props)
    }),
    // transitionConfig: transitionConfig
  }
);

我的 FluidTransitionNavigator 的基础知识:

const FluidTransitionNavigator = FluidNavigator({
  SignInOrRegister: {
    screen: SignInOrRegister
  },
  Login: {
    screen: Login
  }
});

我的 SignInOrRegister 页面:

class SignInOrRegister extends Component {
  onRegisterPress() {
  }

  onSignInPress() {
    this.props.navigation.push('Login');
  }

  render() {
    return (
      <View style={styles.mainViewStyle} testID='signInOrRegisterPage'>

        <Transition appear="horizontal">
          <View style={{ flex: 1, zIndex: 2}}>
            <Text style={styles.welcomeTextStyle}>Welcome to the App</Text>
            <View style={styles.logoViewStyle}>
              <Image
                source={require('./images/Logo.png')}
                style={styles.logoStyle}
              />
            </View>
            <Text style={styles.instructionTextStyle}>
              I just installed the app.
            </Text>
            <UniButton testID='btnRegisterForApp' style={{ marginTop: 10 }} type='primary' label='Register for App' onPress={this.onRegisterPress.bind(this)} />
            <UniButton testID='btnSignIn' style={{ marginTop: 30, zIndex: 10 }} type='secondary' label='I just want to Sign In' onPress={this.onSignInPress.bind(this)} />
          </View>
        </Transition>

        <Transition shared="brand_btm">
          <View style={styles.brandingImageViewStyle}>
            <BrandingBottom />
          </View>
        </Transition>
      </View>
    );
  }
}

我也尝试从 SignInOrRegister 组件中删除 Transition 元素:

render() {
    return (
      <View style={styles.mainViewStyle} testID='signInOrRegisterPage'>

        {/* <Transition appear="horizontal"> */}
          <View style={{ flex: 1, zIndex: 2}}>
            <Text style={styles.welcomeTextStyle}>Welcome to the CompCare Member App</Text>
            <View style={styles.logoViewStyle}>
              <Image
                source={require('./images/Logo.png')}
                style={styles.logoStyle}
              />
            </View>
            <Text style={styles.instructionTextStyle}>
              I just installed the app.
            </Text>
            <UniButton testID='btnRegisterForApp' style={{ marginTop: 10 }} type='primary' label='Register for App' onPress={this.onRegisterPress.bind(this)} />
            <UniButton testID='btnSignIn' style={{ marginTop: 30, zIndex: 10 }} type='secondary' label='I just want to Sign In' onPress={this.onSignInPress.bind(this)} />
          </View>
        {/* </Transition> */}

        {/* <Transition shared="brand_btm"> */}
          <View style={styles.brandingImageViewStyle}>
            <BrandingBottom />
          </View>
        {/* </Transition> */}
      </View>
    );
  }

但我仍然没有通过测试。

这是整个视图层次结构:

Hierarchy: <UIWindow:0x7fb6326273e0; AX=N; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |--<RCTRootView:0x7fb632519780; AX=N; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |--<RCTRootContentView:0x7fb634a00450; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |--<RCTView:0x7fb632530950; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |--<RCTView:0x7fb63252ef50; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |--<RCTView:0x7fb63252e960; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |--<RCTView:0x7fb63252e390; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |--<RCTView:0x7fb63252d340; AX=N; AX.frame={{0, 0}, {375, 64}}; AX.activationPoint={187.5, 32}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 64}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |--<RCTView:0x7fb63252ced0; AX=N; AX.frame={{-375, 0}, {375, 64}}; AX.activationPoint={-187.5, 32}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{-375, 0}, {375, 64}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |--<RCTView:0x7fb63252ca60; AX=N; AX.frame={{-375, 0}, {375, 64}}; AX.activationPoint={-187.5, 32}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 64}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb63252b8f0; AX=N; AX.frame={{-375, 20}, {375, 43.5}}; AX.activationPoint={-187.5, 41.75}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 20}, {375, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |--<RCTView:0x7fb634b02770; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |--<RCTView:0x7fb634a02910; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |--<RCTView:0x7fb634a02610; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb634a01240; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632536870; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=0; UIE=N>
      |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632536260; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 50}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632533f30; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632532ed0; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632532900; AX=Y; AX.label='I just want to Sign In'; AX.frame={{0, 384.5}, {375, 43.5}}; AX.activationPoint={187.5, 406.25}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 334.5}, {375, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb6325322e0; AX=N; AX.label='I just want to Sign In'; AX.frame={{85.5, 384.5}, {204, 43.5}}; AX.activationPoint={187.5, 406.25}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{85.5, 0}, {204, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb632531e70; AX=Y; AX.label='I just want to Sign In'; AX.frame={{106.5, 395.5}, {163, 22}}; AX.activationPoint={188, 406.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{21, 11}, {163, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632531860; AX=Y; AX.label='Register for App'; AX.frame={{0, 311}, {375, 43.5}}; AX.activationPoint={187.5, 332.75}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 261}, {375, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632524d20; AX=N; AX.label='Register for App'; AX.frame={{100.5, 311}, {174, 43.5}}; AX.activationPoint={187.5, 332.75}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{100.5, 0}, {174, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb63251b750; AX=Y; AX.label='Register for App'; AX.frame={{121.5, 322}, {132, 22}}; AX.activationPoint={187.5, 333}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{21, 11}, {132, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb632523100; AX=Y; AX.label='I just installed the app.'; AX.frame={{0, 279.5}, {375, 22}}; AX.activationPoint={187.5, 290.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 229.5}, {375, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb63251bd20; AX=N; AX.frame={{0, 150.5}, {375, 114}}; AX.activationPoint={187.5, 207.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 100.5}, {375, 114}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTImageView:0x7fb63251c190; AX=N; AX.frame={{49.5, 165.5}, {276, 99}}; AX.activationPoint={187.5, 215}; AX.traits='UIAccessibilityTraitImage'; AX.focused='N'; frame={{49.5, 15}, {276, 99}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb632526d30; AX=Y; AX.label='Welcome to the App'; AX.frame={{0, 80}, {375, 71}}; AX.activationPoint={187.5, 115.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 30}, {375, 71}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb63252ad20; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb63252a890; AX=N; AX.label='Welcome to the CompCare Member App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      +  +  +  +  +  +  +  +  +  +  +  +  +--<RCTView:0x7fb63252a270; AX=N; AX.id='signInOrRegisterPage'; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 0}, {375, 667}}; AX.activationPoint={187.5, 333.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 667}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb6348012c0; AX=N; AX.frame={{0, 395}, {375, 272}}; AX.activationPoint={187.5, 531}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 395}, {375, 272}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb6349019d0; AX=N; AX.frame={{0, 395}, {375, 272}}; AX.activationPoint={187.5, 531}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 272}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632720000; AX=N; AX.frame={{0, 395}, {375, 272}}; AX.activationPoint={187.5, 531}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 272}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb634800d30; AX=N; AX.frame={{0, 395}, {375, 272}}; AX.activationPoint={187.5, 531}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 272}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTImageView:0x7fb63271fd20; AX=N; AX.frame={{0, 395}, {375, 272}}; AX.activationPoint={187.5, 531}; AX.traits='UIAccessibilityTraitImage'; AX.focused='N'; frame={{0, 0}, {375, 272}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632717e80; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 50}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632718cf0; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb6327189f0; AX=N; AX.label='Welcome to the App I just installed the app. Register for App I just want to Sign In'; AX.frame={{0, 50}, {375, 617}}; AX.activationPoint={187.5, 358.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 0}, {375, 617}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb6327186f0; AX=Y; AX.label='I just want to Sign In'; AX.frame={{0, 384.5}, {375, 43.5}}; AX.activationPoint={187.5, 406.25}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 334.5}, {375, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632529b40; AX=N; AX.label='I just want to Sign In'; AX.frame={{85.5, 384.5}, {204, 43.5}}; AX.activationPoint={187.5, 406.25}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{85.5, 0}, {204, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb63250ce50; AX=Y; AX.label='I just want to Sign In'; AX.frame={{106.5, 395.5}, {163, 22}}; AX.activationPoint={188, 406.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{21, 11}, {163, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632719c90; AX=Y; AX.label='Register for App'; AX.frame={{0, 311}, {375, 43.5}}; AX.activationPoint={187.5, 332.75}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 261}, {375, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632719990; AX=N; AX.label='Register for App'; AX.frame={{100.5, 311}, {174, 43.5}}; AX.activationPoint={187.5, 332.75}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{100.5, 0}, {174, 43.5}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb632715c30; AX=Y; AX.label='Register for App'; AX.frame={{121.5, 322}, {132, 22}}; AX.activationPoint={187.5, 333}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{21, 11}, {132, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb632716a40; AX=Y; AX.label='I just installed the app.'; AX.frame={{0, 279.5}, {375, 22}}; AX.activationPoint={187.5, 290.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 229.5}, {375, 22}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTView:0x7fb632719270; AX=N; AX.frame={{0, 150.5}, {375, 114}}; AX.activationPoint={187.5, 207.5}; AX.traits='UIAccessibilityTraitNone'; AX.focused='N'; frame={{0, 100.5}, {375, 114}}; opaque; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTImageView:0x7fb632702a20; AX=N; AX.frame={{49.5, 165.5}, {276, 99}}; AX.activationPoint={187.5, 215}; AX.traits='UIAccessibilityTraitImage'; AX.focused='N'; frame={{49.5, 15}, {276, 99}}; alpha=1>
      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |--<RCTTextView:0x7fb6348007e0; AX=Y; AX.label='Welcome to the App'; AX.frame={{0, 80}, {375, 71}}; AX.activationPoint={187.5, 115.5}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 30}, {375, 71}}; alpha=1>]

您可以看到我在何处放置了一行加号,以指示它在此层次结构中的何处找到元素。

我很确定(但不是 100% 确定)这个问题是由 react-native-fluid-transitions 库引入的。

该库似乎添加了许多包装器来制作动画功能,它也重复视图。这会导致分配了 testID 的元素在层次结构内部呈现并重复。我通过使用 atIndex(1).

解决了这个问题

我最终使用 atIndex(1) 而不是 atIndex(0) 因为它在尝试执行 tap,索引 0 处的元素不是 可交互的,但是索引 1 处的元素是。

当使用 toBeVisible 期望时,iOS 似乎有问题(与 react-native-fluid-transitions 相关) 具有不透明度,这可能也与动画有关。我通过使用 waitForwithTimeout.

解决了这个问题

我在这里开了一个问题:https://github.com/fram-x/FluidTransitions/issues/138

it('should show the Sign In Or Register page', async () => {

  await waitFor(element(by.id('signInOrRegisterPage')).atIndex(1)).toBeVisible().withTimeout(2000);
});

it('should show the register button and the sign in button', async () => {

  await waitFor(element(by.id('btnRegisterForApp')).atIndex(1)).toBeVisible().withTimeout(2000);
  await waitFor(element(by.id('btnSignIn')).atIndex(1)).toBeVisible().withTimeout(2000);

  await element(by.id('btnSignIn')).atIndex(1).tap();
});



我真的希望这对 react-native-fluid-transitions 库的开发者有用,对其他使用 detox 的人也有用。