Why we need to use wait?
We need to use the wait mechanism because the webdriver is quite faster than the Page load. Sometime it reaches to page and on webpage few of the elements are not loaded fully. In short DOM takes time to load all the elements on screen and this may lead webdriver does not found the element which will raise ElementNotVisible exception.
The main idea behind using waits in our script is to keep webdriver and page in sync by providing some delays between element identification and action performed.
There are two types of waits that are available with webdriver object
1. Implicit wait
2. Explicit wait
Let us see above two waits with real time examples
1. Implicit wait:
Implicit wait tells webdriver object to wait for certain amount of time i.e. whatever we have mentioned in the method. The implicit wait once set, it would be set for the entire life of driver object for that particular session. For example we have defined a implicit wait for 5 secs and DOM takes to load the element for 6 secs then it would raise an exception as ElementNotVisible. Suppose the DOM took 3 secs to load the element then implicit wait would be only 3 secs and would continue with further execution. This is the best way to reduce the time to identify the element on page. The custom method time.sleep(5) would wait of irrespective of whether element is found or not. This may result in slow execution. So its always preferable to use implicit wait rather than using time.sleep() method. There are some cons using implicit wait in your code,
1. The performance issues may be escaped and would never be catch using your script
2. The execution becomes little slower as implicit wait is introduced.
def test_calculator_click_number():
desired_caps = {
'platformName': 'android',
'udid': 'emulator-5554',
'deviceName': 'Pixel API 24',
'platformVersion': '7.0',
'appPackage': 'com.android.calculator2',
'appActivity': 'com.android.calculator2.Calculator',
'systemPort': 8201
}
driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
driver.implicitly_wait(5)
log = BaseClass().get_logger()
log.info("-------------- Click number on calculator app --------------")
cal = Calculator(driver)
cal.click_number(9)
log.info("-------------- Click number on calculator app test is completed --------------")
So in above example, driver object would wait for 5 or less than 5 second to identify the element on page. This would be happening for each statement it goes through the script.
2. Explicit wait:
Once defined explicit wait, the wait is applied only for specific element which takes longer time to load.
Explicit wait is also similar to implicit wait, for example if wait is defined as 5 secs and element is found in 3 seconds then would continue next line of code. This does not make your execution slower which is found in implicit wait. Explicit wait is little complicated to implement than implicit wait because here we have to find the element first on which explicit wait has to be applied and later have to add in the script.
def __init__(self, driver):
self.driver = driver
self.formula = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/formula")))
self.result = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/result")))
self.divide_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/op_div")))
self.multiply_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/op_mul")))
self.minus_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/op_sub")))
self.plus_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/op_add")))
self.equals_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/eq")))
self.delete_button = WebDriverWait(self.driver, 5).until(
e.visibility_of_element_located((
MobileBy.ID, "com.android.calculator2:id/del")))