python-client: Appium cannot find element by ID, but can by XPATH

The problem

I’ve been working on dual Appium/Selenium test suite for a web page and mobile app. When using Appium, it is unable to find the element by ID. If I change it to use XPATH, it works as expected, then fails to find the next element by ID. This may not sound like a problem, but other elements in the app are not easily distinguished by XPATH values.

This test suite worked previously with manual app install and the Appium Service running on Mac. I’ve since tried to automate the process to install the application and run Appium Service programmatically. I am wondering if the way I’ve set this up is causing it not to detect elements by ID.

I know for certain the ID is correct. It works for the Selenium + web page combination, and I’ve tried digging into the app with Appium Studio. It displays the ID correctly in the app, and copy pasting the ID into my code doesn’t change anything.

Environment

  • Appium version (or git revision) that exhibits the issue: All versions I’ve tried experience this (currently using 1.14.2)
  • Desktop OS/version used to run Appium: MacOS Catalina
  • Node.js version (unless using Appium.app|exe): 10.15.0
  • Npm or Yarn package manager: NPM
  • Mobile platform/version under test: Android 8.1
  • Real device or emulator/simulator: Real Device
  • Appium CLI or Appium.app|exe: Appium CLI

Link to Appium logs

Unfortunately, it doesn’t look like the AppiumService in Python creates logs. If it does, I’ll attach them when I find them or somebody tells me where they are

Code To Reproduce Issue [ Good To Have ]

Code below (redesign_tags and redesign_locators contain some sensitive info, but they work as intended in the Selenium flow):

class Driver:
    desired_capabilities = {}

    def __init__(self):
        # AppiumService was not called in previous version
        redesign_tags.appium_service = AppiumService()
        redesign_tags.appium_service.start()

        self.desired_capabilities[redesign_tags.platform_name_label] = redesign_tags.platform_device_name_android_label
        self.desired_capabilities[redesign_tags.no_reset_label] = redesign_tags.no_reset_value
        self.desired_capabilities[redesign_tags.platform_device_name_label] = redesign_tags.platform_device_name_galaxy_8
        self.desired_capabilities["app"] = "/Path/To/android-app.apk" # this line did not exist in the old version
        self.desired_capabilities[redesign_tags.app_package_label] = redesign_tags.app_package_value_dev
        self.desired_capabilities[redesign_tags.app_activity_label] = redesign_tags.app_activity_value
        self.instance = webdriver.Remote(redesign_tags.link_to_wd_hub, self.desired_capabilities)
        time.sleep(10)  # wait for application install
        print("Installed application")

def setupDevice():
    if redesign_tags.platform == "Android":
        print("Installing application...")
        driver = Driver()
    elif redesign_tags.platform == "Chrome":
        options = webdriver.ChromeOptions()
        options.add_argument('--start-maximized')
        options.add_argument('--unlimited-storage')
        driver = webdriver.Chrome(options=options)
        driver.get("localhost:8100")
        redesign_tags.webdriver = driver
        driver.set_window_position(0, 0)
        driver.maximize_window()
    else:
        print("Invalid platform specified")
        return False

    print("Registering device...")
    pairing = PairingPage(driver)
    # this element is not found by Appium
    pairing_credentials = pairing.get_element_by_id(redesign_locators.pairing_credentials_button, 25)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 31 (7 by maintainers)

Most upvoted comments

it’s crazy but the only thing that worked for me was to use

`xpath://*[@resource-id='${selector}']`

I had updated Appium globally, tried to change the capabilities to be more accurate and everything but this solve the issue right away. Before I even had strange behavior where I needed to click somewhere else for the next click to work.

Yes.

It depends on the app under test. You can find elements by io.appium.android.apis:id/text1 if the app under test had their customised resource id. Android’s general component could have android: prefixed resource id if nothing developers specified.

The behaviour is not Appium specific.

^ This could also be an issue with accessibility identifiers naming (app identifier prefix is missing). Then https://github.com/appium/appium/issues/15138#issuecomment-1127709588 could be used as a workaround.

I am trying to replicate this behavior in my code. I am using this function to wait for the element to appear:

def wait_for_element_by_id(self, id, time):
        try:
            WebDriverWait(self.driver, time).until(EC.visibility_of_element_located((MobileBy.ID, id)))
        except NoSuchElementException:
            print("Element not found: " + id)
            return False
        except TimeoutException:
            print("Timeout occurred: " + id)
            return False
        return True

My understanding is MobileBy.ID will not work. I do not see MobileBy.Resource_ID. I’ve also tried experimenting with just getting the element without a wait using this:

    def is_element_present_by_id(self, id):
        try:
            element = self.driver.find_element_by_id("android:id/"+id)
            if element is None:
                return False
        except NoSuchElementException:
            return False
        except TimeoutException:
            return False
        return True

I also tried element = self.driver.find_element_by_id("io.appium.android.apis:id/"+id) but this is not working either. The original code used self.driver.find_element(MobileBy.ID, id). I checked in Appium Studio. The ID and Resource ID are the same value.

I also tried downloading Appium Desktop just to be sure. It looks like the application I already have and was previously using to manually set up the Appium service. However, Mac is being difficult and says the app can’t be opened with no explanation why. The version of Appium Desktop I already have doesn’t have any element inspection services that I know of.

Hey Did you find the way to find elements by id?

@ws-cdavis just wondering if you ever found a resolution for this? I’m afraid I’m not proficient in python like you clearly are so I’m utilising the appiumlibrary that’s part of robot framework, however, I too have a problem that if I express as id=X it fails to find the element. If I express that same element as //*[@resource-id=“X”] it works flawlessly.