Пример #1
0
    def __init__(self,
                 base_url='https://tn-devel.appspot.com/tap',
                 trailing_slash_flag=True):
        "Constructor"
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.screenshot_counter = 1
            self.set_directory_structure()
            self.set_screenshot_dir()  # Create screenshot directory
            self.image_url_list = []
            self.msg_list = []
            self.window_structure = {}
            self.testrail_flag = False
            self.browserstack_flag = False
            self.driver = None
            self.result_counter = 0  #Increment whenever success or failure are called
            self.pass_counter = 0  #Increment everytime success is called
            self.mini_check_counter = 0  #Increment when conditional_write is called
            self.mini_check_pass_counter = 0  #Increment when conditional_write is called with True
            self.failure_message_list = []

        #We assume relative URLs start without a / in the beginning
        if base_url[-1] != '/' and trailing_slash_flag is True:
            base_url += '/'
        self.base_url = base_url
        self.driver_obj = DriverFactory()
        self.log_obj = Base_Logging(level=logging.DEBUG)
        self.log_obj.set_stream_handler_level(self.log_obj.getStreamHandler(),
                                              level=logging.DEBUG)
        if self.driver is not None:
            self.start()  #Visit and initialize xpaths for the appropriate page
Пример #2
0
 def __init__(self, level=logging.DEBUG, log_file_path=None):
     self.logger = Base_Logging(log_file_name=log_file_path, level=level)
     self.total = 0  # Increment whenever success or failure are called
     self.passed = 0  # Increment everytime success is called
     self.written = 0  # Increment when conditional_write is called
     # Increment when conditional_write is called with True
     self.written_passed = 0
     self.failure_message_list = []
Пример #3
0
 def register_driver(self, browserstack_flag, os_name, os_version, browser,
                     browser_version):
     "Register the driver with Page"
     self.driver = self.driver_obj.get_web_driver(browserstack_flag,
                                                  os_name, os_version,
                                                  browser, browser_version)
     self.set_screenshot_dir()  # Create screenshot directory
     self.log_obj = Base_Logging(level=logging.DEBUG)
     self.log_obj.set_stream_handler_level(self.log_obj.getStreamHandler(),
                                           level=logging.DEBUG)
     self.driver.implicitly_wait(5)
     self.driver.maximize_window()
     if (browserstack_flag.lower() == 'y'):
         print "Before registering bs"
         self.register_browserstack()
         self.session_url = self.browserstack_obj.get_session_url()
         self.browserstack_msg = 'BrowserStack session URL:'
         self.write(self.browserstack_msg + '\n' + str(self.session_url))
     self.start()
