1

Issue description: Using xpath with text description works fine, but using xpath having id is not working.

[Sensitive parts being masked in picture and code]

I'm trying to perform a mock project on a mobile app with latest appium version. Having following dependency in my pom file

java-client: 8.1.1 | selenium-java: 4.2.0

<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>8.1.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.2.0</version>
</dependency>

Below is the screen shot of the app, where i'm trying to identify text. "Hey Ram,"

enter image description here

Using xpath option in appium studio,i'm finding both the xpath.

  1. Copy Unique Xpath ==> //*[@text='Hey Ram,']
  2. Copy Unique Xpath (skip text) ==> //*[@id='dialog_fr_tv_title']

enter image description here

I'm identifying the the text using appium inspector filter and it clearly identifying uniquely.

  1. Using option Copy Unique Xpath (xpath = //*[@text='Hey Ram,'])

enter image description here

  1. Using option Copy Unique Xpath (skip text) (xpath= //*[@id='dialog_fr_tv_title'])

enter image description here

This clearly shows, both xpath one with text, and another with id is clearly identifying the element uniquely.

I have written the following Java code, where i try to extract the text and print the value.

package basics;

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

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.SupportsLegacyAppManagement;
import io.appium.java_client.android.AndroidDriver;

public class SimpleAppiumClass {
    @SuppressWarnings({ "null", "deprecation" })
    public static void main(String[] args) {

        AppiumDriver driver=null;
        
        //Set the Desired Capabilities
        DesiredCapabilities caps = new DesiredCapabilities();
        //caps.setCapability("udid", "emulator-5554"); //Give Device ID of your mobile phone
        caps.setCapability("udid", "d278263c");
        caps.setCapability("platformName", "Android");
        caps.setCapability("platformVersion", "11");
        caps.setCapability("automationName", "UiAutomator2");
        caps.setCapability("appPackage", "com.xx.vxx.xxxxxx");
        caps.setCapability("appActivity", "com.xx.vxx.xxxxxx.view.activity.SVSplashScreenActivity");
        caps.setCapability("noReset", "true");
        
        //Instantiate Appium Driver
        try {
            driver = new AndroidDriver(new URL("http://0.0.0.0:4723/wd/hub"), caps);
            driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
            WebElement elementId = driver.findElement(By.id("dialog_fr_tv_title"));
            System.out.println("id text: "+elementId.getText());
            WebElement elementTextXpath = driver.findElement(By.xpath("//*[@text='Hey Ram,']"));
            System.out.println("using text(xpath)=: "+elementTextXpath.getText());
            //*[@text='Hey Ram,']
            WebElement elementIdXpath = driver.findElement(By.xpath("//*[@id='dialog_fr_tv_title']"));
            System.out.println("using id(xpath)=: "+elementIdXpath.getText());
            
            ((SupportsLegacyAppManagement) driver).closeApp(); 


            
        } catch (MalformedURLException e) {
            System.out.println(e.getMessage());
            ((SupportsLegacyAppManagement) driver).closeApp(); 
        }
        
        System.out.println("---End of execution---"); 
    }
}

First time, i'm using By.id [driver.findElement(By.id("dialog_fr_tv_title"))] print me "Hey Ram," text as expected.

Second time, using By.xpath [driver.findElement(By.xpath("//*[@text='Hey Ram,']"))] print me also 'Hey Ram?," text as expected. This time xpath is written using text option.

Thrid time, using By.xpath [driver.findElement(By.xpath("//*[@id='dialog_fr_tv_title']"))] throws me error "Exception in thread "main" org.openqa.selenium.NoSuchElementException: "

Not only for this element, trying to give xpath for button "Continue with mobile number" throws same error.

For button without text: //*[@id='dialog_fr_mobile_btn'] --> throws error

For buttom with text: //*[@text='Continue with Mobile Number'] --> works fine.

Execution logs

id text: Hey Ram,
using text(xpath)=: Hey Ram,
Exception in thread "main" org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters.
For documentation on this error, please visit: https://selenium.dev/exceptions/#no_such_element
Build info: version: '4.3.0', revision: 'a4995e2c09*'
System info: host: 'LAPTOP-0LQSGR9A', ip: '172.31.98.220', os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '18.0.1.1'
Driver info: io.appium.java_client.android.AndroidDriver
Command: [f30292c6-4f04-4d4f-939c-a8d98c801efb, findElement {using=xpath, value=//*[@id='dialog_fr_tv_title']}]
Capabilities {appium:appActivity: com.tv.v18.viola.view.activ..., appium:appPackage: com.tv.v18.viola, appium:automationName: UiAutomator2, appium:databaseEnabled: false, appium:desired: {appActivity: com.tv.v18.viola.view.activ..., appPackage: com.tv.v18.viola, automationName: UiAutomator2, noReset: true, platformName: android, platformVersion: 11, udid: d278263c}, appium:deviceApiLevel: 28, appium:deviceManufacturer: OnePlus, appium:deviceModel: ONEPLUS A5000, appium:deviceName: d278263c, appium:deviceScreenDensity: 380, appium:deviceScreenSize: 1080x1920, appium:deviceUDID: d278263c, appium:javascriptEnabled: true, appium:locationContextEnabled: false, appium:networkConnectionEnabled: true, appium:noReset: true, appium:pixelRatio: 2.375, appium:platformVersion: 9, appium:statBarHeight: 57, appium:takesScreenshot: true, appium:udid: d278263c, appium:viewportRect: {height: 1863, left: 0, top: 57, width: 1080}, appium:warnings: {}, appium:webStorageEnabled: false, platformName: ANDROID}
Session ID: f30292c6-4f04-4d4f-939c-a8d98c801efb
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:200)
    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:133)
    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184)
    at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:180)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:569)
    at org.openqa.selenium.remote.ElementLocation$ElementFinder$2.findElement(ElementLocation.java:162)
    at org.openqa.selenium.remote.ElementLocation.findElement(ElementLocation.java:60)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:387)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:379)
    at basics.SimpleAppiumClass.main(SimpleAppiumClass.java:40)

