Search code examples
pythonappiumandroid-uiautomatorsaucelabs

NoSuchElementException with uiautomator2


I'm trying to run my Python code on Sauce Labs and it works fine with automationName capability not set (which defaults it to Appium as per http://appium.io/docs/en/writing-running-appium/caps/). However, when I set this capability to UiAutomator2, it throws below error at the line element_some_text = self.driver.find_element_by_xpath("//android.widget.TextView[@text='Some Text']"):

NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

Here's my code:

import lemoncheesecake.api as lcc
from appium import webdriver


@lcc.suite("My test suite")
class my_test_suite:
    caps = {}
    driver = None

    def setup_suite(self):
        self.caps['appiumVersion'] = "1.8.1"
        self.caps['deviceName'] = "Android GoogleAPI Emulator"
        self.caps['deviceOrientation'] = "portrait"
        self.caps['platformVersion'] = "7.1"
        self.caps['platformName'] = "Android"
        self.caps['automationName'] = 'uiautomator2'
        self.caps['autoGrantPermissions'] = True
        self.caps['app'] = 'https://somesite.com/storage/my_app.apk'
        self.caps['appPackage'] = 'com.xxx.abc.my_app'
        self.driver = webdriver.Remote(
            'http://username:[email protected]:80/wd/hub', self.caps)

    @lcc.test("My app test")
    def verify_app_launch(self):
        self.driver.implicitly_wait(10)
        element_some_text = self.driver.find_element_by_xpath("//android.widget.TextView[@text='Some Text']")
        element_some_text.click()

    def teardown_suite(self):
        self.driver.quit()

Solution

  • Using the explicit wait on the invisibility of an element (defined below) appearing prior to the required Some Text element resolved the issue. Strangely though, this explicit wait was not required in case of the default automationName.

    wait = WebDriverWait(self.driver, 20)
    wait.until(EC.invisibility_of_element_located((By.ID, "com.xxx.abc.my_app:id/prior_element")))
    

    PS: While I understand this answer might get a few downvotes, I strongly believe this is a strange behaviour from the UiAutomator2 engine.