class Base_Page(Borg, unittest.TestCase):
    "Page class that all page models can inherit from"

    def __init__(self, base_url, trailing_slash_flag=True):
        "Constructor"
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.set_directory_structure()
            self.image_url_list = []
            self.msg_list = []
            self.current_console_log_errors = []
            self.window_structure = {}
            self.testrail_flag = False
            self.tesults_flag = False
            self.images = []
            self.browserstack_flag = False
            self.test_run_id = None

            self.reset()

        #We assume relative URLs start without a / in the beginning
        if base_url[-1] != '/' and trailing_slash_flag is True:
            base_url += '/'
        self.base_url = base_url
        self.driver_obj = DriverFactory()
        if self.driver is not None:
            self.start()  #Visit and initialize xpaths for the appropriate page

    def reset(self):
        "Reset the base page object"
        self.driver = None
        self.result_counter = 0  #Increment whenever success or failure are called
        self.pass_counter = 0  #Increment everytime success is called
        self.mini_check_counter = 0  #Increment when conditional_write is called
        self.mini_check_pass_counter = 0  #Increment when conditional_write is called with True
        self.failure_message_list = []
        self.screenshot_counter = 1
        self.exceptions = []

    def get_failure_message_list(self):
        "Return the failure message list"
        return self.failure_message_list

    def switch_page(self, page_name):
        "Switch the underlying class to the required Page"
        self.__class__ = PageFactory.PageFactory.get_page_object(
            page_name, base_url=self.base_url).__class__

    def register_driver(self, remote_flag, os_name, os_version, browser,
                        browser_version, remote_project_name,
                        remote_build_name):
        "Register the driver with Page"
        self.set_screenshot_dir(os_name, os_version, browser,
                                browser_version)  # Create screenshot directory
        self.set_log_file()
        self.driver = self.driver_obj.get_web_driver(remote_flag, os_name,
                                                     os_version, browser,
                                                     browser_version,
                                                     remote_project_name,
                                                     remote_build_name)
        self.driver.implicitly_wait(5)
        self.driver.maximize_window()

        if Conf.REMOTE_BROWSER_PLATFORM == 'BS' and remote_flag.lower() == 'y':
            self.register_browserstack()
            self.session_url = self.browserstack_obj.get_session_url()
            self.browserstack_msg = 'BrowserStack session URL:'
            self.write(self.browserstack_msg + '\n' + str(self.session_url))

        self.start()

    def get_current_driver(self):
        "Return current driver"
        return self.driver

    def register_testrail(self):
        "Register TestRail with Page"
        self.testrail_flag = True
        self.tr_obj = Test_Rail()

    def set_test_run_id(self, test_run_id):
        "Set TestRail's test run id"
        self.test_run_id = test_run_id

    def register_tesults(self):
        "Register Tesults with Page"
        self.tesults_flag = True

    def register_browserstack(self):
        "Register Browser Stack with Page"
        self.browserstack_flag = True
        self.browserstack_obj = BrowserStack_Library()

    def get_calling_module(self):
        "Get the name of the calling module"
        calling_file = inspect.stack()[-1][1]
        if 'runpy' or 'string' in calling_file:
            calling_file = inspect.stack()[4][3]
        calling_filename = calling_file.split(os.sep)
        #This logic bought to you by windows + cygwin + git bash
        if len(calling_filename) == 1:  #Needed for
            calling_filename = calling_file.split('/')
        self.calling_module = calling_filename[-1].split('.')[0]

        return self.calling_module

    def set_directory_structure(self):
        "Setup the required directory structure if it is not already present"
        try:
            self.screenshots_parent_dir = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'screenshots'))
            if not os.path.exists(self.screenshots_parent_dir):
                os.makedirs(self.screenshots_parent_dir)
            self.logs_parent_dir = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'log'))
            if not os.path.exists(self.logs_parent_dir):
                os.makedirs(self.logs_parent_dir)
        except Exception as e:
            self.write("Exception when trying to set directory structure")
            self.write(str(e))
            self.exceptions.append(
                "Error when setting up the directory structure")

    def set_screenshot_dir(self, os_name, os_version, browser,
                           browser_version):
        "Set the screenshot directory"
        try:
            self.screenshot_dir = self.get_screenshot_dir(os_name,
                                                          os_version,
                                                          browser,
                                                          browser_version,
                                                          overwrite_flag=True)
            if not os.path.exists(self.screenshot_dir):
                os.makedirs(self.screenshot_dir)
        except Exception as e:
            self.write("Exception when trying to set screenshot directory")
            self.write(str(e))
            self.exceptions.append(
                "Error when setting up the screenshot directory")

    def get_screenshot_dir(self,
                           os_name,
                           os_version,
                           browser,
                           browser_version,
                           overwrite_flag=False):
        "Get the name of the test"
        if os_name == 'OS X':
            os_name = 'OS_X'
        if isinstance(os_name, list):
            windows_browser_combination = browser.lower()
        else:
            windows_browser_combination = os_name.lower() + '_' + str(
                os_version).lower() + '_' + browser.lower() + '_' + str(
                    browser_version)
        self.testname = self.get_calling_module()
        self.testname = self.testname.replace('<', '')
        self.testname = self.testname.replace('>', '')
        self.testname = self.testname + '[' + str(
            windows_browser_combination) + ']'
        self.screenshot_dir = self.screenshots_parent_dir + os.sep + self.testname
        if os.path.exists(self.screenshot_dir) and overwrite_flag is True:
            for i in range(1, 4096):
                if os.path.exists(self.screenshot_dir + '_' + str(i)):
                    continue
                else:
                    os.rename(self.screenshot_dir,
                              self.screenshot_dir + '_' + str(i))
                    break

        return self.screenshot_dir

    def set_log_file(self):
        'set the log file'
        self.log_name = self.testname + '.log'
        self.log_obj = Base_Logging(log_file_name=self.log_name,
                                    level=logging.DEBUG)

    def append_latest_image(self, screenshot_name):
        "Get image url list from Browser Stack"
        screenshot_url = self.browserstack_obj.get_latest_screenshot_url()
        image_dict = {}
        image_dict['name'] = screenshot_name
        image_dict['url'] = screenshot_url
        self.image_url_list.append(image_dict)

    def save_screenshot(self,
                        screenshot_name,
                        pre_format="      #Debug screenshot: "):
        "Take a screenshot"
        if os.path.exists(self.screenshot_dir + os.sep + screenshot_name +
                          '.png'):
            for i in range(1, 100):
                if os.path.exists(self.screenshot_dir + os.sep +
                                  screenshot_name + '_' + str(i) + '.png'):
                    continue
                else:
                    os.rename(
                        self.screenshot_dir + os.sep + screenshot_name +
                        '.png', self.screenshot_dir + os.sep +
                        screenshot_name + '_' + str(i) + '.png')
                    break
        self.driver.get_screenshot_as_file(self.screenshot_dir + os.sep +
                                           screenshot_name + '.png')
        #self.conditional_write(flag=True,positive= screenshot_name + '.png',negative='', pre_format=pre_format)
        if self.browserstack_flag is True:
            self.append_latest_image(screenshot_name)
        if self.tesults_flag is True:
            self.images.append(screenshot_name)

    def open(self, url, wait_time=2):
        "Visit the page base_url + url"
        url = self.base_url + url
        if self.driver.current_url != url:
            self.driver.get(url)
        self.wait(wait_time)

    def get_current_url(self):
        "Get the current URL"
        return self.driver.current_url

    def get_page_title(self):
        "Get the current page title"
        return self.driver.title

    def get_page_paths(self, section):
        "Open configurations file,go to right sections,return section obj"
        pass

    def get_current_window_handle(self):
        "Return the latest window handle"
        return self.driver.current_window_handle

    def set_window_name(self, name):
        "Set the name of the current window name"
        try:
            window_handle = self.get_current_window_handle()
            self.window_structure[window_handle] = name
        except Exception as e:
            self.write("Exception when trying to set windows name")
            self.write(str(e))
            self.exceptions.append(
                "Error when setting up the name of the current window")

    def get_window_by_name(self, window_name):
        "Return window handle id based on name"
        window_handle_id = None
        for id, name in self.window_structure.iteritems():
            if name == window_name:
                window_handle_id = id
                break

        return window_handle_id

    def switch_window(self, name=None):
        "Make the driver switch to the last window or a window with a name"
        result_flag = False
        try:
            if name is not None:
                window_handle_id = self.get_window_by_name(name)
            else:
                window_handle_id = self.driver.window_handles[-1]

            if window_handle_id is not None:
                self.driver.switch_to_window(window_handle_id)
                result_flag = True

            self.conditional_write(
                result_flag,
                'Automation switched to the browser window: %s' % name,
                'Unable to locate and switch to the window with name: %s' %
                name,
                level='debug')
        except Exception as e:
            self.write("Exception when trying to switch window")
            self.write(str(e))
            self.exceptions.append("Error when switching browser window")

        return result_flag

    def close_current_window(self):
        "Close the current window"
        result_flag = False
        try:
            before_window_count = len(self.get_window_handles())
            self.driver.close()
            after_window_count = len(self.get_window_handles())
            if (before_window_count - after_window_count) == 1:
                result_flag = True
        except Exception as e:
            self.write('Could not close the current window')
            self.write(str(e))
            self.exceptions.append(
                "Error when trying to close the current window")

        return result_flag

    def get_window_handles(self):
        "Get the window handles"
        return self.driver.window_handles

    def get_current_window_handle(self):
        "Get the current window handle"
        pass

    def switch_frame(self, name=None, index=None, wait_time=2):
        "switch to iframe"
        self.wait(wait_time)
        self.driver.switch_to.default_content()
        if name is not None:
            self.driver.switch_to.frame(name)
        elif index is not None:
            self.driver.switch_to.frame(
                self.driver.find_elements_by_tag_name("iframe")[index])

    def _get_locator(key):
        "fetches locator from the locator conf"
        value = None
        try:
            path_conf_file = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'conf',
                             'locators.conf'))
            if path_conf_file is not None:
                value = Conf_Reader.get_value(path_conf_file, key)
        except Exception as e:
            print(str(e))
            self.exceptions.append(
                "Error when fetching locator from the locator.conf")

        return value

    def get_element(self, locator, verbose_flag=True):
        "Return the DOM element of the path or 'None' if the element is not found "
        dom_element = None
        try:
            locator = self.split_locator(locator)
            dom_element = self.driver.find_element(*locator)
        except Exception as e:
            if verbose_flag is True:
                self.write(str(e), 'debug')
                self.write(
                    "Check your locator-'%s,%s' in the conf/locators.conf file"
                    % (locator[0], locator[1]))
            self.exceptions.append(
                "Check your locator-'%s,%s' in the conf/locators.conf file" %
                (locator[0], locator[1]))

        return dom_element

    def split_locator(self, locator):
        "Split the locator type and locator"
        result = ()
        try:
            result = tuple(locator.split(',', 1))
        except Exception as e:
            self.write("Error while parsing locator")
            self.exceptions.append(
                "Unable to split the locator-'%s' in the conf/locators.conf file"
                % (locator[0], locator[1]))

        return result

    def get_elements(self, locator, msg_flag=True):
        "Return a list of DOM elements that match the locator"
        dom_elements = []
        try:
            locator = self.split_locator(locator)
            dom_elements = self.driver.find_elements(*locator)
        except Exception as e:
            if msg_flag == True:
                self.write(str(e), 'debug')
                self.write(
                    "Check your locator-'%s,%s' in the conf/locators.conf file"
                    % (locator[0], locator[1]))
            self.exceptions.append(
                "Unable to locate the element with the xpath -'%s,%s' in the conf/locators.conf file"
                % (locator[0], locator[1]))

        return dom_elements

    def click_element(self, locator, wait_time=3):
        "Click the button supplied"
        result_flag = False
        try:
            link = self.get_element(locator)
            if link is not None:
                link.click()
                result_flag = True
                self.wait(wait_time)
        except Exception as e:
            self.write(str(e), 'debug')
            self.write('Exception when clicking link with path: %s' % locator)
            self.exceptions.append(
                "Error when clicking the element with path,'%s' in the conf/locators.conf file"
                % locator)

        return result_flag

    def set_text(self, locator, value, clear_flag=True):
        "Set the value of the text field"
        text_field = None
        try:
            text_field = self.get_element(locator)
            if text_field is not None and clear_flag is True:
                try:
                    text_field.clear()
                except Exception as e:
                    self.write(str(e), 'debug')
                    self.exceptions.append(
                        "Could not clear the text field- '%s' in the conf/locators.conf file"
                        % locator)
        except Exception as e:
            self.write(
                "Check your locator-'%s,%s' in the conf/locators.conf file" %
                (locator[0], locator[1]))

        result_flag = False
        if text_field is not None:
            try:
                text_field.send_keys(value)
                result_flag = True
            except Exception as e:
                self.write('Could not write to text field: %s' % locator,
                           'debug')
                self.write(str(e), 'debug')
                self.exceptions.append(
                    "Could not write to text field- '%s' in the conf/locators.conf file"
                    % locator)

        return result_flag

    def get_text(self, locator):
        "Return the text for a given path or the 'None' object if the element is not found"
        text = ''
        try:
            text = self.get_element(locator).text
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when getting text from the path-'%s' in the conf/locators.conf file"
                % locator)
            return None
        else:
            return text.encode('utf-8')

    def get_dom_text(self, dom_element):
        "Return the text of a given DOM element or the 'None' object if the element has no attribute called text"
        text = None
        try:
            text = dom_element.text
            text = text.encode('utf-8')
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when getting text from the DOM element-'%s' in the conf/locators.conf file"
                % locator)

        return text

    def select_checkbox(self, locator):
        "Select a checkbox if not already selected"
        result_flag = False
        try:
            checkbox = self.get_element(locator)
            if checkbox.is_selected() is False:
                result_flag = self.toggle_checkbox(locator)
            else:
                result_flag = True
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when selecting checkbox-'%s' in the conf/locators.conf file"
                % locator)

        return result_flag

    def deselect_checkbox(self, locator):
        "Deselect a checkbox if it is not already deselected"
        result_flag = False
        try:
            checkbox = self.get_element(locator)
            if checkbox.is_selected() is True:
                result_flag = self.toggle_checkbox(locator)
            else:
                result_flag = True
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when deselecting checkbox-'%s' in the conf/locators.conf file"
                % locator)

        return result_flag

    unselect_checkbox = deselect_checkbox  #alias the method

    def toggle_checkbox(self, locator):
        "Toggle a checkbox"
        try:
            return self.click_element(locator)
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when toggling checkbox-'%s' in the conf/locators.conf file"
                % locator)

    def select_dropdown_option(self, locator, option_text):
        "Selects the option in the drop-down"
        result_flag = False
        try:
            dropdown = self.get_element(locator)
            for option in dropdown.find_elements_by_tag_name('option'):
                if option.text == option_text:
                    option.click()
                    result_flag = True
                    break
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Error when selecting option from the drop-down '%s' " %
                locator)

        return result_flag

    def check_element_present(self, locator):
        "This method checks if the web element is present in page or not and returns True or False accordingly"
        result_flag = False
        if self.get_element(locator, verbose_flag=False) is not None:
            result_flag = True

        return result_flag

    def check_element_displayed(self, locator):
        "This method checks if the web element is present in page or not and returns True or False accordingly"
        result_flag = False
        try:
            if self.get_element(locator) is not None:
                element = self.get_element(locator, verbose_flag=False)
                if element.is_displayed() is True:
                    result_flag = True
        except Exception as e:
            self.write(e)
            self.exceptions.append(
                "Web element not present in the page, please check the locator is correct -'%s' in the conf/locators.conf file"
                % locator)

        return result_flag

    def hit_enter(self, locator, wait_time=2):
        "Hit enter"
        try:
            element = self.get_element(locator)
            element.send_keys(Keys.ENTER)
            self.wait(wait_time)
        except Exception as e:
            self.write(str(e), 'debug')
            self.exceptions.append("An exception occurred when hitting enter")
            return None

    def scroll_down(self, locator, wait_time=2):
        "Scroll down"
        try:
            element = self.get_element(locator)
            element.send_keys(Keys.PAGE_DOWN)
            self.wait(wait_time)
        except Exception as e:
            self.write(str(e), 'debug')
            self.exceptions.append("An exception occured when scrolling down")
            return None

    def hover(self, locator, wait_seconds=2):
        "Hover over the element"
        #Note: perform() of ActionChains does not return a bool
        #So we have no way of returning a bool when hover is called
        element = self.get_element(locator)
        action_obj = ActionChains(self.driver)
        action_obj.move_to_element(element)
        action_obj.perform()
        self.wait(wait_seconds)

    def teardown(self):
        "Tears down the driver"
        self.driver.quit()
        self.reset()

    def write(self, msg, level='info'):
        "Log the message"
        msg = str(msg)
        self.msg_list.append('%-8s:  ' % level.upper() + msg)
        if self.browserstack_flag is True:
            if self.browserstack_msg not in msg:
                self.msg_list.pop(
                    -1)  #Remove the redundant BrowserStack message
        self.log_obj.write(msg, level)

    def report_to_testrail(self, case_id, test_run_id, result_flag, msg=''):
        "Update Test Rail"
        if self.testrail_flag is True:
            msg += '\n'.join(self.msg_list)
            msg = msg + "\n"
            if self.browserstack_flag is True:
                for image in self.image_url_list:
                    msg += '\n' + '[' + image['name'] + '](' + image[
                        'url'] + ')'
                msg += '\n\n' + '[' + 'Watch Replay On BrowserStack' + '](' + self.session_url + ')'
            self.tr_obj.update_testrail(case_id,
                                        test_run_id,
                                        result_flag,
                                        msg=msg)
        self.image_url_list = []
        self.msg_list = []

    def add_tesults_case(self,
                         name,
                         desc,
                         suite,
                         result_flag,
                         msg='',
                         files=[],
                         params={},
                         custom={}):
        "Update Tesults with test results"
        if self.tesults_flag is True:
            result = "unknown"
            failReason = ""
            if result_flag == True:
                result = "pass"
            if result_flag == False:
                result = "fail"
                failReason = msg
            for image in self.images:
                files.append(self.screenshot_dir + os.sep + image + '.png')
            self.images = []
            caseObj = {
                'name': name,
                'suite': suite,
                'desc': desc,
                'result': result,
                'reason': failReason,
                'files': files,
                'params': params
            }
            for key, value in custom.items():
                caseObj[key] = str(value)
            Tesults.add_test_case(caseObj)

    def wait(self, wait_seconds=5, locator=None):
        "Performs wait for time provided"
        if locator is not None:
            self.smart_wait(wait_seconds, locator)
        else:
            time.sleep(wait_seconds)

    def smart_wait(self, wait_seconds, locator):
        "Performs an explicit wait for a particular element"
        result_flag = False
        try:
            path = self.split_locator(locator)
            WebDriverWait(self.driver, wait_seconds).until(
                EC.presence_of_element_located(path))
            result_flag = True
        except Exception as e:
            self.conditional_write(
                result_flag,
                positive='Located the element: %s' % locator,
                negative=
                'Could not locate the element %s even after %.1f seconds' %
                (locator, wait_seconds))

        return result_flag

    def success(self, msg, level='info', pre_format='PASS: '******'critical':
            level = 'info'
        self.log_obj.write(pre_format + msg, level)
        self.result_counter += 1
        self.pass_counter += 1

    def failure(self, msg, level='info', pre_format='FAIL: '):
        "Write out a failure message"
        self.log_obj.write(pre_format + msg, level)
        self.result_counter += 1
        self.failure_message_list.append(pre_format + msg)
        if level.lower() == 'critical':
            self.teardown()
            raise Stop_Test_Exception("Stopping test because: " + msg)

    def log_result(self, flag, positive, negative, level='info'):
        "Write out the result of the test"
        if level.lower() == "inverse":
            if flag is True:
                self.failure(positive, level="error")
            else:
                self.success(negative, level="info")
        else:
            if flag is True:
                self.success(positive, level=level)
            else:
                self.failure(negative, level=level)

    def read_browser_console_log(self):
        "Read Browser Console log"
        log = None
        try:
            log = self.driver.get_log('browser')
            return log
        except Exception as e:
            self.write("Exception when reading Browser Console log")
            self.write(str(e))
            return log

    def conditional_write(self, flag, positive, negative, level='info'):
        "Write out either the positive or the negative message based on flag"
        if level.lower() == "inverse":
            msg = positive
            if flag is True:
                positive = negative
                self.write(positive, level='error')
                self.mini_check_pass_counter += 1
            else:
                negative = msg
                self.write(negative, level='info')
                self.mini_check_counter += 1
        else:
            if flag is True:
                self.write(positive, level='info')
                self.mini_check_pass_counter += 1
            else:
                self.write(negative, level='info')
                self.mini_check_counter += 1

    def execute_javascript(self, js_script, *args):
        "Execute javascipt"
        try:
            self.driver.execute_script(js_script)
            result_flag = True
        except Exception as e:
            result_flag = False

        return result_flag

    def write_test_summary(self):
        "Print out a useful, human readable summary"
        self.write(
            '\n\n************************\n--------RESULT--------\nTotal number of checks=%d'
            % self.result_counter)
        self.write(
            'Total number of checks passed=%d\n----------------------\n************************\n\n'
            % self.pass_counter)
        self.write('Total number of mini-checks=%d' % self.mini_check_counter)
        self.write('Total number of mini-checks passed=%d' %
                   self.mini_check_pass_counter)
        failure_message_list = self.get_failure_message_list()
        if len(failure_message_list) > 0:
            self.write('\n--------FAILURE SUMMARY--------\n')
            for msg in failure_message_list:
                self.write(msg)
        if len(self.exceptions) > 0:
            self.exceptions = list(set(self.exceptions))
            self.write('\n--------USEFUL EXCEPTION--------\n')
            for (i, msg) in enumerate(self.exceptions, start=1):
                self.write(str(i) + "- " + msg)
        self.write('************************')

    def start(self):
        "Overwrite this method in your Page module if you want to visit a specific URL"
        pass

    _get_locator = staticmethod(_get_locator)
 def set_log_file(self):
     'set the log file'
     self.log_name = self.testname + '.log'
     self.log_obj = Base_Logging(log_file_name=self.log_name,
                                 level=logging.DEBUG)
Пример #6
0
class Mobile_Base_Page(Borg, unittest.TestCase):
    "Page class that all page models can inherit from"

    def __init__(self):
        "Constructor"
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.set_directory_structure()
            self.image_url_list = []
            self.msg_list = []
            self.window_structure = {}
            self.testrail_flag = False
            self.browserstack_flag = False
            self.test_run_id = None

            self.reset()

        self.driver_obj = DriverFactory()
        if self.driver is not None:
            self.start()  #Visit and initialize xpaths for the appropriate page

    def reset(self):
        "Reset the base page object"
        self.driver = None
        self.result_counter = 0  #Increment whenever success or failure are called
        self.pass_counter = 0  #Increment everytime success is called
        self.mini_check_counter = 0  #Increment when conditional_write is called
        self.mini_check_pass_counter = 0  #Increment when conditional_write is called with True
        self.failure_message_list = []
        self.screenshot_counter = 1

    def get_failure_message_list(self):
        "Return the failure message list"
        return self.failure_message_list

    def switch_page(self, page_name):
        "Switch the underlying class to the required Page"
        self.__class__ = PageFactory.PageFactory.get_page_object(
            page_name).__class__

    def register_driver(self, mobile_os_name, mobile_os_version, device_name,
                        app_package, app_activity, remote_flag, device_flag,
                        app_name, app_path, ud_id, org_id, signing_id,
                        no_reset_flag, appium_version):
        "Register the mobile driver"
        self.driver = self.driver_obj.run_mobile(
            mobile_os_name, mobile_os_version, device_name, app_package,
            app_activity, remote_flag, device_flag, app_name, app_path, ud_id,
            org_id, signing_id, no_reset_flag, appium_version)
        self.set_screenshot_dir()  # Create screenshot directory
        self.set_log_file()
        self.start()

    def get_current_driver(self):
        "Return current driver"
        return self.driver

    def get_driver_title(self):
        "Return the title of the current page"
        return self.driver.title

    def register_testrail(self):
        "Register TestRail with Page"
        self.testrail_flag = True
        self.tr_obj = Test_Rail()
        self.write('Automation registered with TestRail', level='debug')

    def set_test_run_id(self, test_run_id):
        "Set TestRail's test run id"
        self.test_run_id = test_run_id

    def register_tesults(self):
        "Register Tesults with Page"
        self.tesults_flag = True

    def register_browserstack(self):
        "Register Browser Stack with Page"
        self.browserstack_flag = True
        self.browserstack_obj = BrowserStack_Library()

    def get_calling_module(self):
        "Get the name of the calling module"
        calling_file = inspect.stack()[-1][1]
        if 'runpy' or 'string' in calling_file:
            calling_file = inspect.stack()[4][3]
        calling_filename = calling_file.split(os.sep)
        #This logic bought to you by windows + cygwin + git bash
        if len(calling_filename) == 1:  #Needed for
            calling_filename = calling_file.split('/')

        self.calling_module = calling_filename[-1].split('.')[0]

        return self.calling_module

    def set_directory_structure(self):
        "Setup the required directory structure if it is not already present"
        try:
            self.screenshots_parent_dir = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'screenshots'))
            if not os.path.exists(self.screenshots_parent_dir):
                os.makedirs(self.screenshots_parent_dir)
            self.logs_parent_dir = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'log'))
            if not os.path.exists(self.logs_parent_dir):
                os.makedirs(self.logs_parent_dir)
        except Exception as e:
            self.write("Exception when trying to set directory structure")
            self.write(str(e))

    def set_screenshot_dir(self):
        "Set the screenshot directory"
        try:
            self.screenshot_dir = self.get_screenshot_dir()
            if not os.path.exists(self.screenshot_dir):
                os.makedirs(self.screenshot_dir)
        except Exception as e:
            self.write("Exception when trying to set screenshot directory")
            self.write(str(e))

    def get_screenshot_dir(self):
        "Get the name of the test"
        self.testname = self.get_calling_module()
        self.testname = self.testname.replace('<', '')
        self.testname = self.testname.replace('>', '')
        self.screenshot_dir = self.screenshots_parent_dir + os.sep + self.testname
        if os.path.exists(self.screenshot_dir):
            for i in range(1, 4096):
                if os.path.exists(self.screenshot_dir + '_' + str(i)):
                    continue
                else:
                    os.rename(self.screenshot_dir,
                              self.screenshot_dir + '_' + str(i))
                    break

        return self.screenshot_dir

    def set_log_file(self):
        'set the log file'
        self.log_name = self.testname + '.log'
        self.log_obj = Base_Logging(log_file_name=self.log_name,
                                    level=logging.DEBUG)

    def append_latest_image(self, screenshot_name):
        "Get image url list from Browser Stack"
        screenshot_url = self.browserstack_obj.get_latest_screenshot_url()
        image_dict = {}
        image_dict['name'] = screenshot_name
        image_dict['url'] = screenshot_url
        self.image_url_list.append(image_dict)

    def save_screenshot(self, screenshot_name):
        "Take a screenshot"
        if os.path.exists(self.screenshot_dir + os.sep + screenshot_name +
                          '.png'):
            for i in range(1, 100):
                if os.path.exists(self.screenshot_dir + os.sep +
                                  screenshot_name + '_' + str(i) + '.png'):
                    continue
                else:
                    os.rename(
                        self.screenshot_dir + os.sep + screenshot_name +
                        '.png', self.screenshot_dir + os.sep +
                        screenshot_name + '_' + str(i) + '.png')
                    break
        self.driver.get_screenshot_as_file(self.screenshot_dir + os.sep +
                                           screenshot_name + '.png')
        if self.browserstack_flag is True:
            self.append_latest_image(screenshot_name)

    def open(self, wait_time=2):
        "Visit the page base_url + url"
        self.wait(wait_time)

    def get_page_paths(self, section):
        "Open configurations file,go to right sections,return section obj"
        pass

    def get_element(self, locator, verbose_flag=True):
        "Return the DOM element of the path or 'None' if the element is not found "
        dom_element = None
        try:
            locator = self.split_locator(locator)
            dom_element = self.driver.find_element(*locator)
        except Exception as e:
            if verbose_flag is True:
                self.write(str(e), 'debug')
                self.write(
                    "Check your locator-'%s,%s' in the conf/locators.conf file"
                    % (locator[0], locator[1]))
                self.get_session_details()

        return dom_element

    def split_locator(self, locator):
        "Split the locator type and locator"
        result = ()
        try:
            result = tuple(locator.split(',', 1))
        except Exception as e:
            self.write(str(e), 'debug')
            self.write("Error while parsing locator")

        return result

    def get_elements(self, locator, msg_flag=True):
        "Return a list of DOM elements that match the locator"
        dom_elements = []
        try:
            locator = self.split_locator(locator)
            dom_elements = self.driver.find_elements(*locator)
        except Exception as e:
            if msg_flag == True:
                self.write(e, 'debug')
                self.write(
                    "Check your locator-'%s' in the conf/locators.conf file" %
                    locator)

        return dom_elements

    def click_element(self, locator, wait_time=3):
        "Click the button supplied"
        link = self.get_element(locator)
        if link is not None:
            try:
                link.click()
                self.wait(wait_time)
            except Exception as e:
                self.write('Exception when clicking link with path: %s' %
                           locator)
                self.write(e)
            else:
                return True

        return False

    def set_text(self, locator, value, clear_flag=True):
        "Set the value of the text field"
        text_field = self.get_element(locator)
        try:
            if clear_flag is True:
                text_field.clear()
        except Exception as e:
            self.write('ERROR: Could not clear the text field: %s' % locator,
                       'debug')

        result_flag = False
        try:
            text_field.send_keys(value)
            result_flag = True
        except Exception as e:
            self.write('Unable to write to text field: %s' % locator, 'debug')
            self.write(str(e), 'debug')

        return result_flag

    def get_text(self, locator):
        "Return the text for a given xpath or the 'None' object if the element is not found"
        text = ''
        try:
            text = self.get_element(locator).text
        except Exception as e:
            self.write(e)
            return None
        else:
            return text.encode('utf-8')

    get_text_by_locator = get_text  #alias the method

    def get_dom_text(self, dom_element):
        "Return the text of a given DOM element or the 'None' object if the element has no attribute called text"
        text = None
        try:
            text = dom_element.text
            text = text.encode('utf-8')
        except Exception as e:
            self.write(e)

        return text

    def select_checkbox(self, locator):
        "Select a checkbox if not already selected"
        checkbox = self.self.get_element(locator)
        if checkbox.is_selected() is False:
            result_flag = self.toggle_checkbox(locator)
        else:
            result_flag = True

        return result_flag

    def deselect_checkbox(self, locator):
        "Deselect a checkbox if it is not already deselected"
        checkbox = self.get_element(locator)
        if checkbox.is_selected() is True:
            result_flag = self.toggle_checkbox(locator)
        else:
            result_flag = True

        return result_flag

    unselect_checkbox = deselect_checkbox  #alias the method

    def toggle_checkbox(self, locator):
        "Toggle a checkbox"
        return self.click_element(locator)

    def select_dropdown_option(self, locator, option_text):
        "Selects the option in the drop-down"
        result_flag = False
        dropdown = self.get_element(locator)
        for option in dropdown.find_elements_by_tag_name('option'):
            if option.text == option_text:
                option.click()
                result_flag = True
                break

        return result_flag

    def check_element_present(self, locator):
        "This method checks if the web element is present in page or not and returns True or False accordingly"
        result_flag = False
        if self.get_element(locator, verbose_flag=False) is not None:
            result_flag = True

        return result_flag

    def check_element_displayed(self, locator):
        "This method checks if the web element is visible on the page or not and returns True or False accordingly"
        result_flag = False
        if self.get_element(locator) is not None:
            element = self.get_element(locator, verbose_flag=False)
            if element.is_displayed() is True:
                result_flag = True

        return result_flag

    def teardown(self):
        "Tears down the driver"
        self.driver.quit()
        self.reset()

    def write(self, msg, level='info'):
        "Log the message"
        self.msg_list.append('%-8s:  ' % level.upper() + msg)
        if self.browserstack_flag is True:
            if self.browserstack_msg not in msg:
                self.msg_list.pop(
                    -1)  #Remove the redundant BrowserStack message
        self.log_obj.write(msg, level)

    def report_to_testrail(self, case_id, test_run_id, result_flag, msg=''):
        "Update Test Rail"
        if self.testrail_flag is True:
            self.write(
                'Automation is about to update TestRail for case id: %s' %
                str(case_id),
                level='debug')
            msg += '\n'.join(self.msg_list)
            msg = msg + "\n"
            if self.browserstack_flag is True:
                for image in self.image_url_list:
                    msg += '\n' + '[' + image['name'] + '](' + image[
                        'url'] + ')'
                msg += '\n\n' + '[' + 'Watch Replay On BrowserStack' + '](' + self.session_url + ')'
            self.tr_obj.update_testrail(case_id,
                                        test_run_id,
                                        result_flag,
                                        msg=msg)
        self.image_url_list = []
        self.msg_list = []

    def wait(self, wait_seconds=5, locator=None):
        "Performs wait for time provided"
        if locator is not None:
            self.smart_wait(wait_seconds, locator)
        else:
            time.sleep(wait_seconds)

    def smart_wait(self, wait_seconds, locator):
        "Performs an explicit wait for a particular element"
        result_flag = False
        try:
            path = self.split_locator(locator)
            WebDriverWait(self.driver, wait_seconds).until(
                EC.presence_of_element_located(path))
            result_flag = True
        except Exception as e:
            self.conditional_write(
                result_flag,
                positive='Located the element: %s' % locator,
                negative=
                'Could not locate the element %s even after %.1f seconds' %
                (locator, wait_time))

        return result_flag

    def success(self, msg, level='info', pre_format='PASS: '******'critical':
            level = 'info'
        self.log_obj.write(pre_format + msg, level)
        self.result_counter += 1
        self.pass_counter += 1

    def failure(self, msg, level='info', pre_format='FAIL: '):
        "Write out a failure message"
        self.log_obj.write(pre_format + msg, level)
        self.result_counter += 1
        self.failure_message_list.append(pre_format + msg)
        if level.lower() == 'critical':
            self.teardown()
            raise Stop_Test_Exception("Stopping test because: " + msg)

    def log_result(self, flag, positive, negative, level='info'):
        "Write out the result of the test"
        if flag is True:
            self.success(positive, level=level)
        if flag is False:
            self.failure(negative, level=level)

    def conditional_write(self,
                          flag,
                          positive,
                          negative,
                          level='debug',
                          pre_format="  - "):
        "Write out either the positive or the negative message based on flag"
        if flag is True:
            self.write(pre_format + positive, level)
            self.mini_check_pass_counter += 1
        if flag is False:
            self.write(pre_format + negative, level)
        self.mini_check_counter += 1

    def write_test_summary(self):
        "Print out a useful, human readable summary"
        self.write(
            '\n\n************************\n--------RESULT--------\nTotal number of checks=%d'
            % self.result_counter)
        self.write(
            'Total number of checks passed=%d\n----------------------\n************************\n\n'
            % self.pass_counter)
        self.write('Total number of mini-checks=%d' % self.mini_check_counter)
        self.write('Total number of mini-checks passed=%d' %
                   self.mini_check_pass_counter)
        failure_message_list = self.get_failure_message_list()
        if len(failure_message_list) > 0:
            self.write('\n--------FAILURE SUMMARY--------\n')
            for msg in failure_message_list:
                self.write(msg)

    def start(self):
        "Dummy method to be over-written by child classes"
        pass
 def __init__(self,url=None):
     Borg.__init__(self)
     if self.is_first_time():
         #Do these actions if this the first time this class is initialized
         self.log_obj = Base_Logging(level=logging.DEBUG)
         self.reset(url=url)
class Base_Mechanize(Borg):
    "Main base class for Mechanize based scripts"
    def __init__(self,url=None):
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.log_obj = Base_Logging(level=logging.DEBUG)
            self.reset(url=url)
    

    def reset(self,url=None):
        "Visit the URL given - usually URL is like https://www.client.com/"
        base_url = conf.base_url #Fetch the url from the conf file
        if base_url == None:
            print "NO URL GIVEN!" #Provide client url
        else:
            if base_url[1] == "/": #Removing trailing slash because a lot of the url we use later start with a slash
                base_url = base_url[:-1]
            self.base_url = base_url
        self.browser = mechanize.Browser()
        self.browser.set_handle_robots(False)


    def goto_url(self,url=None):
        "Visit a given url"
        response = None
        if url == None:
            print 'Cant goto a null url, will launch default url instead'
        else:
            response = self.browser.open(url)
        return response
    
    
    def get(self,url,headers={}):
        "Mechanize Get request"
        response = self.browser.open(mechanize.Request(url,headers=headers))
        return response
    

    def post(self,url,data=None,headers={}):
        "Mechanize Post request"
        response = self.browser.open(mechanize.Request(url=url, data= data, headers=headers))
        return response
    
        
    def delete(self,url):
        "Mechanize Delete request"
        response = self.browser.open(Mechanize_Delete(url))
        return response
    
    
    def put(self,url):
        "Mechanize Put request"
        response = self.browser.open(Mechanize_Put(url, data=data, headers=headers))
        return response
    

    def write(self,msg,level='info'):
        " This method use the logging method"
        self.log_obj.write(msg,level)


    def get_url(self,key):
        "fetches locator from the locator conf"
        value = None
        try:
            path_conf_file = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'conf', 'url.conf'))
            if path_conf_file is not None:
                value = Conf_Reader.get_value(path_conf_file, key)
        except Exception,e:
            print str(e)

        return value
