The following examples include a base script for creating Python-based synthetic transaction scripts on Selenium and two example scripts that manipulate webpage content.

Basic Selenium Python structure

The following code snippet shows a basic Python script that imports the packages needed for the Selenium-Python environment, identifies where to insert your code, and has a main section.

# Read the following instructions on how to write a Python file to complete the required transaction and generate metrics from that

# Necessary packages are needed to be imported as per the user requirement
# Need to add options/preferences/capabilities according to their usage and as per their desired browser
# User needs to create a Python script as a process where in user needs to write their Python script as per their transaction
# User needs to surround their every step of action with try and catch and in catch they need to update the warnings dictionary for the purpose of catching issues while performing transaction
# If user gets any exception in middle of the transaction, the user needs to clean up the chrome and python processes and the processes spawned by the user in the transaction as well.
# The output JSON file must be in a specified format and an example is cited below:
# {
#     "responseTime" : "5560.868979", ------- indicates the time taken in milliseconds to complete the overall transaction
#     "warningInfo" : "", ----- to know when any warnings or exceptions occurred in the flow           
#     "errorInfo" : "",   ----- to know when we have any critical exceptions occurred in the flow
#     "granularSteps" : [  ---- needs to be added when user needs to calculate response times for individual actions
#     {
#         "stepName": "",                          ----- to show the metric in UI, if this is blank then this metric value is not shown in the UI
#         "uiLocatorString": "https://www.mysubdomain.com/",----- to know the locator of that webelement  
#         "timeTaken": "5143.960953",              ----- time taken in milliseconds to do the action from the scratch
#         "actionPerfomed": "openURL"              ----- action performed in the transaction
#     }, 
#     {
#         "stepName": "clickUser", 
#         "uiLocatorString": "css=#users-container > h1", 
#         "timeTaken": "5408.558846", 
#         "actionPerfomed": "click"
#     }, 
#     {
#         "stepName": "editText", 
#         "uiLocatorString": " xpath=//*[@id=snow-container]/div[2]/div[1] edit content", 
#         "timeTaken": "5453.449011", 
#         "actionPerfomed": "editContent"
#     }
# ]
# }
 

# These are the default imports user must include

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait  
from selenium.webdriver.support import expected_conditions 
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import sys
import json
import os
import signal
import logging as logger
import datetime
import multiprocessing
from multiprocessing import Manager
import time
import re as regex


# By default, we use chrome

# The following options must be set because these set of rules are followed for a transaction
chromeOptions = webdriver.ChromeOptions()
chromeOptions.binary_location ="/usr/bin/google-chrome"  # specify the path of the browser binary
chromeOptions.add_argument('--no-sandbox')               # 
chromeOptions.add_argument('--start-maximized')          # to start the browser window in full size
chromeOptions.add_argument('--ignore-certificate-errors')# to ignore SSL certificate errors
chromeOptions.add_argument('--disable-extensions')       # to disable extensions in the browser
chromeOptions.add_argument('--headless')                 # to run the transaction in headlesss mode
chromeOptions.add_argument('--disable-gpu')              # to disable graphical user interface
chromeOptions.add_argument('window-size=1200x600')       # setting the window size with utmost values




chromeCapabilities=chromeOptions.to_capabilities()
chromeCapabilities['acceptSslCerts']=True               # to accept all kind of ssl certificates
chromeCapabilities['acceptInsecureCerts']=True          # to accept insecure certificates 




sys.tracebacklimit=0           # to limit the output stack traceback
class metricsProcessed:        # to take individual metric as an object with certain attributes as listed
    def __init__(self,actionPerformed,uiLocatorString,metricTimeTaken,stepName=None):
        self.actionPerformed=actionPerformed
        self.uiLocatorString=uiLocatorString
        self.stepName=stepName
        self.metricTimeTaken=metricTimeTaken

        
def isMetricJsonDictionaryEmpty(metricDictionary):  # to check whether the specified metric dictionary is empty or not
    if json.dumps(metricDictionary)=="null":
        logger.info("The metric Dictionary is null")
        return "\"\""
    else:
        logger.info("Metric Dictionary is not null")
        return str("\""+str(metricDictionary)+"\"")
    
