Automated Test Library

This is a Python class definition file meant to be used with Selenium WebDriver from the command line, either directly or via a testrunner compatible with the unittest framework. It provides some baseline utility methods for interactions with a complex application with multiple interfaces facing different clients.

It is important to note that this is not meant to provide for a complete test suite; its purpose was to support an automated acceptance test, and as a proof of concept for future test development.

A wider set of tools was planned, but the project's focus was shifted midway by upper management.


liquid.py:
from selenium import webdriver
from selenium.common.exceptions import ElementNotVisibleException

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

import unittest


wait = WebDriverWait


class LiquidTestCase(unittest.TestCase):

    def setUp(self):
        self.browser = webdriver.Chrome()
        self.browser.get('[MACHINE NAME REMOVED]')

    def tearDown(self):
        self.browser.quit()

    def s(self, selector):
        result = wait(self.browser, 10).until(
            lambda browser: self.browser.find_elements_by_css_selector(selector)
        )

        if len(result) == 1:
            return result[0]
        else:
            return result

    def l(self, link_text):
        return wait(self.browser, 10).until(
            lambda browser: self.browser.find_element_by_link_text(link_text)
        )

    def hover(self, element):
        ActionChains(self.browser).move_to_element(element).perform()

    def wait_for(self, selector, visible=True):
        if visible:
            detection_method = expected_conditions.element_to_be_clickable
        else:
            detection_method = expected_conditions.invisibility_of_element_located

        wait(self.browser, 10).until(
            detection_method((
                By.CSS_SELECTOR,
                selector
            ))
        )

    def wait_for_change(self, selector, attribute):
        initial_state = self.s(selector).get_attribute(attribute)
        wait(self.browser, 10).until(lambda browser: self.s(selector).get_attribute(attribute) != initial_state)

    def wait_for_ajax_load(self):
        self.wait_for('#loadingdiv', visible=False)

    def log_in(self, username, password):
        username_field = self.s('#username')
        username_field.clear()
        username_field.send_keys(username)

        password_field = self.s('#password')
        password_field.clear()
        password_field.send_keys(password)

        self.s('#login_submit').click()

    def log_in_as_sys_admin(self):
        self.log_in('[LOGIN REMOVED]', '[PASSWORD REMOVED]')

    def key_first_from_dropdown(self, selector, typed_text):
        element = self.s(selector)

        element.clear()
        element.send_keys(typed_text)

        self.wait_for('#as_ul li')

        element.send_keys(
            Keys.ARROW_DOWN,
            Keys.ENTER
        )

    def click_first_from_dropdown(self, selector, typed_text):
        element = self.s(selector)

        if element.get_attribute('value') != '':
            element.clear()

        try:
            element.send_keys(typed_text)
        except ElementNotVisibleException:
            self.browser.execute_script("$('" + selector + "').val('" + typed_text + "').trigger('keyup');")
            pass

        self.wait_for('#as_ul')
        self.s('#as_ul li a')[0].click()
        self.wait_for('#as_ul', visible=False)

    def switch_system_to(self, system_name):
        self.s('#clientLogo').click()

        logo_selector = '.logoPlaceholder.' + system_name
        self.wait_for(logo_selector)
        self.s(logo_selector).click()

    def open_entity_management(self):
        self.hover(self.l('Admin'))
        self.l('Entity Management').click()

        self.wait_for('#liquidreturn')
        self.wait_for_ajax_load()

    def overtake_user(self, username):
        self.open_entity_management()
        self.s('#search_username').send_keys(username)
        self.hover(self.s('.cell:nth-child(2)'))
        self.wait_for('#entity_tooltip')
        self.s('#dijit_form_Button_0_label').click()
        self.wait_for('#liquidreturn')

    def open_timesheet(self):
        self.hover(self.l('New'))
        self.hover(self.l('Timesheet'))
        self.hover(self.l('Past W/E Dates:'))
        self.l('03/09/2014').click()