Let me know if anything I missed or issue with latest version (known issue), any work around. Using text in some scenario will not be good thing if I try to code.

Regards, Ramkumar

Ramkumar
  • 116
  • 1
  • 11
  • Kind of long stretch but have you tried `//*[@resource-id='dialog_fr_mobile_btn']` instead of just `@id`? – drunkencheetah Jun 28 '22 at 06:49
  • @drunkencheetah -> Using resource-id as xpath is working. But not working with @id=dialog_fr_tv_title WebElement elementIdXpath = driver.findElement(By.xpath("//*[@resource-id='com.tv.v18.viola:id/dialog_fr_tv_title']")); System.out.println("using id(xpath)=: "+elementIdXpath.getText()); Thanks – Ramkumar Jun 28 '22 at 07:15
  • I believe this is because for native elements the selector strategy on Android is `resource-id`, you can refer to the information [here](https://appium.io/docs/en/commands/element/find-elements/index.html#selector-strategies). Also I haven't done this in a while but I think you can use `resource-id` without providing the package name :) – drunkencheetah Jun 28 '22 at 07:29
  • WebElement elementIdXpath = driver.findElement(By.xpath("//*[@resource-id='dialog_fr_tv_title']")); System.out.println("using id(xpath)=: "+elementIdXpath.getText()); Only with package name[com.tv.v18.viola:id/dialog_fr_tv_title] it works. Without package name [dialog_fr_tv_title] it throws NoSuchElementException – Ramkumar Jun 28 '22 at 08:33
  • I don't know that ObjectSpy you are using but I did a quick check with Appium Inspector on the Android Settings app and for me both `id` and `resource-id` are the same and they both contain the package name. I would suggest you just go with `resource-id` because this is what the Appium documentation states should be used for native selector – drunkencheetah Jun 28 '22 at 09:45

0 Answers0