# to compute metric values and update them in the output JSON file
    
def computeGranularResponseMetric(uiLocatorString,actionPerfomed,actionTime,stepName,windowStartTime,exceptionTime=0,isCompleted=False):
    timeTaken=round((actionTime-windowStartTime-exceptionTime)*1000,6)
    uiLocatorString=uiLocatorString.replace("\"","").replace("\\","")
    if isCompleted:
        responseTimeMetric.update({"responseTime":timeTaken})
    else:
        metricObjects.append(metricsProcessed(actionPerfomed,uiLocatorString,timeTaken,stepName))
    
    
def formMetricJson():           # to create output metric json file with specified metrics and their attributes and overall response time/ warning info/critical info in the format as shown above
    filePointer=open(sys.argv[0]+'.json','w')  # the output metric json file name must be the id.py.json because the platform uses the same format, user should not change this
    filePointer.write("{\n") # the output metric json file must be in the specified format because the platform computes in this in this way do display the graphs in the UI
    filePointer.write("\t\"responseTime\" : "+isMetricJsonDictionaryEmpty(responseTimeMetric.get("responseTime")))
    filePointer.write(",\n\t\"warningInfo\" : "+isMetricJsonDictionaryEmpty(warnings.get("Exception")))
    filePointer.write(",\n\t\"errorInfo\" : "+isMetricJsonDictionaryEmpty(errors.get("Exception")))
    filePointer.write(",\n\t\"granularSteps\" : "+json.dumps([{"timeTaken":str(round(obj.metricTimeTaken,6)),"actionPerfomed":obj.actionPerformed,"uiLocatorString":obj.uiLocatorString,"stepName":obj.stepName} for obj in metricObjects],indent=4))
    filePointer.write("\n}")
    filePointer.close()
    
    
    
    
    
    
    
    
def scriptCode():    # where the whole transaction code goes in 
    logger.info(str(datetime.datetime.now())+" - before webdriver invocation")  
    driver=webdriver.Chrome(desired_capabilities=chromeCapabilities)  # invoke a webbrowser session with desired options and capabilities set prior
    logger.info(str(datetime.datetime.now())+" - webdriver invoked")
    driver.delete_all_cookies()     # delete the cookies before performing the transaction
    logger.info(str(datetime.datetime.now())+" - webdriver cookies deleted")
    wait=WebDriverWait(driver,20)   # to have smart waits at each step of transaction 20 seconds 
    windowStartTime=time.time()     # a timer needs to be started before the start of the transaction to calculate the overall response time
    exceptionTime=0
    
#    <YOUR CODE GOES HERE>
#    We need to write code with all the possible locators in order not to break the flow of transaction if some exception occurs
#    Example code :
#     logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.ID,"clientLogo"''')
#     stepTimeStart=time.time()
#     try:
#         wait.until(expected_conditions.element_to_be_clickable((By.ID,"clientLogo"))).click()
#     except Exception as exp :
#         stepTimeStop=time.time()
#         exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#         logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
#         logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.NAME,"clientLogo"''')
#         stepTimeStart=time.time()
#         try:
#             wait.until(expected_conditions.element_to_be_clickable((By.NAME,"clientLogo"))).click()
#         except Exception as exp :
#             stepTimeStop=time.time()
#             exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#             logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
#             logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.CSS_SELECTOR,"#clientLogo"''')
#             stepTimeStart=time.time()
#             try:
#                 wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR,"#clientLogo"))).click()
#             except Exception as exp :
#                 stepTimeStop=time.time()
#                 exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#                 logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
#                 logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//input[@id='clientLogo']"''')
#                 stepTimeStart=time.time()
#                 try:
#                     wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//input[@id='clientLogo']"))).click()
#                 except Exception as exp :
#                     stepTimeStop=time.time()
#                     exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#                     logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
#                     logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//form[@id='updateClientLogo']/div/div/div/div/div/span/span/input"''')
#                     stepTimeStart=time.time()
#                     try:
#                         wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//form[@id='updateClientLogo']/div/div/div/div/div/span/span/input"))).click()
#                     except Exception as exp :
#                         stepTimeStop=time.time()
#                         exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#                         logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
#                         logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//span/input"''')
#                         stepTimeStart=time.time()
#                         try:
#                             wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//span/input"))).click()
#                         except Exception as exp:
#                             stepTimeStop=time.time()
#                             exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
#                             logger.error(str(datetime.datetime.now())+''' - webdriver clicking on id=clientLogo failed due to :'''+str(exp))
#                             stepTimeStart=time.time()
#                             try:
#                                 ActionChains(driver).move_to_element(driver.find_element(By.ID,"clientLogo")).click().perform()
#                             except Exception as ex:
#                                 logger.error(str(datetime.datetime.now())+''' - webdriver clicking on id=clientLogo with action chains failed due to :'''+str(ex))
#                                 warnings.update({'''Exception''':'''- id=clientLogo cannot be clicked'''})
#                                 raise Exception('''Exception:id=clientLogo cannot be clicked''')
#                                 return
#     computeGranularResponseMetric('''id=clientLogo''','click',time.time(),'',windowStartTime,exceptionTime)    
    

    
    computeGranularResponseMetric("responseTime","",time.time(),"",windowStartTime,exceptionTime,True)  # transaction is finished and overall response time metric is calculated
    driver.quit()

