tttstudios / react-native-otp-input

Tiny Javascript library which provides an elegant UI for user to input one time passcode.
MIT License
530 stars 239 forks source link

Detox testID is missing #118

Open oussamaraboija opened 3 years ago

oussamaraboija commented 3 years ago

Our QA dev is having a difficult time writing e2e tests because we used this library. We use Detox which needs a testID for components. But this input doesn't have testID prop. What do you suggest we do? Thank you in advance for any fixes or suggestions.

jamesmcn1 commented 3 years ago

+1 for Test ID

My workaround: The OTP input is made up of a series of textfields, one for each digit (in my case 6). You can use the following during Detox tests to type digits:

      await waitFor(element(by.id('OTPInputView'))).toExist();
      // OTP input is a series of 6 separate textfields, one for each digit
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('1');
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('2');
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('3');
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('4');
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('5');
      await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText('6')
Shail-Patel-1 commented 1 year ago

@jamesmcn1 @oussamaraboija can you please suggest a work around for test cases written using testing library ?

dids-reyes commented 10 months ago

Thanks for this @jamesmcn1

modified it:

const otp = '123456';

for(let i = 0; i < otp.length; i++) {
    const currentDigit = otp[i];
    await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText(currentDigit);
}
VishalKumar2016 commented 8 months ago

Where do we pass this id? @jamesmcn1 @skedaddl3 by.id('OTPInputView'))

dids-reyes commented 8 months ago

@VishalKumar2016 OTPInputView id doesn't work for you?

make sure that the OTP field is displayed or popped up before using it

VishalKumar2016 commented 8 months ago

@skedaddl3 thanks for your reply please see my code

  <View testID='optView'>
        <OTPInputView
          pinCount={6}
          codeInputFieldStyle={Styles.codeInputFieldStyle}
          codeInputHighlightStyle={Styles.codeInputHighlightStyle}
          style={Styles.otpStyle}
          code={(props.otp)}
          onCodeChanged={props.onOtpChanged}
        />
      </View>

This is my OtpView

  And this is my test case
          await waitFor(element(by.text('').withAncestor(by.id('otpView'))).atIndex(0)).toBeVisible();

This one is passing but next one fails await element(by.text('').withAncestor(by.id('otpView'))).atIndex(0).replaceText('1');

Is this how you are using it?

dids-reyes commented 8 months ago

@VishalKumar2016 You don't need to add this <View testID='optView'> it should be <View> only

Did you try to copy and paste this?

https://github.com/tttstudios/react-native-otp-input/issues/118#issuecomment-1803299043

This should work in your case, you just need to display the OTP, and try the workaround

// This will be the trigger to display your OTP
await element(by.id('this-should-display-your-otp')).tap();

// This should add the digits in each OTP field
const otp = '123456';

for(let i = 0; i < otp.length; i++) {
    const currentDigit = otp[i];
    await element(by.text('').withAncestor(by.id('OTPInputView'))).atIndex(0).replaceText(currentDigit);
}
VishalKumar2016 commented 8 months ago

@skedaddl3 Ohh!! I thought I need to pass OTPInputView as testID to my View. Your code works like a charm. Thank you.