The appium test is to perform certain combination of few input fields, and one field is password field.
If the username is already taken, a corresponding message will be shown below the password button saying "username already taken". But if username is valid, but password is wrong, the message will be shown below as "username and password combo didn't work".
The error message in above cases is shown in a android.widget.TextView
**
Two questions:
- I recorded the test using Appium Studio. When I run the test, I want to wait for couple of second and grab the text of error message. How to do the wait part and grab the text? (More details below). THe challenge is there is no resource id for the textView, but xpath and other details are available.
Note: Since the error message is shown right below the pwd field, it has no resouceid, only xpath available.
This is the structure
<android.widget.LinearLayout resource-id="com.a.b/textinputlayout_lgin_username">
<android.widget.FrameLayout>
<android.widget.EditText resource-id="com.a.b/lgin_username_edit">
<!--above 3 lines are for username field, just added for more clarity -->
<android.widget.LinearLayout resource-id="com.a.b:id/textinputlayout_lgin_pwd">
<android.widget.FrameLayout>
<android.widget.EditText>
<android.widget.ImageButton resource-id="com.a.b/text_input_end_icon">
<android.widget.TextView> <!-- ** this is the text I'm trying to grab -->
<android.widget.TextView resource-id="com.a.b/tv_forgotpwd">
<android.widget.Button resource-id="com.a.b/btn_login">
Please help. Thanks.
CodePudding user response:
I assume, you have no ability to update the app in order to add resource id for the element.
The best, you can do in this case, is to use xpath.
Find the first parent by resorce-id attribute, and then go down and search by tag. I see 2 text tag elements here in LinearLayout, so you might try to get the first text tag by index, or search for text tag without resouce id attribute.
"(//android.widget.LinearLayout[@resouce-id='com.a.b:id/textinputlayout_lgin_pwd']//android.widget.TextView)[1]"
or
"//android.widget.LinearLayout[@resouce-id='com.a.b:id/textinputlayout_lgin_pwd']//android.widget.TextView[not(@resouce-id)]"
Based on appium client you're using, just utilize webdriver wait expected conditions and use xpath location strategy for the element.
PS: Here is the code
public class Test_9 {
private String reportDirectory = "reports";
private String reportFormat = "xml";
private String testName = "Untitled";
protected AndroidDriver<AndroidElement> driver = null;
DesiredCapabilities dc = new DesiredCapabilities();
@BeforeEach
public void setUp() throws MalformedURLException {
dc.setCapability("reportDirectory", reportDirectory);
dc.setCapability("reportFormat", reportFormat);
dc.setCapability("testName", testName);
dc.setCapability(MobileCapabilityType.UDID, "123456");
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.a.b");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.base.SplashActivity");
driver = new AndroidDriver<>(new URL("http://localhost:4723/wd/hub"), dc);
driver.setLogLevel(Level.INFO);
}
@Test
public void testUntitled() {
driver.findElement(By.xpath("(//*[@contentDescription='Google Map']/*[@class='android.view.View'])[26]")).click();
driver.findElement(By.xpath("//*[@text='log in']")).click();
driver.findElement(By.xpath("//*[@id='lgin_edit']")).sendKeys("1234567789");
driver.findElement(By.xpath("//*[@class='android.widget.EditText' and (./preceding-sibling::* | ./following-sibling::*)[@id='text_input_end_icon']]")).sendKeys("qwer");
new WebDriverWait(driver, 120).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@class='android.widget.EditText' and (./preceding-sibling::* | ./following-sibling::*)[@id='text_input_end_icon']]")));
driver.hideKeyboard();
driver.findElement(By.xpath("//*[@class='android.widget.EditText' and (./preceding-sibling::* | ./following-sibling::*)[@id='text_input_end_icon']]")).click();
driver.findElement(By.xpath("//*[@text='Log In']")).click();
driver.findElement(By.xpath("//*[@text='Log In']")).click();
}
@AfterEach
public void tearDown() {
//driver.quit();
}
}
CodePudding user response:
Ok, this is what resolved my issue.
After posting the questino I realized, the button wasn't enabled, that's because the previous input text field is not clicked or something.
All this time I was recording via Appium, but I was manually clicking the keyboard and buttons on mobile phone, not the mobile simulator of appium.
After 2.5 days, I used mouse pointer of my computer to click all the fields and all simulation on the simulator of appium and recorded and re-ran the tests and it worked.
I did try printing out the button state and it was always btn.isEnabled() was returning false.