### main starts from here
logEnablingFlag=False                       # to enable/disable logs
processManager=Manager()                    # to propagate changes made to attributes inside a process
responseTimeMetric=processManager.dict()    # to store response time
warnings=processManager.dict()              # to store warnings or exceptions occurred in the transaction
errors=processManager.dict()                # to store critical exception occurred in the transaction
metricObjects=processManager.list()         # to process all the metric objects for metric computation

if logEnablingFlag:  # to have logs while performing the transaction
    logger.basicConfig(filename=sys.argv[0]+".log",filemode='w',level=logger.INFO)
logger.info(str(datetime.datetime.now())+" - start") 
try:
    try:
        scriptProcess = multiprocessing.Process(target=scriptCode)  # the transaction written in the scriptCode method is taken as a process 
        scriptProcess.start()
        scriptProcess.join(float(sys.argv[1])/1000)  # command line argument is taken to specify the connection timeout of the transaction, which is given by the application
        if scriptProcess.is_alive():
            errors.update({'''Exception''':'''connection timeout'''})
            raise Exception("Exception: connection timeout")
    except Exception,ex:
        pass
except Exception,ex:
    os.killpg(os.getpgid(scriptProcess.pid),signal.SIGTERM)  # raising termination signal if some exception occurs while running the above process
finally:
    formMetricJson()      # need to call this function to finally update the attributes in the json which is shown in UI
    scriptProcess.terminate()   # Termination of the script process at the end of the transaction and json computation

Text example

In the following example, the script edits the contents of a text field, changing the default text.

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import sys
import json
import os
import signal
import logging as logger
import datetime
import multiprocessing
from multiprocessing import Manager
import time
import re as regex

chromeOptions = webdriver.ChromeOptions()
chromeOptions.binary_location ="/usr/bin/google-chrome"
chromeOptions.add_argument('--no-sandbox')
chromeOptions.add_argument('--start-maximized')
chromeOptions.add_argument('--ignore-certificate-errors')
chromeOptions.add_argument('--disable-extensions')
chromeOptions.add_argument('--headless')
chromeOptions.add_argument('--disable-gpu')
chromeOptions.add_argument('window-size=1200x600')

chromeCapabilities=chromeOptions.to_capabilities()
chromeCapabilities['acceptSslCerts']=True
chromeCapabilities['acceptInsecureCerts']=True




sys.tracebacklimit=0
class metricsProcessed:
	def __init__(self,actionPerformed,uiLocatorString,metricTimeTaken,stepName=None):
		self.actionPerformed=actionPerformed
		self.uiLocatorString=uiLocatorString
		self.stepName=stepName
		self.metricTimeTaken=metricTimeTaken
def regexCheckSelect(value,dropDownElement): 
	try:
		value=value.replace("regexp:","");
		pattern=regex.compile(value)
		for dropDownOption in dropDownElement.options :
			if(pattern.match(dropDownOption.text)):
				dropDownElement.select_by_visible_text(dropDownOption.text)
				break
	except Exception as exp:
		logger.error("Error Occured while Parsing Regex values "+str(exp))
