Search code examples
javaandroidseleniumappiumgenymotion

Creating Xpath for an Android element without ID in java


I have been searching for this issue for a while so I decided to create an account and ask this myself. This is my first post so I'll do my best.

I want to fill three text fields in a certain screen. These fields do not have an id, index or content-desc. All the fields have the same class and package. The only detail they have is text.

I'm using Genymotion, Appium and Selenium.

This is my code:

package Steps;
import cucumber.api.PendingException;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;


public class MyStepdefs {

    AndroidDriver driver;

    @Before
    public void setUp() throws MalformedURLException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName", "192.168.150.101:5555");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("appPackage", "com.android.contacts");
        capabilities.setCapability("appActivity", "com.android.contacts.activities.PeopleActivity");
        driver = new AndroidDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);
        driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }

So I want to add a new contact in my virtual device. I'm able to open the correct screen to add a new contact but now I need to fill in some text fields and this is where my problem starts.

I want to use the sendKeys method for the following field: Screenshot of UiAutomatorViewer

I tried the following Xpath:

MobileElement nameField = (MobileElement) driver.findElement(By.xpath("//android.widget.EditText[@text='Name']"));
    nameField.click();
    nameField.sendKeys("Test");

My Appium log:

    [HTTP] {"using":"xpath","value":"//android.widget.EditText[@text='Name']"}
[W3C] Calling AppiumDriver.findElement() with args: ["xpath","//android.widget.EditText[@text='Name']","e8c8c5fc-0dbc-42b5-835d-f27b0a365a95"]
[BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[BaseDriver] Waiting up to 15000 ms for condition
[AndroidBootstrap] Sending command to android: {"cmd":"action","action":"find","params":{"strategy":"xpath","selector":"//android.widget.EditText[@text='Name']","context":"","multiple":false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"xpath","selector":"//android.widget.EditText[@text='Name']","context":"","multiple":false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding '//android.widget.EditText[@text='Name']' using 'XPATH' with the contextId: '' multiple: false
[HTTP] <-- POST /wd/hub/session/e8c8c5fc-0dbc-42b5-835d-f27b0a365a95/element - - ms - -
[HTTP] 
[HTTP] --> DELETE /wd/hub/session/e8c8c5fc-0dbc-42b5-835d-f27b0a365a95
[HTTP] {}
[W3C] Calling AppiumDriver.deleteSession() with args: ["e8c8c5fc-0dbc-42b5-835d-f27b0a365a95"]
[BaseDriver] Event 'quitSessionRequested' logged at 1530018954452 (15:15:54 GMT+0200 (W. Europe Daylight Time))
[Appium] Removing session e8c8c5fc-0dbc-42b5-835d-f27b0a365a95 from our master session list
[AndroidDriver] Shutting down Android driver
[ADB] Running 'D:\Handleiding\SDK\platform-tools\adb.exe -P 5037 -s 192.168.150.101\:5555 shell am force-stop com.android.contacts'
[ADB] Pressing the HOME button
[ADB] Running 'D:\Handleiding\SDK\platform-tools\adb.exe -P 5037 -s 192.168.150.101\:5555 shell input keyevent 3'
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Failed to locate element. Clearing Accessibility cache and retrying.
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding '//android.widget.EditText[@text='Name']' using 'XPATH' with the contextId: '' multiple: false
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":7,"value":"No element found"}
[AndroidBootstrap] Received command result from bootstrap
[MJSONWP] Matched JSONWP error code 7 to NoSuchElementError
[AndroidBootstrap] Sending command to android: {"cmd":"shutdown"}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"shutdown"}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type SHUTDOWN
[AndroidBootstrap] Received command result from bootstrap
[UiAutomator] Shutting down UiAutomator
[UiAutomator] Moving to state 'stopping'
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":0,"value":"OK, shutting down"}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Closed client connection
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: numtests=1
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: stream=.
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: test=testRunServer
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap
[UiAutomator] UiAutomator shut down normally
[UiAutomator] Moving to state 'stopped'
[ADB] Attempting to kill all uiautomator processes
[ADB] Getting all processes with uiautomator
[ADB] Running 'D:\Handleiding\SDK\platform-tools\adb.exe -P 5037 -s 192.168.150.101\:5555 shell ps'
[ADB] No uiautomator process found to kill, continuing...
[UiAutomator] Moving to state 'stopped'
[Logcat] Stopping logcat capture
[ADB] Running 'D:\Handleiding\SDK\platform-tools\adb.exe -P 5037 -s 192.168.150.101\:5555 shell am force-stop io.appium.unlock'
[AndroidDriver] Not cleaning generated files. Add `clearSystemFiles` capability if wanted.
[BaseDriver] Event 'quitSessionFinished' logged at 1530018960995 (15:16:00 GMT+0200 (W. Europe Daylight Time))
[W3C] Received response: null
[W3C] But deleting session, so not returning
[W3C] Responding to client with driver.deleteSession() result: null
[HTTP] <-- DELETE /wd/hub/session/e8c8c5fc-0dbc-42b5-835d-f27b0a365a95 200 6545 ms - 14
[HTTP] 

I also tried the easy way, same result:

driver.findElement(By.xpath("//android.widget.EditText[@text='Name']")).click();
driver.findElement(By.xpath("//android.widget.EditText[@text='Name']")).sendKeys("Test");

And I even tried a List, same result:

List<AndroidElement> txtbox = driver.findElements(By.className("android.widget.EditText"));
txtbox.get(0).sendKeys("Test");
txtbox.get(1).sendKeys("0612345678");
txtbox.get(2).sendKeys("test@testtest.test");

Please let me know if you have any suggestions to my post so I can edit it.

Thanks in advance!


Solution

  • Try defining your webdriver as AndroidDriver in both the declaration and the instantiation.

    Also change the MobileElement to AndroidElement.

    Your xpath looks correct to me.