Пример #9
0
class Results(object):
    """ Base class for logging intermediate test outcomes """

    def __init__(self, level=logging.DEBUG, log_file_path=None):
        self.logger = Base_Logging(log_file_name=log_file_path, level=level)
        self.total = 0  # Increment whenever success or failure are called
        self.passed = 0  # Increment everytime success is called
        self.written = 0  # Increment when conditional_write is called
        # Increment when conditional_write is called with True
        self.written_passed = 0
        self.failure_message_list = []


    def assert_results(self):
        """ Check if the test passed or failed """
        assert self.passed == self.total


    def write(self, msg, level='info'):
        """ This method use the logging method """
        self.logger.write(msg, level)


    def conditional_write(self, condition, positive, negative, level='info', pre_format="  - "):
        """ Write out either the positive or the negative message based on flag """
        if condition:
            self.write(pre_format + positive, level)
            self.written_passed += 1
        else:
            self.write(pre_format + negative, level)
        self.written += 1


    def log_result(self, flag, positive, negative, level='info'):
        """ Write out the result of the test """
        if flag is True:
            self.success(positive, level=level)
        if flag is False:
            self.failure(negative, level=level)
            raise Exception
        self.write('~~~~~~~~\n', level)


    def success(self, msg, level='info', pre_format='PASS: '******'info', pre_format='FAIL: '):
        """ Write out a failure message """
        self.logger.write(pre_format + msg, level)
        self.total += 1
        self.failure_message_list.append(pre_format + msg)


    def get_failure_message_list(self):
        """ Return the failure message list """

        return self.failure_message_list


    def write_test_summary(self):
        """ Print out a useful, human readable summary """
        self.write('\n************************\n--------RESULT--------\nTotal number of checks=%d' % self.total)
        self.write('Total number of checks passed=%d\n----------------------\n************************\n\n' % self.passed)
        self.write('Total number of mini-checks=%d' % self.written)
        self.write('Total number of mini-checks passed=%d' % self.written_passed)
        failure_message_list = self.get_failure_message_list()
        if len(failure_message_list) > 0:
            self.write('\n--------FAILURE SUMMARY--------\n')
            for msg in failure_message_list:
                self.write(msg)