def isJsonDictionaryEmpty(metricDictionary): 
	if json.dumps(metricDictionary)=="null":
		logger.info("The metric Dictionary is null")
		return "\"\""
	else:
		logger.info("Metric Dictionary is not null")
		return str("\""+str(metricDictionary)+"\"")
def computeMetric(uiLocatorString,actionPerfomed,actionTime,stepName,windowStartTime,exceptionTime=0,isCompleted=False):
	timeTaken=round((actionTime-windowStartTime-exceptionTime)*1000,6)
	uiLocatorString=uiLocatorString.replace("\"","").replace("\\","")
	if isCompleted:
		responseTimeMetric.update({"responseTime":timeTaken})
	else:
		metricObjects.append(metricsProcessed(actionPerfomed,uiLocatorString,actionTime,stepName))
def formMetricJson():
	filePointer=open(sys.argv[0]+'.json','w')
	filePointer.write("{\n")
	filePointer.write("\t\"responseTime\" : "+isJsonDictionaryEmpty(responseTimeMetric.get("responseTime")))
	filePointer.write(",\n\t\"warningInfo\" : "+isJsonDictionaryEmpty(warnings.get("Exception")))
	filePointer.write(",\n\t\"errorInfo\" : "+isJsonDictionaryEmpty(errors.get("Exception")))
	filePointer.write(",\n\t\"granularSteps \" : "+json.dumps([{"timeTaken":str(round(obj.metricTimeTaken,6)),"actionPerfomed":obj.actionPerformed,"uiLocatorString":obj.uiLocatorString,"stepName":obj.stepName} for obj in metricObjects],indent=4))
	filePointer.write("\n}")
	filePointer.close()
def scriptCode():
	logger.info(str(datetime.datetime.now())+" - before webdriver invocation")
	driver=webdriver.Chrome(desired_capabilities=chromeCapabilities)
	logger.info(str(datetime.datetime.now())+" - webdriver invoked")
	driver.delete_all_cookies()
	logger.info(str(datetime.datetime.now())+" - webdriver cookies deleted")
	wait=WebDriverWait(driver,20)
	windowStartTime=time.time()
	exceptionTime=0
	try:
		logger.info(str(datetime.datetime.now())+''' - webdriver hitting url : https://www.mysubdomain.com/''')
		driver.get("https://www.mysubdomain.com/")
	except Exception as exp:
		logger.info(str(datetime.datetime.now())+''' - webdriver url hit : https://www.mysubdomain.com/''')
		errors.update({'''Exception''':'''error in hitting https://www.mysubdomain.com/'''})
		raise Exception('''Error in hitting https://www.mysubdomain.com/''')
		return
	computeMetric('''https://www.mysubdomain.com''','openURL',time.time(),'Action_1',windowStartTime,exceptionTime)
	
	logger.info(str(datetime.datetime.now())+''' - webdriver setting window size as 1366x689 dimensions''')
	driver.set_window_size(1366,689)	
	logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.CSS_SELECTOR,"#users-container > h1"''')
	stepTimeStart=time.time()
	try:
		wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR,"#users-container > h1"))).click()
	except Exception as exp :
		stepTimeStop=time.time()
		exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
		logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
		logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//div[@id='users-container']/h1"''')
		stepTimeStart=time.time()
		try:
			wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//div[@id='users-container']/h1"))).click()
		except Exception as exp :
			stepTimeStop=time.time()
			exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
			logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
			logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//h1"''')
			stepTimeStart=time.time()
			try:
				wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//h1"))).click()
			except Exception as exp :
				stepTimeStop=time.time()
				exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
				logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
				logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//h1[contains(.,'Your powerful rich text editor.')]"''')
				stepTimeStart=time.time()
				try:
					wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//h1[contains(.,'Your powerful rich text editor.')]"))).click()
				except Exception as exp:
					stepTimeStop=time.time()
					exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
					logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=#users-container > h1 failed due to :'''+str(exp))
					stepTimeStart=time.time()
					try:
						ActionChains(driver).move_to_element(driver.find_element(By.CSS_SELECTOR,"#users-container > h1")).click().perform()
					except Exception as ex:
						logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=#users-container > h1 with action chains failed due to :'''+str(ex))
						warnings.update({'''Exception''':'''css=#users-container > h1 cannot be clicked'''})
						raise Exception('''Exception:css=#users-container > h1 cannot be clicked''')
						return
	computeMetric('''css=#users-container > h1''','click',time.time(),'Action_2',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+''' - webdriver editing content of By.XPATH,"//*[@id='snow-container']/div[2]/div[1]" as Changed By Webdriver''')
	try:
		element=driver.find_element(By.XPATH,"//*[@id='snow-container']/div[2]/div[1]")
		driver.execute_script("arguments[0].innerText = 'Changed By Webdriver'",element)
	except Exception as exp:
		logger.info(str(datetime.datetime.now())+''' - webdriver cannot edit content of By.XPATH,"//*[@id='snow-container']/div[2]/div[1]" as Changed By Webdriver due to : '''+str(exp))
		warnings.update({'''Exception''':''' Changed By Webdriver edit content error'''})
		raise Exception('''Exception: Changed By Webdriver edit content error''') 
		return
	computeMetric(''' xpath=//*[@id="snow-container"]/div[2]/div[1] edit content''','editContent',time.time(),'Action_3',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+" - webdriver window/tab close")
	driver.close()	


	computeMetric("responseTime","",time.time(),"",windowStartTime,exceptionTime,True)
	driver.quit()

