Exemple #1
0
 def _load(self):
     self.log = Log(log_path=self.settings.get('log_output_file'),
                    log_name=self.settings.get('log_name'),
                    log_level=self.settings.get('log_level'))
     required_keys = [
         'mode',
         'browser',
         'options',
         'url_hub',
         'drivers_path',
         'drivers_names',
         'log_name',
         'log_output_file',
         'log_level',
     ]
     for setting in self.settings.keys():
         if setting not in required_keys:
             msg = ("Key for config isn't valid for"
                    " key='{}'").format(setting)
             raise CoreException(msg, log=self.log)
     # Configure browser settings
     browser_name = self.settings.get('browser')
     headless_enabled = self.settings.get('options').get('headless')
     # Instance selenium settings classes
     self.curr_caps = self.get_capabilities(browser_name=browser_name)
     self.curr_options = self.get_options(browser_name=browser_name,
                                          headless_enabled=headless_enabled)
     # Open browser based on mode from settings.json
     if self.settings.get('mode') == 'local':
         self.mode_local(browser_name=browser_name)
     elif self.settings.get('mode') == 'remote':
         self.mode_remote(browser_name=browser_name)
     else:
         msg = "Bad mode selected, mode={}".format(
             self.settings.get('mode'))
         raise CoreException(msg, log=self.log)
     # Instance all needed for BotBase instance
     self.curr_driver_wait = WebDriverWait(self.curr_driver, 10)
     self.curr_driver_actions = ActionChains(self.curr_driver)
     self.curr_driver_touch = TouchActions(self.curr_driver)
     self.navigation = NavBase(self.curr_driver,
                               self.log,
                               driver_wait=self.curr_driver_wait,
                               driver_actions=self.curr_driver_actions,
                               driver_touch=self.curr_driver_touch)
Exemple #2
0
 def test_reportertestlink_ok(self):
     """Test: test_reportertestlink_ok"""
     settings = SETTINGS.get("bot")
     log = Log(
         log_path=settings.get('log_output_file'),
         log_name=settings.get('log_name'),
         log_level=settings.get('log_level'))
     with pytest.raises(NotImplementedError):
         ReporterTestlink(log=log)
Exemple #3
0
class CoreException(Exception):
    """Base Exception class for inherit new exceptions on library"""
    def __init__(self, msg=NOT_MSG, log=None, info_bot=None):
        """Allow to handle Qacode and/or Selenium exceptions

        Keyword Arguments:
            msg {str} -- Exception message (default: {NOT_MSG})
            log {Log} -- Logging class (default: {None})
            info_bot {dict} -- Qacode+Selenium information (default: {None})
        """
        self.is_just_msg = False
        self.msg = msg
        if info_bot is None:
            info_bot = {}
            self.is_just_msg = True
        self.info_bot = info_bot
        self.browser = self.info_bot.get("browser") or ""
        self.mode = self.info_bot.get("mode") or ""
        self.method = self.info_bot.get("method") or ""
        self.err = info_bot.get("err") or {}
        if log is None:
            self.log = Log()
        else:
            self.log = log
        self.log.error(str(self))

    def __str__(self):
        """Representation of class"""
        msg = ""
        if self.is_just_msg:
            return self.msg
        msg += " | "
        msg += "browser='{}' ".format(self.browser)
        msg += "mode='{}' ".format(self.mode)
        msg += "method='{}' ".format(self.method)
        if self.err is None:
            return msg
        if isinstance(self.err, WebDriverException):
            msg += "{}{} - args='{}'".format("Selenium error: ",
                                             type(self.err), self.err.args)
        return "{}".format(msg)
Exemple #4
0
    def __init__(self, msg=NOT_MSG, log=None, info_bot=None):
        """Allow to handle Qacode and/or Selenium exceptions

        Keyword Arguments:
            msg {str} -- Exception message (default: {NOT_MSG})
            log {Log} -- Logging class (default: {None})
            info_bot {dict} -- Qacode+Selenium information (default: {None})
        """
        self.is_just_msg = False
        self.msg = msg
        if info_bot is None:
            info_bot = {}
            self.is_just_msg = True
        self.info_bot = info_bot
        self.browser = self.info_bot.get("browser") or ""
        self.mode = self.info_bot.get("mode") or ""
        self.method = self.info_bot.get("method") or ""
        self.err = info_bot.get("err") or {}
        if log is None:
            self.log = Log()
        else:
            self.log = log
        self.log.error(str(self))