Пример #10
0
class Base_Page(Borg, unittest.TestCase):
    "Page class that all page models can inherit from"

    def __init__(self, base_url='http://qxf2.com/', trailing_slash_flag=True):
        "Constructor"
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.set_directory_structure()
            self.image_url_list = []
            self.msg_list = []
            self.current_console_log_errors = []
            self.window_structure = {}
            self.testrail_flag = False
            self.browserstack_flag = False

            self.reset()

        #We assume relative URLs start without a / in the beginning
        if base_url[-1] != '/' and trailing_slash_flag is True:
            base_url += '/'
        self.base_url = base_url
        self.driver_obj = DriverFactory()
        if self.driver is not None:
            self.start()  #Visit and initialize xpaths for the appropriate page

    def reset(self):
        "Reset the base page object"
        self.driver = None
        self.result_counter = 0  #Increment whenever success or failure are called
        self.pass_counter = 0  #Increment everytime success is called
        self.mini_check_counter = 0  #Increment when conditional_write is called
        self.mini_check_pass_counter = 0  #Increment when conditional_write is called with True
        self.failure_message_list = []
        self.screenshot_counter = 1

    def get_failure_message_list(self):
        "Return the failure message list"
        return self.failure_message_list

    def switch_page(self, page_name):
        "Switch the underlying class to the required Page"
        self.__class__ = PageFactory.PageFactory.get_page_object(
            page_name, base_url=self.base_url).__class__

    def register_driver(self, browserstack_flag, os_name, os_version, browser,
                        browser_version):
        "Register the driver with Page"
        self.driver = self.driver_obj.get_web_driver(browserstack_flag,
                                                     os_name, os_version,
                                                     browser, browser_version)
        self.set_screenshot_dir()  # Create screenshot directory
        self.log_obj = Base_Logging(level=logging.DEBUG)
        self.log_obj.set_stream_handler_level(self.log_obj.getStreamHandler(),
                                              level=logging.DEBUG)
        self.driver.implicitly_wait(5)
        self.driver.maximize_window()
        if (browserstack_flag.lower() == 'y'):
            print "Before registering bs"
            self.register_browserstack()
            self.session_url = self.browserstack_obj.get_session_url()
            self.browserstack_msg = 'BrowserStack session URL:'
            self.write(self.browserstack_msg + '\n' + str(self.session_url))
        self.start()

    def get_current_driver(self):
        "Return current driver"

        return self.driver

    def register_testrail(self):
        "Register TestRail with Page"
        self.testrail_flag = True
        self.tr_obj = Test_Rail()

    def register_browserstack(self):
        "Register Browser Stack with Page"
        self.browserstack_flag = True
        self.browserstack_obj = BrowserStack_Library()

    def get_calling_module(self):
        "Get the name of the calling module"
        calling_file = inspect.stack()[-1][1]
        if 'runpy' in calling_file:
            calling_file = inspect.stack()[5][1]
        calling_filename = calling_file.split(os.sep)

        #This logic bought to you by windows + cygwin + git bash
        if len(calling_filename) == 1:  #Needed for
            calling_filename = calling_file.split('/')

        self.calling_module = calling_filename[-1].split('.')[0]

        return self.calling_module

    def set_directory_structure(self):
        "Setup the required directory structure if it is not already present"
        try:
            screenshots_parent_dir = os.path.abspath(
                os.path.join(os.path.dirname(__file__), '..', 'screenshots'))
            if not os.path.exists(screenshots_parent_dir):
                os.makedirs(screenshots_parent_dir)
        except Exception, e:
            self.write("Exception when trying to set directory structure")
            self.write(str(e))