### main starts from here
logEnablingFlag=False
processManager=Manager()
responseTimeMetric=processManager.dict()
warnings=processManager.dict()
errors=processManager.dict()
metricObjects=processManager.list()

if logEnablingFlag:
	logger.basicConfig(filename=sys.argv[0]+".log",filemode='w',level=logger.INFO)
logger.info(str(datetime.datetime.now())+" - start") 
try:
	try:
		scriptProcess = multiprocessing.Process(target=scriptCode)
		scriptProcess.start()
		scriptProcess.join(float(sys.argv[1])/1000)
		if scriptProcess.is_alive():
			errors.update({'''Exception''':'''connection timeout'''})
			raise Exception("Exception: connection timeout")
	except Exception,ex:
		pass
except Exception,ex:
	os.killpg(os.getpgid(scriptProcess.pid),signal.SIGTERM)
finally:
	formMetricJson()
	scriptProcess.terminate()

Alert button example

In the following example, the script asserts an html alert that displays when the button is double-clicked.

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import sys
import json
import os
import signal
import logging as logger
import datetime
import multiprocessing
from multiprocessing import Manager
import time
import re as regex

chromeOptions = webdriver.ChromeOptions()
chromeOptions.binary_location ="/usr/bin/google-chrome"
chromeOptions.add_argument('--no-sandbox')
chromeOptions.add_argument('--start-maximized')
chromeOptions.add_argument('--ignore-certificate-errors')
chromeOptions.add_argument('--disable-extensions')
chromeOptions.add_argument('--headless')
chromeOptions.add_argument('--disable-gpu')
chromeOptions.add_argument('window-size=1200x600')

chromeCapabilities=chromeOptions.to_capabilities()
chromeCapabilities['acceptSslCerts']=True
chromeCapabilities['acceptInsecureCerts']=True




sys.tracebacklimit=0
class metricsProcessed:
	def __init__(self,actionPerformed,uiLocatorString,metricTimeTaken,stepName=None):
		self.actionPerformed=actionPerformed
		self.uiLocatorString=uiLocatorString
		self.stepName=stepName
		self.metricTimeTaken=metricTimeTaken
def regexCheckSelect(value,dropDownElement): 
	try:
		value=value.replace("regexp:","");
		pattern=regex.compile(value)
		for dropDownOption in dropDownElement.options :
			if(pattern.match(dropDownOption.text)):
				dropDownElement.select_by_visible_text(dropDownOption.text)
				break
	except Exception as exp:
		logger.error("Error Occured while Parsing Regex values "+str(exp))
def isJsonDictionaryEmpty(metricDictionary): 
	if json.dumps(metricDictionary)=="null":
		logger.info("The metric Dictionary is null")
		return "\"\""
	else:
		logger.info("Metric Dictionary is not null")
		return str("\""+str(metricDictionary)+"\"")
