Not able to find element by XPATH using Appium / Python

I am automating a flow that consists in tapping in the Product Name from a Product List which is a Xamarin ListView to go into de Product Details Page.

I have set in my ListView:

AutomationProperties.IsInAccessibleTree="false"

And in the Product Name Label:

AutomationId="ProductName"

The funny thing is that when using Appium Desktop UI inspection tool I can see the XPATH and if I record tapping into it, it actually works and I get this script:

MobileElement el1 = (MobileElement) driver.findElementByXPath("(//XCUIElementTypeStaticText[@name=\"ProductName\"])[1]");
el1.click();

For that I know that the XPATH exists and is visible to Appium. It works in the inspection tool.

Now, when I translate this to Python, something goes wrong:

el1 = self.driver.find_element_by_xpath("(//XCUIElementTypeStaticText[@name=\"ProductName\"])[1]")

I get this error message:

el = self.driver.find_element_by_xpath(element_query) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 393, in find_element_by_xpath return self.find_element(by=By.XPATH, value=xpath) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 966, in find_element 'value': value})['value'] File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 320, in execute self.error_handler.check_response(response) File "/Users/joseclua/Library/Python/3.7/lib/python/site-packages/appium/webdriver/errorhandler.py", line 29, in check_response raise wde File "/Users/joseclua/Library/Python/3.7/lib/python/site-packages/appium/webdriver/errorhandler.py", line 24, in check_response super(MobileErrorHandler, self).check_response(response) File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

Upvotes: 1

Views: 7264

Answers (4)

Nafeez Quraishi
Nafeez Quraishi

Reputation: 6168

I would suggest in general its safer to check for visibility of an element for sometime before triggering click on the element. Something like this:

    elem_to_find = WebDriverWait(
        driver, 5).until(
            EC.visibility_of_element_located(
                ('xpath or id or class of the element, considering xpath in this case', MobileBy.XPATH)))
    elem_to_find.click()

Upvotes: 0

Nauman Malik
Nauman Malik

Reputation: 188

You can use other methods to find elements as well like id, UIAutomator, classname etc.

for id use *driver.findElementById("id").click();

for UIAutomator use driver.findElementByAndroidUIAutomator("text(\"Text\")").click();

for Classname use driver.findElementByClassName("Class Name").click();

Hope this helps.

Upvotes: 0

Thanks to Suban's insight I was able to tap the list element and also avoiding the XPath which is not recommended.

This is the code I have working now on iOS. I still need to test in Android.

def list_item_tap(self, el_name):
    print("list_item_tap {0}", el_name)
    li = self.driver.find_elements_by_accessibility_id(el_name)
    print("list items: {0}", len(li))
    if len(li) > 0:
        el = li[0]
        time.sleep(2)
        el.click()

The click seems to fail without the sleep.

Thank you Suban

Upvotes: 1

Suban Dhyako
Suban Dhyako

Reputation: 2526

Using Xpath is not recommended in appium

you can use cont-desc, id, resource-id for you automation. Since you are using xamarin project, you can add automation code in project.

Then you can see cont-desc while inspecting the app. Then you can use element as:

el = self.driver.find_elements_by_accessibility_id('ProductName');

Upvotes: 0

Related Questions