Пример #11
0
class Mobile_Base_Page(Borg, unittest.TestCase):
    "Page class that all page models can inherit from"

    def __init__(self,
                 base_url='https://tn-devel.appspot.com/tap',
                 trailing_slash_flag=True):
        "Constructor"
        Borg.__init__(self)
        if self.is_first_time():
            #Do these actions if this the first time this class is initialized
            self.screenshot_counter = 1
            self.set_directory_structure()
            self.set_screenshot_dir()  # Create screenshot directory
            self.image_url_list = []
            self.msg_list = []
            self.window_structure = {}
            self.testrail_flag = False
            self.browserstack_flag = False
            self.driver = None
            self.result_counter = 0  #Increment whenever success or failure are called
            self.pass_counter = 0  #Increment everytime success is called
            self.mini_check_counter = 0  #Increment when conditional_write is called
            self.mini_check_pass_counter = 0  #Increment when conditional_write is called with True
            self.failure_message_list = []

        #We assume relative URLs start without a / in the beginning
        if base_url[-1] != '/' and trailing_slash_flag is True:
            base_url += '/'
        self.base_url = base_url
        self.driver_obj = DriverFactory()
        self.log_obj = Base_Logging(level=logging.DEBUG)
        self.log_obj.set_stream_handler_level(self.log_obj.getStreamHandler(),
                                              level=logging.DEBUG)
        if self.driver is not None:
            self.start()  #Visit and initialize xpaths for the appropriate page

    def switch_page(self, page_name):
        "Switch the underlying class to the required Page"
        self.__class__ = PageFactory.PageFactory.get_page_object(
            page_name).__class__

    def register_driver(self, sauce_flag, os_name, os_version, browser,
                        browser_version):
        "Register the driver with Page"
        self.driver = self.driver_obj.get_web_driver(sauce_flag, os_name,
                                                     os_version, browser,
                                                     browser_version)
        self.driver.implicitly_wait(5)
        self.driver.maximize_window()
        self.start()

    def register_mobile_driver(self, mobile_os_name, mobile_os_version,
                               device_name, app_package, app_activity,
                               mobile_sauce_flag, device_flag):
        "Register the mobile driver"
        self.driver = self.driver_obj.run_mobile(
            mobile_os_name, mobile_os_version, device_name, app_package,
            app_activity, mobile_sauce_flag, device_flag)
        self.start()

    def get_current_driver(self):
        "Return current driver"
        return self.driver

    def get_console_log(self):
        "Return current browser's console logs from driver"
        return self.driver.get_log('browser')

    def get_driver_title(self):
        "Return the title of the current page"
        return self.driver.title

    def get_current_url(self):
        "Return the current url"
        return self.driver.current_url

    def register_testrail(self):
        "Register TestRail with Page"
        self.testrail_flag = True
        self.tr_obj = Test_Rail()
        self.write('Automation registered with TestRail', level='debug')

    def register_browserstack(self):
        "Register Browser Stack with Page"
        self.browserstack_flag = True
        self.browserstack_obj = BrowserStack_Library()

    def set_locator_conf(self, locator_path):
        "Set the path of the configuration file with locators"
        self.xpath_conf_file = locator_path

    def start(self):
        "Dummy method to be over-written by child classes"
        pass

    def _screenshot(func):
        "Decorator for taking screenshot"

        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            screenshot_name = '%003d' % args[
                0].screenshot_counter + '_' + func.__name__
            args[0].screenshot_counter += 1
            args[0].save_screenshot(screenshot_name)
            return result

        return wrapper

    def _exceptionHandler(f):
        "Decorator to handle exceptions"
        argspec = getargspec(f)

        def inner(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except Exception, e:
                args[0].write('You have this exception')
                args[0].write('Exception in method: %s' % str(f.__name__))
                args[0].write('PYTHON SAYS: %s' % str(e))

        return inner