def computeMetric(uiLocatorString,actionPerfomed,actionTime,stepName,windowStartTime,exceptionTime=0,isCompleted=False):
	timeTaken=round((actionTime-windowStartTime-exceptionTime)*1000,6)
	uiLocatorString=uiLocatorString.replace("\"","").replace("\\","")
	if isCompleted:
		responseTimeMetric.update({"responseTime":timeTaken})
	else:
		metricObjects.append(metricsProcessed(actionPerfomed,uiLocatorString,timeTaken,stepName))
def formMetricJson():
	filePointer=open(sys.argv[0]+'.json','w')
	filePointer.write("{\n")
	filePointer.write("\t\"responseTime\" : "+isJsonDictionaryEmpty(responseTimeMetric.get("responseTime")))
	filePointer.write(",\n\t\"warningInfo\" : "+isJsonDictionaryEmpty(warnings.get("Exception")))
	filePointer.write(",\n\t\"errorInfo\" : "+isJsonDictionaryEmpty(errors.get("Exception")))
	filePointer.write(",\n\t\"granularSteps\" : "+json.dumps([{"timeTaken":str(round(obj.metricTimeTaken,6)),"actionPerfomed":obj.actionPerformed,"uiLocatorString":obj.uiLocatorString,"stepName":obj.stepName} for obj in metricObjects],indent=4))
	filePointer.write("\n}")
	filePointer.close()
