Unable to set the text of an OTP on Mobile (Android app)

I am able to capture the 6 digit OTP but Unable to set the text of the same OTP on Mobile (Android app) emulator device.

Issue screenshot:

Could you please help
@helpdesk @Chris_Trevarthen @ThanhTo @Russ_Thomas @duyluong

@ayesha.khanam
Maybe the following will help you.

@ayesha.khanam

You cannot sendKeys or setText on RelativeLayout. Please find the field: EditText and use the keywords on it.

hey @duyluong
IT doesn’t have edit text
Tried the below code but still the same issue
Mobile.setText(findTestObject(‘TestApk/android.widget.TextView0 (1)’), value[0])
where value[0] is the first digit of my otp code fetched from a API

@grylion54 Unfortunately it did not work

Could you please help
@helpdesk @Chris_Trevarthen @ThanhTo @Russ_Thomas @duyluong @grylion54

@ayesha.khanam

Can you share us full screen of the ALL OBJECTS view?

Hi @ayesha.khanam,

Like @duyluong mentioned, sendKeys and setText only work on input fields. If you don’t have an input field, then you could try another approach:

  1. Make your test tap the first field in the OTP entry (or whatever action you need to do to bring up the keyboard)
  2. Use the AppiumDriver directly to interact with the keyboard to send the keys:

At the top of your test Script file, add:

import io.appium.java_client.android.AndroidDriver
import io.appium.java_client.android.nativekey.AndroidKey
import io.appium.java_client.android.nativekey.KeyEvent

Then in your test, use the steps:

AndroidDriver<?> driver = MobileDriverFactory.getDriver()

driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_0));
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_1));
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_2));
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_3));
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_4));
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_5));
driver.pressKey(new KeyEvent(AndroidKey.ENTER));

This should hopefully fill out the OTP fields and submit the form.

If this doesn’t work, then we’ll need to see the full All Objects list for the screen with the OTP entry.

Hope this helps,

Chris

2 Likes

Hi @Chris_Trevarthen &
@duyluong
Here OTP is dynamic in nature
Please find the All objects view below

Hi @ayesha.khanam,

From the object list, it looks like there is an android.widget.EditText object. I’m wondering if you can capture that object using Mobile Spy and then use setText or sendKeys on it?

Hope this helps,

Chris

Hey @Chris_Trevarthen,

Edit text object is for the entire 6 digit otp field as shown below,
I still tried it but unfortunately it didn’t work

Hi @ayesha.khanam,

If you were testing manually, how would you get the keyboard to show up to enter the OTP? Do you tap on one of the blank OTP fields?

I’m thinking that you could do the same thing in a test - either capture a Katalon TestObject for the EditText or the first TextView for the OTP. Then, in your test, tap that TestObject to open the keyboard. Once the keyboard is open, try using the driver.pressKey commands that I shared above.

Hope this helps,

Chris

If I am testing it manually as soon as I click on the first otp object i.e., (Linear Layout/Relative Layout/TextView) keypad will pops in. Not using the keypad though

I am using a dynamic 6 digit OTP as soon as I get it from an API.
If I pass it manually also I need to pull the first number from the 6 digit otp and pass it in the first otp object displayed on the UI. Similarly next 5 objects one at a time.
1
I tried the above approach but unfortunately it did not work

Hi @ayesha.khanam,

OK, so the keyboard is opening, that is good. Since the user will be interacting with the keypad to input the OTP, simulating that interaction could be the way to go.

Because your OTP is generated each time, you’ll need to split the OTP into the individual characters using Groovy’s string split function (https://www.tutorialspoint.com/groovy/groovy_split.htm) and then loop through each of the numbers to tap the correct number pad entry.

If the option above for using driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_0)); to tap a key doesn’t work with the keypad, then another option, although not very elegant, is to do a Mobile.tapAtPosition(x, y) where the number buttons are located. It might take a little trial and error to find those coordinates, unless you can use Mobile Spy to capture the key coordinates.

Once you have the coordinates for each number, you could create an if or switch statement to tap in the correct location based on the individual OTP numbers.

Hope this helps,

Chris

Hey @Chris_Trevarthen

Appreciate your suggestions !

I used the below code for passing a hard coded OTP value and able to pass the otp in the first place but after passing the OTP1 i.e.,5 it is replacing with next OTP2

image

Any suggestions on this??

Code Used
AndroidDriver<?> driver = ((MobileDriverFactory.getDriver()) as AndroidDriver<?>)
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_0))
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_1))
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_2))
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_3))
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_4))
driver.pressKey(new KeyEvent(AndroidKey.NUMPAD_5))
driver.pressKey(new KeyEvent(AndroidKey.ENTER))

//Set the hard coded otp
Mobile.tap(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP1’), 0)
Mobile.setText(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP1’), ‘5’, 0)
Mobile.tap(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP2’), 0)
Mobile.setText(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP2’), ‘1’, 0)
Mobile.setText(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP3’), ‘4’, 0)
Mobile.setText(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP4’), ‘7’, 0)
Mobile.setText(findTestObject(‘TestApk/android.widget.RelativeLayoutOTP5’), ‘9’, 0)

Xpath/objects used

Hi @ayesha.khanam,

That is really weird that it keeps seeming to reuse that field. I’m wondering if it’s because of the way the xpath is being interpreted. From your Test Object, it looks like you’ve got the only attribute set for xpath. It’s a very complicated xpath that seems very brittle.

I noticed that you actually have a unique resource-id available for each of the OTP numbers. I think that’s a more reliable way to get the element. So, if you change your Test Object to “Detect object by” resource-id instead of xpath, can you try to see if that will let you set each individual field?

Hope this helps,

Chris

On Katalon Studio 8.2.0 we need to input the OTP using “Digit” function as the “NUMPAD” does not seem to work. This code works for me

AndroidDriver<?> driver = MobileDriverFactory.getDriver()
driver.pressKey(new KeyEvent(AndroidKey.DIGIT_0));
driver.pressKey(new KeyEvent(AndroidKey.DIGIT_1));

Could you please help us ^^

image