Though not as glamorous not vital as using scripts to maintain core infrastructure, every organization has its share of embedded vendor software that require administration and upkeep that help to keep the lights on in other ways.
Though perhaps I’d rather not, some weeks I spend a considerable amount of time creating elections, research surveys and mailing lists. Rather than risk burning out my click-finger clicking around the browser, I thought that it would be a good idea to automate some of the processes using Python and the Selenium testing library.
My first attempt looked something like this:
import pyautogui
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
chrome_options = Options ()
chrome_options . add_experimental_option ( "detach" , True )
#Store variables for mailing list configuration
ls_name = pyautogui . prompt ( "What is the name of the list?" )
ls_title = pyautogui . prompt ( "What is the title of the list?" )
ls_owner = pyautogui . prompt ( "What is the email address of the list owner?" )
class TestCreationMenuTest ():
def setup_method ( self , method ):
self . driver = webdriver . Chrome ( '.../pythonProject1/chromedriver' , options = chrome_options )
self . vars = {}
def teardown_method ( self , method ):
self . driver . quit ()
def test_creationMenuTest ( self ):
self . driver . get ( "companynewsletter.ca/admin" )
self . driver . find_element ( By . ID , "login.cell" ). click ()
self . driver . find_element ( By . ID , "Email Address" ). click ()
self . driver . find_element ( By . ID , "Email Address" ). send_keys (
"oliver@company.ca" )
self . driver . find_element ( By . ID , "Password" ). click ()
self . driver . find_element ( By . ID , "Password" ). send_keys ( "password" )
self . driver . find_element ( By . NAME , "e" ). click ()
self . driver . find_element ( By . CSS_SELECTOR , "body" ). click ()
self . driver . find_element ( By . ID , "admnsub.cell" ). click ()
self . driver . find_element ( By . ID , "admn_listsub.cell" ). click ()
element = self . driver . find_element ( By . ID , "admn_list.createsub.cell" )
actions = ActionChains ( self . driver )
actions . move_to_element ( element ). click_and_hold (). perform ()
element = self . driver . find_element ( By . CSS_SELECTOR ,
"td:nth-child(2) > h2" )
actions = ActionChains ( self . driver )
actions . move_to_element ( element ). release (). perform ()
self . driver . find_element ( By . CSS_SELECTOR , "label:nth-child(2)" ). click ()
self . driver . find_element ( By . ID , "List Name" ). click ()
self . driver . find_element ( By . ID , "List Name" ). send_keys ( ls_name )
self . driver . find_element ( By . ID , "List Title" ). click ()
self . driver . find_element ( By . ID , "List Title" ). send_keys ( ls_title )
self . driver . find_element ( By . NAME , "N" ). click ()
self . driver . find_element ( By . ID , "List Owner" ). click ()
self . driver . find_element ( By . ID , "List Owner" ). send_keys ( ls_owner )
self . driver . find_element ( By . ID , "Announcement List" )
#Give 5 minutes until browser closes to manually confirm creation
time . sleep ( 300 )
self . driver . close ()
This script worked very quickly, and saved a lot of time in configuring the basics of the newsletter service. That being said, there are some issues that could be addressed for the other platforms:
If we were to hypothetically push an interface update from QA, its likely that the CSS classes will change. The login credentials are hard-coded, which is not good OpSec and could leave me in a tricky spot. Therefore, I made several modifications for the survey application script.
import pyautogui
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
chrome_options = Options ()
chrome_options . add_experimental_option ( "detach" , True )
admin_usr = pyautogui . prompt ( "Enter admin username:" )
admin_pw = pyautogui . prompt ( "Enter admin password:" )
survey_name = pyautogui . prompt ( "What is the name of the survey owner?" )
survey_email = pyautogui . prompt ( "What is the email of the survey owner?" )
class TestLimeSurveyv3siteadduser ():
def setup_method ( self , method ):
self . driver = webdriver . Chrome ( '/Users/oliverherman/PycharmProjects/pythonProject1/chromedriver' , options = chrome_options )
self . vars = {}
def teardown_method ( self , method ):
self . driver . quit ()
def test_limeSurveyv3AddInternalUser ( self ):
self . driver . get (
"https://companyresearch/login" )
self . driver . find_element ( By . ID , "select2-authMethod-container" ). click ()
self . driver . find_element ( By . CSS_SELECTOR ,
".select2-search__field" ). send_keys ( "Internal Authentication" )
self . driver . find_element ( By . CSS_SELECTOR ,
".select2-search__field" ). send_keys ( Keys . ENTER )
self . driver . find_element ( By . ID , "user" ). click ()
self . driver . find_element ( By . ID , "user" ). send_keys (
admin_usr )
self . driver . find_element ( By . ID , "password" ). click ()
self . driver . find_element ( By . ID , "password" ). send_keys ( admin_pw )
self . driver . find_element ( By . NAME , "login_submit" ). click ()
self . driver . find_element ( By . LINK_TEXT , "Configuration" ). click ()
element = self . driver . find_element ( By . LINK_TEXT ,
"Manage survey administrators" )
actions = ActionChains ( self . driver )
actions . move_to_element ( element ). perform ()
self . driver . find_element ( By . LINK_TEXT ,
"Manage survey administrators" ). click ()
element = self . driver . find_element ( By . CSS_SELECTOR , "body" )
actions = ActionChains ( self . driver )
actions . move_to_element ( element , 0 , 0 ). perform ()
self . driver . find_element ( By . ID , "add_user_admin" ). click ()
self . driver . find_element ( By . ID , "new_user" ). click ()
self . driver . find_element ( By . ID , "new_user" ). send_keys (
survey_email )
self . driver . find_element ( By . ID , "new_email" ). click ()
self . driver . find_element ( By . ID , "new_email" ). send_keys (
survey_email )
self . driver . find_element ( By . ID , "new_full_name" ). click ()
self . driver . find_element ( By . ID , "new_full_name" ). send_keys ( survey_name )
self . driver . find_element ( By . ID , "add_user_btn" ). click ()
self . driver . find_element ( By . CSS_SELECTOR ,
".btn-default:nth-child(2)" ). click ()
self . driver . find_element ( By . ID , "btnToggleAdvanced" ). click ()
self . driver . find_element ( By . ID , "all_auth_db" ). click ()
self . driver . find_element ( By . ID , "all_auth_ldap" ). click ()
self . driver . find_element ( By . ID , "perm_surveys_create" ). click ()
#Give 5 minutes until browser closes to manually confirm creation
time . sleep ( 300 )
self . driver . close ()