From 7376893e8d66387954c1502e2a113bb5f47ba235 Mon Sep 17 00:00:00 2001 From: "Netzulo.com" Date: Sun, 22 Jul 2018 12:21:09 +0200 Subject: [PATCH] [qacode] creating control_group , #134 (#184) * [qacode] creating control_group , #134 * [qacode] update CIs + fix flake8 errors * [qacode] fix nav tests, added SKIP key * [qacode] fix controls testcases * [qacode] fixing tests + fix for issue #156 , enable deselect tests for multiple select tag + updated settings, added keys for each control package + update default log to INFO + update USAGE.rst * [qacode] fix tox flake8 erros * [qacode] trying to fix travis py35 * [qacode] removed sonarqube suppot * [qacode] update packaging dependency, CIs failing * [qacode] remove assert calls at setup_class --- .travis.yml | 13 +- README.rst | 27 --- USAGE.rst | 7 +- qacode/configs/settings.json | 120 +++++------ qacode/core/webs/controls/__init__.py | 3 +- qacode/core/webs/controls/control_base.py | 32 ++- qacode/core/webs/controls/control_form.py | 1 - qacode/core/webs/controls/control_group.py | 86 ++++++++ setup.py | 2 +- sonar-project.properties | 26 --- tests/000_unitaries/suite_001_config.py | 15 +- tests/001_functionals/suite_004_navbase.py | 36 ++-- .../001_functionals/suite_005_controlbase.py | 199 ++++++++---------- .../001_functionals/suite_006_controlform.py | 134 +++++++----- .../001_functionals/suite_007_controlgroup.py | 119 +++++++++++ ..._007_pagebase.py => suite_008_pagebase.py} | 55 +++-- ...uite_008_tlbase.py => suite_009_tlbase.py} | 0 17 files changed, 533 insertions(+), 342 deletions(-) create mode 100644 qacode/core/webs/controls/control_group.py delete mode 100644 sonar-project.properties create mode 100644 tests/001_functionals/suite_007_controlgroup.py rename tests/001_functionals/{suite_007_pagebase.py => suite_008_pagebase.py} (70%) rename tests/001_functionals/{suite_008_tlbase.py => suite_009_tlbase.py} (100%) diff --git a/.travis.yml b/.travis.yml index 7a8de035..0daa084e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,6 @@ env: - secure: Cb5inPwNlfEREkhKa17tgThrTvFWV+RgfbIX3o2JZQ0Re9dlwNOoxxTd2NrYyRAWSj0LK/Dmev+wG56Jxovva2Kqt+xfpVF2y8C1BCNQlAXY4unoKy3pQ4dyk+iW2qHM0UuZDbyxLofPEKPi7GgoR/77fhdxHgvKPBRG1WixcDyz3NAjjP86M02gv5gY48S6DRPTGKX4kFii/VyEMpM62AKJBFvf6/NAB06E0zuV7l/DZn7JEYQ68upmB7CwhNA5NCMUqX1dVkGpSi4WFrCF2L38uIXDF8JF9nAJ8Cm9dZQobvTRGCeJHU+5t8a2q93zGcTae1147IqqmhbYvpW/69bzlsDsiv90Eg65yOYw8pUkY3FyX0r7jsm1Mo0tap8lYshh7Hc6VYcmDsaAp/XqHJOQWGwW3q6f694D8qe6jxxYMjXnfOuXJfQN/TmvrD++YHwxv1RPkpVXsmEL+IyuoY4PoY3oDRyX6CZ4HDn3zbp3S9Pv2jCGn0JVgZyXZY3lN/9AWPy3XPxuiPNOL8D6Y/dsJxhL4mCzRE3NlZ2m93RVk3mXLAbErwaAisglscpMb9/NDAydDsy8cuXK7Qq5anAfi516GJYr03zzEvz3KAxy3Dcxc1p4CQp65dnvnLgQqQpr/I0GmPRWUnCZSvOf5L5WuG0as8tM1CtD5A89aqI= # GITHUB_TOKEN - secure: LYqe4kN1i8BqVEAO8fdO+CYrx9z8h1ab+NxCgYubLcP70DZoKNRj1/egULOd3uvDHFigFVeaACRR6vUQnHbHsffSkMr4nqwOeJMbxOdspHPuA4oMUy5RZKRC7P+v6Dlwpg4Psg/VsEnP6lHWb/RbosBE8tU8ukewD14EU3o29Ql+lBfvvOW/81UTGokMQa1zrW9o70oEaTYqePT9YzM9UcKgukshYtcxKE3oiwLm3fB8zBAUJwzkEvBGNpXjqBEDCUjrS80CqgY3BRsPfnPk90LgjeORaZKoP1f/bZE4UtgeESK0xpWsKEcDCRkSfGxYw8rD7nwc6H5LiCeoS87oQpUCMsoijmGL1yLrBBMIRAWoMC/o+h/QI5bb+IyLba6KLihY4LpExnWj2V8Mh6qs6AeV8v/Dl1WdyIi72WIkMBrmVrOhtoJJ45QaZJbrwSMeM4/ShS5NdiLFnGKeYOjMJ+DQZa+//SIwnvsOegm918TmOZqCr2YabI6WYixOzYjQPvI2KliZGekaX9uSNxVwoWZDE8jvdhvBWtHsL6hMqAv5ehEJw1aseLwjEGHQjIY0YBqJI38QmFr0vro6/9U2EehXHeW3ycCrPguQJ50nIK/DwiGMadUhrxU0xfZ6+TfFpGY0RivEPLD+Cup9C5oVFAppPJncdBdXUqouR90/8NI= -addons: - sonarqube: - branches: - - master language: python matrix: include: @@ -30,14 +26,11 @@ matrix: before_install: - pip freeze +# Fix for python3.5 +- pip uninstall --yes packaging +# qacode setup required - pip install qautils install: - pip install tox script: - tox -e "{$TOXENV},flake8" -after_script: -- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then - sonar-scanner -X -Dsonar.login=${SONAR_GITHUB_TOKEN} -Dsonar.host.url=http://qalab.tk:82 ; - else - sonar-scanner -X -Dsonar.login=${SONAR_GITHUB_TOKEN} -Dsonar.host.url=http://qalab.tk:82 -Dsonar.github.repository=netzulo/qacode -Dsonar.github.pullRequest=${TRAVIS_PULL_REQUEST} -Dsonar.github.oauth=${GITHUB_TOKEN} -Dsonar.analysis.mode=preview ; - fi diff --git a/README.rst b/README.rst index ed6cd9cc..84de09dc 100755 --- a/README.rst +++ b/README.rst @@ -35,33 +35,6 @@ Python tested versions +-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+ -Code Metrics by sonarqube -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. image:: http://qalab.tk:82/api/badges/gate?key=qacode - :alt: Quality Gate - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=lines - :alt: Lines - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=bugs - :alt: Bugs - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=vulnerabilities - :alt: Vulnerabilities - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=code_smells - :alt: Code Smells - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=sqale_debt_ratio - :alt: Debt ratio - :target: http://qalab.tk:82/api/badges/gate?key=qacode -.. image:: http://qalab.tk:82/api/badges/measure?key=qacode&metric=comment_lines_density - :alt: Comments - :target: http://qalab.tk:82/api/badges/gate?key=qacode - - - Prerequisites ------------- diff --git a/USAGE.rst b/USAGE.rst index c8d79b6a..f92fab9d 100644 --- a/USAGE.rst +++ b/USAGE.rst @@ -65,7 +65,6 @@ It's base control to load web element from ``WebDriver + browser session`` , *th + Param **locator** : This text it's parsed down selenium class ``selenium.webdriver.common.by.By`` (*default:* ``css selector`` == ``By.CSS_SELECTOR``) + Param **instance** : Allow to generate your own inherit classes from ``ControlBase`` and instance them using qacode strategy (*default:* ``ControlBase``) + Param **auto_reload** : Allow to reload element searching first when need to use some function of control instance and isn't loaded (*default:* ``True``) -+ Param **selector_multiple** : allow to search multiple elements with one selectors, first is loaded down ``control.element`` , and all elements will be added to ``control.elements`` list (*default:* ``False``) + Param **on_instance_search** : enable searching element at instance `ControlBase` (*default:* `False`) + Param **on_instance_load** : enable loading ``ControlBase`` properties when element it's loaded (*default:* ``False``) , will need enabled if want to access to base properties values obtained from selenium methods at ``BotBase.navigation`` @@ -119,6 +118,12 @@ ControlForm + Param **strict_rules** : Allow to add strict_rules configuration to laod StrictRule class for each rule ( example: ``strict_rule = StrictRule('my_named_rule', StrictType.TAG, StrictSeverity.HIGHT)`` ) +ControlGroup +~~~~~~~~~~~~ + ++ Param **on_instance_group** : by default it's disabled, at enable raises when strict_rules type warning logs message with 'hight severity' or when type error log messages with 'medium or more severity' ++ Param **group** : allow to track all ControlBase elements using `elements` (*instances of WebElement*) and `group` (*instances of ControlBase*) properties + Pages ----- diff --git a/qacode/configs/settings.json b/qacode/configs/settings.json index 6b23c2ab..25a6e987 100644 --- a/qacode/configs/settings.json +++ b/qacode/configs/settings.json @@ -1,11 +1,11 @@ { "bot": { "log_output_file": "logs/", "log_name": "qacode", - "log_level": "DEBUG", + "log_level": "INFO", "mode": "remote", "browser": "chrome", "options": { "headless": false }, - "url_hub": "http://qalab.tk:11000/wd/hub", + "url_hub": "http://ntz-qa.tk:11000/wd/hub", "drivers_path": "../qadrivers", "drivers_names": [ "chromedriver_32.exe", @@ -28,7 +28,7 @@ }, "testlink": { "enabled": false, - "url_api": "http://qalab.tk:86/lib/api/xmlrpc/v1/xmlrpc.php", + "url_api": "http://ntz-qa.tk:86/lib/api/xmlrpc/v1/xmlrpc.php", "dev_key": "ae2f4839476bea169f7461d74b0ed0ac", "data":{ "generate": false, @@ -44,99 +44,65 @@ "drivers_remote": false, "bot_multiple": false, "bot_unique": false, - "web_controls": false, + "bot_navigations": false, + "web_controls": { + "control_base": false, + "control_form": false, + "control_group": false + }, "web_pages": false, "benchmarks": true }, "apps": [ - { - "name": "nav_tests", - "pages": [ - { - "name": "nav_tests_home", - "url": "http://the-internet.herokuapp.com/", - "locator": "css selector", - "go_url": false, - "wait_url": 0, - "maximize": false, - "controls": [] - } - ] - }, - { - "name": "pages_tests", + { "name": "qadmin", "pages": [ - { - "name": "page_base", - "url": "http://the-internet.herokuapp.com/", + { "name": "qacode_login", + "url": "http://ntz-qa.tk:83/qacode/login", "locator": "css selector", "go_url": false, "wait_url": 0, "maximize": false, - "controls": [] - }, - { - "name": "page_login", - "url": "http://the-internet.herokuapp.com/login", - "locator": "css selector", - "go_url": true, - "wait_url": 0, - "maximize": false, "controls": [ - { - "name": "txt_username", - "locator": "css selector", - "selector": "#username", - "instance": "ControlBase", - "on_instance_search": true, - "on_instance_load": false - }, - { - "name": "txt_password", + { "name": "form_login", "locator": "css selector", - "selector": "#password", + "selector": "#frmLogin", "instance": "ControlBase", "on_instance_search": true, "on_instance_load": false }, - { - "name": "btn_submit", + { "name": "txt_username", "locator": "css selector", - "selector": "button[type='submit']", + "selector": "#txtUsername-field", "instance": "ControlBase", "on_instance_search": true, "on_instance_load": false }, - { - "name": "login_container", + { "name": "txt_password", "locator": "css selector", - "selector": "#content", + "selector": "#txtPassword-field", "instance": "ControlBase", "on_instance_search": true, "on_instance_load": false }, - { - "name": "login_container_title", + { "name": "btn_submit", "locator": "css selector", - "selector": "h2", + "selector": "#btnLogin", "instance": "ControlBase", "on_instance_search": true, "on_instance_load": false } ] }, - { - "name": "page_dropdown", - "url": "http://the-internet.herokuapp.com/dropdown", + { "name": "qacode_inputs", + "url": "http://ntz-qa.tk:83/qacode/forms/inputs", "locator": "css selector", - "go_url": true, + "go_url": false, "wait_url": 0, "maximize": false, "controls": [ - { - "name": "dropdown", + { "name": "dd_base", "locator": "css selector", - "selector": "#dropdown", + "selector": "#txtTest002", "instance": "ControlForm", "on_instance_search": true, "on_instance_load": true, @@ -144,6 +110,42 @@ "strict_rules": [ { "tag": "select", "type": "tag", "severity": "hight" } ] + }, + { "name": "dd_multiple", + "locator": "css selector", + "selector": "#txtTest003", + "instance": "ControlForm", + "on_instance_search": true, + "on_instance_load": true, + "on_instance_strict": true, + "strict_rules": [ + { "tag": "select", "type": "tag", "severity": "hight" } + ] + } + ] + }, + { "name": "qacode_logout", + "url": "http://ntz-qa.tk:83/qacode/logout", + "locator": "css selector", + "go_url": true, + "wait_url": 0, + "maximize": false, + "controls": [ + { "name": "btn_logout", + "locator": "css selector", + "selector": "a[href='/qacode/logout']", + "instance": "ControlBase", + "on_instance_search": true, + "on_instance_load": true, + "on_instance_strict": true + }, + { "name": "btn_login", + "locator": "css selector", + "selector": "a[href='/qacode/login']", + "instance": "ControlBase", + "on_instance_search": true, + "on_instance_load": true, + "on_instance_strict": true } ] } diff --git a/qacode/core/webs/controls/__init__.py b/qacode/core/webs/controls/__init__.py index 561b4ab3..76f3af99 100755 --- a/qacode/core/webs/controls/__init__.py +++ b/qacode/core/webs/controls/__init__.py @@ -4,6 +4,7 @@ from qacode.core.webs.controls import control_base from qacode.core.webs.controls import control_form +from qacode.core.webs.controls import control_group -__all__ = ['control_base', 'control_form'] +__all__ = ['control_base', 'control_form', 'control_group'] diff --git a/qacode/core/webs/controls/control_base.py b/qacode/core/webs/controls/control_base.py index cda18b35..457c15c2 100644 --- a/qacode/core/webs/controls/control_base.py +++ b/qacode/core/webs/controls/control_base.py @@ -23,11 +23,9 @@ class ControlBase(object): on_instance_search = None on_instance_load = None auto_reload = None - selector_multiple = None instance = None # Element properties element = None - elements = None tag = None text = None is_displayed = None @@ -76,7 +74,6 @@ def load_settings_keys(self, settings, update=False, default_keys=None): ("on_instance_search", False), ("on_instance_load", False), ("auto_reload", True), - ("selector_multiple", False), ("instance", 'ControlBase') ] default_settings = defaultdict(list, default_keys) @@ -108,29 +105,26 @@ def _load_search(self, enabled=False, selector_multiple_pos=0): return False self.bot.log.debug("control | _load_search: searching element...") try: - if self.selector_multiple: - self.bot.log.debug(("control | _load_search:" - " searching multiple elements...")) - self.elements = self.bot.navigation.find_elements( - self.selector, locator=self.locator) - self.element = self.elements[selector_multiple_pos] - else: - self.element = self.bot.navigation.find_element( - self.selector, locator=self.locator) + self.element = self.bot.navigation.find_element( + self.selector, locator=self.locator) except CoreException: self.bot.log.warning( "control | _load_search: waiting for element...") - if self.selector_multiple: - self.elements = self.bot.navigation.find_elements_wait( - self.selector, locator=self.locator) - self.element = self.elements[selector_multiple_pos] - else: - self.element = self.bot.navigation.find_element_wait( - self.selector, locator=self.locator) + self.element = self.bot.navigation.find_element_wait( + self.selector, locator=self.locator) self.bot.log.debug("control | _load_search: element found!") return True def _load_properties(self, enabled=False): + """Load default properties for base element + + Keyword Arguments: + enabled {bool} -- load at enabled (default: {False}) + + Raises: + ControlException -- if enabled and settings + haven't key on_instance_search + """ if enabled and not self.settings.get('on_instance_search'): msg = ("Can't call to load_properties " "wihout call first to load_search") diff --git a/qacode/core/webs/controls/control_form.py b/qacode/core/webs/controls/control_form.py index a843802b..19850389 100644 --- a/qacode/core/webs/controls/control_form.py +++ b/qacode/core/webs/controls/control_form.py @@ -62,7 +62,6 @@ def load_settings_keys(self, settings, update=False): ("on_instance_search", False), ("on_instance_load", False), ("auto_reload", True), - ("selector_multiple", False), ("instance", 'ControlForm'), ("on_instance_strict", False), ("strict_rules", []), diff --git a/qacode/core/webs/controls/control_group.py b/qacode/core/webs/controls/control_group.py new file mode 100644 index 00000000..9ce4d5ec --- /dev/null +++ b/qacode/core/webs/controls/control_group.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +"""Package module qacode.core.webs.control_group""" + + +from qacode.core.webs.controls.control_base import By +from qacode.core.webs.controls.control_base import ControlBase +from qacode.core.webs.controls.control_base import CoreException + + +class ControlGroup(ControlBase): + """Requirements: #164""" + + # Settings properties + on_instance_group = None + group = None + # Element properties + elements = None + + def __init__(self, bot, **kwargs): + """Instance of ControlGroup""" + super(ControlGroup, self).__init__(bot, **kwargs) + self.load(**kwargs) + # TODO: make sense + + def load(self, **kwargs): + """Load properties from settings dict. + Some elements need to search False to be search at future + """ + self.elements = [] + self.group = [] + # needed for self._load_* functions + self.load_settings_keys(kwargs.copy(), update=True) + # instance logic + if not self.on_instance_group: + self._load_search(enabled=self.on_instance_search) + self._load_properties(enabled=self.on_instance_load) + else: + self._load_group(enabled=self.on_instance_group) + self._load_properties(enabled=self.on_instance_load) + + def load_settings_keys(self, settings, update=False): + """Load default setting for ControlGroup instance""" + self.bot.log.debug( + "control_group | load_settings_keys: loading keys...") + super(ControlGroup, self).load_settings_keys( + settings, + update=update, + default_keys=[ + ("selector", None), # required + ("name", "UNNAMED"), + ("locator", By.CSS_SELECTOR), + ("on_instance_search", False), + ("on_instance_load", False), + ("auto_reload", True), + ("instance", 'ControlGroup'), + ("on_instance_group", False), + ("group", []), + ] + ) + self.bot.log.debug( + "control_group | load_settings_keys: loaded keys!") + + def _load_group(self, enabled=False, ): + """Load default properties for each element at group dict + + Keyword Arguments: + enabled {bool} -- load at enabled (default: {False}) + """ + if not enabled or enabled is None: + self.bot.log.warning( + ("control | _load_group: " + "!Disabled searching group of elements!")) + return False + self.bot.log.debug( + ("control | _load_group: " + "searching group of elements...")) + try: + self.elements = self.bot.navigation.find_elements( + self.selector, locator=self.locator) + except CoreException: + self.bot.log.warning( + "control | _load_group: waiting for elements...") + self.elements = self.bot.navigation.find_elements_wait( + self.selector, locator=self.locator) + self.bot.log.debug("control | _load_group: elements found!") + return True diff --git a/setup.py b/setup.py index 9ecd45e7..171a73d5 100755 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ CURR_PATH = "{}{}".format(path.abspath(path.dirname(__file__)), '/') INSTALL_REQUIRES = [ 'appdirs', - 'packaging==16.8', + 'packaging>=16.8', 'pyparsing', 'six==1.10.0', 'selenium==3.12.0', diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index 7ddbb058..00000000 --- a/sonar-project.properties +++ /dev/null @@ -1,26 +0,0 @@ -# Required metadata -sonar.projectKey=qacode -sonar.projectName=qacode -sonar.projectDescription=Python library to automate functional testing -sonar.projectVersion=5.4 -# Language -sonar.language=py -# Comma-separated paths to directories with sources (required) -sonar.sources=qacode -sonar.tests=tests -# Encoding of the source files -sonar.sourceEncoding=UTF-8 -# Smoke tests -sonar.python.pylint=/usr/local/bin/pylint -sonar.python.pylint_config=.pylintrc -sonar.python.pylint.reportPath=pylint-report.txt -# Unit tests -sonar.python.xunit.reportPath=tests/reports/report_xunit*.xml -# Integration tests -sonar.python.coverage.overallReportPath=tests/reports/report_coverage.xml - -# GITHUB -sonar.links.homepage=https://github.com/netzulo/qacode -sonar.links.ci=https://travis-ci.org/netzulo/qacode -sonar.links.scm=https://github.com/netzulo/qacode -sonar.links.issue=https://github.com/netzulo/qacode/issues diff --git a/tests/000_unitaries/suite_001_config.py b/tests/000_unitaries/suite_001_config.py index 71ff06a5..0555fb77 100644 --- a/tests/000_unitaries/suite_001_config.py +++ b/tests/000_unitaries/suite_001_config.py @@ -44,7 +44,7 @@ def test_config_bot_keys(self, key_name): """TODO: doc method""" if SKIP_CONFIG: pytest.skip(msg=SKIP_CONFIG_MSG) - key_value = settings()['bot'][key_name] + key_value = self.config['bot'][key_name] if key_name == 'mode': valid_values = ["local", "remote"] self.assert_in(key_value, valid_values) @@ -75,7 +75,7 @@ def test_config_tests_keys(self, key_name): """TODO: doc method""" if SKIP_CONFIG: pytest.skip(msg=SKIP_CONFIG_MSG) - key_value = settings()['tests'][key_name] + key_value = self.config['tests'][key_name] if key_name == 'skip': self.assert_is_instance(key_value, dict) self.assert_is_instance( @@ -89,7 +89,13 @@ def test_config_tests_keys(self, key_name): self.assert_is_instance( key_value.get('bot_unique'), bool) self.assert_is_instance( - key_value.get('web_controls'), bool) + key_value.get('web_controls'), dict) + self.assert_is_instance( + key_value.get('web_controls').get('control_base'), bool) + self.assert_is_instance( + key_value.get('web_controls').get('control_form'), bool) + self.assert_is_instance( + key_value.get('web_controls').get('control_group'), bool) self.assert_is_instance( key_value.get('web_pages'), bool) self.assert_is_instance( @@ -109,3 +115,6 @@ def test_config_tests_keys(self, key_name): self.assert_is_instance(page_config.get('maximize'), bool) self.assert_is_instance(page_config.get('controls'), list) # TODO: handle control list + ctl_configs = page_config.get('controls') + for control in ctl_configs: + self.assert_is_instance(control.get('selector'), str) diff --git a/tests/001_functionals/suite_004_navbase.py b/tests/001_functionals/suite_004_navbase.py index da0807a0..f09df2a2 100644 --- a/tests/001_functionals/suite_004_navbase.py +++ b/tests/001_functionals/suite_004_navbase.py @@ -9,53 +9,53 @@ SETTINGS = settings(file_path="qacode/configs/") -SKIP_REMOTES = SETTINGS['tests']['skip']['drivers_remote'] -SKIP_REMOTES_MSG = 'drivers_remote DISABLED by config file' +SKIP_NAVS = SETTINGS['tests']['skip']['bot_navigations'] +SKIP_NAVS_MSG = 'bot_navigations DISABLED by config file' class TestNavBase(TestInfoBotUnique): """Test Suite for class NavBase""" app = None - page_home = None + page = None @classmethod def setup_class(cls, **kwargs): """TODO: doc method""" super(TestNavBase, cls).setup_class( config=settings(file_path="qacode/configs/"), - skip_force=SKIP_REMOTES) + skip_force=SKIP_NAVS) def setup_method(self, test_method, close=True): """Configure self.attribute""" super(TestNavBase, self).setup_method( test_method, config=settings(file_path="qacode/configs/")) - self.add_property('app', self.settings_app('nav_tests')) - self.add_property('page_home', self.settings_page('nav_tests_home')) + self.add_property('app', self.settings_app('qadmin')) + self.add_property('page', self.settings_page('qacode_login')) - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) def test_navbase_instance(self): """Testcase: test_navbase_instance""" self.assert_is_instance(self.bot.navigation, NavBase) - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) def test_gourl_without_waits(self): """Testcase: test_gourl_without_waits""" - self.bot.navigation.get_url(self.page_home.get('url')) + self.bot.navigation.get_url(self.page.get('url')) - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) def test_gourl_with_waitsparam(self): """Testcase: test_gourl_with_waitsparam""" self.bot.navigation.get_url( - self.page_home.get('url'), wait_for_load=0) + self.page.get('url'), wait_for_load=0) - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) - def test_getmaximizewindow(self): + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) + def test_get_maximizewindow(self): """Testcase: test_getmaximizewindow""" self.bot.navigation.get_maximize_window() - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) def test_getcapabilities(self): """Testcase: test_getcapabilities""" caps = self.bot.navigation.get_capabilities() @@ -63,20 +63,20 @@ def test_getcapabilities(self): self.assert_is_instance(caps['chrome'], dict) self.assert_equals(caps['browserName'], 'chrome') - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) def test_getlog_default(self): """Testcase: test_getlog_default""" - self.bot.navigation.get_url(self.page_home.get('url')) + self.bot.navigation.get_url(self.page.get('url')) log_data = self.bot.navigation.get_log() self.assert_not_none(log_data) self.log.debug("selenium logs, browser={}".format(log_data)) - @pytest.mark.skipIf(SKIP_REMOTES, SKIP_REMOTES_MSG) + @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) @pytest.mark.parametrize( "log_name", ['browser', 'driver', 'client', 'server']) def test_getlog_lognames(self, log_name): """Testcase: test_getlog_logname""" - self.bot.navigation.get_url(self.page_home.get('url')) + self.bot.navigation.get_url(self.page.get('url')) log_data = self.bot.navigation.get_log(log_name=log_name) self.assert_not_none(log_data) msg = "selenium logs, log_name={}, log_data={}".format( diff --git a/tests/001_functionals/suite_005_controlbase.py b/tests/001_functionals/suite_005_controlbase.py index ada659c1..05500012 100644 --- a/tests/001_functionals/suite_005_controlbase.py +++ b/tests/001_functionals/suite_005_controlbase.py @@ -11,15 +11,23 @@ SETTINGS = settings(file_path="qacode/configs/") -SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls'] +SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls']['control_base'] SKIP_CONTROLS_MSG = 'web_controls DISABLED by config file' class TestControlBase(TestInfoBotUnique): """Test Suite for ControlBase class""" + # app from config app = None - page_login_config = None + # page from config + page = None + url = None + # elements from config + form_login = None + txt_username = None + txt_password = None + btn_submit = None @classmethod def setup_class(cls, **kwargs): @@ -33,24 +41,33 @@ def setup_method(self, test_method): super(TestControlBase, self).setup_method( test_method, config=settings(file_path="qacode/configs/")) self.add_property( - 'app', value=self.settings_app('pages_tests')) + 'app', value=self.settings_app('qadmin')) self.add_property( - 'page_login_config', value=self.settings_page('page_login')) + 'page', value=self.settings_page('qacode_login')) self.add_property( - 'url', value=self.page_login_config.get('url')) + 'url', value=self.page.get('url')) + self.add_property( + 'txt_username', + value=self.settings_control('txt_username')) + self.add_property( + 'txt_password', + value=self.settings_control('txt_password')) + self.add_property( + 'btn_submit', + value=self.settings_control('btn_submit')) + self.add_property( + 'form_login', + value=self.settings_control('form_login')) self.bot.navigation.get_url(self.url) - curr_url = self.bot.curr_driver.current_url - self.assert_equals_url(curr_url, self.url) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - @pytest.mark.parametrize("selector", ["#username"]) + @pytest.mark.parametrize("selector", ["#txtUsername-field"]) @pytest.mark.parametrize("instance", ["ControlBase"]) @pytest.mark.parametrize("on_instance_search", [False, True]) @pytest.mark.parametrize("on_instance_load", [False, True]) @pytest.mark.parametrize("auto_reload", [True]) - @pytest.mark.parametrize("selector_multiple", [False]) def test_instance_base(self, selector, instance, on_instance_search, - on_instance_load, auto_reload, selector_multiple): + on_instance_load, auto_reload): """Testcase: test_instance_base""" # must be supported at: test_instance_raises_base if not on_instance_search and on_instance_load: @@ -64,7 +81,6 @@ def test_instance_base(self, selector, instance, on_instance_search, "on_instance_search": on_instance_search, "on_instance_load": on_instance_load, "auto_reload": auto_reload, - "selector_multiple": selector_multiple } control = ControlBase(self.bot, **control_config) self.assert_is_instance(control, ControlBase) @@ -90,9 +106,6 @@ def test_instance_base(self, selector, instance, on_instance_search, self.assert_equals( control.auto_reload, control_config.get('auto_reload')) - self.assert_equals( - control.selector_multiple, - control_config.get('selector_multiple')) self.assert_equals( control.instance, control_config.get('instance')) @@ -101,12 +114,10 @@ def test_instance_base(self, selector, instance, on_instance_search, @pytest.mark.parametrize("on_instance_load", [None]) @pytest.mark.parametrize("on_instance_search", [None, True]) @pytest.mark.parametrize("instance", ["ControlBase"]) - @pytest.mark.parametrize("selector", [None, "#username"]) + @pytest.mark.parametrize("selector", [None, "#txtUsername-field"]) @pytest.mark.parametrize("auto_reload", [False]) - @pytest.mark.parametrize("selector_multiple", [False]) def test_instance_base_raises(self, selector, instance, on_instance_search, - on_instance_load, auto_reload, - selector_multiple): + on_instance_load, auto_reload): """Testcase: test_instance_raises_base""" # must be supported at: test_instance_base if on_instance_search and on_instance_load is None: @@ -120,7 +131,6 @@ def test_instance_base_raises(self, selector, instance, on_instance_search, "on_instance_search": on_instance_search, "on_instance_load": on_instance_load, "auto_reload": auto_reload, - "selector_multiple": selector_multiple } if ( on_instance_search is None and @@ -161,108 +171,80 @@ def test_instance_raises_nonesettings(self): @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_findchild(self): """Testcase: test_method_findchild""" - login_container_config = self.settings_control('login_container') - login_container_title_config = self.settings_control( - 'login_container_title') - control = ControlBase(self.bot, **login_container_config) + cfg_parent = self.form_login.copy() + child_selector = self.settings_control( + 'txt_username').get('selector') + control = ControlBase(self.bot, **cfg_parent) self.assert_is_instance( - control.find_child( - login_container_title_config.get('selector')), + control.find_child(child_selector), ControlBase) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_property_gettext(self): """Testcase: test_property_gettext""" - login_container_title_config = self.settings_control( - 'login_container_title').copy() - login_container_title_config.update({ - "on_instance_load": True - }) - control = ControlBase( - self.bot, **login_container_title_config) - self.assert_equals(control.text, 'Login Page') + cfg_btn = self.btn_submit.copy() + cfg_btn.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_btn) + self.assert_equals(control.text, 'Login') @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_property_raises_gettext(self): """Testcase: test_property_raises_gettext""" - login_container_title_config = self.settings_control( - 'login_container_title') - control = ControlBase( - self.bot, **login_container_title_config) + cfg_btn = self.btn_submit.copy() + control = ControlBase(self.bot, **cfg_btn) self.assert_equals(control.text, None) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_gettext(self): """Testcase: test_method_gettext""" - login_container_title_config = self.settings_control( - 'login_container_title') - login_container_title_config.update({ - "on_instance_load": True - }) - control = ControlBase( - self.bot, **login_container_title_config) - self.assert_equals(control.get_text(), 'Login Page') + cfg_btn = self.btn_submit.copy() + cfg_btn.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_btn) + self.assert_equals(control.get_text(), 'Login') @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_property_attr_id(self): """Testcase: test_property_attr_id""" - txt_username_config = self.settings_control( - 'txt_username') - txt_username_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **txt_username_config) - self.assert_equals(control.attr_id, 'username') + cfg_input = self.txt_username.copy() + cfg_input.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_input) + self.assert_not_none(control.attr_id) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_property_attr_class(self): """Testcase: test_property_attr_class""" - login_container_config = self.settings_control( - 'login_container') - login_container_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **login_container_config) - self.assert_in('large-12', control.attr_class) - self.assert_in('columns', control.attr_class) + cfg_form = self.form_login.copy() + cfg_form.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_form) + self.assert_in('ember-view', control.attr_class) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_getattrvalue(self): """Testcase: test_method_getattrvalue""" - login_container_config = self.settings_control( - 'login_container') - login_container_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **login_container_config) - self.assert_equals(control.get_attr_value('id'), 'content') + cfg_form = self.form_login.copy() + cfg_form.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_form) + self.assert_not_none(control.get_attr_value('id')) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_get_attrs(self): """Testcase: test_method_get_attrs""" - login_container_config = self.settings_control( - 'login_container') - login_container_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **login_container_config) + cfg_form = self.form_login.copy() + cfg_form.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_form) attrs = control.get_attrs(['id', 'class']) self.assert_equals(attrs[0]['name'], 'id') - self.assert_equals(attrs[0]['value'], 'content') + self.assert_equals(attrs[0]['value'], 'frmLogin') self.assert_equals(attrs[1]['name'], 'class') - self.assert_in('large-12', attrs[1]['value']) - self.assert_in('columns', attrs[1]['value']) + self.assert_in('ember-view', attrs[1]['value']) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_property_tag(self): """Testcase: test_property_tag""" - login_container_config = self.settings_control( - 'login_container') - login_container_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **login_container_config) - self.assert_equals(control.tag, 'div') + cfg_form = self.form_login.copy() + cfg_form.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_form) + self.assert_equals(control.tag, 'form') @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) @pytest.mark.parametrize("control_name", ['txt_username']) @@ -280,7 +262,7 @@ def test_property_tag(self): def test_method_typetext(self, control_name, control_config, clear): """Testcase: test_method_typetext_cleartrue""" text_to_type = 'test' - ctl_config = self.settings_control(control_name) + ctl_config = getattr(self, control_name).copy() ctl_config.update(control_config) control = ControlBase(self.bot, **ctl_config) control.type_text(text_to_type, clear=clear) @@ -290,50 +272,43 @@ def test_method_typetext(self, control_name, control_config, clear): @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_getcssvalue(self): """Testcase: test_method_getcssvalue""" - txt_username_config = self.settings_control( - 'txt_username') - txt_username_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **txt_username_config) + cfg_input = self.txt_username.copy() + cfg_input.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_input) self.assert_equals( - control.get_css_value('color'), 'rgba(0, 0, 0, 0.75)') + control.get_css_value('color'), + 'rgba(73, 80, 87, 1)') @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_setcssrule(self): """Testcase: test_method_setcssrule""" - txt_username_config = self.settings_control( - 'txt_username') - txt_username_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **txt_username_config) + cfg_input = self.txt_username.copy() + cfg_input.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_input) control.type_text('test') control.set_css_value('color', 'red') self.assert_equals( - control.get_css_value('color'), 'rgba(255, 0, 0, 1)') + control.get_css_value('color'), + 'rgba(255, 0, 0, 1)') @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_gettext_onscreenfalse(self): """Testcase: test_method_gettext_onscreenfalse""" - login_container_title_config = self.settings_control( - 'login_container_title') - login_container_title_config.update({ - "on_instance_load": True - }) - control = ControlBase(self.bot, **login_container_title_config) + msg_err = 'Failed at obtain text, open issue on Github' + cfg_btn = self.btn_submit.copy() + cfg_btn.update({"on_instance_load": True}) + control = ControlBase(self.bot, **cfg_btn) control.set_css_value('display', 'none') text = control.get_text(on_screen=False) - self.assert_greater( - len(text), 0, msg='Failed at obtain text, open issue on Github') + self.assert_greater(len(text), 0, msg=msg_err) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - @pytest.mark.parametrize("selector", ["#username"]) + @pytest.mark.parametrize("selector", ["#txtUsername-field"]) @pytest.mark.parametrize("instance", ["ControlBase"]) def test_method_reload_base(self, selector, instance): """Testcase: test_method_setcssrule""" # must be supported - control_config = { + cfg_base = { "name": "txt_username_base", "locator": "css selector", "selector": selector, @@ -341,17 +316,17 @@ def test_method_reload_base(self, selector, instance): "on_instance_search": False, "on_instance_load": False, } - control = ControlBase(self.bot, **control_config) + control = ControlBase(self.bot, **cfg_base) self.assert_equals(control.on_instance_search, False) self.assert_equals(control.on_instance_load, False) self.assert_none(control.element) # Real test behaviour - update_config = { + cfg_update = { "on_instance_search": True, "on_instance_load": True } - control_config.update(update_config) - control.reload(**control_config) + cfg_base.update(cfg_update) + control.reload(**cfg_base) self.assert_equals(control.on_instance_search, True) self.assert_equals(control.on_instance_load, True) self.assert_is_instance(control.element, WebElement) diff --git a/tests/001_functionals/suite_006_controlform.py b/tests/001_functionals/suite_006_controlform.py index b66425ce..17c23d5d 100644 --- a/tests/001_functionals/suite_006_controlform.py +++ b/tests/001_functionals/suite_006_controlform.py @@ -12,16 +12,29 @@ SETTINGS = settings(file_path="qacode/configs/") -SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls'] +SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls']['control_form'] SKIP_CONTROLS_MSG = 'web_controls DISABLED by config file' class TestControlForm(TestInfoBotUnique): """Test Suite for ControlBase class""" + # app from config app = None - page_dropdown_config = None - ctl_dropdown_config = None + # page from config: app + page = None + url = None + # page from config: app + page_inputs = None + url_inputs = None + # elements from config: page + form_login = None + txt_username = None + txt_password = None + btn_submit = None + # elements from config: page_inputs + dd_base = None + dd_multiple = None @classmethod def setup_class(cls, **kwargs): @@ -29,31 +42,60 @@ def setup_class(cls, **kwargs): super(TestControlForm, cls).setup_class( config=settings(file_path="qacode/configs/"), skip_force=SKIP_CONTROLS) + cls.add_property( + 'app', value=cls.settings_app('qadmin')) + # page + cls.add_property( + 'page', value=cls.settings_page('qacode_login')) + cls.add_property( + 'url', value=cls.page.get('url')) + cls.add_property( + 'form_login', + value=cls.settings_control('form_login')) + cls.add_property( + 'txt_username', + value=cls.settings_control('txt_username')) + cls.add_property( + 'txt_password', + value=cls.settings_control('txt_password')) + cls.add_property( + 'btn_submit', + value=cls.settings_control('btn_submit')) + # page_inputs + cls.add_property( + 'page_inputs', value=cls.settings_page('qacode_inputs')) + cls.add_property( + 'url_inputs', value=cls.page_inputs.get('url')) + cls.add_property( + 'dd_base', + value=cls.settings_control('dd_base')) + cls.add_property( + 'dd_multiple', + value=cls.settings_control('dd_multiple')) + # start setup + cls.bot.navigation.get_url(cls.url) + # login + txt_username = cls.bot.navigation.find_element( + cls.txt_username.get('selector')) + txt_password = cls.bot.navigation.find_element( + cls.txt_password.get('selector')) + btn_submit = cls.bot.navigation.find_element( + cls.btn_submit.get('selector')) + txt_username.send_keys('admin') + txt_password.send_keys('admin') + btn_submit.click() def setup_method(self, test_method): """Configure self.attribute""" super(TestControlForm, self).setup_method( test_method, config=settings(file_path="qacode/configs/")) - self.add_property( - 'app', value=self.settings_app('pages_tests')) - self.add_property( - 'page_dropdown_config', value=self.settings_page('page_dropdown')) - self.add_property( - 'url', value=self.page_dropdown_config.get('url')) - self.add_property( - 'ctl_dropdown_config', value=self.settings_control( - "dropdown", page_name="page_dropdown")) - self.bot.navigation.get_url(self.url) - curr_url = self.bot.curr_driver.current_url - self.assert_equals_url(curr_url, self.url) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - @pytest.mark.parametrize("selector", ["#dropdown"]) + @pytest.mark.parametrize("selector", ["#txtTest002"]) @pytest.mark.parametrize("instance", ["ControlForm"]) @pytest.mark.parametrize("on_instance_search", [True]) @pytest.mark.parametrize("on_instance_load", [True]) @pytest.mark.parametrize("auto_reload", [True]) - @pytest.mark.parametrize("selector_multiple", [False]) @pytest.mark.parametrize("on_instance_strict", [True, False]) @pytest.mark.parametrize("strict_rules", [ [ @@ -62,7 +104,7 @@ def setup_method(self, test_method): ]) def test_instance_form(self, selector, instance, on_instance_search, on_instance_load, on_instance_strict, strict_rules, - auto_reload, selector_multiple): + auto_reload): """Testcase: test_001_instance_selector""" control_config = { "name": "txt_username_strict", @@ -72,7 +114,6 @@ def test_instance_form(self, selector, instance, on_instance_search, "on_instance_search": on_instance_search, "on_instance_load": on_instance_load, "auto_reload": auto_reload, - "selector_multiple": selector_multiple, "on_instance_strict": on_instance_strict, "strict_rules": strict_rules } @@ -95,9 +136,6 @@ def test_instance_form(self, selector, instance, on_instance_search, self.assert_equals( control.auto_reload, control_config.get('auto_reload')) - self.assert_equals( - control.selector_multiple, - control_config.get('selector_multiple')) self.assert_equals( control.instance, control_config.get('instance')) @@ -116,12 +154,10 @@ def test_instance_form(self, selector, instance, on_instance_search, control.dropdown) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - @pytest.mark.parametrize("selector", ["#dropdown"]) + @pytest.mark.parametrize("selector", ["#txtTest002"]) @pytest.mark.parametrize("instance", ["ControlForm"]) @pytest.mark.parametrize("auto_reload", [True]) - @pytest.mark.parametrize("selector_multiple", [False]) - def test_method_reload_form(self, selector, instance, - auto_reload, selector_multiple): + def test_method_reload_form(self, selector, instance, auto_reload): """Testcase: test_method_setcssrule""" # must be supported control_config = { @@ -130,7 +166,6 @@ def test_method_reload_form(self, selector, instance, "selector": selector, "instance": instance, "auto_reload": auto_reload, - "selector_multiple": selector_multiple, "on_instance_search": False, "on_instance_load": False, "on_instance_strict": False, @@ -155,61 +190,62 @@ def test_method_reload_form(self, selector, instance, self.assert_is_instance(control.element, WebElement) @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - @pytest.mark.parametrize("text", ["Option 1", "Option 2"]) + @pytest.mark.parametrize("text", ["Link 1.1", "Link 1.2"]) def test_method_dropdown_select_by_text(self, text): """Testcase: test_method_dropdown_select_by_text""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_base) control.dropdown_select(text) + # TODO: an assert here @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) @pytest.mark.parametrize("text", ["1", "2"]) def test_method_dropdown_select_by_value(self, text): """Testcase: test_method_dropdown_select_by_value""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_base) control.dropdown_select(text, by_value=True) + # TODO: an assert here @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) @pytest.mark.parametrize("index", [0, 1]) def test_method_dropdown_select_by_index(self, index): """Testcase: test_method_dropdown_select_by_index""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_base) control.dropdown_select(index, by_index=True) + # TODO: an assert here - @pytest.mark.skipIf( - True, - "Github issue: https://github.com/netzulo/qacode/issues/156") - @pytest.mark.parametrize("text", ["Option 1", "Option 2"]) + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) + @pytest.mark.parametrize("text", ["Link 1.1", "Link 1.2"]) def test_method_dropdown_deselect_by_text(self, text): """Testcase: test_method_dropdown_deselect_by_text""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_multiple) control.dropdown_select(text) control.dropdown_deselect(text) + # TODO: an assert here - @pytest.mark.skipIf( - True, - "Github issue: https://github.com/netzulo/qacode/issues/156") + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) @pytest.mark.parametrize("text", ["1", "2"]) def test_method_dropdown_deselect_by_value(self, text): """Testcase: test_method_dropdown_deselect_by_value""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_multiple) control.dropdown_select(text, by_value=True) control.dropdown_deselect(text, by_value=True) + # TODO: an assert here - @pytest.mark.skipIf( - True, - "Github issue: https://github.com/netzulo/qacode/issues/156") + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) @pytest.mark.parametrize("index", [0, 1]) def test_method_dropdown_deselect_by_index(self, index): """Testcase: test_method_dropdown_deselect_by_index""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) + control = ControlForm(self.bot, **self.dd_multiple) control.dropdown_select(index, by_index=True) control.dropdown_deselect(index, by_index=True) + # TODO: an assert here - @pytest.mark.skipIf( - True, - "Github issue: https://github.com/netzulo/qacode/issues/156") + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_dropdown_deselect_all(self): """Testcase: test_method_dropdown_deselect_all""" - control = ControlForm(self.bot, **self.ctl_dropdown_config) - control.dropdown_select("Option 1") + texts = ["Link 1.1", "Link 1.2"] + control = ControlForm(self.bot, **self.dd_multiple) + for text in texts: + control.dropdown_select(text) control.dropdown_deselect_all() + # TODO: an assert here diff --git a/tests/001_functionals/suite_007_controlgroup.py b/tests/001_functionals/suite_007_controlgroup.py new file mode 100644 index 00000000..d2c5ef23 --- /dev/null +++ b/tests/001_functionals/suite_007_controlgroup.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +"""Testsuite for package qacode.core.webs.controls""" + + +import pytest +from qacode.core.testing.test_info import TestInfoBotUnique +from qacode.core.webs.controls.control_group import ControlGroup +from qautils.files import settings +from selenium.webdriver.remote.webelement import WebElement + + +SETTINGS = settings(file_path="qacode/configs/") +SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls']['control_group'] +SKIP_CONTROLS_MSG = 'web_controls DISABLED by config file' + + +class TestControlGroup(TestInfoBotUnique): + """Test Suite for ControlBase class""" + + # app from config + app = None + # page from config + page = None + url = None + # elements from config + form_login = None + txt_username = None + txt_password = None + btn_submit = None + + @classmethod + def setup_class(cls, **kwargs): + """TODO: doc method""" + super(TestControlGroup, cls).setup_class( + config=settings(file_path="qacode/configs/"), + skip_force=SKIP_CONTROLS) + + def setup_method(self, test_method): + """Configure self.attribute""" + super(TestControlGroup, self).setup_method( + test_method, config=settings(file_path="qacode/configs/")) + self.add_property( + 'app', value=self.settings_app('qadmin')) + self.add_property( + 'page', value=self.settings_page('qacode_login')) + self.add_property( + 'url', value=self.page.get('url')) + self.add_property( + 'txt_username', + value=self.settings_control('txt_username')) + self.add_property( + 'txt_password', + value=self.settings_control('txt_password')) + self.add_property( + 'btn_submit', + value=self.settings_control('btn_submit')) + self.add_property( + 'form_login', + value=self.settings_control('form_login')) + self.bot.navigation.get_url(self.url) + + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) + @pytest.mark.parametrize("selector", ["#txtUsername-field", "input"]) + @pytest.mark.parametrize("instance", ["ControlGroup"]) + @pytest.mark.parametrize("on_instance_search", [False, True]) + @pytest.mark.parametrize("on_instance_load", [False, True]) + @pytest.mark.parametrize("auto_reload", [True]) + @pytest.mark.parametrize("on_instance_group", [False, True]) + def test_instance_group(self, selector, instance, on_instance_search, + on_instance_load, auto_reload, on_instance_group): + """Testcase: test_instance_group""" + # must be supported at: test_instance_raises_base + if not on_instance_search and on_instance_load: + pytest.skip( + "Test must be supported at: test_instance_raises_group") + # must be supported + control_config = { + "name": "txt_username_base", + "locator": "css selector", + "selector": selector, + "instance": instance, + "on_instance_search": on_instance_search, + "on_instance_load": on_instance_load, + "auto_reload": auto_reload, + "on_instance_group": on_instance_group, + } + control = ControlGroup(self.bot, **control_config) + self.assert_is_instance(control, ControlGroup) + if on_instance_search: + for ele in control.elements: + self.assert_is_instance(ele, WebElement) + else: + self.assert_none(control.element) + # main config + self.assert_equals( + control.selector, control_config.get('selector')) + self.assert_equals( + control.name, control_config.get('name')) + self.assert_equals( + control.locator, control_config.get('locator')) + self.assert_equals( + control.on_instance_search, + control_config.get('on_instance_search')) + self.assert_equals( + control.on_instance_load, + control_config.get('on_instance_load')) + self.assert_equals( + control.auto_reload, + control_config.get('auto_reload')) + self.assert_equals( + control.instance, + control_config.get('instance')) + self.assert_equals( + control.on_instance_group, + control_config.get('on_instance_group')) + if control_config.get('on_instance_group'): + self.assert_greater(len(control.elements), 1) + else: + self.assert_equals(len(control.elements), 0) diff --git a/tests/001_functionals/suite_007_pagebase.py b/tests/001_functionals/suite_008_pagebase.py similarity index 70% rename from tests/001_functionals/suite_007_pagebase.py rename to tests/001_functionals/suite_008_pagebase.py index b83837cb..b7dccc2f 100644 --- a/tests/001_functionals/suite_007_pagebase.py +++ b/tests/001_functionals/suite_008_pagebase.py @@ -6,6 +6,7 @@ from qacode.core.testing.test_info import TestInfoBotUnique from qacode.core.webs.controls.control_base import ControlBase from qacode.core.webs.controls.control_form import ControlForm +from qacode.core.webs.controls.control_group import ControlGroup from qacode.core.webs.pages.page_base import PageBase from qautils.files import settings @@ -18,9 +19,18 @@ class TestPageBase(TestInfoBotUnique): """Test Suite for class NavBase""" + # app from config app = None - page_base_config = None - page_login_config = None + # page from config: qacode_logout + page = None + url = None + # page from config: qacode_login + page_base = None + # elements from config: page + form_login = None + txt_username = None + txt_password = None + btn_submit = None @classmethod def setup_class(cls, **kwargs): @@ -29,18 +39,31 @@ def setup_class(cls, **kwargs): config=settings(file_path="qacode/configs/"), skip_force=SKIP_PAGES) - def setup_method(self, test_method, close=True): - """Unload self.attribute""" + def setup_method(self, test_method): + """Configure self.attribute""" super(TestPageBase, self).setup_method( test_method, config=settings(file_path="qacode/configs/")) - self.add_property('app', self.settings_app('pages_tests')) - self.page_base_config = self.settings_page('page_base') - self.page_login_config = self.settings_page('page_login') + self.add_property( + 'app', value=self.settings_app('qadmin')) + # page + self.add_property( + 'page', value=self.settings_page('qacode_logout')) + self.add_property( + 'url', value=self.page.get('url')) + self.add_property( + 'btn_logout', + value=self.settings_control('btn_logout')) + self.add_property( + 'btn_login', + value=self.settings_control('btn_login')) + self.add_property( + 'page_base', value=self.settings_page('qacode_login')) + self.bot.navigation.get_url(self.page_base.get('url')) @pytest.mark.skipIf(SKIP_PAGES, SKIP_PAGES_MSG) def test_instance_url(self): """Testcase: test_001_instance_url""" - cfg = self.page_base_config.copy() + cfg = self.page.copy() cfg.update({ "go_url": True }) @@ -48,12 +71,12 @@ def test_instance_url(self): self.assert_is_instance(page, PageBase) self.assert_equals_url( self.bot.curr_driver.current_url, - self.page_base_config.get('url')) + self.page.get('url')) @pytest.mark.skipIf(SKIP_PAGES, SKIP_PAGES_MSG) def test_instance_notgourl(self): """Testcase: test_002_instance_notgourl""" - cfg = self.page_login_config.copy() + cfg = self.page.copy() cfg.update({ "go_url": False, "controls": [] @@ -67,13 +90,13 @@ def test_instance_notgourl(self): @pytest.mark.skipIf(SKIP_PAGES, SKIP_PAGES_MSG) def test_instance_element(self): """Testcase: test_003_instance_element""" - cfg = self.page_login_config.copy() + cfg = self.page.copy() page = PageBase(self.bot, **cfg) self.assert_is_instance(page, PageBase) self.assert_equals_url( self.bot.curr_driver.current_url, cfg.get('url')) - for control in self.page_login_config.get('controls'): + for control in self.page.get('controls'): name = control.get('name') self.assert_in(name, dir(page)) element = page.__dict__[name] @@ -82,7 +105,7 @@ def test_instance_element(self): @pytest.mark.skipIf(SKIP_PAGES, SKIP_PAGES_MSG) def test_instance_maximized(self): """Testcase: test_004_instance_maximized""" - cfg = self.page_login_config.copy() + cfg = self.page.copy() cfg.update({ "go_url": True, "maximize": True, @@ -97,13 +120,13 @@ def test_instance_maximized(self): @pytest.mark.skipIf(SKIP_PAGES, SKIP_PAGES_MSG) def test_method_getelement(self): """Testcase: test_004_instance_maximized""" - cfg = self.page_login_config.copy() + cfg = self.page.copy() page = PageBase(self.bot, **cfg) self.assert_is_instance(page, PageBase) self.assert_equals_url( self.bot.curr_driver.current_url, cfg.get('url')) - for config_control in self.page_login_config.get('controls'): + for config_control in self.page.get('controls'): name = config_control.get('name') instance_name = config_control.get('instance') ctl = page.get_element(config_control) @@ -111,4 +134,6 @@ def test_method_getelement(self): self.assert_is_instance(ctl, ControlBase) elif instance_name == 'ControlForm': self.assert_is_instance(ctl, ControlForm) + elif instance_name == 'ControlGroup': + self.assert_is_instance(ctl, ControlGroup) self.assert_in(name, dir(page)) diff --git a/tests/001_functionals/suite_008_tlbase.py b/tests/001_functionals/suite_009_tlbase.py similarity index 100% rename from tests/001_functionals/suite_008_tlbase.py rename to tests/001_functionals/suite_009_tlbase.py