12

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.

Community
  • 1
  • 1
fkang9
  • 121
  • 1
  • 1
  • 3

5 Answers5

14

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="FakeEmail@example.com"]')))

        ## Locating test account and selecting it.
        account = wd.find_element_by_android_uiautomator('text("FakeEmail@example.com")')
        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.

Cynic
  • 6,779
  • 2
  • 30
  • 49
2

The python usage is:

driver.implicitly_wait(timeToWaitSec)

Selenium sourcecode(Py)

jkbz
  • 101
  • 1
  • 4
1

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)
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
1

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)))
Stipe
  • 480
  • 5
  • 18
0

You can use implicitWait. Something like remoteWebDriver.implicitlyWait(time, timeUnit) This of course is for java. Something similar should be available for python.

Vinay
  • 648
  • 4
  • 12