Exemple #5
0
 def test_log_notparams(self):
     """Testcase: test_log_notlogname"""
     log = Log(**{})
     ASSERT.equals(log._name, "qacode")
     ASSERT.equals(log._name_file, "qacode.log")
     ASSERT.equals(log._path, "./logs/")
# -*- coding: utf-8 -*-
"""Testsuite for package bots"""

import pytest
from qacode.core.bots.bot_base import BotBase
from qacode.core.loggers.logger_manager import Log
from qacode.core.testing.asserts import Assert
from qacode.core.testing.test_info import TestInfoBase
from qacode.utils import settings

ASSERT = Assert()
SETTINGS = settings(file_path="qacode/configs/")
SKIP = SETTINGS['tests']['skip']['benchmarks']
SKIP_MSG = 'benchmarks DISABLED by config file'
# TODO: must be setteable from config JSON
LOGGER_MANAGER = Log(log_level=SETTINGS['bot']['log_level'])
ITERATIONS = 2
ROUNDS = 2


class TestBotBase(TestInfoBase):
    """Testcases for class BotBase"""
    def setup_method(self, test_method):
        """Setup test_method to be executed"""
        super(TestBotBase,
              self).setup_method(test_method,
                                 config=settings(file_path="qacode/configs/"),
                                 skip_force=SKIP)

    def bot_benchmark(self, browser_name, driver_mode, is_headless):
        """Allow to open and close any browser_name with
Exemple #7
0
class BotBase(object):
    """Class Base for handle selenium functionality throught this wrapper

        curr_caps -- Capabilities class

        curr_driver -- WebDriver class

        curr_driver_path -- WebDriver browser executable path

        curr_driver_wait -- Wait for expected conditions

        curr_driver_actions -- Performs actions on elements

        curr_driver_touch -- Perform touch actions on elements

        navigation -- Bot methods to brigde selenium functions

        bot_config -- Bot configuration object

        Log -- logger manager class loaded from Log object to write messages
    """

    settings = None

    curr_caps = None
    curr_driver = None
    curr_driver_path = None
    # Browser options
    curr_options = None
    # Wait for expected conditions
    curr_driver_wait = None
    # Performs actions on elements
    curr_driver_actions = None
    # Perform touch actions on elements
    curr_driver_touch = None
    navigation = None
    log = None
    IS_64BITS = sys.maxsize > 2**32
    IS_WIN = os.name == 'nt'
    BROWSERS_WITHOUT_OPTIONS = ('iexplorer', 'edge')

    def __init__(self, **kwargs):
        """Create new Bot browser based on options object what can be
            (help for each option can be found on settings.json)

        Arguments:
            settings {dict} -- configuracion obtained from JSON
                file to dict instance

        Raises:
            CoreException -- Fail at instance Log class
            CoreException -- settings is None
            CoreException -- settings.get('mode') is not in [local, remote]
        """
        self.settings = kwargs.get("bot")
        # default read from qacode.configs, file named 'settings.json'
        if not self.settings:
            self.settings = settings().get('bot')
        self._load()

    def _load(self):
        self.log = Log(log_path=self.settings.get('log_output_file'),
                       log_name=self.settings.get('log_name'),
                       log_level=self.settings.get('log_level'))
        required_keys = [
            'mode',
            'browser',
            'options',
            'url_hub',
            'drivers_path',
            'drivers_names',
            'log_name',
            'log_output_file',
            'log_level',
        ]
        for setting in self.settings.keys():
            if setting not in required_keys:
                msg = ("Key for config isn't valid for"
                       " key='{}'").format(setting)
                raise CoreException(msg, log=self.log)
        # Configure browser settings
        browser_name = self.settings.get('browser')
        headless_enabled = self.settings.get('options').get('headless')
        # Instance selenium settings classes
        self.curr_caps = self.get_capabilities(browser_name=browser_name)
        self.curr_options = self.get_options(browser_name=browser_name,
                                             headless_enabled=headless_enabled)
        # Open browser based on mode from settings.json
        if self.settings.get('mode') == 'local':
            self.mode_local(browser_name=browser_name)
        elif self.settings.get('mode') == 'remote':
            self.mode_remote(browser_name=browser_name)
        else:
            msg = "Bad mode selected, mode={}".format(
                self.settings.get('mode'))
            raise CoreException(msg, log=self.log)
        # Instance all needed for BotBase instance
        self.curr_driver_wait = WebDriverWait(self.curr_driver, 10)
        self.curr_driver_actions = ActionChains(self.curr_driver)
        self.curr_driver_touch = TouchActions(self.curr_driver)
        self.navigation = NavBase(self.curr_driver,
                                  self.log,
                                  driver_wait=self.curr_driver_wait,
                                  driver_actions=self.curr_driver_actions,
                                  driver_touch=self.curr_driver_touch)

    def get_capabilities(self, browser_name='chrome'):
        """Instance DesiredCapabilities class from selenium and return it

        Keyword Arguments:
            browser_name {str} -- name of a valid browser name for selenium
                (default: {'chrome'})

        Raises:
            CoreException -- if name of browser isn't supported

        Returns:
            [DesiredCapabilities] -- DesiredCapabilities inherit
                class instanced for one browser
        """
        capabilities = None
        try:
            capabilities = {
                "chrome": DesiredCapabilities.CHROME.copy(),
                "firefox": DesiredCapabilities.FIREFOX.copy(),
                "iexplorer": DesiredCapabilities.INTERNETEXPLORER.copy(),
                "edge": DesiredCapabilities.EDGE.copy(),
            }[browser_name]
            capabilities['acceptInsecureCerts'] = True
        except KeyError:
            msg = 'Bad browser selected at load options'
            raise CoreException(msg, log=self.log)
        return capabilities

    def __check_driver_ready__(self, driver_path, capabilities, options):
        """Some checks to ensure driver path, caps and options
            are ready to be used
        """
        if driver_path is None:
            driver_path = self.curr_driver_path
        if capabilities is None:
            capabilities = self.curr_caps
        if options is None:
            options = self.curr_options

    def get_options(self, browser_name='chrome', headless_enabled=False):
        """Instance Options class from selenium and return it

        Keyword Arguments:
            browser_name {str} -- name of a valid browser name for selenium
                (default: {'chrome'})
            headless_enabled {bool} -- allow to configure --headless param
                (default: {False})

        Raises:
            CoreException -- if name of browser isn't supported

        Returns:
            [Options] -- Options inherit
                class instanced for one browser
        """
        options = None
        msg_not_conf = ("get_options | : doesn't have configurations"
                        " for browser='{}'".format(browser_name))
        try:
            options = {
                "chrome": ChromeOptions(),
                "firefox": FirefoxOptions(),
            }[browser_name]
            if headless_enabled:
                options.add_argument("--headless")
        except KeyError:
            if browser_name in self.BROWSERS_WITHOUT_OPTIONS:
                self.log.debug(msg_not_conf)
            else:
                raise CoreException("Bad browser selected", log=self.log)
        return options

    def driver_name_filter(self, driver_name=None):
        """Filter names of driver to search selected on config list

        Keyword Arguments:
            driver_name {str} -- driver_name_format is
                {driver_name}{arch}{os} (default: {None})

        Raises:
            CoreException -- driver_name param is None
            CoreException -- driver_name not in

        Returns:
            str -- name of driver
                (example: chromedriver_32.exe)
        """
        driver_name_format = "{}{}{}"
        if driver_name is None:
            raise CoreException("driver_name received it\'s None")
        driver_name_format = driver_name_format.format(driver_name, "{}", "{}")
        if self.IS_WIN:
            driver_name_format = driver_name_format.format("{}", ".exe")
        else:
            driver_name_format = driver_name_format.format("{}", "")
        if self.IS_64BITS:
            driver_name_format = driver_name_format.format("driver_64")
        else:
            driver_name_format = driver_name_format.format("driver_32")
        for name in self.settings.get("drivers_names"):
            if name.endswith(driver_name_format):
                return driver_name_format
        msg = "Driver name not found {}".format(driver_name_format)
        raise CoreException(msg, log=self.log)

    def get_driver_chrome(self,
                          driver_path=None,
                          capabilities=None,
                          options=None):
        """Open WebDriver selenium based on Chrome browser

        Keyword Arguments:
            driver_path {str} -- Path for driver binary path
                (default: {None})
            capabilities {DesiredCapabilities} -- Capabilities for browser
                (default: {None})
            options {Options} -- Options for browser (default: {None})

        Returns:
            [WebDriver.Chrome] -- WebDriver opened and ready to be used
        """
        self.__check_driver_ready__(driver_path, capabilities, options)
        return WebDriver.Chrome(executable_path=driver_path,
                                desired_capabilities=capabilities,
                                chrome_options=options)

    def get_driver_firefox(self,
                           driver_path=None,
                           capabilities=None,
                           options=None):
        """Open WebDriver selenium based on Firefox browser

        Keyword Arguments:
            driver_path {str} -- Path for driver binary path
                (default: {None})
            capabilities {DesiredCapabilities} -- Capabilities for browser
                (default: {None})
            options {Options} -- Options for browser (default: {None})

        Returns:
            [WebDriver.Firefox] -- WebDriver opened and ready to be used
        """
        self.__check_driver_ready__(driver_path, capabilities, options)
        return WebDriver.Firefox(executable_path=driver_path,
                                 capabilities=capabilities,
                                 firefox_options=options)

    def get_driver_iexplorer(self, driver_path=None, capabilities=None):
        """Open WebDriver selenium based on InternetExplorer browser

        Keyword Arguments:
            driver_path {str} -- Path for driver binary path
                (default: {None})
            capabilities {DesiredCapabilities} -- Capabilities for browser
                (default: {None})

        Returns:
            [WebDriver.Ie] -- WebDriver opened and ready to be used
        """
        self.__check_driver_ready__(driver_path, capabilities)
        return WebDriver.Ie(executable_path=driver_path,
                            capabilities=capabilities)

    def get_driver_edge(self, driver_path=None, capabilities=None):
        """Open WebDriver selenium based on Edge browser

        Keyword Arguments:
            driver_path {str} -- Path for driver binary path
                (default: {None})
            capabilities {DesiredCapabilities} -- Capabilities for browser
                (default: {None})
            options {Options} -- Options for browser (default: {None})

        Returns:
            [WebDriver.Edge] -- WebDriver opened and ready to be used
        """
        self.__check_driver_ready__(driver_path, capabilities)
        return WebDriver.Edge(executable_path=driver_path,
                              capabilities=capabilities)

    def mode_local(self, browser_name='chrome'):
        """Open new brower on local mode

        Raises:
            CoreException -- driver_name on config JSON
                file is not valid value
        """
        driver_name = self.driver_name_filter(driver_name=browser_name)
        # TODO: Need it ? maybe a test for this ?
        self.curr_driver_path = os.path.abspath("{}/{}".format(
            self.settings.get('drivers_path'), driver_name))
        sys.path.append(self.curr_driver_path)
        self.log.debug('Starting browser with mode : LOCAL ...')
        try:
            self.curr_driver = {
                "chrome": self.get_driver_chrome(),
                "firefox": self.get_driver_firefox(),
                "iexplorer": self.get_driver_iexplorer(),
                "edge": self.get_driver_edge(),
            }[browser_name]
        except KeyError:
            msg = ("config file error, SECTION=bot, KEY=browser isn't "
                   "valid value: {}".format(browser_name))
            raise CoreException(msg, log=self.log)
        self.log.info('Started browser with mode : LOCAL OK')

    def mode_remote(self, browser_name='chrome'):
        """Open new brower on remote mode

        Raises:
            CoreException -- browser name is not in valid values list
        """
        url_hub = self.settings.get('url_hub')
        self.log.debug('Starting browser with mode : REMOTE ...')
        self.curr_driver = RemoteWebDriver(command_executor=url_hub,
                                           desired_capabilities=self.curr_caps,
                                           options=self.curr_options)
        self.log.info('Started browser with mode : REMOTE OK')

    def close(self):
        """Close curr_driver browser"""
        self.log.debug('Closing browser...')
        self.curr_driver.quit()
        self.log.info('Closed browser')

    def __repr__(self):
        """Show basic properties for this object"""
        _settings = None
        if self.settings.get("mode") == "remote":
            hidden = {
                "drivers_names":
                ["Hidden at '__repr__' for remote drivers..."]
            }
            _settings = self.settings.copy()
            _settings.update(hidden)
        return ("BotBase: IS_WIN={}, IS_64BITS={}\n"
                "  navigation={} \n"
                "  settings={}").format(self.IS_WIN, self.IS_64BITS,
                                        repr(self.navigation), self.settings)