I create a framework using Selenium and Python.
My data driven framework consists of 2 files so far:
The 1st file- Setup.py
contains class Actions()
that consist of all possible functions that I will use
in my framework, such as:
def __init__():
def setup():
def tearDown():
def click():
def sendKeys():
My click
and sendKeys
functions have a minimum of 2 parameters.
They take the first parameter such us :id_for_element
,
xp_for_element
, or css_for_element
, slicing words until
they get the 1st two characters and find element by either
id, xp or any other way. Then they use the 2nd parameter to
specify an element's value, and 3rd parameter to specify
a value for send_keys()
function. All of these functions
are now working, but so far value hardcoded in my test file.
setup.py file
:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
class Actions(object):
def __init__(self,driver=None):
if driver != None:
self.driver = driver
def setUp(self, browserName):
if browserName == 'Chrome':
self.driver = webdriver.Chrome()
self.driver.delete_all_cookies()
self.driver.maximize_window()
elif browserName == 'Safari':
self.driver = webdriver.Safari()
self.driver.delete_all_cookies()
self.driver.maximize_window()
elif browserName == 'Firefox':
self.driver = webdriver.Firefox()
self.driver.delete_all_cookies()
self.driver.maximize_window()
self.driver.implicitly_wait(30)
def tearDown(self, browserName):
self.driver.quit()
def webPage(self):
self.driver.get('https://www.yahoo.com')
def click(self, elemLocator, elemValue):
elp = elemLocator
flp = slice(0,2)
if elp[flp] == 'id':#return by ID
try:
self.driver.find_element_by_id(elemValue).click()
except:
pass
elif elp[flp] == 'xp':#return by XPATH
try:
self.driver.find_element_by_xpath(elemValue).click()
except:
pass
def sendKeys(self, elemLocator, elemValue, messageValue):
elp = elemLocator
flp = slice(0,2)
if elp[flp] == 'id':#return by ID
try:
self.driver.find_element_by_id(elemValue).click()
self.driver.find_element_by_id(elemValue).clear()
self.driver.find_element_by_id(elemValue).send_keys(messageValue)
except:
pass
elif elp[flp] == 'xp':#return by XPATH
try:
self.driver.find_element_by_xpath(elemValue).click()
self.driver.find_element_by_xpath(elemValue).clear()
self.driver.find_element_by_xpath(elemValue).send_keys(messageValue)
except:
pass
#test.py file
from Setup import Actions
class test_case_1: #find element by id
action = Actions(object)
action.setUp('Chrome')
action.webPage()
action.click('id_of_yahoo_logo', 'uh-logo')
action.tearDown('Chrome')
class test_case_2: #find element by xpath
action = Actions(object)
action.setUp('Chrome')
action.webPage()
action.click('xp_of signIn_button', '//*[@id="uh-signin"]')
action.tearDown('Chrome')
class test_case_3: #login to email
action = Actions(object)
action.setUp('Chrome')
action.webPage()
action.click('xp_of signIn_button', '//*[@id="uh-signin"]')
action.sendKeys('id_username_login_inp_field','login-username','deniska')
action.click('id_of submit_button', 'login-signin')
action.tearDown('Chrome')
Instead I am trying to pass value for parameters from another
file as described by the best practices for data driven testing
framework. My next step is to create a data.json
file that
I will use to map out all elements of the DOM in the following
format: "id_login_button":"some id value", "xp_input_field":"some
xp value" etc. Can someone, please, help me figure out
how to implement this technique?
Here is the simple approach if you want to use the json as your uiRepo.
sample.json:
{
"id_of_yahoo_logo":"uh-logo",
"xp_of_signIn_button":"//*[@id='uh-signin']",
"id_username_login_inp_field":"New York",
"id_of_submit_button":"login-signin"
}
test.py
# you have to just specify the name as shown below
action.click('xp_of_signIn_button)
Reading value in Actions.py:
import json
#parse json
with open('sample.json') as f:
uiRepo = json.load(f)
# update the generic methods to get the property form json
print(uiRepo['id_of_yahoo_logo'])
Edit 1:setup.py Un-Tested updates
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import json
class Actions(object):
# initialize uiRepo
uiRepo = None
def __init__(self,driver=None):
if driver != None:
self.driver = driver
# load the uiRepo from json when you init the driver
with open('sample.json') as repo:
uiRepo = json.load(repo)
def setUp(self, browserName):
browserName = browserName.lower()
if browserName == 'chrome':
self.driver = webdriver.Chrome()
elif browserName == 'safari':
self.driver = webdriver.Safari()
elif browserName == 'firefox':
self.driver = webdriver.Firefox()
self.driver.delete_all_cookies() #< === moved this line
self.driver.maximize_window() #< === moved this line
self.driver.implicitly_wait(30)
def tearDown(self): #< === Removed browser here as you don't need browser name while closing it.
self.driver.quit()
def webPage(self,url): #< === Added url as param, rather hard code
self.driver.get(url)
# new method to get the element based on the jsonKey
def getElement(self, jsonKey):
locatorStrategy = jsonKey[:2] # <=== getting first 2 chars to figure out if it's id/xp
locator = uiRepo[jsonKey] # < == getting value from json
ele = None
try:
if locatorStrategy == 'id': # return by ID
ele = self.driver.find_element_by_id(locator).click() # <=== using the locator got from json
elif locatorStrategy == 'xp': # return by XPATH
ele = self.driver.find_element_by_xpath(locator).click()
except:
pass
# if you want you can add additional logic something like highlighting the element
return ele
def click(self, jsonKey): # < ==== updated method to accept only jsonElementName (Removed the element value param)
ele = self.findElement(jsonKey)
ele.click()