Devansh Shukla
Devansh Shukla

Reputation: 15

Integration testing using Flutter Driver for OTPTextField widget in flutter

I am trying to do integration testing using flutter driver. I am using await driver.enterText(find.byType('OTPTextField')) to enter the otp using flutter driver. But it's stuck at that screen and does nothing and the test fails after termination error. The OTPTextField widget kind of has a different UI than normal text field. I am not sure whether enterText function will work in this or not. If not, what are some alternatives?

Here is my code for OTPTextField widget:

OTPTextField(
                key: const Key('otpvalue'),
                length: 6,
                textFieldAlignment: MainAxisAlignment.spaceAround,
                fieldWidth: 30,
                fieldStyle: FieldStyle.underline,
                width: MediaQuery.of(context).size.width / 2,
                style: TextStyle(
                    fontSize: 17,
                    color: Colors.black,
                    fontWeight: FontWeight.bold),
                onCompleted: (pin) async {
                  print("Completed: " + pin);
                  print(_user.status);
                  if (_user.status == Status.VerifyingOTP ||
                      _user.status == Status.VerifiedOTP) {
                    Navigator.of(context).push(
                        MaterialPageRoute(builder: (_) => LoaderScreen()));
                      return;
                  }
                  if (widget.isSignup) {
                    if (await _user.signUpWithPhoneNumber(
                      pin.toString(),
                      context,
                      email: widget.emailId,
                      firstName: widget.firstName,
                      lastName: widget.lastName,
                    )) {
                      Navigator.of(context).pushReplacement(
                          MaterialPageRoute(
                              builder: (context) => OtpVerified()));
                    } else {
                      Navigator.of(context).push(
                          MaterialPageRoute(
                              builder: (context) => LoaderScreen()));
                    }
                  } else {
                    if (await _user.signInWithPhoneNumber(
                        pin.toString(), context, _user.language, _user.country)) {
                      Navigator.of(context).pushReplacement(
                          MaterialPageRoute(
                              builder: (context) => OtpVerified()));
                    } else {
                      Navigator.of(context).push(
                          MaterialPageRoute(
                              builder: (context) => LoaderScreen()));
                    }
                  }
                },
              ),

And here is the code for integration testing what I tried for this widget.

test('enter otp', () async {
 SerializableFinder enterotp = find.byValueKey('otpvalue');
  await driver.tap(enterotp);
  await driver.enterText('123456');
  expect(await driver.getText(enterotp), "123456");
});

Upvotes: 0

Views: 1404

Answers (2)

lucapada
lucapada

Reputation: 1

I tried this solution when I was doing widget testing, and it worked well for me.

final otpField = find.descendant(
  of: find.byType(OtpTextField),
  matching: find.byType(TextFormField),
);

final int numOfDigits = 6;

for(int i = 0; i < numOfDigits; i++) {
  await tester.enterText(otpField.at(i), '1');
  await tester.pump();
}

Upvotes: 0

Mohamad Hammoud
Mohamad Hammoud

Reputation: 122

Maybe there is some animation happening and blocking the driver from finding the widget, for this try solution 1. If it did not work, try solution 2:

Solution 1:

test('enter otp', () async {
  await driver.runUnsynchronized(() async {
    SerializableFinder enterotp = find.byValueKey('otpvalue');
    await driver.tap(enterotp);
    await driver.enterText('123456');
    expect(await driver.getText(enterotp), "123456");


});
});

Solution 2:

       final otpField = find.descendant(
        of: find.byType('OTPTextField'),
        matching: find.byType('AnimatedContainer'),
       
    );
      await driver.tap(otpField);
      await driver.enterText('111111');

Upvotes: 0

Related Questions