Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for element to load when testing an iOS app using Appium and Python?

Tags:

python

ios

appium

I am testing a native iOS app and need to wait for some elements to load in some of my testing. Appium is going too fast on some screens right now.

Can someone please point me to an example of using a WebDriverWait style of waiting for Appium iOS testing? There was a question that was answered for Ruby here: Wait for element to load when testing an iOS app using Appium and Ruby?. Looking for something similar in Python.

The Python client documentation doesn't seem to document the wait functions.

Thanks.

like image 852
fkang9 Avatar asked Jun 13 '14 01:06

fkang9


4 Answers

At the top of the test import these.

from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

TL/DR is this should work, you may have to change self.driver to just driver in the wait = section depending on how you're doing things. Also, obviously change the By.XPath to whatever locator you're using:

wait = WebDriverWait(self.driver, 20)
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//UIAApplication[1]/UIAWindow[1]/UIAButton[@text="example text"]')))

Or you could just tell the driver to use implicit waits.

self.driver.implicitly_wait(10)
myElement = driver.find_element_by_id("fakeid")
myElement.click()

Most of this is explained here.

Here's an example of using wait to log into an Android App (Haven't used it on ios but it should be the similar) using the default account selector then asserting the right text appeared. During the setup, I'm loading my desired capabilities from another file.

class TrainUpSmokeTests(unittest.TestCase): 
    def setUp(self):
         desired_caps = desired_capabilities.get_desired_capabilities('app-debug.apk')
         self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

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

    def example_test(self):
        wd = self.driver

        ## Depending on how you're running the test the first variable may just be driver. Or in my case self.driver which I shortened above. The number is how many seconds it should wait before timing out. 
        wait = WebDriverWait(wd, 20)
        ## Waiting for account selector to be clickable.
        currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//android.widget.CheckedTextView[@text="[email protected]"]')))

        ## Locating test account and selecting it.
        account = wd.find_element_by_android_uiautomator('text("[email protected]")')
        account.click()
        ok_button = wd.find_element_by_android_uiautomator('text("OK")')
        ok_button.click()

        ## Waiting for an Element on the home screen to be locatable.
        currently_waiting_for = wait.until(EC.presence_of_element_located((By.XPATH,'//android.widget.RelativeLayout[@resource-id="com.name.app:id/overview"]')))
        hero_headline = wd.find_element_by_android_uiautomator('new UiSelector().description("Example Header")')
        self.assertIsNotNone(hero_headline)

if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrainUpSmokeTests)
unittest.TextTestRunner(verbosity=2).run(suite)

It's a your testings a website using appium (instead of an app). Change the setup so self.driver opens a browser.

 self.driver = webdriver.Firefox()

And then use By selectors like class, name, id, e.g. the example below.

currently_waiting_for = wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'search-results')))

This article also helped. Also if you don't know how to find xpaths, look into setting up uiautomatorviewer that comes with appium.

like image 174
Cynic Avatar answered Nov 11 '22 16:11

Cynic


You can use WaitForElement class:

class WaitForElement:
    @staticmethod
    def wait(driver, id, time_out=100):
        try:
            WebDriverWait(driver, time_out).until(
                lambda driver: driver.find_element(*id))
        except TimeoutException:
            print('Not able to find ID:' + id)
like image 21
Jitesh Mohite Avatar answered Nov 11 '22 15:11

Jitesh Mohite


The python usage is:

driver.implicitly_wait(timeToWaitSec)

Selenium sourcecode(Py)

like image 41
jkbz Avatar answered Nov 11 '22 15:11

jkbz


You can find all you need in selenium.webdriver.support.expected_conditions

Then from it you can do something like:

def wait_for_element_visible(self, by=By.XPATH, value=None, text=None, wait_time=20):
    if text is not None:
        value = value % text
    wait = WebDriverWait(self.driver, wait_time)
    return wait.until(EC.visibility_of_element_located((by, value)))
like image 26
Stipe Avatar answered Nov 11 '22 16:11

Stipe