Synchronization/Waits(Implicit and Explicit) Statements in Selenium
In selenium " Synchronization/Waits"
play an important role in executing tests. Most of the web applications
are developed using Ajax and JavaScript. When a page is loaded by the browser
the elements which we want to interact with may load at different time
intervals. While executing scripts, sometimes we may face an exception “Element
Not Visible Exception“. This exception appears when there is a delay in loading
time of the elements which we are interacting. To overcome this issue, we need
to use Wait Commands.
Synchronization can be
classified into two categories:
1. Unconditional
2. Conditional Synchronization
Unconditional:
we just specify timeout value
only. We will make the tool to wait until certain amount of time and then
proceed further.
time.sleep(time)
Ex: time.sleep(2)
Note: For this you need import
time module.
The main disadvantage is ,
there is a chances of unnecessary waiting time even though the application is
ready.
The advantages are like in a
situation where we interact for third party systems like interfaces, it is not
possible to write a condition or check for a condition. We have to make the
application to wait for certain amount of time by specifying the timeout value.
Conditional Synchronization:
We specify a condition along
with timeout value, so that tool will wait to check for the condition and then
come out if nothing happens.
It is very important to set the
timeout value in conditional synchronization, because the tool should proceed
further instead of making the tool to wait for a particular condition to
satisfy.
Different Types of Selenium Synchronization
/Wait Commands are:
1)
Implicit Wait
2)
Explicit Wait
Implicit Wait
The implicit wait tells the
WebDriver to wait for certain amount of time before it throws an exception.
Once we set the time, WebDriver will wait for the element based on the time we
set before it throws an exception. The default setting is 0 (zero). We need to
set some wait time to make WebDriver to wait for the required time.
Note: Implicit Wait is in place
for the entire time the browser is open. Time taken to search all the elements
are based on the time fixed for the implicit wait.
Syntax:
driver.implicitly_wait(timeout)
Ex: driver.implicitly_wait(20)#
seconds
Implicit Wait time is applied
to all the elements in the script until modified By default, the implicit wait
time set is 0.
Scenario :
Invoke Google Chrome
browser.
Enter UserName and
Password
Click on the Login
button.
Verify the Window Title
Close the browser
from selenium import
webdriver
from time
chromePath="C:\\resources\\executables\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
driver.implicitly_wait(30)
# seconds
print(driver.title)
driver.close()
It tells the Web driver
to poll the DOM for a certain amount of time , here for 30 seconds, when trying
to find an element or elements if they are not immediately available
Explicit Wait
The explicit wait is used to
tell the Web Driver to wait for certain conditions (Expected Conditions) or the
maximum time exceeded before throwing an exception.
The explicit wait is an
intelligent kind of wait, but it can be applied only for specified elements.
Explicit wait gives better options than that of an implicit wait as it will
wait for dynamically loaded Ajax elements.
In worst case time.sleep(),
which sets the condition to an exact time period to wait. There are some
convenience methods provided that help you write code that will wait only as
long as required. Once we declare explicit wait we have to use
"ExpectedCondtions"
WebDriver introduces
classes/modules like WebDriverWait and ExpectedConditions to enforce Explicit
waits into the test scripts.
Ex:
wait = WebDriverWait (driver,
15);
wait. until(ExpectedConditions.presenceOfElementLocated(ElementLocator));
Here the webDriver
instance will wait until the condition specified is met i.e. the presence Of
Element located by the ElementLocator with the maximum wait time of 15 seconds
after which if the condition is still not met than it will throw exception.
If you want to use
explicit wait you should import below two modules
from
selenium.webdriver.support.ui import WebDriverWait
from
selenium.webdriver.support import
expected_conditions
Scenario :
Invoke Google Chrome
browser.
Enter UserName and
Password
Click on the Login
button.
Wait for Continue button
to be visible after page load
Close the browser
Script:
from selenium
import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
chromePath="C:\\resources\\executables\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
wait.until(EC.visibility_of_element_located((By.XPATH,"//input[@type='image' and @name='findFlights']")))
print(driver.title)
driver.close()
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
wait.until(EC.visibility_of_element_located((By.XPATH,"//input[@type='image' and @name='findFlights']")))
print(driver.title)
driver.close()
This waits up to 15 seconds before throwing a TimeoutException
unless it finds the element to return within 15 seconds. WebDriverWait by
default calls the ExpectedCondition every 500 milliseconds, which is called
poll frequency, until it returns successfully.
Explicit wait you can write like this also
eleVisiblity=EC.visibility_of_element_located((By.XPATH,"//input[@type='image'
and @name='findFlights']"))
wait=WebDriverWait(driver,15)
wait.until(eleVisiblity)
wait=WebDriverWait(driver,15)
wait.until(eleVisiblity)
The expected_conditions module contains a set of predefined
conditions to use with WebDriverWait.
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
Custom Wait Conditions
You can also create custom wait conditions when none of the method
matches your requirements. A custom wait condition can be created using a class
with __call__ method or using lambda function which returns False/TimeoutException
when the condition doesn’t match.
Scenario :
Invoke Google Chrome
browser.
Enter UserName and
Password
Click on the Login
button.
Wait for Continue button
after page load
Close the browser
Note: using lambda
function.
Script:
from selenium
import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
chromePath="C:\\resources\\executables\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
wait.until(lambda s: s.find_element_by_xpath("//input[@type='image' and @name='findFlights']").get_attribute("name")=='findFlights')
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
chromePath="C:\\resources\\executables\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
wait.until(lambda s: s.find_element_by_xpath("//input[@type='image' and @name='findFlights']").get_attribute("name")=='findFlights')
print(driver.title)
driver.close()
driver.close()
In the above example
webdriver will wait for 15 seconds until the “name” attribute matches for the element
else it will throw TimeoutException.
A custom wait condition
can be created using a class with __call__ method which returns False when the
condition doesn’t match.
Scenario :
Invoke Google Chrome
browser.
Enter UserName and
Password
Click on the Login
button.
Wait for Continue button
after page load
Close the browser
Note: using __call__
function.
The ”elementWaitStatement”
function has to be written as:
class elementWaitStatement:
def __init__(self,loc,attribute,value):
self._loc=loc
self._attribute=attribute
self._attr_value=value
def __call__(self, driver):
ele=driver.find_element_by_xpath(self._loc)
actAttributeValue=ele.get_attribute(self._attribute)
if actAttributeValue==self._attr_value:
return actAttributeValue
else:
return False
def __init__(self,loc,attribute,value):
self._loc=loc
self._attribute=attribute
self._attr_value=value
def __call__(self, driver):
ele=driver.find_element_by_xpath(self._loc)
actAttributeValue=ele.get_attribute(self._attribute)
if actAttributeValue==self._attr_value:
return actAttributeValue
else:
return False
the above script
save it as elementWait.py
Script:
from selenium
import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from elementWait import elementWaitStatement
import time
chromePath="C:\\resources\\executables\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://newtours.demoaut.com")
driver.find_element_by_name("userName").send_keys("hello")
driver.find_element_by_name("password").send_keys("hello")
driver.find_element_by_name("login").click()
wait=WebDriverWait(driver,15)
eleValue=wait.until(elementWaitStatement("//input[@type='image'
and @name='findFlights']","name","findFlights"))
print(eleValue)
driver.close()
driver.close()
In the above example
webdriver will wait for 15 seconds until the “name” attribute matches for the
element else it will return false.
Note: you should Import “elementWaitStatement” from elementwait, it is custom define wait statement.
Difference between Implicit Wait Vs
Explicit Wait
Implicit Wait
1) Implicit Wait time is
applied to all the elements in the script.
2) we need not specify
"anyExpectedConditions" on the element to be located.
3) It is recommended to use
when the elements are located with the time frame specified in implicit wait.
Explicit Wait
1) Explicit Wait time is
applied only to those elements which are intended by us.
2) In Explicit Wait, we need
to specify "ExpectedConditions" on the element to be located.
3) It is recommended to use
when the elements are taking long time to load and also for verifying the
property of the element.
Comments
Post a Comment