def scriptCode():
	logger.info(str(datetime.datetime.now())+" - before webdriver invocation")
	driver=webdriver.Chrome(desired_capabilities=chromeCapabilities)
	logger.info(str(datetime.datetime.now())+" - webdriver invoked")
	driver.delete_all_cookies()
	logger.info(str(datetime.datetime.now())+" - webdriver cookies deleted")
	wait=WebDriverWait(driver,20)
	windowStartTime=time.time()
	exceptionTime=0
	try:
		logger.info(str(datetime.datetime.now())+''' - webdriver hitting url : http://www.mysubdomain.com/test/simple_context_menu.html''')
		driver.get("http://www.mysubdomain.com/test/simple_context_menu.html")
	except Exception as exp:
		logger.info(str(datetime.datetime.now())+''' - webdriver url hit : http://www.mysubdomain.com/test/simple_context_menu.html''')
		errors.update({'''Exception''':'''error in hitting http://www.mysubdomain.com/test/simple_context_menu.html'''})
		raise Exception('''Error in hitting http://www.mysubdomain.com/test/simple_context_menu.html''')
		return
	computeMetric('''http://www.mysubdomain.com''','openURL',time.time(),'',windowStartTime,exceptionTime)
	
	logger.info(str(datetime.datetime.now())+''' - webdriver setting window size as 1366x689 dimensions''')
	driver.set_window_size(1366,689)	
	logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.CSS_SELECTOR,"button"''')
	stepTimeStart=time.time()
	try:
		wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR,"button"))).click()
	except Exception as exp :
		stepTimeStop=time.time()
		exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
		logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
		logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//body[@id='authentication']/button"''')
		stepTimeStart=time.time()
		try:
			wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//body[@id='authentication']/button"))).click()
		except Exception as exp :
			stepTimeStop=time.time()
			exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
			logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
			logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//button"''')
			stepTimeStart=time.time()
			try:
				wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//button"))).click()
			except Exception as exp :
				stepTimeStop=time.time()
				exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
				logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
				logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//button[contains(.,'Double-Click Me To See Alert')]"''')
				stepTimeStart=time.time()
				try:
					wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//button[contains(.,'Double-Click Me To See Alert')]"))).click()
				except Exception as exp:
					stepTimeStop=time.time()
					exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
					logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=button failed due to :'''+str(exp))
					stepTimeStart=time.time()
					try:
						ActionChains(driver).move_to_element(driver.find_element(By.CSS_SELECTOR,"button")).click().perform()
					except Exception as ex:
						logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=button with action chains failed due to :'''+str(ex))
						warnings.update({'''Exception''':'''- css=button cannot be clicked'''})
						raise Exception('''Exception:css=button cannot be clicked''')
						return
	computeMetric('''css=button''','click',time.time(),'',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.CSS_SELECTOR,"button"''')
	stepTimeStart=time.time()
	try:
		wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR,"button"))).click()
	except Exception as exp :
		stepTimeStop=time.time()
		exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
		logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
		logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//body[@id='authentication']/button"''')
		stepTimeStart=time.time()
		try:
			wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//body[@id='authentication']/button"))).click()
		except Exception as exp :
			stepTimeStop=time.time()
			exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
			logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
			logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//button"''')
			stepTimeStart=time.time()
			try:
				wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//button"))).click()
			except Exception as exp :
				stepTimeStop=time.time()
				exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
				logger.error(str(datetime.datetime.now())+''' - webdriver getting error as '''+ str(exp))
				logger.info(str(datetime.datetime.now())+''' - webdriver clicking on By.XPATH,"//button[contains(.,'Double-Click Me To See Alert')]"''')
				stepTimeStart=time.time()
				try:
					wait.until(expected_conditions.element_to_be_clickable((By.XPATH,"//button[contains(.,'Double-Click Me To See Alert')]"))).click()
				except Exception as exp:
					stepTimeStop=time.time()
					exceptionTime=exceptionTime+stepTimeStop-stepTimeStart
					logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=button failed due to :'''+str(exp))
					stepTimeStart=time.time()
					try:
						ActionChains(driver).move_to_element(driver.find_element(By.CSS_SELECTOR,"button")).click().perform()
					except Exception as ex:
						logger.error(str(datetime.datetime.now())+''' - webdriver clicking on css=button with action chains failed due to :'''+str(ex))
						warnings.update({'''Exception''':'''- css=button cannot be clicked'''})
						raise Exception('''Exception:css=button cannot be clicked''')
						return
	computeMetric('''css=button''','click',time.time(),'',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+''' - webdriver double clicking onBy.CSS_SELECTOR,"button"''')
	try:
		ActionChains(driver).double_click(wait.until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR,"button")))).perform()		

	except Exception as exp:
		logger.error(str(datetime.datetime.now())+''' - webdriver cannot locate By.CSS_SELECTOR,button due to '''+ str(exp))
		warnings.update({'''Exception''':'''- By.CSS_SELECTOR,button cannot be located'''})
		raise Exception('''Exception:By.CSS_SELECTOR,"button" cannot be located''')
		return
	computeMetric('''By.CSS_SELECTOR,button''','doubleClick',time.time(),'',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+''' - webdriver aserting text with You double clicked me.. Thank You.. ''')
	try:
		wait.until(expected_conditions.alert_is_present(),"You double clicked me.. Thank You..")
	except Exception as exp:
		logger.info(str(datetime.datetime.now())+''' - webdriver aserting text with You double clicked me.. Thank You.. failed : '''+str(exp))

		warnings.update({'''Exception''':'''- You double clicked me.. Thank You.. No such Alert Exists'''})
		raise Exception('''Exception : You double clicked me.. Thank You.. No Such Alert Exists''') 
		return
	computeMetric(''' : You double clicked me.. Thank You.. Alert''','assertAlert',time.time(),'',windowStartTime,exceptionTime)	
	logger.info(str(datetime.datetime.now())+" - webdriver window/tab close")
	driver.close()	


	computeMetric("responseTime","",time.time(),"",windowStartTime,exceptionTime,True)
	driver.quit()

### main starts from here
logEnablingFlag=False
processManager=Manager()
responseTimeMetric=processManager.dict()
warnings=processManager.dict()
errors=processManager.dict()
metricObjects=processManager.list()

if logEnablingFlag:
	logger.basicConfig(filename=sys.argv[0]+".log",filemode='w',level=logger.INFO)
logger.info(str(datetime.datetime.now())+" - start") 
try:
	try:
		scriptProcess = multiprocessing.Process(target=scriptCode)
		scriptProcess.start()
		scriptProcess.join(float(sys.argv[1])/1000)
		if scriptProcess.is_alive():
			errors.update({'''Exception''':'''connection timeout'''})
			raise Exception("Exception: connection timeout")
	except Exception,ex:
		pass
except Exception,ex:
	os.killpg(os.getpgid(scriptProcess.pid),signal.SIGTERM)
finally:
	formMetricJson()
	scriptProcess.terminate()