From 30c1be8530bb3342a530f176669317ce5a0b08a3 Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 29 Jan 2020 19:59:01 +0100 Subject: [PATCH 01/43] [qacode] refactoring all library + with SPEC+TEST on testlink installation --- .gitignore | 8 +- pytest.ini | 2 +- qacode/core/__init__.py | 8 +- qacode/core/bots/bot.py | 63 +++++ qacode/core/browsers/browser.py | 0 qacode/core/controls/control.py | 0 qacode/core/pages/page.py | 0 qacode/core/testing/__init__.py | 17 +- qacode/core/testing/asserts.py | 217 ++++++++++++++++++ qacode_old/__init__.py | 12 + qacode_old/configs/__init__.py | 2 + qacode_old/core/__init__.py | 12 + {qacode => qacode_old}/core/bots/__init__.py | 0 {qacode => qacode_old}/core/bots/bot_base.py | 0 .../core/bots/modules/__init__.py | 0 .../core/bots/modules/nav_base.py | 0 {qacode => qacode_old}/core/enums/__init__.py | 0 .../core/enums/enum_base.py | 0 .../core/exceptions/__init__.py | 0 .../core/exceptions/control_exception.py | 0 .../core/exceptions/core_exception.py | 0 .../core/exceptions/page_exception.py | 0 .../core/loggers/__init__.py | 0 .../core/loggers/logger_manager.py | 0 .../core/loggers/logger_messages.py | 0 qacode_old/core/testing/__init__.py | 9 + .../core/testing/test_info.py | 0 .../core/testing/testlink/__init__.py | 0 .../testing/testlink/reporter_testlink.py | 0 {qacode => qacode_old}/core/webs/__init__.py | 0 .../core/webs/controls/__init__.py | 0 .../core/webs/controls/control_base.py | 0 .../core/webs/controls/control_dropdown.py | 0 .../core/webs/controls/control_form.py | 0 .../core/webs/controls/control_table.py | 0 .../core/webs/css_properties.py | 0 .../core/webs/html_attrs.py | 0 {qacode => qacode_old}/core/webs/html_tags.py | 0 .../core/webs/pages/__init__.py | 0 .../core/webs/pages/page_base.py | 0 .../core/webs/strict_rules.py | 0 qacode_old/utils.py | 82 +++++++ tests/bots/__init__.py | 2 + tests/bots/suite_bots.py | 33 +++ tests/reports/__init__.py | 2 - .../000_unitaries/__init__.py | 0 .../000_unitaries/suite_001_config.py | 0 .../000_unitaries/suite_002_testinfobase.py | 0 .../000_unitaries/suite_003_testenumbase.py | 0 .../suite_004_teststrictrules.py | 0 .../001_functionals/__init__.py | 0 .../001_functionals/suite_001_botbase.py | 0 .../001_functionals/suite_002_testinfobot.py | 0 .../suite_003_testinfobotunique.py | 0 .../001_functionals/suite_004_navbase.py | 0 .../001_functionals/suite_005_controlbase.py | 0 .../001_functionals/suite_006_controlform.py | 0 .../suite_007_controldropdown.py | 0 .../001_functionals/suite_008_controltable.py | 0 .../001_functionals/suite_009_pagebase.py | 0 .../suite_010_reportertestlink.py | 0 .../002_benchmarks/__init__.py | 0 .../002_benchmarks/suite_001_browsers.py | 0 tests_old/__init__.py | 2 + 64 files changed, 452 insertions(+), 19 deletions(-) create mode 100644 qacode/core/bots/bot.py create mode 100644 qacode/core/browsers/browser.py create mode 100644 qacode/core/controls/control.py create mode 100644 qacode/core/pages/page.py create mode 100644 qacode/core/testing/asserts.py create mode 100644 qacode_old/__init__.py create mode 100644 qacode_old/configs/__init__.py create mode 100644 qacode_old/core/__init__.py rename {qacode => qacode_old}/core/bots/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/bots/bot_base.py (100%) rename {qacode => qacode_old}/core/bots/modules/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/bots/modules/nav_base.py (100%) rename {qacode => qacode_old}/core/enums/__init__.py (100%) rename {qacode => qacode_old}/core/enums/enum_base.py (100%) rename {qacode => qacode_old}/core/exceptions/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/exceptions/control_exception.py (100%) rename {qacode => qacode_old}/core/exceptions/core_exception.py (100%) rename {qacode => qacode_old}/core/exceptions/page_exception.py (100%) rename {qacode => qacode_old}/core/loggers/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/loggers/logger_manager.py (100%) rename {qacode => qacode_old}/core/loggers/logger_messages.py (100%) create mode 100644 qacode_old/core/testing/__init__.py rename {qacode => qacode_old}/core/testing/test_info.py (100%) rename {qacode => qacode_old}/core/testing/testlink/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/testing/testlink/reporter_testlink.py (100%) rename {qacode => qacode_old}/core/webs/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/webs/controls/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/webs/controls/control_base.py (100%) rename {qacode => qacode_old}/core/webs/controls/control_dropdown.py (100%) rename {qacode => qacode_old}/core/webs/controls/control_form.py (100%) rename {qacode => qacode_old}/core/webs/controls/control_table.py (100%) rename {qacode => qacode_old}/core/webs/css_properties.py (100%) rename {qacode => qacode_old}/core/webs/html_attrs.py (100%) rename {qacode => qacode_old}/core/webs/html_tags.py (100%) rename {qacode => qacode_old}/core/webs/pages/__init__.py (100%) mode change 100755 => 100644 rename {qacode => qacode_old}/core/webs/pages/page_base.py (100%) rename {qacode => qacode_old}/core/webs/strict_rules.py (100%) create mode 100644 qacode_old/utils.py create mode 100644 tests/bots/__init__.py create mode 100644 tests/bots/suite_bots.py delete mode 100644 tests/reports/__init__.py rename {tests => tests_old}/000_unitaries/__init__.py (100%) rename {tests => tests_old}/000_unitaries/suite_001_config.py (100%) rename {tests => tests_old}/000_unitaries/suite_002_testinfobase.py (100%) rename {tests => tests_old}/000_unitaries/suite_003_testenumbase.py (100%) rename {tests => tests_old}/000_unitaries/suite_004_teststrictrules.py (100%) rename {tests => tests_old}/001_functionals/__init__.py (100%) rename {tests => tests_old}/001_functionals/suite_001_botbase.py (100%) rename {tests => tests_old}/001_functionals/suite_002_testinfobot.py (100%) rename {tests => tests_old}/001_functionals/suite_003_testinfobotunique.py (100%) rename {tests => tests_old}/001_functionals/suite_004_navbase.py (100%) rename {tests => tests_old}/001_functionals/suite_005_controlbase.py (100%) rename {tests => tests_old}/001_functionals/suite_006_controlform.py (100%) rename {tests => tests_old}/001_functionals/suite_007_controldropdown.py (100%) rename {tests => tests_old}/001_functionals/suite_008_controltable.py (100%) rename {tests => tests_old}/001_functionals/suite_009_pagebase.py (100%) rename {tests => tests_old}/001_functionals/suite_010_reportertestlink.py (100%) rename {tests => tests_old}/002_benchmarks/__init__.py (100%) rename {tests => tests_old}/002_benchmarks/suite_001_browsers.py (100%) create mode 100644 tests_old/__init__.py diff --git a/.gitignore b/.gitignore index 281457c5..3fc850a4 100755 --- a/.gitignore +++ b/.gitignore @@ -103,9 +103,11 @@ ENV/ # QACODE ignores qacode/configs/settings.json -tests/reports/* -tests/reports/coverage/* -tests/reports/benchmarks/benchmark.*.svg +qacode_old/configs/settings.json + +tests_old/reports/* +tests_old/reports/coverage/* +tests_old/reports/benchmarks/benchmark.*.svg # Visual Studio .vs/ # Visual code diff --git a/pytest.ini b/pytest.ini index 3ee7820a..939e6edf 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,7 +2,7 @@ addopts = --verbose testpaths = tests console_output_style = progress -python_files = suite_*_*.py +python_files = suite_*.py python_classes = Test* python_functions = test_*_* filterwarnings = diff --git a/qacode/core/__init__.py b/qacode/core/__init__.py index 0a595103..a2a00672 100755 --- a/qacode/core/__init__.py +++ b/qacode/core/__init__.py @@ -3,10 +3,10 @@ from qacode.core import bots -from qacode.core import exceptions -from qacode.core import loggers +from qacode.core import browsers +from qacode.core import controls +from qacode.core import pages from qacode.core import testing -from qacode.core import webs -__all__ = ['bots', 'exceptions', 'loggers', 'testing', 'webs'] +__all__ = ['bots', 'browsers', 'controls', 'pages', 'testing'] diff --git a/qacode/core/bots/bot.py b/qacode/core/bots/bot.py new file mode 100644 index 00000000..b7a3ce5a --- /dev/null +++ b/qacode/core/bots/bot.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +class Bot(object): + """Class Base for handle selenium functionality throught this wrapper""" + + def __init__(self, **kwargs): + """TODO: doc method""" + self._browsers = [] + self._pages = [] + self._controls = [] + + def browser(self, session_id): + """TODO: doc method""" + for browser in self.browsers: + if browser.session_id == session_id: + return browser + raise Exception("browser not found") + + def page(self, url): + """TODO: doc method""" + for page in self.pages: + if page.url == url: + return page + raise Exception("page not found") + + def control(self, selector): + """TODO: doc method""" + for control in self.controls: + if control.selector == selector: + return control + raise Exception("control not found") + + @property + def browsers(self): + """TODO: doc method""" + return self._browsers + + @browsers.setter + def browsers(self, value): + """TODO: doc method""" + self._browsers = value + + @property + def pages(self): + """TODO: doc method""" + return self._pages + + @pages.setter + def pages(self, value): + """TODO: doc method""" + self._pages = value + + @property + def controls(self): + """TODO: doc method""" + return self._controls + + @controls.setter + def controls(self, value): + """TODO: doc method""" + self._controls = value diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py new file mode 100644 index 00000000..e69de29b diff --git a/qacode/core/controls/control.py b/qacode/core/controls/control.py new file mode 100644 index 00000000..e69de29b diff --git a/qacode/core/pages/page.py b/qacode/core/pages/page.py new file mode 100644 index 00000000..e69de29b diff --git a/qacode/core/testing/__init__.py b/qacode/core/testing/__init__.py index 6a35e1c7..5d1f0cb6 100755 --- a/qacode/core/testing/__init__.py +++ b/qacode/core/testing/__init__.py @@ -1,9 +1,8 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.testing""" - - -from qacode.core.testing import test_info -from qacode.core.testing import testlink - - -__all__ = ['test_info', 'testlink'] +# -*- coding: utf-8 -*- +"""package qacode.core.testing""" + + +from qacode.core.testing import asserts + + +__all__ = ['asserts'] diff --git a/qacode/core/testing/asserts.py b/qacode/core/testing/asserts.py new file mode 100644 index 00000000..17c6bc79 --- /dev/null +++ b/qacode/core/testing/asserts.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +"""Base module for asserts on Test Suites""" + + +import os +import re + + +ASSERT_MSG_DEFAULT = "Fails at '{}': actual={}, expected={}" +ASSERT_REGEX_URL = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" # noqa: E501 + + +class Assert(object): + """Base class for inherit new Test classes""" + + @classmethod + def message(cls, assert_name, actual, expected, msg=None): + """Generate assert message for method that calls for it + + Arguments: + assert_name {str} -- Assert method name that call + actual {any} -- Actual value to compare + expected {any} -- Expected value to compare + + Keyword Arguments: + msg {[type]} -- [description] (default: {None}) + + Returns: + str -- Message to be use on Assert method + """ + if msg is not None: + return msg + return ASSERT_MSG_DEFAULT.format( + assert_name, + actual, + expected) + + def equals(self, actual, expected, msg=None): + """Allow to compare 2 values and check if 1st it's equals to + 2nd value + """ + _msg = self.message("assert_equals", actual, expected, msg=msg) + if actual != expected: + raise AssertionError(actual, expected, _msg) + return True + + def not_equals(self, actual, expected, msg=None): + """Allow to compare 2 value to check if 1st isn't equals to + 2nd value + """ + _msg = self.message( + "assert_not_equals", actual, expected, msg=msg) + if actual == expected: + raise AssertionError(actual, expected, _msg) + return True + + def equals_url(self, actual, expected, msg=None, wait=0): + """Allow to compare 2 urls and check if 1st it's equals to 2nd url + + Arguments: + actual {type} -- actual value + expected {type} -- expected value + + Keyword Arguments: + wait {int} -- Wait time on Runtime execution before execute + next lane of code (default: {0}) + + Raises: + AssertionError -- [description] + """ + _msg = self.message( + "assert_equals_url", actual, expected, msg=msg) + self.sleep(wait) + if actual != expected: + raise AssertionError(actual, expected, _msg) + return True + + def not_equals_url(self, actual, expected, msg=None, wait=0): + """Allow to compare 2 urls to check if 1st isn't equals to 2nd url""" + _msg = self.message( + "assert_not_equals_url", actual, expected, msg=msg) + self.sleep(wait) + if actual == expected: + raise AssertionError(actual, expected, _msg) + return True + + def contains_url(self, actual, contains, msg=None, wait=0): + """Allow to compare 2 urls and check if 1st contains 2nd url""" + _msg = self.message( + "assert_contains_url", actual, contains, msg=msg) + self.sleep(wait) + if actual not in contains: + raise AssertionError(actual, contains, _msg) + return True + + def not_contains_url(self, actual, contains, msg=None, wait=0): + """Allow to compare 2 urls and check if 1st not contains 2nd url""" + _msg = self.message( + "assert_not_contains_url", actual, contains, msg=msg) + self.sleep(wait) + if actual in contains: + raise AssertionError(actual, contains, _msg) + return True + + def is_instance(self, instance, class_type, msg=None): + """Allow to encapsulate method assertIsInstance(obj, cls, msg='')""" + _msg = self.message( + "assert_is_instance", instance, class_type, msg=msg) + if not isinstance(class_type, type): + class_type = type(class_type) + if not isinstance(instance, class_type): + raise AssertionError(instance, class_type, _msg) + return True + + def greater(self, actual, greater, msg=None): + """Allow to encapsulate method assertGreater(a, b, msg=msg)""" + _msg = self.message( + "assert_greater", actual, greater, msg=msg) + if actual < greater: + raise AssertionError(actual, greater, _msg) + return True + + def lower(self, actual, lower, msg=None): + """Allow to encapsulate method assertLower(a, b, msg=msg)""" + _msg = self.message( + "assert_lower", actual, lower, msg=msg) + if actual > lower: + raise AssertionError(actual, lower, _msg) + return True + + def in_list(self, actual, valid_values, msg=None): + """Allow to compare if value it's in to 2nd list of values""" + _msg = self.message( + "assert_in_list", actual, valid_values, msg=msg) + if actual not in valid_values: + raise AssertionError(actual, valid_values, _msg) + return True + + def not_in_list(self, actual, invalid_values, msg=None): + """Allow to compare if value it's not in to 2nd list of values""" + _msg = self.message( + "assert_not_in_list", actual, invalid_values, msg=msg) + if actual in invalid_values: + raise AssertionError(actual, invalid_values, _msg) + return True + + def regex(self, actual, pattern, msg=None): + """Allow to compare if value match pattern""" + _msg = self.message( + "assert_regex", actual, pattern, msg=msg) + is_match = re.match(pattern, actual) + if not is_match: + raise AssertionError(actual, pattern, _msg) + return True + + def not_regex(self, actual, pattern, msg=None): + """Allow to compare if value not match pattern""" + _msg = self.message( + "assert_not_regex", actual, pattern, msg=msg) + is_match = re.match(pattern, actual) + if is_match: + raise AssertionError(actual, pattern, _msg) + return True + + def regex_url(self, actual, pattern=None, msg=None): + """Allow to compare if value match url pattern, can use + custom pattern + """ + if not pattern: + pattern = ASSERT_REGEX_URL + return self.assert_regex(actual, pattern, msg=msg) + + def path_exist(self, actual, is_dir=True, msg=None): + """Allow to check if path exist, can check if is_dir also""" + _msg = self.message( + "assert_path_exist", + actual, + "is_dir={}".format(is_dir), + msg=msg) + if not os.path.exists(actual): + raise AssertionError(actual, "PATH_NOT_EXIST", _msg) + _is_dir = os.path.isdir(actual) + if is_dir: + if not _is_dir: + raise AssertionError(actual, "PATH_NOT_DIR", _msg) + else: + if _is_dir: + raise AssertionError(actual, "PATH_IS_DIR_AND_MUST_NOT", _msg) + return True + + def path_not_exist(self, actual, msg=None): + """Allow to check if path not exist, can check if is_dir also""" + _msg = self.message( + "assert_path_not_exist", actual, "", msg=msg) + if os.path.exists(actual): + raise AssertionError(actual, "PATH_EXIST_AND_MUST_NOT", _msg) + return True + + def true(self, actual, msg=None): + """Allow to compare and check if value it's equals to 'True'""" + self.assert_is_instance(actual, bool) + self.assert_equals(actual, True, msg=msg) + return True + + def false(self, actual, msg=None): + """Allow to compare and check if value it's equals to 'False'""" + self.assert_is_instance(actual, bool) + self.assert_equals(actual, False, msg=msg) + return True + + def none(self, actual, msg=None): + """Allow to compare and check if value it's equals to 'None'""" + return self.assert_equals(actual, None, msg=msg) + + def not_none(self, actual, msg=None): + """Allow to compare and check if value it's not equals to 'None'""" + return self.assert_not_equals(actual, None, msg=msg) \ No newline at end of file diff --git a/qacode_old/__init__.py b/qacode_old/__init__.py new file mode 100644 index 00000000..6b4ccef7 --- /dev/null +++ b/qacode_old/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +"""package qacode + Created on 04 march 2017 + @author: ntz +""" + + +from qacode import configs +from qacode import core +from qacode import utils + +__all__ = ['configs', 'core', 'utils'] diff --git a/qacode_old/configs/__init__.py b/qacode_old/configs/__init__.py new file mode 100644 index 00000000..d83f2fff --- /dev/null +++ b/qacode_old/configs/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.configs""" diff --git a/qacode_old/core/__init__.py b/qacode_old/core/__init__.py new file mode 100644 index 00000000..0a595103 --- /dev/null +++ b/qacode_old/core/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +"""package qacode.core""" + + +from qacode.core import bots +from qacode.core import exceptions +from qacode.core import loggers +from qacode.core import testing +from qacode.core import webs + + +__all__ = ['bots', 'exceptions', 'loggers', 'testing', 'webs'] diff --git a/qacode/core/bots/__init__.py b/qacode_old/core/bots/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/bots/__init__.py rename to qacode_old/core/bots/__init__.py diff --git a/qacode/core/bots/bot_base.py b/qacode_old/core/bots/bot_base.py similarity index 100% rename from qacode/core/bots/bot_base.py rename to qacode_old/core/bots/bot_base.py diff --git a/qacode/core/bots/modules/__init__.py b/qacode_old/core/bots/modules/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/bots/modules/__init__.py rename to qacode_old/core/bots/modules/__init__.py diff --git a/qacode/core/bots/modules/nav_base.py b/qacode_old/core/bots/modules/nav_base.py similarity index 100% rename from qacode/core/bots/modules/nav_base.py rename to qacode_old/core/bots/modules/nav_base.py diff --git a/qacode/core/enums/__init__.py b/qacode_old/core/enums/__init__.py similarity index 100% rename from qacode/core/enums/__init__.py rename to qacode_old/core/enums/__init__.py diff --git a/qacode/core/enums/enum_base.py b/qacode_old/core/enums/enum_base.py similarity index 100% rename from qacode/core/enums/enum_base.py rename to qacode_old/core/enums/enum_base.py diff --git a/qacode/core/exceptions/__init__.py b/qacode_old/core/exceptions/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/exceptions/__init__.py rename to qacode_old/core/exceptions/__init__.py diff --git a/qacode/core/exceptions/control_exception.py b/qacode_old/core/exceptions/control_exception.py similarity index 100% rename from qacode/core/exceptions/control_exception.py rename to qacode_old/core/exceptions/control_exception.py diff --git a/qacode/core/exceptions/core_exception.py b/qacode_old/core/exceptions/core_exception.py similarity index 100% rename from qacode/core/exceptions/core_exception.py rename to qacode_old/core/exceptions/core_exception.py diff --git a/qacode/core/exceptions/page_exception.py b/qacode_old/core/exceptions/page_exception.py similarity index 100% rename from qacode/core/exceptions/page_exception.py rename to qacode_old/core/exceptions/page_exception.py diff --git a/qacode/core/loggers/__init__.py b/qacode_old/core/loggers/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/loggers/__init__.py rename to qacode_old/core/loggers/__init__.py diff --git a/qacode/core/loggers/logger_manager.py b/qacode_old/core/loggers/logger_manager.py similarity index 100% rename from qacode/core/loggers/logger_manager.py rename to qacode_old/core/loggers/logger_manager.py diff --git a/qacode/core/loggers/logger_messages.py b/qacode_old/core/loggers/logger_messages.py similarity index 100% rename from qacode/core/loggers/logger_messages.py rename to qacode_old/core/loggers/logger_messages.py diff --git a/qacode_old/core/testing/__init__.py b/qacode_old/core/testing/__init__.py new file mode 100644 index 00000000..6a35e1c7 --- /dev/null +++ b/qacode_old/core/testing/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +"""package qacode.core.testing""" + + +from qacode.core.testing import test_info +from qacode.core.testing import testlink + + +__all__ = ['test_info', 'testlink'] diff --git a/qacode/core/testing/test_info.py b/qacode_old/core/testing/test_info.py similarity index 100% rename from qacode/core/testing/test_info.py rename to qacode_old/core/testing/test_info.py diff --git a/qacode/core/testing/testlink/__init__.py b/qacode_old/core/testing/testlink/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/testing/testlink/__init__.py rename to qacode_old/core/testing/testlink/__init__.py diff --git a/qacode/core/testing/testlink/reporter_testlink.py b/qacode_old/core/testing/testlink/reporter_testlink.py similarity index 100% rename from qacode/core/testing/testlink/reporter_testlink.py rename to qacode_old/core/testing/testlink/reporter_testlink.py diff --git a/qacode/core/webs/__init__.py b/qacode_old/core/webs/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/webs/__init__.py rename to qacode_old/core/webs/__init__.py diff --git a/qacode/core/webs/controls/__init__.py b/qacode_old/core/webs/controls/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/webs/controls/__init__.py rename to qacode_old/core/webs/controls/__init__.py diff --git a/qacode/core/webs/controls/control_base.py b/qacode_old/core/webs/controls/control_base.py similarity index 100% rename from qacode/core/webs/controls/control_base.py rename to qacode_old/core/webs/controls/control_base.py diff --git a/qacode/core/webs/controls/control_dropdown.py b/qacode_old/core/webs/controls/control_dropdown.py similarity index 100% rename from qacode/core/webs/controls/control_dropdown.py rename to qacode_old/core/webs/controls/control_dropdown.py diff --git a/qacode/core/webs/controls/control_form.py b/qacode_old/core/webs/controls/control_form.py similarity index 100% rename from qacode/core/webs/controls/control_form.py rename to qacode_old/core/webs/controls/control_form.py diff --git a/qacode/core/webs/controls/control_table.py b/qacode_old/core/webs/controls/control_table.py similarity index 100% rename from qacode/core/webs/controls/control_table.py rename to qacode_old/core/webs/controls/control_table.py diff --git a/qacode/core/webs/css_properties.py b/qacode_old/core/webs/css_properties.py similarity index 100% rename from qacode/core/webs/css_properties.py rename to qacode_old/core/webs/css_properties.py diff --git a/qacode/core/webs/html_attrs.py b/qacode_old/core/webs/html_attrs.py similarity index 100% rename from qacode/core/webs/html_attrs.py rename to qacode_old/core/webs/html_attrs.py diff --git a/qacode/core/webs/html_tags.py b/qacode_old/core/webs/html_tags.py similarity index 100% rename from qacode/core/webs/html_tags.py rename to qacode_old/core/webs/html_tags.py diff --git a/qacode/core/webs/pages/__init__.py b/qacode_old/core/webs/pages/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qacode/core/webs/pages/__init__.py rename to qacode_old/core/webs/pages/__init__.py diff --git a/qacode/core/webs/pages/page_base.py b/qacode_old/core/webs/pages/page_base.py similarity index 100% rename from qacode/core/webs/pages/page_base.py rename to qacode_old/core/webs/pages/page_base.py diff --git a/qacode/core/webs/strict_rules.py b/qacode_old/core/webs/strict_rules.py similarity index 100% rename from qacode/core/webs/strict_rules.py rename to qacode_old/core/webs/strict_rules.py diff --git a/qacode_old/utils.py b/qacode_old/utils.py new file mode 100644 index 00000000..bce09f71 --- /dev/null +++ b/qacode_old/utils.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +"""Utils tasks for files operations and settings operations""" + + +import json +from os import path +from sys import version_info + + +def path_format(file_path=None, file_name=None, is_abspath=False, + ignore_raises=False): + """ + Get path joined checking before if path and filepath exist, + if not, raise an Exception + if ignore_raise it's enabled, then file_path must include '/' at end lane + """ + path_formatted = "{}{}".format(file_path, file_name) + if ignore_raises: + return path_formatted + if file_path is None or not path.exists(file_path): + raise IOError("Path '{}' doesn't exists".format(file_path)) + if file_name is None or not path.exists(path_formatted): + raise IOError( + "File '{}{}' doesn't exists".format(file_path, file_name)) + if is_abspath: + return path.abspath(path.join(file_path, file_name)) + else: + return path.join(file_path, file_name) + + +def read_file(is_json=False, file_path=None, encoding='utf-8', + is_encoding=True, ignore_raises=False): + """Returns file object from file_path, + compatible with all py versiones + optionals: + can be use to return dict from json path + can modify encoding used to obtain file + """ + text = None + try: + if file_path is None: + raise Exception("File path received it's None") + if version_info.major >= 3: + if not is_encoding: + encoding = None + with open(file_path, encoding=encoding) as buff: + text = buff.read() + if version_info.major <= 2: + with open(file_path) as buff: + if is_encoding: + text = buff.read().decode(encoding) + else: + text = buff.read() + if is_json: + return json.loads(text) + except Exception as err: + if not ignore_raises: + raise Exception(err) + return text + + +def read(file_path='./', file_name=None, is_encoding=True, + ignore_raises=False): + """Read file""" + if file_name is None: + raise Exception("File name not provided") + return read_file( + is_encoding=is_encoding, + ignore_raises=ignore_raises, + file_path=path_format( + file_path=file_path, + file_name=file_name, + ignore_raises=ignore_raises)) + + +def settings(file_path='./', file_name='settings.json', + is_abspath=True): + """Returns file settings as a dict to be use on qacode lib""" + return read_file(is_json=True, + file_path=path_format(file_path=file_path, + file_name=file_name, + is_abspath=is_abspath)) diff --git a/tests/bots/__init__.py b/tests/bots/__init__.py new file mode 100644 index 00000000..e895d0d9 --- /dev/null +++ b/tests/bots/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests.bots""" diff --git a/tests/bots/suite_bots.py b/tests/bots/suite_bots.py new file mode 100644 index 00000000..65cbce2d --- /dev/null +++ b/tests/bots/suite_bots.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for qacode.core.bots package""" + + +import pytest +from qacode.core.bots.bot import Bot +from qacode.core.testing.asserts import Assert + +_assert = Assert() + +@pytest.mark.dependency(name="bot_create") +def test_bot_create(): + """TODO: doc method""" + bot = Bot() + _assert.equals(type(bot), Bot) + + +@pytest.mark.dependency(depends=['bot_create']) +def test_bot_browsers(): + """TODO: doc method""" + pytest.fail("Not developed yet") + + +@pytest.mark.dependency(depends=['bot_create']) +def test_bot_pages(): + """TODO: doc method""" + pytest.fail("Not developed yet") + + +@pytest.mark.dependency(depends=['bot_create']) +def test_bot_controls(): + """TODO: doc method""" + pytest.fail("Not developed yet") \ No newline at end of file diff --git a/tests/reports/__init__.py b/tests/reports/__init__.py deleted file mode 100644 index 315107c6..00000000 --- a/tests/reports/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.tests.reports""" diff --git a/tests/000_unitaries/__init__.py b/tests_old/000_unitaries/__init__.py similarity index 100% rename from tests/000_unitaries/__init__.py rename to tests_old/000_unitaries/__init__.py diff --git a/tests/000_unitaries/suite_001_config.py b/tests_old/000_unitaries/suite_001_config.py similarity index 100% rename from tests/000_unitaries/suite_001_config.py rename to tests_old/000_unitaries/suite_001_config.py diff --git a/tests/000_unitaries/suite_002_testinfobase.py b/tests_old/000_unitaries/suite_002_testinfobase.py similarity index 100% rename from tests/000_unitaries/suite_002_testinfobase.py rename to tests_old/000_unitaries/suite_002_testinfobase.py diff --git a/tests/000_unitaries/suite_003_testenumbase.py b/tests_old/000_unitaries/suite_003_testenumbase.py similarity index 100% rename from tests/000_unitaries/suite_003_testenumbase.py rename to tests_old/000_unitaries/suite_003_testenumbase.py diff --git a/tests/000_unitaries/suite_004_teststrictrules.py b/tests_old/000_unitaries/suite_004_teststrictrules.py similarity index 100% rename from tests/000_unitaries/suite_004_teststrictrules.py rename to tests_old/000_unitaries/suite_004_teststrictrules.py diff --git a/tests/001_functionals/__init__.py b/tests_old/001_functionals/__init__.py similarity index 100% rename from tests/001_functionals/__init__.py rename to tests_old/001_functionals/__init__.py diff --git a/tests/001_functionals/suite_001_botbase.py b/tests_old/001_functionals/suite_001_botbase.py similarity index 100% rename from tests/001_functionals/suite_001_botbase.py rename to tests_old/001_functionals/suite_001_botbase.py diff --git a/tests/001_functionals/suite_002_testinfobot.py b/tests_old/001_functionals/suite_002_testinfobot.py similarity index 100% rename from tests/001_functionals/suite_002_testinfobot.py rename to tests_old/001_functionals/suite_002_testinfobot.py diff --git a/tests/001_functionals/suite_003_testinfobotunique.py b/tests_old/001_functionals/suite_003_testinfobotunique.py similarity index 100% rename from tests/001_functionals/suite_003_testinfobotunique.py rename to tests_old/001_functionals/suite_003_testinfobotunique.py diff --git a/tests/001_functionals/suite_004_navbase.py b/tests_old/001_functionals/suite_004_navbase.py similarity index 100% rename from tests/001_functionals/suite_004_navbase.py rename to tests_old/001_functionals/suite_004_navbase.py diff --git a/tests/001_functionals/suite_005_controlbase.py b/tests_old/001_functionals/suite_005_controlbase.py similarity index 100% rename from tests/001_functionals/suite_005_controlbase.py rename to tests_old/001_functionals/suite_005_controlbase.py diff --git a/tests/001_functionals/suite_006_controlform.py b/tests_old/001_functionals/suite_006_controlform.py similarity index 100% rename from tests/001_functionals/suite_006_controlform.py rename to tests_old/001_functionals/suite_006_controlform.py diff --git a/tests/001_functionals/suite_007_controldropdown.py b/tests_old/001_functionals/suite_007_controldropdown.py similarity index 100% rename from tests/001_functionals/suite_007_controldropdown.py rename to tests_old/001_functionals/suite_007_controldropdown.py diff --git a/tests/001_functionals/suite_008_controltable.py b/tests_old/001_functionals/suite_008_controltable.py similarity index 100% rename from tests/001_functionals/suite_008_controltable.py rename to tests_old/001_functionals/suite_008_controltable.py diff --git a/tests/001_functionals/suite_009_pagebase.py b/tests_old/001_functionals/suite_009_pagebase.py similarity index 100% rename from tests/001_functionals/suite_009_pagebase.py rename to tests_old/001_functionals/suite_009_pagebase.py diff --git a/tests/001_functionals/suite_010_reportertestlink.py b/tests_old/001_functionals/suite_010_reportertestlink.py similarity index 100% rename from tests/001_functionals/suite_010_reportertestlink.py rename to tests_old/001_functionals/suite_010_reportertestlink.py diff --git a/tests/002_benchmarks/__init__.py b/tests_old/002_benchmarks/__init__.py similarity index 100% rename from tests/002_benchmarks/__init__.py rename to tests_old/002_benchmarks/__init__.py diff --git a/tests/002_benchmarks/suite_001_browsers.py b/tests_old/002_benchmarks/suite_001_browsers.py similarity index 100% rename from tests/002_benchmarks/suite_001_browsers.py rename to tests_old/002_benchmarks/suite_001_browsers.py diff --git a/tests_old/__init__.py b/tests_old/__init__.py new file mode 100644 index 00000000..bdfeecf1 --- /dev/null +++ b/tests_old/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests""" From 99f4f85ea4d86c8e3c62b169b31d92ff6af369a1 Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 29 Jan 2020 20:02:53 +0100 Subject: [PATCH 02/43] [qacode] pair testlink elements --- tests/documents/specification.xml | 116 ++++++++++++++++++++++++++++ tests/documents/testproject.xml | 122 ++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 tests/documents/specification.xml create mode 100644 tests/documents/testproject.xml diff --git a/tests/documents/specification.xml b/tests/documents/specification.xml new file mode 100644 index 00000000..66b08afe --- /dev/null +++ b/tests/documents/specification.xml @@ -0,0 +1,116 @@ + + + + + + + + Todos los documentos de especificacion que se pueden referenciar entre diferentes casos de uso

]]>
+
+ + + + + + Como cliente, quiero poder crear un Bot

]]>
+ + + <![CDATA[Crear un Bot]]> + 1 + 1 + 1 + Como cliente quiero poder crear un Bot

]]>
+ + + + +
+ + UC-00002 + UC-00001 + 3 + + + UC-00001 + UC-00003 + 2 + + + UC-00001 + UC-00004 + 2 + +
+ + + + + + Como cliente quiero poder listar todos los navegadores en un Bot

]]>
+ + + <![CDATA[Listar navegadores en un Bot]]> + 1 + 2 + 1 + + + + + + + + UC-00002 + UC-00001 + 3 + +
+ + + + + + Como cliente quiero poder listar todos las páginas en un Bot

]]>
+ + + <![CDATA[Listar paginas en un Bot]]> + 1 + 2 + 1 + + + + + + + + UC-00001 + UC-00003 + 2 + +
+ + + + + + Como cliente quiero poder listar todos los controles en un Bot

]]>
+ + + <![CDATA[Listar controles en un Bot]]> + 1 + 3 + 1 + + + + + + + + UC-00001 + UC-00004 + 2 + +
+
diff --git a/tests/documents/testproject.xml b/tests/documents/testproject.xml new file mode 100644 index 00000000..978ca0f7 --- /dev/null +++ b/tests/documents/testproject.xml @@ -0,0 +1,122 @@ + + + +
+ + +
+ + + + + + + Como cliente quiero crear un Bot

+]]>
+ Un servidor remoto de selenium que permita abrir navegadores

+]]>
+ + + + 1 + 1 + 1 + + + + Generar un objeto de la clase Bot

+]]>
+ Sin errores de sintaxis
+El objeto es del tipo de clase esperado

+]]>
+ +
+
+ + + + + + <![CDATA[Crear un Bot]]> + + +
+ + + + + + + Como cliente quiero listar navegadores en un Bot

+]]>
+ Un servidor remoto de selenium que permita abrir navegadores

+]]>
+ + + + 1 + 1 + 1 + + + + + + + <![CDATA[Listar navegadores en un Bot]]> + + +
+ + + + + + + Como cliente quiero listar navegadores en un Bot

+]]>
+ Un servidor remoto de selenium que permita abrir navegadores

+]]>
+ + + + 1 + 1 + 1 + + + + + + + <![CDATA[Listar paginas en un Bot]]> + + +
+ + + + + + + Como cliente quiero listar navegadores en un Bot

+]]>
+ Un servidor remoto de selenium que permita abrir navegadores

+]]>
+ + + + 1 + 1 + 1 + + + + + + + <![CDATA[Listar controles en un Bot]]> + + +
+
\ No newline at end of file From 5e7abef064ee9da80346b2b0cd708b21cd82d8fa Mon Sep 17 00:00:00 2001 From: netzulo Date: Sat, 1 Feb 2020 23:01:53 +0100 Subject: [PATCH 03/43] [qacode] update test bots+ added tests browsers --- qacode/configs/settings.json | 133 +++-------------------- qacode/core/__init__.py | 10 +- qacode/core/bots/bot.py | 50 +++++++++ qacode/core/bots/bot_config.py | 46 ++++++++ qacode/core/browsers/browser.py | 96 ++++++++++++++++ qacode/core/browsers/browser_config.py | 30 +++++ qacode/core/exceptions/core_exception.py | 54 +++++++++ qacode/core/loggers/log.py | 80 ++++++++++++++ tests/bots/suite_bots.py | 18 ++- tests/browsers/__init__.py | 2 + tests/browsers/suite_browsers.py | 19 ++++ 11 files changed, 417 insertions(+), 121 deletions(-) create mode 100644 qacode/core/bots/bot_config.py create mode 100644 qacode/core/browsers/browser_config.py create mode 100644 qacode/core/exceptions/core_exception.py create mode 100644 qacode/core/loggers/log.py create mode 100644 tests/browsers/__init__.py create mode 100644 tests/browsers/suite_browsers.py diff --git a/qacode/configs/settings.json b/qacode/configs/settings.json index 511b2dc2..5504abab 100644 --- a/qacode/configs/settings.json +++ b/qacode/configs/settings.json @@ -1,29 +1,19 @@ -{ "bot": { - "log_output_file": "logs/", - "log_name": "qacode", - "log_level": "INFO", - "mode": "remote", - "browser": "chrome", - "options": { "headless": false }, - "url_hub": "http://netzulo.tk:11000/wd/hub", +{ + "log":{ + "path": "logs/", "name": "qacode", "level": "INFO" + }, + "bot":{ "drivers_path": "../qadrivers", - "drivers_names": [ - "chromedriver_32.exe", - "chromedriver_64.exe", - "chromedriver_32", - "chromedriver_64", - "firefoxdriver_32.exe", - "firefoxdriver_64.exe", - "firefoxdriver_64", - "firefoxdriver_32", - "iexplorerdriver_32.exe", - "iexplorerdriver_64.exe", - "edgedriver_32.exe", - "edgedriver_64.exe", - "operadriver_32.exe", - "operadriver_64.exe", - "operadriver_32", - "operadriver_64" + "drivers_names": { + "chrome": "chromedriver_64.exe", + "firefox": "firefoxdriver_64.exe", + "opera": "operadriver_64.exe", + "iexplorer": "iexplorerdriver_64.exe", + "edge": "edgedriver_64.exe" + }, + "browsers": [ + {"browser": "chrome", "mode": "remote", "options": {"headless": false}}, + {"browser": "chrome", "mode": "local", "options": {"headless": false}} ] }, "testlink": { @@ -34,96 +24,5 @@ }, "dev_key": "1bfd2ef4ceda22b482b12f2b25457495", "log_level":"INFO" - }, - "tests": { - "skip":{ - "test_configs": true, - "browsers": { - "chrome": {"local":true, "remote":false}, - "firefox": {"local":true, "remote":true}, - "iexplorer": {"local":true, "remote":true}, - "edge": {"local":true, "remote":true}, - "opera": {"local":true, "remote":false} - }, - "bot_multiple": false, - "bot_unique": false, - "bot_navigations": false, - "web_controls": { - "control_base": false, - "control_form": false, - "control_dropdown": false, - "control_table": false - }, - "web_pages": false, - "benchmarks": true - }, - "apps": [ - { "name": "qadmin", - "pages": [ - { "name": "qacode_login", - "url": "http://netzulo.tk:83/qacode/login", - "locator": "css selector", - "go_url": false, - "wait_url": 0, - "maximize": false, - "controls": [ - { "name": "form_login", "selector": "#frmLogin", "on_instance_search": true, "on_instance_load": false }, - { "name": "txt_username", "selector": "#txtUsername-field", "on_instance_search": true, "on_instance_load": false }, - { "name": "txt_password", "selector": "#txtPassword-field", "on_instance_search": true, "on_instance_load": false }, - { "name": "btn_submit", "selector": "#btnLogin", "on_instance_search": true, "on_instance_load": false } - ] - }, - { "name": "qacode_lists", - "url": "http://netzulo.tk:83/qacode/data/lists", - "locator": "css selector", - "go_url": false, - "wait_url": 0, - "maximize": false, - "controls": [ - { "name": "lst_ordered", "selector": "ol:nth-child(1)"}, - { "name": "lst_ordered_child", "selector": "li"}, - { "name": "dd_menu_data", "selector": "#ddData"}, - { "name": "dd_menu_data_lists", "selector": "a[href='/qacode/data/lists']"}, - { "name": "tbl_ok", "selector": "#tblOk"}, - { "name": "tbl_html5_ok", "selector": "#tblHtml5Ok"}, - { "name": "tbl_html_tbodies_ok", "selector": "#tblHtml5OkTbodies"} - ] - }, - { "name": "qacode_inputs", - "url": "http://netzulo.tk:83/qacode/forms/inputs", - "locator": "css selector", - "go_url": false, - "wait_url": 0, - "maximize": false, - "controls": [ - { "name": "dd_base", "selector": "#txtTest002", "instance": "ControlForm", - "strict_rules": [ - { "tag": "select", "type": "tag", "severity": "hight" } - ] - }, - { "name": "dd_multiple", "selector": "#txtTest003", "instance": "ControlForm", - "strict_rules": [ - { "tag": "select", "type": "tag", "severity": "hight" } - ] - }, - { "name": "btn_click_invisible", "selector": "#btnInvisibleAtTimeout" }, - { "name": "btn_click_visible", "selector": "#btnVisibleAtTimeout" }, - { "name": "title_buttons", "selector": "#titleButtons" } - ] - }, - { "name": "qacode_logout", - "url": "http://netzulo.tk:83/qacode/logout", - "locator": "css selector", - "go_url": true, - "wait_url": 0, - "maximize": false, - "controls": [ - { "name": "btn_logout", "selector": "a[href='/qacode/logout']" }, - { "name": "btn_login", "selector": "a[href='/qacode/login']" } - ] - } - ] - } - ] } -} \ No newline at end of file +} diff --git a/qacode/core/__init__.py b/qacode/core/__init__.py index a2a00672..16036759 100755 --- a/qacode/core/__init__.py +++ b/qacode/core/__init__.py @@ -5,8 +5,16 @@ from qacode.core import bots from qacode.core import browsers from qacode.core import controls +from qacode.core import loggers from qacode.core import pages from qacode.core import testing -__all__ = ['bots', 'browsers', 'controls', 'pages', 'testing'] +__all__ = [ + 'bots', + 'browsers', + 'controls', + 'loggers', + 'pages', + 'testing', +] diff --git a/qacode/core/bots/bot.py b/qacode/core/bots/bot.py index b7a3ce5a..6abab7f8 100644 --- a/qacode/core/bots/bot.py +++ b/qacode/core/bots/bot.py @@ -2,6 +2,11 @@ """TODO""" +from qacode.core.bots.bot_config import BotConfig +from qacode.core.browsers.browser import Browser +from qacode.core.loggers.log import Log + + class Bot(object): """Class Base for handle selenium functionality throught this wrapper""" @@ -10,6 +15,23 @@ def __init__(self, **kwargs): self._browsers = [] self._pages = [] self._controls = [] + self._config = self.__config__(kwargs) + self._log = Log(**{ + "name": self._config.log_name, + "path": self._config.log_path, + "level": self._config.log_level}) + + def __config__(self, config): + """TODO: doc method""" + _config = None + if config is None: + raise Exception("Can't create browser without configuration") + if isinstance(config, BotConfig): + return config + elif isinstance(config, dict): + return BotConfig(**config) + else: + raise Exception("Just accepted types: dict, BotConfig") def browser(self, session_id): """TODO: doc method""" @@ -32,6 +54,29 @@ def control(self, selector): return control raise Exception("control not found") + def browser_create(self, config): + """TODO: doc method""" + driver_name = self._config.drivers_names[config.get("browser")] + driver_path = self._config.drivers_path + _config = config.copy() + _config.update({ + "driver_path": driver_path, "driver_name": driver_name}) + browser = Browser(self.log, **_config) + import pdb; pdb.set_trace() + self._browsers.append(browser) + return browser + + @property + def config(self): + """TODO: doc method""" + return self._config + + @config.setter + def config(self, value): + """TODO: doc method""" + self._config = self.__config__(value) + + @property def browsers(self): """TODO: doc method""" @@ -61,3 +106,8 @@ def controls(self): def controls(self, value): """TODO: doc method""" self._controls = value + + @property + def log(self): + """TODO: doc method""" + return self._log \ No newline at end of file diff --git a/qacode/core/bots/bot_config.py b/qacode/core/bots/bot_config.py new file mode 100644 index 00000000..50d36e51 --- /dev/null +++ b/qacode/core/bots/bot_config.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +class BotConfig(object): + """TODO: doc class""" + + def __init__(self,**kwargs): + """TODO: doc method + Note1: musn't check win/lin 32/64, use must now + """ + self._log = kwargs.get("log") + self._bot = kwargs.get("bot") + # self._testlink = kwargs.get("testlink") + + @property + def log_name(self): + return self._log.get("name") + + @property + def log_path(self): + return self._log.get("path") + + @property + def log_level(self): + return self._log.get("level") + + @property + def drivers_path(self): + return self._bot.get("drivers_path") + + @property + def drivers_names(self): + return self._bot.get("drivers_names") + + @property + def browsers(self): + return self._bot.get("browsers") + + @property + def pages(self): + return self._bot.get("pages") + + @property + def controls(self): + return self._bot.get("controls") \ No newline at end of file diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py index e69de29b..34a8386d 100644 --- a/qacode/core/browsers/browser.py +++ b/qacode/core/browsers/browser.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +import os +import sys +from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.exceptions.core_exception import CoreException +from qacode.core.loggers.log import Log +from selenium.webdriver import DesiredCapabilities + + +class Browser(object): + """TODO: doc class""" + + def __init__(self, log, **kwargs): + """TODO: doc method""" + self._log = log + self._config = self.__config__(kwargs) + self._driver = None + self._capabilities = self.__capabilities__() + self._driver_abs_path = self.__driver_abs_path__() + + def __config__(self, config): + """TODO: doc method""" + _config = None + if config is None: + raise Exception("Can't create browser without configuration") + if isinstance(config, BrowserConfig): + return config + elif isinstance(config, dict): + return BrowserConfig(**config) + else: + raise Exception("Just accepted types: dict, BrowserConfig") + + def __capabilities__(self): + """TODO: doc method""" + capabilities = None + try: + capabilities = { + "chrome": DesiredCapabilities.CHROME.copy(), + "firefox": DesiredCapabilities.FIREFOX.copy(), + "iexplorer": DesiredCapabilities.INTERNETEXPLORER.copy(), + "edge": DesiredCapabilities.EDGE.copy(), + }[self._config.browser] + except KeyError: + msg = 'Bad browser selected at load options' + raise CoreException(msg, log=self._log) + return capabilities + + def __driver_abs_path__(self): + """TODO: doc method""" + driver_path = "{}/{}".format( + self._config.driver_path, self._config.driver_name) + abs_path = os.path.abspath(driver_path) + sys.path.append(abs_path) + return abs_path + + def open(self): + """TODO: doc method""" + # based on mode use or not drivers path + # get capabilities + # bassed on browser get options or not + # others webdrivers ? + raise NotImplementedError("WIP code") + + def close(self): + """TODO: doc method""" + # try to call selenium driver.quit + # try to call selenium driver.close + raise NotImplementedError("WIP code") + + @property + def config(self): + """TODO: doc method""" + return self._config + + @config.setter + def config(self, value): + """TODO: doc method""" + self._config = self.__config__(value) + + @property + def capabilities(self): + """TODO: doc method""" + return self.__capabilities__() + + @property + def driver_abs_path(self): + """TODO: doc method""" + return self.__driver_abs_path__() + + @property + def session_id(self): + """TODO: doc method""" + return self._driver.session_id diff --git a/qacode/core/browsers/browser_config.py b/qacode/core/browsers/browser_config.py new file mode 100644 index 00000000..5c9f5677 --- /dev/null +++ b/qacode/core/browsers/browser_config.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +class BrowserConfig(object): + """TODO: doc class""" + + def __init__(self, **kwargs): + """TODO: doc method""" + self._config = kwargs + + @property + def browser(self): + return self._config.get("browser") + + @property + def mode(self): + return self._config.get("mode") + + @property + def options(self): + return self._config.get("options") + + @property + def driver_path(self): + return self._config.get("driver_path") + + @property + def driver_name(self): + return self._config.get("driver_name") diff --git a/qacode/core/exceptions/core_exception.py b/qacode/core/exceptions/core_exception.py new file mode 100644 index 00000000..bc09a9eb --- /dev/null +++ b/qacode/core/exceptions/core_exception.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +"""Main Exceptions for qacode library""" + + +from qacode.core.loggers.log import Log +from selenium.common.exceptions import WebDriverException + + +NOT_MSG = 'Exception without message' + + +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}) + """ + raise NotImplementedError("WIP: pending refactor all class") + 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) diff --git a/qacode/core/loggers/log.py b/qacode/core/loggers/log.py new file mode 100644 index 00000000..1c33c0d9 --- /dev/null +++ b/qacode/core/loggers/log.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +"""Module related with all logging tasks""" + + +from logging import ( + FileHandler, Formatter, INFO, StreamHandler, getLogger) +from qacode.utils import path_format + + +class Log(object): + """Manager for logger""" + + # ATTRIBUTES + _name = None + _name_file = None + _path = None + _path_join = None + _level = None + _formatter = None + _logger = None + + def __init__(self, *args, **kwargs): + """TODO: doc method""" + self._name = kwargs.get('name') or "qacode" + self._name_file = "{}.log".format(self._name) + self._path = kwargs.get('path') or './logs/' + self._path_join = path_format( + file_path=self._path, file_name=self._name_file) + self._level = kwargs.get('level') or INFO + + self._formatter = Formatter( + ("[pid:%(process)d][%(asctime)s][%(name)s]" + "[%(levelname)s]: %(message)s")) + self._handlers = self.__handlers__() or {} + self.__logger__() + + def __logger__(self): + """TODO: doc method""" + self._logger = getLogger(self._name) + self._logger.setLevel(self._level) + # Remove handlers added to logging module + for old_handler in self._logger.handlers: + self._logger.removeHandler(old_handler) + # Add new handlers + if not self._logger.handlers: + self._logger.addHandler(self._handlers['console']) + self._logger.addHandler(self._handlers['file']) + + def __handlers__(self): + """TODO: doc method""" + handlers = [StreamHandler(), FileHandler(self._path_join)] + for handler in handlers: + handler.setFormatter(self._formatter) + handler.setLevel(self._level) + return { + "console": handlers[0], + "file": handlers[1], + } + + # PUBLIC METHODS + + def debug(self, msg): + """TODO: doc method""" + self._logger.debug(msg) + + def info(self, msg): + """TODO: doc method""" + self._logger.info(msg) + + def warning(self, msg): + """TODO: doc method""" + self._logger.warning(msg) + + def error(self, msg): + """TODO: doc method""" + self._logger.warning(msg) + + def critical(self, msg): + """TODO: doc method""" + self._logger.critical(msg) diff --git a/tests/bots/suite_bots.py b/tests/bots/suite_bots.py index 65cbce2d..749da7f1 100644 --- a/tests/bots/suite_bots.py +++ b/tests/bots/suite_bots.py @@ -4,15 +4,20 @@ import pytest from qacode.core.bots.bot import Bot +from qacode.core.browsers.browser import Browser from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") -_assert = Assert() @pytest.mark.dependency(name="bot_create") def test_bot_create(): """TODO: doc method""" bot = Bot() - _assert.equals(type(bot), Bot) + ASSERT.is_instance(bot, Bot) @pytest.mark.dependency(depends=['bot_create']) @@ -30,4 +35,11 @@ def test_bot_pages(): @pytest.mark.dependency(depends=['bot_create']) def test_bot_controls(): """TODO: doc method""" - pytest.fail("Not developed yet") \ No newline at end of file + pytest.fail("Not developed yet") + +@pytest.mark.dependency(name="bot_browser_create", depends=['bot_create']) +def test_bot_browser_create(): + """TODO: doc method""" + bot = Bot(**CFG) + browser = bot.browser_create(bot.config.browsers[0]) + ASSERT.is_instance(browser, Browser) diff --git a/tests/browsers/__init__.py b/tests/browsers/__init__.py new file mode 100644 index 00000000..db8bf780 --- /dev/null +++ b/tests/browsers/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests.browsers""" diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py new file mode 100644 index 00000000..1e6e03c7 --- /dev/null +++ b/tests/browsers/suite_browsers.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for qacode.core.bots package""" + + +import pytest +from qacode.core.bots.bot import Bot +from qacode.core.browsers.browser import Browser +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + +@pytest.mark.dependency(name="bot_browser_create", depends=['bot_create']) +def test_bot_browser_create(): + """TODO: doc method""" + browser = Browser(**CFG) + ASSERT.is_instance(browser, Browser) From 5e81fd3da39ff5ecb138ca7ae51b5cb9b77b9875 Mon Sep 17 00:00:00 2001 From: netzulo Date: Sun, 2 Feb 2020 23:25:32 +0100 Subject: [PATCH 04/43] [qacode] more update tests bots+browsers + now can open some browsers --- qacode/configs/settings.json | 5 +- qacode/core/bots/bot.py | 5 +- qacode/core/bots/bot_config.py | 6 +- qacode/core/browsers/browser.py | 112 +++++++++++++++++++++-- qacode/core/browsers/browser_config.py | 4 + qacode/core/exceptions/core_exception.py | 62 ++++++------- tests/bots/suite_bots.py | 3 +- tests/browsers/suite_browsers.py | 26 +++++- 8 files changed, 177 insertions(+), 46 deletions(-) diff --git a/qacode/configs/settings.json b/qacode/configs/settings.json index 5504abab..84338e5c 100644 --- a/qacode/configs/settings.json +++ b/qacode/configs/settings.json @@ -3,6 +3,7 @@ "path": "logs/", "name": "qacode", "level": "INFO" }, "bot":{ + "hub_url": "http://localhost:11000/wd/hub", "drivers_path": "../qadrivers", "drivers_names": { "chrome": "chromedriver_64.exe", @@ -14,7 +15,9 @@ "browsers": [ {"browser": "chrome", "mode": "remote", "options": {"headless": false}}, {"browser": "chrome", "mode": "local", "options": {"headless": false}} - ] + ], + "pages": [], + "controls": [] }, "testlink": { "connection":{ diff --git a/qacode/core/bots/bot.py b/qacode/core/bots/bot.py index 6abab7f8..fd8dab20 100644 --- a/qacode/core/bots/bot.py +++ b/qacode/core/bots/bot.py @@ -60,9 +60,10 @@ def browser_create(self, config): driver_path = self._config.drivers_path _config = config.copy() _config.update({ - "driver_path": driver_path, "driver_name": driver_name}) + "driver_path": driver_path, + "driver_name": driver_name, + "hub_url": self._config.hub_url}) browser = Browser(self.log, **_config) - import pdb; pdb.set_trace() self._browsers.append(browser) return browser diff --git a/qacode/core/bots/bot_config.py b/qacode/core/bots/bot_config.py index 50d36e51..d381cbc8 100644 --- a/qacode/core/bots/bot_config.py +++ b/qacode/core/bots/bot_config.py @@ -43,4 +43,8 @@ def pages(self): @property def controls(self): - return self._bot.get("controls") \ No newline at end of file + return self._bot.get("controls") + + @property + def hub_url(self): + return self._bot.get("hub_url") diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py index 34a8386d..8ab1f973 100644 --- a/qacode/core/browsers/browser.py +++ b/qacode/core/browsers/browser.py @@ -7,7 +7,14 @@ from qacode.core.browsers.browser_config import BrowserConfig from qacode.core.exceptions.core_exception import CoreException from qacode.core.loggers.log import Log +from selenium.webdriver import (Chrome, Firefox, Ie, Edge) from selenium.webdriver import DesiredCapabilities +from selenium.webdriver.chrome.options import Options as ChromeOptions +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.touch_actions import TouchActions +from selenium.webdriver.firefox.options import Options as FirefoxOptions +from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver +from selenium.webdriver.support.ui import WebDriverWait class Browser(object): @@ -17,9 +24,10 @@ def __init__(self, log, **kwargs): """TODO: doc method""" self._log = log self._config = self.__config__(kwargs) - self._driver = None self._capabilities = self.__capabilities__() + self._options = self.__options__() self._driver_abs_path = self.__driver_abs_path__() + self._driver = None def __config__(self, config): """TODO: doc method""" @@ -56,13 +64,90 @@ def __driver_abs_path__(self): sys.path.append(abs_path) return abs_path + def __options__(self): + """TODO: doc method""" + is_headless = self._config.options.get("headless") + try: + options = { + "chrome": ChromeOptions(), + "firefox": FirefoxOptions(), + }[self._config.browser] + except KeyError: + # this browser hasn't options + pass + if is_headless: + options.add_argument("--headless") + return options + + def __driver_local__(self): + """TODO: doc method""" + driver = None + try: + driver = { + "chrome": Chrome, + "firefox": Firefox, + "iexplorer": Ie, + "edge": Edge + }[self._config.browser] + except KeyError: + msg = ("Just browser names allowed: " + "chrome, firefox, iexplorer, edge") + raise Exception(msg) + return driver + + def __driver_remote__(self): + """TODO: doc method""" + return RemoteWebDriver + + def __open_local__(self): + """TODO: doc method""" + driver_class = self.__driver_local__() + try: + driver = driver_class( + executable_path=self.driver_abs_path, + capabilities=self.capabilities, + options=self.options) + return driver + except (AttributeError) as err: + raise Exception(str(err)) + + def __open_remote__(self): + """TODO: doc method""" + driver_class = self.__driver_remote__() + try: + import pdb; pdb.set_trace() + driver = driver_class( + command_executor=self._config.hub_url, + desired_capabilities=self.capabilities, + options=self.options) + return driver + except (AttributeError) as err: + if err.args[0] == "'NoneType' object has no attribute 'execute'": + raise Exception( + "Check if hub it's running at: {}".format( + self._config.hub_url)) + raise Exception(str(err)) + + def __drivers_selenium__(self): + """TODO: doc method""" + self._driver_wait = WebDriverWait(self.curr_driver, 10) + self._driver_actions = ActionChains(self.curr_driver) + self._driver_touch = TouchActions(self.curr_driver) + + def __drivers_modules__(self): + """TODO: doc method""" + self._navs = {} + def open(self): """TODO: doc method""" - # based on mode use or not drivers path - # get capabilities - # bassed on browser get options or not - # others webdrivers ? - raise NotImplementedError("WIP code") + if self._config.mode == "local": + self._driver = self.__open_local__() + elif self._config.mode == "remote": + self._driver = self.__open_remote__() + else: + raise Exception("Just allowed modes: local, remote") + self.__drivers_selenium__() + self.__drivers_modules__() def close(self): """TODO: doc method""" @@ -85,11 +170,26 @@ def capabilities(self): """TODO: doc method""" return self.__capabilities__() + @property + def options(self): + """TODO: doc method""" + return self.__options__() + @property def driver_abs_path(self): """TODO: doc method""" return self.__driver_abs_path__() + @property + def driver(self): + """TODO: doc method""" + return self._driver + + @property + def navs(self): + """TODO: doc method""" + return self._navs + @property def session_id(self): """TODO: doc method""" diff --git a/qacode/core/browsers/browser_config.py b/qacode/core/browsers/browser_config.py index 5c9f5677..cbfe046f 100644 --- a/qacode/core/browsers/browser_config.py +++ b/qacode/core/browsers/browser_config.py @@ -28,3 +28,7 @@ def driver_path(self): @property def driver_name(self): return self._config.get("driver_name") + + @property + def hub_url(self): + return self._config.get("hub_url") diff --git a/qacode/core/exceptions/core_exception.py b/qacode/core/exceptions/core_exception.py index bc09a9eb..f5d108a8 100644 --- a/qacode/core/exceptions/core_exception.py +++ b/qacode/core/exceptions/core_exception.py @@ -21,34 +21,34 @@ def __init__(self, msg=NOT_MSG, log=None, info_bot=None): info_bot {dict} -- Qacode+Selenium information (default: {None}) """ raise NotImplementedError("WIP: pending refactor all class") - 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) +# 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) diff --git a/tests/bots/suite_bots.py b/tests/bots/suite_bots.py index 749da7f1..7219bbaa 100644 --- a/tests/bots/suite_bots.py +++ b/tests/bots/suite_bots.py @@ -16,7 +16,7 @@ @pytest.mark.dependency(name="bot_create") def test_bot_create(): """TODO: doc method""" - bot = Bot() + bot = Bot(**CFG) ASSERT.is_instance(bot, Bot) @@ -37,6 +37,7 @@ def test_bot_controls(): """TODO: doc method""" pytest.fail("Not developed yet") + @pytest.mark.dependency(name="bot_browser_create", depends=['bot_create']) def test_bot_browser_create(): """TODO: doc method""" diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index 1e6e03c7..e8faa6bd 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -3,17 +3,35 @@ import pytest -from qacode.core.bots.bot import Bot from qacode.core.browsers.browser import Browser +from qacode.core.loggers.log import Log from qacode.core.testing.asserts import Assert from qacode.utils import settings ASSERT = Assert() CFG = settings(file_path="qacode/configs/", file_name="settings.json") +BROWSERS = CFG.get('bot').get('browsers') +HUB_URL = CFG.get("bot").get("hub_url") +LOG = Log(**CFG.get('log')) -@pytest.mark.dependency(name="bot_browser_create", depends=['bot_create']) -def test_bot_browser_create(): + +def config_browser_remote(): + """TODO: doc method""" + cfg = BROWSERS[0] + cfg.update({"hub_url": HUB_URL}) + return cfg + + +@pytest.mark.dependency(name="browser_create") +def test_browser_create(): """TODO: doc method""" - browser = Browser(**CFG) + browser = Browser(LOG, **config_browser_remote()) ASSERT.is_instance(browser, Browser) + + +@pytest.mark.dependency(name="browser_open", depends=['browser_create']) +def test_browser_open(): + """TODO: doc method""" + browser = Browser(LOG, **config_browser_remote()) + browser.open() From 3aebafeadae552738f28d9c7adf438ead3a40783 Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 3 Feb 2020 00:10:22 +0100 Subject: [PATCH 05/43] [qacode] fix flake errors --- qacode/core/bots/bot.py | 8 ++-- qacode/core/bots/bot_config.py | 21 ++++++++--- qacode/core/browsers/browser.py | 48 ++++++++++++------------ qacode/core/browsers/browser_config.py | 8 +++- qacode/core/controls/control.py | 2 + qacode/core/exceptions/core_exception.py | 4 +- qacode/core/pages/page.py | 2 + qacode/core/testing/asserts.py | 12 +++--- tests/browsers/suite_browsers.py | 30 +++++++++++++++ 9 files changed, 92 insertions(+), 43 deletions(-) diff --git a/qacode/core/bots/bot.py b/qacode/core/bots/bot.py index fd8dab20..fba3ba7d 100644 --- a/qacode/core/bots/bot.py +++ b/qacode/core/bots/bot.py @@ -23,7 +23,6 @@ def __init__(self, **kwargs): def __config__(self, config): """TODO: doc method""" - _config = None if config is None: raise Exception("Can't create browser without configuration") if isinstance(config, BotConfig): @@ -77,7 +76,6 @@ def config(self, value): """TODO: doc method""" self._config = self.__config__(value) - @property def browsers(self): """TODO: doc method""" @@ -87,7 +85,7 @@ def browsers(self): def browsers(self, value): """TODO: doc method""" self._browsers = value - + @property def pages(self): """TODO: doc method""" @@ -97,7 +95,7 @@ def pages(self): def pages(self, value): """TODO: doc method""" self._pages = value - + @property def controls(self): """TODO: doc method""" @@ -111,4 +109,4 @@ def controls(self, value): @property def log(self): """TODO: doc method""" - return self._log \ No newline at end of file + return self._log diff --git a/qacode/core/bots/bot_config.py b/qacode/core/bots/bot_config.py index d381cbc8..43b42d4a 100644 --- a/qacode/core/bots/bot_config.py +++ b/qacode/core/bots/bot_config.py @@ -5,7 +5,7 @@ class BotConfig(object): """TODO: doc class""" - def __init__(self,**kwargs): + def __init__(self, **kwargs): """TODO: doc method Note1: musn't check win/lin 32/64, use must now """ @@ -15,36 +15,45 @@ def __init__(self,**kwargs): @property def log_name(self): + """TODO: doc method""" return self._log.get("name") - + @property def log_path(self): + """TODO: doc method""" return self._log.get("path") - + @property def log_level(self): + """TODO: doc method""" return self._log.get("level") @property def drivers_path(self): + """TODO: doc method""" return self._bot.get("drivers_path") - + @property def drivers_names(self): + """TODO: doc method""" return self._bot.get("drivers_names") @property def browsers(self): + """TODO: doc method""" return self._bot.get("browsers") @property def pages(self): + """TODO: doc method""" return self._bot.get("pages") - + @property def controls(self): + """TODO: doc method""" return self._bot.get("controls") - + @property def hub_url(self): + """TODO: doc method""" return self._bot.get("hub_url") diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py index 8ab1f973..4ff5ab68 100644 --- a/qacode/core/browsers/browser.py +++ b/qacode/core/browsers/browser.py @@ -6,8 +6,9 @@ import sys from qacode.core.browsers.browser_config import BrowserConfig from qacode.core.exceptions.core_exception import CoreException -from qacode.core.loggers.log import Log -from selenium.webdriver import (Chrome, Firefox, Ie, Edge) +# from qacode.core.loggers.log import Log +from selenium.common.exceptions import SessionNotCreatedException +from selenium.webdriver import (Chrome, Edge, Firefox, Ie) from selenium.webdriver import DesiredCapabilities from selenium.webdriver.chrome.options import Options as ChromeOptions from selenium.webdriver.common.action_chains import ActionChains @@ -31,7 +32,6 @@ def __init__(self, log, **kwargs): def __config__(self, config): """TODO: doc method""" - _config = None if config is None: raise Exception("Can't create browser without configuration") if isinstance(config, BrowserConfig): @@ -72,12 +72,12 @@ def __options__(self): "chrome": ChromeOptions(), "firefox": FirefoxOptions(), }[self._config.browser] + if is_headless: + options.add_argument("--headless") + return options except KeyError: # this browser hasn't options - pass - if is_headless: - options.add_argument("--headless") - return options + return None def __driver_local__(self): """TODO: doc method""" @@ -98,7 +98,7 @@ def __driver_local__(self): def __driver_remote__(self): """TODO: doc method""" return RemoteWebDriver - + def __open_local__(self): """TODO: doc method""" driver_class = self.__driver_local__() @@ -115,13 +115,12 @@ def __open_remote__(self): """TODO: doc method""" driver_class = self.__driver_remote__() try: - import pdb; pdb.set_trace() driver = driver_class( command_executor=self._config.hub_url, desired_capabilities=self.capabilities, options=self.options) return driver - except (AttributeError) as err: + except (AttributeError, SessionNotCreatedException) as err: if err.args[0] == "'NoneType' object has no attribute 'execute'": raise Exception( "Check if hub it's running at: {}".format( @@ -130,13 +129,13 @@ def __open_remote__(self): def __drivers_selenium__(self): """TODO: doc method""" - self._driver_wait = WebDriverWait(self.curr_driver, 10) - self._driver_actions = ActionChains(self.curr_driver) - self._driver_touch = TouchActions(self.curr_driver) + self._driver_wait = WebDriverWait(self._driver, 10) + self._driver_actions = ActionChains(self._driver) + self._driver_touch = TouchActions(self._driver) def __drivers_modules__(self): """TODO: doc method""" - self._navs = {} + self._modules = {} def open(self): """TODO: doc method""" @@ -151,9 +150,12 @@ def open(self): def close(self): """TODO: doc method""" - # try to call selenium driver.quit - # try to call selenium driver.close - raise NotImplementedError("WIP code") + self.driver.quit() + self._driver = None + self._driver_wait = None + self._driver_actions = None + self._driver_touch = None + self._modules = None @property def config(self): @@ -164,17 +166,17 @@ def config(self): def config(self, value): """TODO: doc method""" self._config = self.__config__(value) - + @property def capabilities(self): """TODO: doc method""" return self.__capabilities__() - + @property def options(self): """TODO: doc method""" return self.__options__() - + @property def driver_abs_path(self): """TODO: doc method""" @@ -184,11 +186,11 @@ def driver_abs_path(self): def driver(self): """TODO: doc method""" return self._driver - + @property - def navs(self): + def modules(self): """TODO: doc method""" - return self._navs + return self._modules @property def session_id(self): diff --git a/qacode/core/browsers/browser_config.py b/qacode/core/browsers/browser_config.py index cbfe046f..252b0cb5 100644 --- a/qacode/core/browsers/browser_config.py +++ b/qacode/core/browsers/browser_config.py @@ -11,24 +11,30 @@ def __init__(self, **kwargs): @property def browser(self): + """TODO: doc method""" return self._config.get("browser") @property def mode(self): + """TODO: doc method""" return self._config.get("mode") @property def options(self): + """TODO: doc method""" return self._config.get("options") @property def driver_path(self): + """TODO: doc method""" return self._config.get("driver_path") @property def driver_name(self): + """TODO: doc method""" return self._config.get("driver_name") - + @property def hub_url(self): + """TODO: doc method""" return self._config.get("hub_url") diff --git a/qacode/core/controls/control.py b/qacode/core/controls/control.py index e69de29b..6513fe92 100644 --- a/qacode/core/controls/control.py +++ b/qacode/core/controls/control.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""TODO: doc module""" diff --git a/qacode/core/exceptions/core_exception.py b/qacode/core/exceptions/core_exception.py index f5d108a8..e9e1ab4c 100644 --- a/qacode/core/exceptions/core_exception.py +++ b/qacode/core/exceptions/core_exception.py @@ -2,8 +2,8 @@ """Main Exceptions for qacode library""" -from qacode.core.loggers.log import Log -from selenium.common.exceptions import WebDriverException +# from qacode.core.loggers.log import Log +# from selenium.common.exceptions import WebDriverException NOT_MSG = 'Exception without message' diff --git a/qacode/core/pages/page.py b/qacode/core/pages/page.py index e69de29b..6513fe92 100644 --- a/qacode/core/pages/page.py +++ b/qacode/core/pages/page.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""TODO: doc module""" diff --git a/qacode/core/testing/asserts.py b/qacode/core/testing/asserts.py index 17c6bc79..c8091ce2 100644 --- a/qacode/core/testing/asserts.py +++ b/qacode/core/testing/asserts.py @@ -198,20 +198,20 @@ def path_not_exist(self, actual, msg=None): def true(self, actual, msg=None): """Allow to compare and check if value it's equals to 'True'""" - self.assert_is_instance(actual, bool) - self.assert_equals(actual, True, msg=msg) + self.is_instance(actual, bool) + self.equals(actual, True, msg=msg) return True def false(self, actual, msg=None): """Allow to compare and check if value it's equals to 'False'""" - self.assert_is_instance(actual, bool) - self.assert_equals(actual, False, msg=msg) + self.is_instance(actual, bool) + self.equals(actual, False, msg=msg) return True def none(self, actual, msg=None): """Allow to compare and check if value it's equals to 'None'""" - return self.assert_equals(actual, None, msg=msg) + return self.equals(actual, None, msg=msg) def not_none(self, actual, msg=None): """Allow to compare and check if value it's not equals to 'None'""" - return self.assert_not_equals(actual, None, msg=msg) \ No newline at end of file + return self.not_equals(actual, None, msg=msg) diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index e8faa6bd..0093eb2c 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -4,6 +4,7 @@ import pytest from qacode.core.browsers.browser import Browser +from qacode.core.browsers.browser_config import BrowserConfig from qacode.core.loggers.log import Log from qacode.core.testing.asserts import Assert from qacode.utils import settings @@ -23,11 +24,20 @@ def config_browser_remote(): return cfg +def browser_close(browser): + """TODO: doc method""" + browser.close() + + @pytest.mark.dependency(name="browser_create") def test_browser_create(): """TODO: doc method""" browser = Browser(LOG, **config_browser_remote()) ASSERT.is_instance(browser, Browser) + ASSERT.is_instance(browser.config, BrowserConfig) + ASSERT.not_none(browser.capabilities) + if browser.config.browser not in ("iexplorer", "edge", "opera"): + ASSERT.not_none(browser.options) @pytest.mark.dependency(name="browser_open", depends=['browser_create']) @@ -35,3 +45,23 @@ def test_browser_open(): """TODO: doc method""" browser = Browser(LOG, **config_browser_remote()) browser.open() + ASSERT.not_none(browser.driver) + ASSERT.is_instance(browser.session_id, str) + ASSERT.not_none(browser._driver_wait) + ASSERT.not_none(browser._driver_actions) + ASSERT.not_none(browser._driver_touch) + ASSERT.is_instance(browser.modules, dict) + browser_close(browser) + + +@pytest.mark.dependency(name="browser_close", depends=['browser_open']) +def test_browser_close(): + """TODO: doc method""" + browser = Browser(LOG, **config_browser_remote()) + browser.open() + browser.close() + ASSERT.none(browser.driver) + ASSERT.none(browser._driver_wait) + ASSERT.none(browser._driver_actions) + ASSERT.none(browser._driver_touch) + ASSERT.none(browser.modules) From 26527a4826cfdbd55a2d0589eecb4c35f8de3d5c Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 3 Feb 2020 23:28:32 +0100 Subject: [PATCH 06/43] [qacode] added modules to browser + need TESTS for modules --- qacode/core/bots/__init__.py | 12 ++ qacode/core/browsers/__init__.py | 12 ++ qacode/core/browsers/browser.py | 12 +- qacode/core/browsers/modules/__init__.py | 14 ++ qacode/core/browsers/modules/commons.py | 142 ++++++++++++++++++++ qacode/core/browsers/modules/elements.py | 160 +++++++++++++++++++++++ qacode/core/browsers/modules/waits.py | 57 ++++++++ tests/browsers/suite_browsers.py | 7 +- 8 files changed, 410 insertions(+), 6 deletions(-) create mode 100644 qacode/core/bots/__init__.py create mode 100644 qacode/core/browsers/__init__.py create mode 100644 qacode/core/browsers/modules/__init__.py create mode 100644 qacode/core/browsers/modules/commons.py create mode 100644 qacode/core/browsers/modules/elements.py create mode 100644 qacode/core/browsers/modules/waits.py diff --git a/qacode/core/bots/__init__.py b/qacode/core/bots/__init__.py new file mode 100644 index 00000000..b76be624 --- /dev/null +++ b/qacode/core/bots/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +"""package qacode.core.bots""" + + +from qacode.core.bots import bot +from qacode.core.bots import bot_config + + +__all__ = [ + 'bot', + 'bot_config', +] diff --git a/qacode/core/browsers/__init__.py b/qacode/core/browsers/__init__.py new file mode 100644 index 00000000..b2623382 --- /dev/null +++ b/qacode/core/browsers/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +"""package qacode.core.browsers""" + + +from qacode.core.browsers import browser +from qacode.core.browsers import browser_config + + +__all__ = [ + 'browser', + 'browser_config', +] diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py index 4ff5ab68..f2fab599 100644 --- a/qacode/core/browsers/browser.py +++ b/qacode/core/browsers/browser.py @@ -5,6 +5,9 @@ import os import sys from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.browsers.modules.commons import ModuleCommons +from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.waits import ModuleWaits from qacode.core.exceptions.core_exception import CoreException # from qacode.core.loggers.log import Log from selenium.common.exceptions import SessionNotCreatedException @@ -29,6 +32,10 @@ def __init__(self, log, **kwargs): self._options = self.__options__() self._driver_abs_path = self.__driver_abs_path__() self._driver = None + # modules + self.Commons = ModuleCommons + self.Elements = ModuleElements + self.Waits = ModuleWaits def __config__(self, config): """TODO: doc method""" @@ -133,10 +140,6 @@ def __drivers_selenium__(self): self._driver_actions = ActionChains(self._driver) self._driver_touch = TouchActions(self._driver) - def __drivers_modules__(self): - """TODO: doc method""" - self._modules = {} - def open(self): """TODO: doc method""" if self._config.mode == "local": @@ -146,7 +149,6 @@ def open(self): else: raise Exception("Just allowed modes: local, remote") self.__drivers_selenium__() - self.__drivers_modules__() def close(self): """TODO: doc method""" diff --git a/qacode/core/browsers/modules/__init__.py b/qacode/core/browsers/modules/__init__.py new file mode 100644 index 00000000..5b1247bf --- /dev/null +++ b/qacode/core/browsers/modules/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +"""package qacode.core.browsers.modules""" + + +from qacode.core.browsers.modules.commons import ModuleCommons +from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.waits import ModuleWaits + + +__all__ = [ + 'ModuleCommons', + 'ModuleElements', + 'ModuleWaits', +] diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py new file mode 100644 index 00000000..49905fba --- /dev/null +++ b/qacode/core/browsers/modules/commons.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +class ModuleCommons(object): + """TODO: doc class""" + + @staticmethod + def get_title(self): + """Obtains the title of the current page and return it""" + return self.driver.title + + @staticmethod + def get_url(driver, url, wait_for_load=0): + """Do get_url including implicit wait for page load""" + if wait_for_load > 0: + driver.implicitly_wait(wait_for_load) + driver.get(url) + + def get_current_url(self): + """Return current url from opened bot""" + try: + return self.driver.current_url + except WebDriverException: + raise Exception("Not selenium driver property 'current_url'") + + def is_url(self, url, ignore_raises=True): + """Check if url it's the same what selenium + current and visible url + """ + if self.get_current_url() != url: + if not ignore_raises: + raise CoreException("'Current url' is not 'param url'") + return False + return True + + @staticmethod + def get_maximize_window(driver): + """Maximize browser window""" + driver.maximize_window() + + @staticmethod + def get_window_handle(driver): + """Get window object to handle with selenium on scripts""" + return driver.current_window_handle + + @staticmethod + def get_capabilities(driver): + """Retrieve current capabilities applied to selenium driver""" + return driver.desired_capabilities + + @staticmethod + def forward(driver): + """Go forward using browser functionality""" + driver.forward() + + @staticmethod + def reload(self): + """Go reload page using browser functionality""" + driver.refresh() + + @staticmethod + def get_log(self, log_name='browser', raises=False): + """Get selenium log by name, this depends of + driver mode and browser what it's using each time + """ + method = self.method_name() + try: + return { + 'browser': self.driver.get_log, + 'driver': self.driver.get_log, + 'client': self.driver.get_log, + 'server': self.driver.get_log, + }[log_name](log_name) + except (KeyError, WebDriverException) as err: + if isinstance(err, KeyError): + raise CoreException( + "Can't use not valid value to get log", + info_bot={"err": err, "method": method}) + self.log.debug(("nav | get_log: Selenium, not all drivers will" + " be handled by them with all optionsvalues")) + self.log.warning("nav | get_log: log_name={}, err={}".format( + log_name, err.msg)) + return list() + + @staticmethod + def get_screenshot_as_base64(driver): + """Gets the screenshot of the current window as a base64 encoded string + which is useful in embedded images in HTML + """ + return driver.get_screenshot_as_base64() + + @staticmethod + def get_screenshot_as_file(driver, file_name): + """Gets the screenshot of the current window. Returns False + if there is any IOError, else returns True. Use full paths + in your filename. + + Arguments: + file_name {str} -- name of file path where + want to save screenshot + + Returns: + list(byte) -- file binary object of screenshot bytes + """ + return driver.get_screenshot_as_file(file_name) + + @staticmethod + def get_screenshot_as_png(driver): + """Gets the screenshot of the current window as a + binary data. + + Returns: + File -- file binary object of screenshot with PNG format + """ + return driver.get_screenshot_as_png() + + @staticmethod + def get_screenshot_save(driver, file_name): + """Gets the screenshot of the current window. Returns False + if there is any IOError, else returns True. + Use full paths in your filename. + + Arguments: + file_name {str} -- name of file path where + want to save screenshot + + Returns: + list(byte) -- file binary object of screenshot bytes + """ + return driver.save_screenshot(file_name) + + @staticmethod + def set_window_size(driver, pos_x=800, pos_y=600): # YES + """Sets the width and height of the current + window. (window.resizeTo) + + Keyword Arguments: + pos_x {int} -- width of new window size (default: {800}) + pos_y {int} -- height of new window size (default: {600}) + """ + driver.set_window_size(pos_x, pos_y) diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py new file mode 100644 index 00000000..b7353116 --- /dev/null +++ b/qacode/core/browsers/modules/elements.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +from selenium.webdriver.common.by import By +from selenium.webdriver.remote.webelement import WebElement +from selenium.webdriver.support import expected_conditions as EC + + +class ModuleElements(object): + """TODO: doc class""" + + @staticmethod + def find_element(driver, selector, locator=By.CSS_SELECTOR): #YES + """Just divided execution ways for search + web element throught selenium + """ + if locator is None: + raise Exception("find_element: Locator can't be None") + try: + return driver.find_element(locator, selector) + except NoSuchElementException: + raise Exception("find_element: Element not found") + + @staticmethod + def find_elements(driver, selector, locator=By.CSS_SELECTOR, raises_zero=True): + """Just divided execution ways for search + web elements throught selenium + """ + if locator is None: + raise Exception("find_elements: Locator can't be None") + try: + elements = driver.find_elements(locator, selector) + if len(elements) == 0 and raises_zero: + raise Exception("find_elements: 0 elements found") + return elements + except NoSuchElementException as err: + raise Exception("find_elements: Element not found") + + @staticmethod + def find_element_wait(driver_wait, selector, + locator=By.CSS_SELECTOR): + """Search element using WebDriverWait class + and ElementConditions presence_of_element_located + """ + try: + return driver_wait.until( + EC.presence_of_element_located((locator, selector))) + except (NoSuchElementException, StaleElementReferenceException): + return driver_wait.until( + EC.visibility_of_element_located((locator, selector))) + + @staticmethod + def find_elements_wait(driver_wait, selector, locator=By.CSS_SELECTOR): + """Search elements using WebDriverWait class + and ElementConditions presence_of_all_elements_located + """ + try: + return driver_wait.until( + EC.presence_of_all_elements_located((locator, selector))) + except (NoSuchElementException, StaleElementReferenceException): + return driver_wait.until( + EC.visibility_of_all_elements_located((locator, selector))) + + @staticmethod + def find_element_child(driver, element, child_selector, + locator=By.CSS_SELECTOR): + """TODO: doc method""" + if element is None or not isinstance(element, WebElement): + raise Exception("Cant find child if not element") + try: + return element.find_element(locator, child_selector) + except (NoSuchElementException, StaleElementReferenceException) as err: + # at Java lang exist 1 expected condition + # named : visibilityOfNestedElementsLocatedBy + # doc : https://selenium-python.readthedocs.io/waits.html + # maybe must exist at python too + # then, create and use new method named: find_element_child_wait() + # raise NotImplementedError("TODO:open an issue at github please") + raise Exception(err) + + @staticmethod + def find_element_children(driver, element, child_selector, + locator=By.CSS_SELECTOR): + """TODO: doc method""" + method = self.method_name() + if element is None or not isinstance(element, WebElement): + raise CoreException("Cant find children if not element found") + try: + return element.find_elements(locator, child_selector) + except (NoSuchElementException, StaleElementReferenceException) as err: + # at Java lang exist 1 expected condition + # named : visibilityOfNestedElementsLocatedBy + # doc : https://selenium-python.readthedocs.io/waits.html + # maybe must exist at python too + # then, create and use new method named: find_element_child_wait() + # raise NotImplementedError("TODO:open an issue at github please") + raise Exception(err) + + @staticmethod + def find_elements_child(self): + """TODO: doc method""" + raise NotImplementedError("TODO: open an issue at github please") + + @staticmethod + def find_elements_children(self): + """TODO: doc method""" + raise NotImplementedError("TODO: open an issue at github please") + + @staticmethod + def ele_click(element): + """Perform click webelement with element + + Returns: + WebElement -- returns element clicked (to allow chaining) + """ + element.click() + return element + + @staticmethod + def ele_write(element, text=None): + """Over element perform send_keys , if not sended will + write empty over element + """ + if not isinstance(element, WebElement): + raise Exception("Param 'element' it's not WebElement") + if text is not None: + element.send_keys(text) + else: + # it's neccessary because some fields shows validation message and + # color after try to send empty message + element.send_keys() + + @staticmethod + def ele_attribute(element, attr_name): + """Returns tuple with (attr, value) if founds + This method will first try to return the value of a property with + the given name. If a property with that name doesn't exist, it + returns the value of the attribute with the same name. If there's + no attribute with that name, None is returned. + """ + value = str(element.get_attribute(attr_name)) + if value is None or value == attr_name: + raise Exception("Attr '{}' not found".format(attr_name)) + return value + + @staticmethod + def ele_input_value(element): + """Return value of value attribute, usefull for inputs""" + return ele_attribute(element, 'value') + + @staticmethod + def ele_clear(element): + """Clear element text""" + return element.clear() + + @staticmethod + def ele_css(element, prop_name): + """Allows to obtain CSS value based on CSS property name""" + return element.value_of_css_property(prop_name) diff --git a/qacode/core/browsers/modules/waits.py b/qacode/core/browsers/modules/waits.py new file mode 100644 index 00000000..1e98feb1 --- /dev/null +++ b/qacode/core/browsers/modules/waits.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +class ModuleWaits(object): + """TODO: doc class""" + + @staticmethod + def ele_wait_invisible(driver, selector, locator=By.CSS_SELECTOR, timeout=0): + """Wait for invisible element (display:none), returns element""" + if selector is None: + raise CoreException( + "Can't wait invisible element if None selector given") + locator_tuple = (locator, selector) + driver_wait = WebDriverWait(driver, timeout) + try: + element = driver_wait.until( + EC.invisibility_of_element_located(locator_tuple)) + except Exception: + raise CoreException("Fails at wait for invisible element") + return element + + @staticmethod + def ele_wait_visible(driver, element, timeout=0): + """Wait for visible condition element, returns self""" + if element is None: + raise CoreException("Can't wait visible if element is None") + driver_wait = WebDriverWait(driver, timeout) + try: + element = driver_wait.until(EC.visibility_of(element)) + except Exception: + raise CoreException("Fails at wait for visible element") + return element + + @staticmethod + def ele_wait_text(WebDriverWait, selector, text, + locator=By.CSS_SELECTOR, timeout=0): + """Wait if the given text is present in the specified element""" + locator_tuple = (locator, selector) + driver_wait = WebDriverWait(driver, timeout) + try: + return driver_wait.until( + EC.text_to_be_present_in_element(locator_tuple, text)) + except Exception: + raise CoreException("Fails at wait for element text") + + @staticmethod + def ele_wait_value(driver, selector, value, + locator=By.CSS_SELECTOR, timeout=0): + """Wait if the given value is present in the specified element""" + locator_tuple = (locator, selector) + driver_wait = WebDriverWait(driver, timeout) + try: + return driver_wait.until( + EC.text_to_be_present_in_element_value(locator_tuple, value)) + except Exception: + raise CoreException("Fails at wait for element value") diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index 0093eb2c..f281878c 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -5,6 +5,9 @@ import pytest from qacode.core.browsers.browser import Browser from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.browsers.modules.commons import ModuleCommons +from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.waits import ModuleWaits from qacode.core.loggers.log import Log from qacode.core.testing.asserts import Assert from qacode.utils import settings @@ -50,7 +53,9 @@ def test_browser_open(): ASSERT.not_none(browser._driver_wait) ASSERT.not_none(browser._driver_actions) ASSERT.not_none(browser._driver_touch) - ASSERT.is_instance(browser.modules, dict) + ASSERT.equals(browser.Commons, ModuleCommons) + ASSERT.equals(browser.Elements, ModuleElements) + ASSERT.equals(browser.Waits, ModuleWaits) browser_close(browser) From 7de7340cc60a58255c6509b5b46d9bfec019aaa1 Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 3 Feb 2020 23:38:33 +0100 Subject: [PATCH 07/43] [qacode] added tests for modules --- qacode/core/browsers/modules/waits.py | 5 ++++ tests/browsers/suite_browsers.py | 2 +- tests/browsers/suite_module_commons.py | 39 +++++++++++++++++++++++++ tests/browsers/suite_module_elements.py | 39 +++++++++++++++++++++++++ tests/browsers/suite_module_waits.py | 39 +++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 tests/browsers/suite_module_commons.py create mode 100644 tests/browsers/suite_module_elements.py create mode 100644 tests/browsers/suite_module_waits.py diff --git a/qacode/core/browsers/modules/waits.py b/qacode/core/browsers/modules/waits.py index 1e98feb1..ef41d16d 100644 --- a/qacode/core/browsers/modules/waits.py +++ b/qacode/core/browsers/modules/waits.py @@ -2,6 +2,11 @@ """TODO""" +from selenium.webdriver.common.by import By +from selenium.webdriver.remote.webelement import WebElement +from selenium.webdriver.support import expected_conditions as EC + + class ModuleWaits(object): """TODO: doc class""" diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index f281878c..4480e10a 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""Test Suite module for qacode.core.bots package""" +"""Test Suite module for tests.browsers package""" import pytest diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py new file mode 100644 index 00000000..5110b57b --- /dev/null +++ b/tests/browsers/suite_module_commons.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers package""" + + +import pytest +from qacode.core.browsers.browser import Browser +from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.browsers.modules.commons import ModuleCommons +from qacode.core.loggers.log import Log +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") +BROWSERS = CFG.get('bot').get('browsers') +HUB_URL = CFG.get("bot").get("hub_url") +LOG = Log(**CFG.get('log')) + + +def browser_remote(): + """TODO: doc method""" + cfg = BROWSERS[0] + cfg.update({"hub_url": HUB_URL}) + browser = Browser(LOG, **cfg) + ASSERT.is_instance(browser, Browser) + return browser + + +@pytest.mark.dependency(name="browser_create") +def test_mod_common_dummy(): + """TODO: doc method""" + browser = browser_remote() + try: + pytest.fail("WIP: not developed yet") + except: + pytest.fail("Failed") + finally: + browser.close() diff --git a/tests/browsers/suite_module_elements.py b/tests/browsers/suite_module_elements.py new file mode 100644 index 00000000..91362802 --- /dev/null +++ b/tests/browsers/suite_module_elements.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers package""" + + +import pytest +from qacode.core.browsers.browser import Browser +from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.loggers.log import Log +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") +BROWSERS = CFG.get('bot').get('browsers') +HUB_URL = CFG.get("bot").get("hub_url") +LOG = Log(**CFG.get('log')) + + +def browser_remote(): + """TODO: doc method""" + cfg = BROWSERS[0] + cfg.update({"hub_url": HUB_URL}) + browser = Browser(LOG, **cfg) + ASSERT.is_instance(browser, Browser) + return browser + + +@pytest.mark.dependency(name="browser_create") +def test_mod_common_dummy(): + """TODO: doc method""" + browser = browser_remote() + try: + pytest.fail("WIP: not developed yet") + except: + pytest.fail("Failed") + finally: + browser.close() diff --git a/tests/browsers/suite_module_waits.py b/tests/browsers/suite_module_waits.py new file mode 100644 index 00000000..c170d100 --- /dev/null +++ b/tests/browsers/suite_module_waits.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers package""" + + +import pytest +from qacode.core.browsers.browser import Browser +from qacode.core.browsers.browser_config import BrowserConfig +from qacode.core.browsers.modules.waits import ModuleWaits +from qacode.core.loggers.log import Log +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") +BROWSERS = CFG.get('bot').get('browsers') +HUB_URL = CFG.get("bot").get("hub_url") +LOG = Log(**CFG.get('log')) + + +def browser_remote(): + """TODO: doc method""" + cfg = BROWSERS[0] + cfg.update({"hub_url": HUB_URL}) + browser = Browser(LOG, **cfg) + ASSERT.is_instance(browser, Browser) + return browser + + +@pytest.mark.dependency(name="browser_create") +def test_mod_common_dummy(): + """TODO: doc method""" + browser = browser_remote() + try: + pytest.fail("WIP: not developed yet") + except: + pytest.fail("Failed") + finally: + browser.close() From d5b6c9f43bd258fd671261444857a57e04e10149 Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 5 Feb 2020 00:33:32 +0100 Subject: [PATCH 08/43] [qacode] working tests --- tests/bots/suite_bots.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/bots/suite_bots.py b/tests/bots/suite_bots.py index 7219bbaa..85dcde77 100644 --- a/tests/bots/suite_bots.py +++ b/tests/bots/suite_bots.py @@ -23,24 +23,30 @@ def test_bot_create(): @pytest.mark.dependency(depends=['bot_create']) def test_bot_browsers(): """TODO: doc method""" - pytest.fail("Not developed yet") + cfg_browsers = CFG.get('bot').get('browsers') + ASSERT.equals(len(Bot(**CFG).config.browsers), len(cfg_browsers)) @pytest.mark.dependency(depends=['bot_create']) def test_bot_pages(): """TODO: doc method""" - pytest.fail("Not developed yet") + cfg_pages = CFG.get('bot').get('pages') + ASSERT.equals(len(Bot(**CFG).config.pages), len(cfg_pages)) @pytest.mark.dependency(depends=['bot_create']) def test_bot_controls(): """TODO: doc method""" - pytest.fail("Not developed yet") + cfg_controls = CFG.get('bot').get('controls') + ASSERT.equals(len(Bot(**CFG).config.controls), len(cfg_controls)) @pytest.mark.dependency(name="bot_browser_create", depends=['bot_create']) def test_bot_browser_create(): """TODO: doc method""" bot = Bot(**CFG) + before = len(bot.browsers) browser = bot.browser_create(bot.config.browsers[0]) ASSERT.is_instance(browser, Browser) + ASSERT.equals(before+1, len(bot.browsers)) + ASSERT.equals(browser, bot.browsers[0]) From 93b96c808768e2902118af83363b9519b87be5ec Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 5 Feb 2020 21:48:57 +0100 Subject: [PATCH 09/43] [qacode] added fixture for browser + added configuration from master branch --- conftest.py | 15 ++++++++++ qacode/configs/settings.json | 25 +++++++++++++++-- qacode/core/browsers/modules/commons.py | 4 +-- tests/browsers/suite_module_commons.py | 28 ++++++------------- .../001_functionals/suite_004_navbase.py | 2 +- 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/conftest.py b/conftest.py index e69de29b..ad06b20a 100644 --- a/conftest.py +++ b/conftest.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +"""Tests fixtures""" + +import pytest +from qacode.core.bots.bot import Bot +from qacode.utils import settings + + +@pytest.fixture(scope="session") +def browser(): + CFG = settings(file_path="qacode/configs/", file_name="settings.json") + bot = Bot(**CFG) + before = len(bot.browsers) + yield bot.browser_create(bot.config.browsers[0]) + bot.browsers[0].close() diff --git a/qacode/configs/settings.json b/qacode/configs/settings.json index 84338e5c..059bfa59 100644 --- a/qacode/configs/settings.json +++ b/qacode/configs/settings.json @@ -16,8 +16,29 @@ {"browser": "chrome", "mode": "remote", "options": {"headless": false}}, {"browser": "chrome", "mode": "local", "options": {"headless": false}} ], - "pages": [], - "controls": [] + "pages": [ + {"name": "login", "url": "http://netzulo.tk:83/qacode/login"}, + {"name": "logout", "url": "http://netzulo.tk:83/qacode/logout"}, + {"name": "inputs", "url": "http://netzulo.tk:83/qacode/forms/inputs"}, + {"name": "lists", "url": "http://netzulo.tk:83/qacode/data/lists"} + ], + "controls": [ + { "name": "form", "selector": "#frmLogin", "pages": ["login"]}, + { "name": "username", "selector": "#txtUsername-field", "pages": ["login"]}, + { "name": "password", "selector": "#txtPassword-field", "pages": ["login"]}, + { "name": "submit", "selector": "#btnLogin", "pages": ["login"]}, + { "name": "btn_logout", "selector": "a[href='/qacode/logout']", "pages": ["logout"]}, + { "name": "btn_login", "selector": "a[href='/qacode/login']", "pages": ["logout"]}, + { "name": "dd_base", "selector": "#txtTest002", "pages": ["inputs"]}, + { "name": "dd_multiple", "selector": "#txtTest003", "pages": ["inputs"]}, + { "name": "lst_ordered", "selector": "ol:nth-child(1)", "pages": ["lists"]}, + { "name": "lst_ordered_child", "selector": "li", "pages": ["lists"]}, + { "name": "dd_menu_data", "selector": "#ddData", "pages": ["lists"]}, + { "name": "dd_menu_data_lists", "selector": "a[href='/qacode/data/lists']", "pages": ["lists"]}, + { "name": "tbl_ok", "selector": "#tblOk", "pages": ["lists"]}, + { "name": "tbl_html5_ok", "selector": "#tblHtml5Ok", "pages": ["lists"]}, + { "name": "tbl_html_tbodies_ok", "selector": "#tblHtml5OkTbodies", "pages": ["lists"]} + ] }, "testlink": { "connection":{ diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 49905fba..e9e68654 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -6,9 +6,9 @@ class ModuleCommons(object): """TODO: doc class""" @staticmethod - def get_title(self): + def get_title(driver): """Obtains the title of the current page and return it""" - return self.driver.title + return driver.title @staticmethod def get_url(driver, url, wait_for_load=0): diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index 5110b57b..1f83f41d 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -12,28 +12,16 @@ ASSERT = Assert() -CFG = settings(file_path="qacode/configs/", file_name="settings.json") -BROWSERS = CFG.get('bot').get('browsers') -HUB_URL = CFG.get("bot").get("hub_url") -LOG = Log(**CFG.get('log')) -def browser_remote(): +def test_common_geturl(browser, url): """TODO: doc method""" - cfg = BROWSERS[0] - cfg.update({"hub_url": HUB_URL}) - browser = Browser(LOG, **cfg) - ASSERT.is_instance(browser, Browser) - return browser + browser.open() + ASSERT.not_none(browser.Commons.get_url( + browser.driver, + "http://netzulo.tk:89")) - -@pytest.mark.dependency(name="browser_create") -def test_mod_common_dummy(): +def test_common_gettitle(browser): """TODO: doc method""" - browser = browser_remote() - try: - pytest.fail("WIP: not developed yet") - except: - pytest.fail("Failed") - finally: - browser.close() + ASSERT.not_none(browser.Commons.get_title(browser.driver)) + diff --git a/tests_old/001_functionals/suite_004_navbase.py b/tests_old/001_functionals/suite_004_navbase.py index 4c6b2a23..7f376b34 100644 --- a/tests_old/001_functionals/suite_004_navbase.py +++ b/tests_old/001_functionals/suite_004_navbase.py @@ -279,7 +279,7 @@ def test_setwindowsize_ok(self): pos_x=1024, pos_y=768) @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gettitle_ok(self): + def test_gettitle_ok(self): # YES """Testcase: test_gettitle_ok""" self.assert_not_none( self.bot.navigation.get_title()) From 90821e038c74b31b1eec869644ed655aff8763da Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 5 Feb 2020 22:11:46 +0100 Subject: [PATCH 10/43] [qacode] added more commons tests --- qacode/core/browsers/modules/commons.py | 11 +++----- tests/browsers/suite_module_commons.py | 27 ++++++++++++++----- .../001_functionals/suite_004_navbase.py | 8 +++--- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index e9e68654..1aafd635 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -17,18 +17,15 @@ def get_url(driver, url, wait_for_load=0): driver.implicitly_wait(wait_for_load) driver.get(url) - def get_current_url(self): + def get_current_url(driver): """Return current url from opened bot""" - try: - return self.driver.current_url - except WebDriverException: - raise Exception("Not selenium driver property 'current_url'") + return driver.current_url - def is_url(self, url, ignore_raises=True): + def is_url(driver, url, ignore_raises=True): """Check if url it's the same what selenium current and visible url """ - if self.get_current_url() != url: + if driver.get_current_url(driver) != url: if not ignore_raises: raise CoreException("'Current url' is not 'param url'") return False diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index 1f83f41d..f5ffb525 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Test Suite module for tests.browsers package""" - +import time import pytest from qacode.core.browsers.browser import Browser from qacode.core.browsers.browser_config import BrowserConfig @@ -12,15 +12,30 @@ ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") - -def test_common_geturl(browser, url): +@pytest.mark.dependency(name="browser_open") +def test_browser_open(browser): """TODO: doc method""" browser.open() - ASSERT.not_none(browser.Commons.get_url( - browser.driver, - "http://netzulo.tk:89")) +@pytest.mark.dependency(name="get_url", depends=['browser_open']) +@pytest.mark.parametrize("wait", [0, 100]) +def test_common_geturl(browser, wait): + """TODO: doc method""" + cfg_url = CFG.get('bot').get('pages')[0].get('url') + ASSERT.not_none(cfg_url) + browser.Commons.get_url(browser.driver, cfg_url, wait_for_load=wait) + +@pytest.mark.dependency(depends=['browser_open', 'get_url']) +def test_common_getcurrenturl(browser): + """TODO: doc method""" + cfg_url = CFG.get('bot').get('pages')[0].get('url') + ASSERT.not_none(cfg_url) + url = browser.Commons.get_current_url(browser.driver) + ASSERT.equals(url, cfg_url) + +@pytest.mark.dependency(depends=['browser_open']) def test_common_gettitle(browser): """TODO: doc method""" ASSERT.not_none(browser.Commons.get_title(browser.driver)) diff --git a/tests_old/001_functionals/suite_004_navbase.py b/tests_old/001_functionals/suite_004_navbase.py index 7f376b34..9fe7e7fa 100644 --- a/tests_old/001_functionals/suite_004_navbase.py +++ b/tests_old/001_functionals/suite_004_navbase.py @@ -87,23 +87,23 @@ def setup_login_to_data(self): # end setup_login @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_navbase_instance(self): + def test_navbase_instance(self): # NO """Testcase: test_navbase_instance""" self.assert_is_instance(self.bot.navigation, NavBase) @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gourl_withoutwaits(self): + def test_gourl_withoutwaits(self): # YES """Testcase: test_gourl_withoutwaits""" self.bot.navigation.get_url(self.page.get('url')) @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gourl_withwaits(self): + def test_gourl_withwaits(self): # YES """Testcase: test_gourl_withwaits""" self.bot.navigation.get_url( self.page.get('url'), wait_for_load=1) @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getcurrenturl_ok(self): + def test_getcurrenturl_ok(self): # YES """Testcase: test_getcurrenturl_ok""" self.assert_equals( self.bot.navigation.get_current_url(), From 730ed97ac1ac05ebd816500fde192f3c12f51c50 Mon Sep 17 00:00:00 2001 From: netzulo Date: Wed, 5 Feb 2020 22:30:00 +0100 Subject: [PATCH 11/43] [qacode] fixe flake errors --- qacode/configs/settings.json | 2 +- qacode/core/browsers/modules/commons.py | 38 ++++++------- qacode/core/browsers/modules/elements.py | 69 +++++++++++++----------- qacode/core/browsers/modules/waits.py | 19 +++---- tests/bots/suite_bots.py | 2 +- tests/browsers/suite_module_commons.py | 11 ++-- tests/browsers/suite_module_elements.py | 30 +---------- tests/browsers/suite_module_waits.py | 30 +---------- 8 files changed, 76 insertions(+), 125 deletions(-) diff --git a/qacode/configs/settings.json b/qacode/configs/settings.json index 059bfa59..0b7f195c 100644 --- a/qacode/configs/settings.json +++ b/qacode/configs/settings.json @@ -3,7 +3,7 @@ "path": "logs/", "name": "qacode", "level": "INFO" }, "bot":{ - "hub_url": "http://localhost:11000/wd/hub", + "hub_url": "http://netzulo.tk:11000/wd/hub", "drivers_path": "../qadrivers", "drivers_names": { "chrome": "chromedriver_64.exe", diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 1aafd635..711d39b4 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -2,6 +2,9 @@ """TODO""" +from selenium.common.exceptions import WebDriverException + + class ModuleCommons(object): """TODO: doc class""" @@ -17,17 +20,19 @@ def get_url(driver, url, wait_for_load=0): driver.implicitly_wait(wait_for_load) driver.get(url) + @staticmethod def get_current_url(driver): """Return current url from opened bot""" return driver.current_url - + + @staticmethod def is_url(driver, url, ignore_raises=True): """Check if url it's the same what selenium current and visible url """ if driver.get_current_url(driver) != url: if not ignore_raises: - raise CoreException("'Current url' is not 'param url'") + raise Exception("'Current url' is not 'param url'") return False return True @@ -45,39 +50,36 @@ def get_window_handle(driver): def get_capabilities(driver): """Retrieve current capabilities applied to selenium driver""" return driver.desired_capabilities - + @staticmethod def forward(driver): """Go forward using browser functionality""" driver.forward() @staticmethod - def reload(self): + def reload(driver): """Go reload page using browser functionality""" driver.refresh() @staticmethod - def get_log(self, log_name='browser', raises=False): + def get_log(driver, log_name='browser', raises=False): """Get selenium log by name, this depends of driver mode and browser what it's using each time """ - method = self.method_name() try: return { - 'browser': self.driver.get_log, - 'driver': self.driver.get_log, - 'client': self.driver.get_log, - 'server': self.driver.get_log, + 'browser': driver.get_log, + 'driver': driver.get_log, + 'client': driver.get_log, + 'server': driver.get_log, }[log_name](log_name) except (KeyError, WebDriverException) as err: if isinstance(err, KeyError): - raise CoreException( - "Can't use not valid value to get log", - info_bot={"err": err, "method": method}) - self.log.debug(("nav | get_log: Selenium, not all drivers will" - " be handled by them with all optionsvalues")) - self.log.warning("nav | get_log: log_name={}, err={}".format( - log_name, err.msg)) + raise Exception("Can't use not valid value to get log") + # self.log.debug(("nav | get_log: Selenium, not all drivers will" + # " be handled by them with all optionsvalues")) + # self.log.warning("nav | get_log: log_name={}, err={}".format( + # log_name, err.msg)) return list() @staticmethod @@ -128,7 +130,7 @@ def get_screenshot_save(driver, file_name): return driver.save_screenshot(file_name) @staticmethod - def set_window_size(driver, pos_x=800, pos_y=600): # YES + def set_window_size(driver, pos_x=800, pos_y=600): """Sets the width and height of the current window. (window.resizeTo) diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py index b7353116..3eb6ec02 100644 --- a/qacode/core/browsers/modules/elements.py +++ b/qacode/core/browsers/modules/elements.py @@ -2,6 +2,10 @@ """TODO""" +from selenium.common.exceptions import ( + NoSuchElementException, + StaleElementReferenceException, +) from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC @@ -10,8 +14,8 @@ class ModuleElements(object): """TODO: doc class""" - @staticmethod - def find_element(driver, selector, locator=By.CSS_SELECTOR): #YES + @classmethod + def find_element(cls, driver, selector, locator=By.CSS_SELECTOR): """Just divided execution ways for search web element throught selenium """ @@ -22,8 +26,9 @@ def find_element(driver, selector, locator=By.CSS_SELECTOR): #YES except NoSuchElementException: raise Exception("find_element: Element not found") - @staticmethod - def find_elements(driver, selector, locator=By.CSS_SELECTOR, raises_zero=True): + @classmethod + def find_elements(cls, driver, selector, locator=By.CSS_SELECTOR, + raises_zero=True): """Just divided execution ways for search web elements throught selenium """ @@ -34,11 +39,11 @@ def find_elements(driver, selector, locator=By.CSS_SELECTOR, raises_zero=True): if len(elements) == 0 and raises_zero: raise Exception("find_elements: 0 elements found") return elements - except NoSuchElementException as err: + except NoSuchElementException: raise Exception("find_elements: Element not found") - @staticmethod - def find_element_wait(driver_wait, selector, + @classmethod + def find_element_wait(cls, driver_wait, selector, locator=By.CSS_SELECTOR): """Search element using WebDriverWait class and ElementConditions presence_of_element_located @@ -50,8 +55,9 @@ def find_element_wait(driver_wait, selector, return driver_wait.until( EC.visibility_of_element_located((locator, selector))) - @staticmethod - def find_elements_wait(driver_wait, selector, locator=By.CSS_SELECTOR): + @classmethod + def find_elements_wait(cls, driver_wait, selector, + locator=By.CSS_SELECTOR): """Search elements using WebDriverWait class and ElementConditions presence_of_all_elements_located """ @@ -62,8 +68,8 @@ def find_elements_wait(driver_wait, selector, locator=By.CSS_SELECTOR): return driver_wait.until( EC.visibility_of_all_elements_located((locator, selector))) - @staticmethod - def find_element_child(driver, element, child_selector, + @classmethod + def find_element_child(cls, driver, element, child_selector, locator=By.CSS_SELECTOR): """TODO: doc method""" if element is None or not isinstance(element, WebElement): @@ -79,13 +85,12 @@ def find_element_child(driver, element, child_selector, # raise NotImplementedError("TODO:open an issue at github please") raise Exception(err) - @staticmethod - def find_element_children(driver, element, child_selector, + @classmethod + def find_element_children(cls, driver, element, child_selector, locator=By.CSS_SELECTOR): """TODO: doc method""" - method = self.method_name() if element is None or not isinstance(element, WebElement): - raise CoreException("Cant find children if not element found") + raise Exception("Cant find children if not element found") try: return element.find_elements(locator, child_selector) except (NoSuchElementException, StaleElementReferenceException) as err: @@ -97,18 +102,18 @@ def find_element_children(driver, element, child_selector, # raise NotImplementedError("TODO:open an issue at github please") raise Exception(err) - @staticmethod - def find_elements_child(self): + @classmethod + def find_elements_child(cls): """TODO: doc method""" raise NotImplementedError("TODO: open an issue at github please") - @staticmethod - def find_elements_children(self): + @classmethod + def find_elements_children(cls): """TODO: doc method""" raise NotImplementedError("TODO: open an issue at github please") - @staticmethod - def ele_click(element): + @classmethod + def ele_click(cls, element): """Perform click webelement with element Returns: @@ -117,8 +122,8 @@ def ele_click(element): element.click() return element - @staticmethod - def ele_write(element, text=None): + @classmethod + def ele_write(cls, element, text=None): """Over element perform send_keys , if not sended will write empty over element """ @@ -131,8 +136,8 @@ def ele_write(element, text=None): # color after try to send empty message element.send_keys() - @staticmethod - def ele_attribute(element, attr_name): + @classmethod + def ele_attribute(cls, element, attr_name): """Returns tuple with (attr, value) if founds This method will first try to return the value of a property with the given name. If a property with that name doesn't exist, it @@ -144,17 +149,17 @@ def ele_attribute(element, attr_name): raise Exception("Attr '{}' not found".format(attr_name)) return value - @staticmethod - def ele_input_value(element): + @classmethod + def ele_input_value(cls, element): """Return value of value attribute, usefull for inputs""" - return ele_attribute(element, 'value') + return cls.ele_attribute(element, 'value') - @staticmethod - def ele_clear(element): + @classmethod + def ele_clear(cls, element): """Clear element text""" return element.clear() - @staticmethod - def ele_css(element, prop_name): + @classmethod + def ele_css(cls, element, prop_name): """Allows to obtain CSS value based on CSS property name""" return element.value_of_css_property(prop_name) diff --git a/qacode/core/browsers/modules/waits.py b/qacode/core/browsers/modules/waits.py index ef41d16d..8fbca290 100644 --- a/qacode/core/browsers/modules/waits.py +++ b/qacode/core/browsers/modules/waits.py @@ -3,18 +3,19 @@ from selenium.webdriver.common.by import By -from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait class ModuleWaits(object): """TODO: doc class""" @staticmethod - def ele_wait_invisible(driver, selector, locator=By.CSS_SELECTOR, timeout=0): + def ele_wait_invisible(driver, selector, locator=By.CSS_SELECTOR, + timeout=0): """Wait for invisible element (display:none), returns element""" if selector is None: - raise CoreException( + raise Exception( "Can't wait invisible element if None selector given") locator_tuple = (locator, selector) driver_wait = WebDriverWait(driver, timeout) @@ -22,23 +23,23 @@ def ele_wait_invisible(driver, selector, locator=By.CSS_SELECTOR, timeout=0): element = driver_wait.until( EC.invisibility_of_element_located(locator_tuple)) except Exception: - raise CoreException("Fails at wait for invisible element") + raise Exception("Fails at wait for invisible element") return element @staticmethod def ele_wait_visible(driver, element, timeout=0): """Wait for visible condition element, returns self""" if element is None: - raise CoreException("Can't wait visible if element is None") + raise Exception("Can't wait visible if element is None") driver_wait = WebDriverWait(driver, timeout) try: element = driver_wait.until(EC.visibility_of(element)) except Exception: - raise CoreException("Fails at wait for visible element") + raise Exception("Fails at wait for visible element") return element @staticmethod - def ele_wait_text(WebDriverWait, selector, text, + def ele_wait_text(driver, selector, text, locator=By.CSS_SELECTOR, timeout=0): """Wait if the given text is present in the specified element""" locator_tuple = (locator, selector) @@ -47,7 +48,7 @@ def ele_wait_text(WebDriverWait, selector, text, return driver_wait.until( EC.text_to_be_present_in_element(locator_tuple, text)) except Exception: - raise CoreException("Fails at wait for element text") + raise Exception("Fails at wait for element text") @staticmethod def ele_wait_value(driver, selector, value, @@ -59,4 +60,4 @@ def ele_wait_value(driver, selector, value, return driver_wait.until( EC.text_to_be_present_in_element_value(locator_tuple, value)) except Exception: - raise CoreException("Fails at wait for element value") + raise Exception("Fails at wait for element value") diff --git a/tests/bots/suite_bots.py b/tests/bots/suite_bots.py index 85dcde77..08a41b58 100644 --- a/tests/bots/suite_bots.py +++ b/tests/bots/suite_bots.py @@ -48,5 +48,5 @@ def test_bot_browser_create(): before = len(bot.browsers) browser = bot.browser_create(bot.config.browsers[0]) ASSERT.is_instance(browser, Browser) - ASSERT.equals(before+1, len(bot.browsers)) + ASSERT.equals(before + 1, len(bot.browsers)) ASSERT.equals(browser, bot.browsers[0]) diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index f5ffb525..b1363751 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -1,12 +1,8 @@ # -*- coding: utf-8 -*- """Test Suite module for tests.browsers package""" -import time + import pytest -from qacode.core.browsers.browser import Browser -from qacode.core.browsers.browser_config import BrowserConfig -from qacode.core.browsers.modules.commons import ModuleCommons -from qacode.core.loggers.log import Log from qacode.core.testing.asserts import Assert from qacode.utils import settings @@ -14,11 +10,13 @@ ASSERT = Assert() CFG = settings(file_path="qacode/configs/", file_name="settings.json") + @pytest.mark.dependency(name="browser_open") def test_browser_open(browser): """TODO: doc method""" browser.open() + @pytest.mark.dependency(name="get_url", depends=['browser_open']) @pytest.mark.parametrize("wait", [0, 100]) def test_common_geturl(browser, wait): @@ -27,6 +25,7 @@ def test_common_geturl(browser, wait): ASSERT.not_none(cfg_url) browser.Commons.get_url(browser.driver, cfg_url, wait_for_load=wait) + @pytest.mark.dependency(depends=['browser_open', 'get_url']) def test_common_getcurrenturl(browser): """TODO: doc method""" @@ -35,8 +34,8 @@ def test_common_getcurrenturl(browser): url = browser.Commons.get_current_url(browser.driver) ASSERT.equals(url, cfg_url) + @pytest.mark.dependency(depends=['browser_open']) def test_common_gettitle(browser): """TODO: doc method""" ASSERT.not_none(browser.Commons.get_title(browser.driver)) - diff --git a/tests/browsers/suite_module_elements.py b/tests/browsers/suite_module_elements.py index 91362802..105ba9a2 100644 --- a/tests/browsers/suite_module_elements.py +++ b/tests/browsers/suite_module_elements.py @@ -3,37 +3,9 @@ import pytest -from qacode.core.browsers.browser import Browser -from qacode.core.browsers.browser_config import BrowserConfig -from qacode.core.browsers.modules.elements import ModuleElements -from qacode.core.loggers.log import Log -from qacode.core.testing.asserts import Assert -from qacode.utils import settings - - -ASSERT = Assert() -CFG = settings(file_path="qacode/configs/", file_name="settings.json") -BROWSERS = CFG.get('bot').get('browsers') -HUB_URL = CFG.get("bot").get("hub_url") -LOG = Log(**CFG.get('log')) - - -def browser_remote(): - """TODO: doc method""" - cfg = BROWSERS[0] - cfg.update({"hub_url": HUB_URL}) - browser = Browser(LOG, **cfg) - ASSERT.is_instance(browser, Browser) - return browser @pytest.mark.dependency(name="browser_create") def test_mod_common_dummy(): """TODO: doc method""" - browser = browser_remote() - try: - pytest.fail("WIP: not developed yet") - except: - pytest.fail("Failed") - finally: - browser.close() + pytest.fail("WIP: not developed yet") diff --git a/tests/browsers/suite_module_waits.py b/tests/browsers/suite_module_waits.py index c170d100..105ba9a2 100644 --- a/tests/browsers/suite_module_waits.py +++ b/tests/browsers/suite_module_waits.py @@ -3,37 +3,9 @@ import pytest -from qacode.core.browsers.browser import Browser -from qacode.core.browsers.browser_config import BrowserConfig -from qacode.core.browsers.modules.waits import ModuleWaits -from qacode.core.loggers.log import Log -from qacode.core.testing.asserts import Assert -from qacode.utils import settings - - -ASSERT = Assert() -CFG = settings(file_path="qacode/configs/", file_name="settings.json") -BROWSERS = CFG.get('bot').get('browsers') -HUB_URL = CFG.get("bot").get("hub_url") -LOG = Log(**CFG.get('log')) - - -def browser_remote(): - """TODO: doc method""" - cfg = BROWSERS[0] - cfg.update({"hub_url": HUB_URL}) - browser = Browser(LOG, **cfg) - ASSERT.is_instance(browser, Browser) - return browser @pytest.mark.dependency(name="browser_create") def test_mod_common_dummy(): """TODO: doc method""" - browser = browser_remote() - try: - pytest.fail("WIP: not developed yet") - except: - pytest.fail("Failed") - finally: - browser.close() + pytest.fail("WIP: not developed yet") From 670a93a5faf6523657d7524220d8536a30c799ba Mon Sep 17 00:00:00 2001 From: netzulo Date: Thu, 6 Feb 2020 23:01:12 +0100 Subject: [PATCH 12/43] [qacode] more tests for commons modules --- qacode/core/browsers/modules/commons.py | 94 ++++++++++++------------- tests/browsers/suite_browsers.py | 1 + tests/browsers/suite_module_commons.py | 60 +++++++++++++++- 3 files changed, 104 insertions(+), 51 deletions(-) diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 711d39b4..074c2f65 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -8,61 +8,59 @@ class ModuleCommons(object): """TODO: doc class""" - @staticmethod - def get_title(driver): + @classmethod + def get_maximize_window(cls, driver): + """Maximize browser window""" + driver.maximize_window() + + @classmethod + def get_title(cls, driver): """Obtains the title of the current page and return it""" return driver.title - @staticmethod - def get_url(driver, url, wait_for_load=0): + @classmethod + def get_window_handle(cls, driver): + """Get window object to handle with selenium on scripts""" + return driver.current_window_handle + + @classmethod + def get_capabilities(cls, driver): + """Retrieve current capabilities applied to selenium driver""" + return driver.desired_capabilities + + @classmethod + def forward(cls, driver): + """Go forward using browser functionality""" + driver.forward() + + @classmethod + def reload(cls, driver): + """Go reload page using browser functionality""" + driver.refresh() + + @classmethod + def get_url(cls, driver, url, wait_for_load=0): """Do get_url including implicit wait for page load""" if wait_for_load > 0: driver.implicitly_wait(wait_for_load) driver.get(url) - @staticmethod - def get_current_url(driver): + @classmethod + def get_current_url(cls, driver): """Return current url from opened bot""" return driver.current_url - @staticmethod - def is_url(driver, url, ignore_raises=True): + @classmethod + def is_url(cls, driver, url): """Check if url it's the same what selenium current and visible url """ - if driver.get_current_url(driver) != url: - if not ignore_raises: - raise Exception("'Current url' is not 'param url'") + if cls.get_current_url(driver) != url: return False return True - @staticmethod - def get_maximize_window(driver): - """Maximize browser window""" - driver.maximize_window() - - @staticmethod - def get_window_handle(driver): - """Get window object to handle with selenium on scripts""" - return driver.current_window_handle - - @staticmethod - def get_capabilities(driver): - """Retrieve current capabilities applied to selenium driver""" - return driver.desired_capabilities - - @staticmethod - def forward(driver): - """Go forward using browser functionality""" - driver.forward() - - @staticmethod - def reload(driver): - """Go reload page using browser functionality""" - driver.refresh() - - @staticmethod - def get_log(driver, log_name='browser', raises=False): + @classmethod + def get_log(cls, driver, log_name='browser'): """Get selenium log by name, this depends of driver mode and browser what it's using each time """ @@ -82,15 +80,15 @@ def get_log(driver, log_name='browser', raises=False): # log_name, err.msg)) return list() - @staticmethod - def get_screenshot_as_base64(driver): + @classmethod + def get_screenshot_as_base64(cls, driver): """Gets the screenshot of the current window as a base64 encoded string which is useful in embedded images in HTML """ return driver.get_screenshot_as_base64() - @staticmethod - def get_screenshot_as_file(driver, file_name): + @classmethod + def get_screenshot_as_file(cls, driver, file_name): """Gets the screenshot of the current window. Returns False if there is any IOError, else returns True. Use full paths in your filename. @@ -104,8 +102,8 @@ def get_screenshot_as_file(driver, file_name): """ return driver.get_screenshot_as_file(file_name) - @staticmethod - def get_screenshot_as_png(driver): + @classmethod + def get_screenshot_as_png(cls, driver): """Gets the screenshot of the current window as a binary data. @@ -114,8 +112,8 @@ def get_screenshot_as_png(driver): """ return driver.get_screenshot_as_png() - @staticmethod - def get_screenshot_save(driver, file_name): + @classmethod + def get_screenshot_save(cls, driver, file_name): """Gets the screenshot of the current window. Returns False if there is any IOError, else returns True. Use full paths in your filename. @@ -129,8 +127,8 @@ def get_screenshot_save(driver, file_name): """ return driver.save_screenshot(file_name) - @staticmethod - def set_window_size(driver, pos_x=800, pos_y=600): + @classmethod + def set_window_size(cls, driver, pos_x=800, pos_y=600): """Sets the width and height of the current window. (window.resizeTo) diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index 4480e10a..e666c33c 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -39,6 +39,7 @@ def test_browser_create(): ASSERT.is_instance(browser, Browser) ASSERT.is_instance(browser.config, BrowserConfig) ASSERT.not_none(browser.capabilities) + ASSERT.not_none(browser.driver_abs_path) if browser.config.browser not in ("iexplorer", "edge", "opera"): ASSERT.not_none(browser.options) diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index b1363751..bb6c6382 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -17,6 +17,42 @@ def test_browser_open(browser): browser.open() +@pytest.mark.dependency(depends=['browser_open']) +def test_common_getmaximizewindow(browser): + """TODO: doc method""" + ASSERT.not_none(browser.Commons.get_maximize_window(browser.driver)) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_gettitle(browser): + """TODO: doc method""" + ASSERT.not_none(browser.Commons.get_title(browser.driver)) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_getwindowhandle(browser): + """TODO: doc method""" + ASSERT.not_none(browser.Commons.get_window_handle(browser.driver)) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_getcapabilities(browser): + """TODO: doc method""" + ASSERT.not_none(browser.Commons.get_capabilities(browser.driver)) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_forward(browser): + """TODO: doc method""" + browser.Commons.forward(browser.driver) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_reload(browser): + """TODO: doc method""" + browser.Commons.reload(browser.driver) + + @pytest.mark.dependency(name="get_url", depends=['browser_open']) @pytest.mark.parametrize("wait", [0, 100]) def test_common_geturl(browser, wait): @@ -35,7 +71,25 @@ def test_common_getcurrenturl(browser): ASSERT.equals(url, cfg_url) -@pytest.mark.dependency(depends=['browser_open']) -def test_common_gettitle(browser): +@pytest.mark.dependency(depends=['browser_open', 'get_url']) +@pytest.mark.parametrize("expected", [False, True]) +def test_common_isurl(browser, expected): """TODO: doc method""" - ASSERT.not_none(browser.Commons.get_title(browser.driver)) + cfg_url = None + if expected: + cfg_url = CFG.get('bot').get('pages')[0].get('url') + _is = browser.Commons.is_url(browser.driver, cfg_url) + ASSERT.equals(_is, expected) + + +@pytest.mark.dependency(depends=['browser_open', 'get_url']) +@pytest.mark.parametrize("log", [None, 'browser', 'driver', 'client', 'server']) +def test_getlog_lognames(browser, log): + """Testcase: test_getlog_lognames""" + if not log: + with pytest.raises(Exception): + logs = browser.Commons.get_log(browser.driver, log_name=log) + return True + logs = browser.Commons.get_log(browser.driver, log_name=log) + ASSERT.not_none(logs) + ASSERT.is_instance(logs, list) From d12748d12cd5bdb9647521295557b96a15033dba Mon Sep 17 00:00:00 2001 From: netzulo Date: Sat, 8 Feb 2020 12:30:20 +0100 Subject: [PATCH 13/43] [qacode] added module for screenshots + divided functions on two modules - screenshots + dummy test - commons + removed property _modules at browser class --- qacode/core/browsers/browser.py | 8 +-- qacode/core/browsers/modules/__init__.py | 2 + qacode/core/browsers/modules/commons.py | 47 ----------------- qacode/core/browsers/modules/screenshots.py | 57 +++++++++++++++++++++ tests/browsers/suite_browsers.py | 3 +- tests/browsers/suite_module_commons.py | 2 +- tests/browsers/suite_module_screenshots.py | 11 ++++ 7 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 qacode/core/browsers/modules/screenshots.py create mode 100644 tests/browsers/suite_module_screenshots.py diff --git a/qacode/core/browsers/browser.py b/qacode/core/browsers/browser.py index f2fab599..73f37237 100644 --- a/qacode/core/browsers/browser.py +++ b/qacode/core/browsers/browser.py @@ -7,6 +7,7 @@ from qacode.core.browsers.browser_config import BrowserConfig from qacode.core.browsers.modules.commons import ModuleCommons from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.screenshots import ModuleScreenshots from qacode.core.browsers.modules.waits import ModuleWaits from qacode.core.exceptions.core_exception import CoreException # from qacode.core.loggers.log import Log @@ -36,6 +37,7 @@ def __init__(self, log, **kwargs): self.Commons = ModuleCommons self.Elements = ModuleElements self.Waits = ModuleWaits + self.Screenshots = ModuleScreenshots def __config__(self, config): """TODO: doc method""" @@ -157,7 +159,6 @@ def close(self): self._driver_wait = None self._driver_actions = None self._driver_touch = None - self._modules = None @property def config(self): @@ -189,11 +190,6 @@ def driver(self): """TODO: doc method""" return self._driver - @property - def modules(self): - """TODO: doc method""" - return self._modules - @property def session_id(self): """TODO: doc method""" diff --git a/qacode/core/browsers/modules/__init__.py b/qacode/core/browsers/modules/__init__.py index 5b1247bf..fe922c03 100644 --- a/qacode/core/browsers/modules/__init__.py +++ b/qacode/core/browsers/modules/__init__.py @@ -4,11 +4,13 @@ from qacode.core.browsers.modules.commons import ModuleCommons from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.screenshots import ModuleScreenshots from qacode.core.browsers.modules.waits import ModuleWaits __all__ = [ 'ModuleCommons', 'ModuleElements', + 'ModuleScreenshots', 'ModuleWaits', ] diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 074c2f65..19d0f519 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -80,53 +80,6 @@ def get_log(cls, driver, log_name='browser'): # log_name, err.msg)) return list() - @classmethod - def get_screenshot_as_base64(cls, driver): - """Gets the screenshot of the current window as a base64 encoded string - which is useful in embedded images in HTML - """ - return driver.get_screenshot_as_base64() - - @classmethod - def get_screenshot_as_file(cls, driver, file_name): - """Gets the screenshot of the current window. Returns False - if there is any IOError, else returns True. Use full paths - in your filename. - - Arguments: - file_name {str} -- name of file path where - want to save screenshot - - Returns: - list(byte) -- file binary object of screenshot bytes - """ - return driver.get_screenshot_as_file(file_name) - - @classmethod - def get_screenshot_as_png(cls, driver): - """Gets the screenshot of the current window as a - binary data. - - Returns: - File -- file binary object of screenshot with PNG format - """ - return driver.get_screenshot_as_png() - - @classmethod - def get_screenshot_save(cls, driver, file_name): - """Gets the screenshot of the current window. Returns False - if there is any IOError, else returns True. - Use full paths in your filename. - - Arguments: - file_name {str} -- name of file path where - want to save screenshot - - Returns: - list(byte) -- file binary object of screenshot bytes - """ - return driver.save_screenshot(file_name) - @classmethod def set_window_size(cls, driver, pos_x=800, pos_y=600): """Sets the width and height of the current diff --git a/qacode/core/browsers/modules/screenshots.py b/qacode/core/browsers/modules/screenshots.py new file mode 100644 index 00000000..1c4a2645 --- /dev/null +++ b/qacode/core/browsers/modules/screenshots.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +"""TODO""" + + +from selenium.common.exceptions import WebDriverException + + +class ModuleScreenshots(object): + """TODO: doc class""" + + + @classmethod + def get_screenshot_as_base64(cls, driver): + """Gets the screenshot of the current window as a base64 encoded string + which is useful in embedded images in HTML + """ + return driver.get_screenshot_as_base64() + + @classmethod + def get_screenshot_as_file(cls, driver, file_name): + """Gets the screenshot of the current window. Returns False + if there is any IOError, else returns True. Use full paths + in your filename. + + Arguments: + file_name {str} -- name of file path where + want to save screenshot + + Returns: + list(byte) -- file binary object of screenshot bytes + """ + return driver.get_screenshot_as_file(file_name) + + @classmethod + def get_screenshot_as_png(cls, driver): + """Gets the screenshot of the current window as a + binary data. + + Returns: + File -- file binary object of screenshot with PNG format + """ + return driver.get_screenshot_as_png() + + @classmethod + def get_screenshot_save(cls, driver, file_name): + """Gets the screenshot of the current window. Returns False + if there is any IOError, else returns True. + Use full paths in your filename. + + Arguments: + file_name {str} -- name of file path where + want to save screenshot + + Returns: + list(byte) -- file binary object of screenshot bytes + """ + return driver.save_screenshot(file_name) diff --git a/tests/browsers/suite_browsers.py b/tests/browsers/suite_browsers.py index e666c33c..eb1d0e1a 100644 --- a/tests/browsers/suite_browsers.py +++ b/tests/browsers/suite_browsers.py @@ -7,6 +7,7 @@ from qacode.core.browsers.browser_config import BrowserConfig from qacode.core.browsers.modules.commons import ModuleCommons from qacode.core.browsers.modules.elements import ModuleElements +from qacode.core.browsers.modules.screenshots import ModuleScreenshots from qacode.core.browsers.modules.waits import ModuleWaits from qacode.core.loggers.log import Log from qacode.core.testing.asserts import Assert @@ -56,6 +57,7 @@ def test_browser_open(): ASSERT.not_none(browser._driver_touch) ASSERT.equals(browser.Commons, ModuleCommons) ASSERT.equals(browser.Elements, ModuleElements) + ASSERT.equals(browser.Screenshots, ModuleScreenshots) ASSERT.equals(browser.Waits, ModuleWaits) browser_close(browser) @@ -70,4 +72,3 @@ def test_browser_close(): ASSERT.none(browser._driver_wait) ASSERT.none(browser._driver_actions) ASSERT.none(browser._driver_touch) - ASSERT.none(browser.modules) diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index bb6c6382..b34281b4 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -20,7 +20,7 @@ def test_browser_open(browser): @pytest.mark.dependency(depends=['browser_open']) def test_common_getmaximizewindow(browser): """TODO: doc method""" - ASSERT.not_none(browser.Commons.get_maximize_window(browser.driver)) + browser.Commons.get_maximize_window(browser.driver) @pytest.mark.dependency(depends=['browser_open']) diff --git a/tests/browsers/suite_module_screenshots.py b/tests/browsers/suite_module_screenshots.py new file mode 100644 index 00000000..35dd84ed --- /dev/null +++ b/tests/browsers/suite_module_screenshots.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers package""" + + +import pytest + + +@pytest.mark.dependency(depends=['browser_open']) +def test_mod_screenshots_dummy(): + """TODO: doc method""" + pytest.fail("WIP: not developed yet") From a2d0b16c5575c75490681e3be21ca2075b4474a0 Mon Sep 17 00:00:00 2001 From: netzulo Date: Sat, 8 Feb 2020 12:36:17 +0100 Subject: [PATCH 14/43] [qacode] coverage 100% for module commons --- qacode/core/browsers/modules/commons.py | 6 +++--- tests/browsers/suite_module_commons.py | 6 ++++++ tests/browsers/suite_module_elements.py | 1 - tests/browsers/suite_module_screenshots.py | 1 - tests/browsers/suite_module_waits.py | 1 - 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 19d0f519..8c609d92 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -81,12 +81,12 @@ def get_log(cls, driver, log_name='browser'): return list() @classmethod - def set_window_size(cls, driver, pos_x=800, pos_y=600): + def set_window_size(cls, driver, x=800, y=600): """Sets the width and height of the current window. (window.resizeTo) Keyword Arguments: - pos_x {int} -- width of new window size (default: {800}) - pos_y {int} -- height of new window size (default: {600}) + x {int} -- width of new window size (default: {800}) + y {int} -- height of new window size (default: {600}) """ driver.set_window_size(pos_x, pos_y) diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index b34281b4..bb751a8b 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -93,3 +93,9 @@ def test_getlog_lognames(browser, log): logs = browser.Commons.get_log(browser.driver, log_name=log) ASSERT.not_none(logs) ASSERT.is_instance(logs, list) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_common_setwindowsize(browser): + """TODO: doc method""" + browser.Commons.set_window_size(browser.driver) diff --git a/tests/browsers/suite_module_elements.py b/tests/browsers/suite_module_elements.py index 105ba9a2..3f744cfc 100644 --- a/tests/browsers/suite_module_elements.py +++ b/tests/browsers/suite_module_elements.py @@ -5,7 +5,6 @@ import pytest -@pytest.mark.dependency(name="browser_create") def test_mod_common_dummy(): """TODO: doc method""" pytest.fail("WIP: not developed yet") diff --git a/tests/browsers/suite_module_screenshots.py b/tests/browsers/suite_module_screenshots.py index 35dd84ed..6510e404 100644 --- a/tests/browsers/suite_module_screenshots.py +++ b/tests/browsers/suite_module_screenshots.py @@ -5,7 +5,6 @@ import pytest -@pytest.mark.dependency(depends=['browser_open']) def test_mod_screenshots_dummy(): """TODO: doc method""" pytest.fail("WIP: not developed yet") diff --git a/tests/browsers/suite_module_waits.py b/tests/browsers/suite_module_waits.py index 105ba9a2..3f744cfc 100644 --- a/tests/browsers/suite_module_waits.py +++ b/tests/browsers/suite_module_waits.py @@ -5,7 +5,6 @@ import pytest -@pytest.mark.dependency(name="browser_create") def test_mod_common_dummy(): """TODO: doc method""" pytest.fail("WIP: not developed yet") From 32347d3a47478ca8956667f2c4b4603940105f9e Mon Sep 17 00:00:00 2001 From: netzulo Date: Sat, 8 Feb 2020 12:39:18 +0100 Subject: [PATCH 15/43] [qacode] flake fix --- qacode/core/browsers/modules/commons.py | 2 +- qacode/core/browsers/modules/screenshots.py | 4 ---- tests/browsers/suite_module_commons.py | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/qacode/core/browsers/modules/commons.py b/qacode/core/browsers/modules/commons.py index 8c609d92..3ba5ac41 100644 --- a/qacode/core/browsers/modules/commons.py +++ b/qacode/core/browsers/modules/commons.py @@ -89,4 +89,4 @@ def set_window_size(cls, driver, x=800, y=600): x {int} -- width of new window size (default: {800}) y {int} -- height of new window size (default: {600}) """ - driver.set_window_size(pos_x, pos_y) + driver.set_window_size(x, y) diff --git a/qacode/core/browsers/modules/screenshots.py b/qacode/core/browsers/modules/screenshots.py index 1c4a2645..b4e5e86d 100644 --- a/qacode/core/browsers/modules/screenshots.py +++ b/qacode/core/browsers/modules/screenshots.py @@ -2,13 +2,9 @@ """TODO""" -from selenium.common.exceptions import WebDriverException - - class ModuleScreenshots(object): """TODO: doc class""" - @classmethod def get_screenshot_as_base64(cls, driver): """Gets the screenshot of the current window as a base64 encoded string diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/suite_module_commons.py index bb751a8b..1c8af5af 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/suite_module_commons.py @@ -83,7 +83,8 @@ def test_common_isurl(browser, expected): @pytest.mark.dependency(depends=['browser_open', 'get_url']) -@pytest.mark.parametrize("log", [None, 'browser', 'driver', 'client', 'server']) +@pytest.mark.parametrize( + "log", [None, 'browser', 'driver', 'client', 'server']) def test_getlog_lognames(browser, log): """Testcase: test_getlog_lognames""" if not log: From 73e2bea87582591bdd591466f2075bc4951d4d4a Mon Sep 17 00:00:00 2001 From: netzulo Date: Sun, 9 Feb 2020 13:29:17 +0100 Subject: [PATCH 16/43] [qacode] added loggers tests --- conftest.py | 9 ++- qacode/core/browsers/modules/elements.py | 68 ++++++++----------- tests/browsers/modules/__init__.py | 2 + .../{ => modules}/suite_module_commons.py | 7 +- .../browsers/modules/suite_module_elements.py | 45 ++++++++++++ .../modules/suite_module_elements_raises.py | 40 +++++++++++ .../{ => modules}/suite_module_screenshots.py | 2 +- .../{ => modules}/suite_module_waits.py | 2 +- tests/browsers/suite_module_elements.py | 10 --- tests/loggers/__init__.py | 2 + tests/loggers/suite_loggers.py | 62 +++++++++++++++++ 11 files changed, 193 insertions(+), 56 deletions(-) create mode 100644 tests/browsers/modules/__init__.py rename tests/browsers/{ => modules}/suite_module_commons.py (92%) create mode 100644 tests/browsers/modules/suite_module_elements.py create mode 100644 tests/browsers/modules/suite_module_elements_raises.py rename tests/browsers/{ => modules}/suite_module_screenshots.py (67%) rename tests/browsers/{ => modules}/suite_module_waits.py (66%) delete mode 100644 tests/browsers/suite_module_elements.py create mode 100644 tests/loggers/__init__.py create mode 100644 tests/loggers/suite_loggers.py diff --git a/conftest.py b/conftest.py index ad06b20a..7fa86478 100644 --- a/conftest.py +++ b/conftest.py @@ -10,6 +10,9 @@ def browser(): CFG = settings(file_path="qacode/configs/", file_name="settings.json") bot = Bot(**CFG) - before = len(bot.browsers) - yield bot.browser_create(bot.config.browsers[0]) - bot.browsers[0].close() + try: + yield bot.browser_create(bot.config.browsers[0]) + except Exception as err: + raise err + finally: + bot.browsers[0].close() diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py index 3eb6ec02..b6cca87c 100644 --- a/qacode/core/browsers/modules/elements.py +++ b/qacode/core/browsers/modules/elements.py @@ -15,62 +15,54 @@ class ModuleElements(object): """TODO: doc class""" @classmethod - def find_element(cls, driver, selector, locator=By.CSS_SELECTOR): + def find(cls, driver, selector, locator=By.CSS_SELECTOR): """Just divided execution ways for search web element throught selenium """ if locator is None: - raise Exception("find_element: Locator can't be None") - try: - return driver.find_element(locator, selector) - except NoSuchElementException: - raise Exception("find_element: Element not found") + raise Exception("find: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + return driver.find_element(locator, selector) @classmethod - def find_elements(cls, driver, selector, locator=By.CSS_SELECTOR, - raises_zero=True): + def finds(cls, driver, selector, locator=By.CSS_SELECTOR, + raises_zero=True): """Just divided execution ways for search web elements throught selenium """ if locator is None: - raise Exception("find_elements: Locator can't be None") - try: - elements = driver.find_elements(locator, selector) - if len(elements) == 0 and raises_zero: - raise Exception("find_elements: 0 elements found") - return elements - except NoSuchElementException: - raise Exception("find_elements: Element not found") + raise Exception("finds: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + elements = driver.find_elements(locator, selector) + if len(elements) == 0 and raises_zero: + raise Exception("finds: 0 elements found") + return elements @classmethod - def find_element_wait(cls, driver_wait, selector, - locator=By.CSS_SELECTOR): + def find_wait(cls, driver_wait, selector, locator=By.CSS_SELECTOR): """Search element using WebDriverWait class and ElementConditions presence_of_element_located """ - try: - return driver_wait.until( - EC.presence_of_element_located((locator, selector))) - except (NoSuchElementException, StaleElementReferenceException): - return driver_wait.until( - EC.visibility_of_element_located((locator, selector))) + if locator is None: + raise Exception("find_wait: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + expectation = EC.presence_of_element_located((locator, selector)) + return driver_wait.until(expectation) @classmethod - def find_elements_wait(cls, driver_wait, selector, - locator=By.CSS_SELECTOR): + def finds_wait(cls, driver_wait, selector, locator=By.CSS_SELECTOR): """Search elements using WebDriverWait class and ElementConditions presence_of_all_elements_located """ - try: - return driver_wait.until( - EC.presence_of_all_elements_located((locator, selector))) - except (NoSuchElementException, StaleElementReferenceException): - return driver_wait.until( - EC.visibility_of_all_elements_located((locator, selector))) + if locator is None: + raise Exception("finds_wait: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + expectation = EC.presence_of_all_elements_located((locator, selector)) + return driver_wait.until(expectation) @classmethod - def find_element_child(cls, driver, element, child_selector, - locator=By.CSS_SELECTOR): + def find_child(cls, driver, element, child_selector, + locator=By.CSS_SELECTOR): """TODO: doc method""" if element is None or not isinstance(element, WebElement): raise Exception("Cant find child if not element") @@ -86,8 +78,8 @@ def find_element_child(cls, driver, element, child_selector, raise Exception(err) @classmethod - def find_element_children(cls, driver, element, child_selector, - locator=By.CSS_SELECTOR): + def find_children(cls, driver, element, child_selector, + locator=By.CSS_SELECTOR): """TODO: doc method""" if element is None or not isinstance(element, WebElement): raise Exception("Cant find children if not element found") @@ -103,12 +95,12 @@ def find_element_children(cls, driver, element, child_selector, raise Exception(err) @classmethod - def find_elements_child(cls): + def finds_child(cls): """TODO: doc method""" raise NotImplementedError("TODO: open an issue at github please") @classmethod - def find_elements_children(cls): + def finds_children(cls): """TODO: doc method""" raise NotImplementedError("TODO: open an issue at github please") diff --git a/tests/browsers/modules/__init__.py b/tests/browsers/modules/__init__.py new file mode 100644 index 00000000..a1c004f5 --- /dev/null +++ b/tests/browsers/modules/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests.browsers.modules""" diff --git a/tests/browsers/suite_module_commons.py b/tests/browsers/modules/suite_module_commons.py similarity index 92% rename from tests/browsers/suite_module_commons.py rename to tests/browsers/modules/suite_module_commons.py index 1c8af5af..4e0e9ddc 100644 --- a/tests/browsers/suite_module_commons.py +++ b/tests/browsers/modules/suite_module_commons.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""Test Suite module for tests.browsers package""" +"""Test Suite module for tests.browsers.modules package""" import pytest @@ -12,9 +12,10 @@ @pytest.mark.dependency(name="browser_open") -def test_browser_open(browser): +def test_commons_browser_open(browser): """TODO: doc method""" - browser.open() + if browser.driver is None: + browser.open() @pytest.mark.dependency(depends=['browser_open']) diff --git a/tests/browsers/modules/suite_module_elements.py b/tests/browsers/modules/suite_module_elements.py new file mode 100644 index 00000000..4ae9c19c --- /dev/null +++ b/tests/browsers/modules/suite_module_elements.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers.modules package""" + + +import pytest +from qacode.core.testing.asserts import Assert +from qacode.utils import settings +from selenium.webdriver.remote.webelement import WebElement + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +@pytest.mark.dependency(name="browser_open") +def test_elements_browser_open(browser): + """TODO: doc method""" + if browser.driver is None: + browser.open() + cfg_url = CFG.get('bot').get('pages')[0].get('url') + ASSERT.not_none(cfg_url) + browser.Commons.get_url(browser.driver, cfg_url) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_find(browser): + """TODO: doc method""" + selector = CFG.get('bot').get('controls')[0].get('selector') + ASSERT.is_instance(selector, str) + ASSERT.greater(len(selector), 0, "invalid empty selector") + element = browser.Elements.find(browser.driver, selector) + ASSERT.is_instance(element, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_finds(browser): + """TODO: doc method""" + _selector = CFG.get('bot').get('controls')[0].get('selector') + selector = "{}{}".format(_selector, " input") + ASSERT.is_instance(selector, str) + ASSERT.greater(len(selector), 0, "invalid empty selector") + elements = browser.Elements.finds(browser.driver, selector) + ASSERT.is_instance(elements, list) + for element in elements: + ASSERT.is_instance(element, WebElement) diff --git a/tests/browsers/modules/suite_module_elements_raises.py b/tests/browsers/modules/suite_module_elements_raises.py new file mode 100644 index 00000000..6a363dfe --- /dev/null +++ b/tests/browsers/modules/suite_module_elements_raises.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.browsers.modules package""" + + +import pytest +from qacode.core.testing.asserts import Assert +from qacode.utils import settings +from selenium.webdriver.common.by import By + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +@pytest.mark.dependency(name="browser_open") +def test_elements_browser_open(browser): + """TODO: doc method""" + if browser.driver is None: + browser.open() + cfg_url = CFG.get('bot').get('pages')[0].get('url') + ASSERT.not_none(cfg_url) + browser.Commons.get_url(browser.driver, cfg_url) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [("invalid", None)]) +def test_elements_find_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(Exception): + browser.Elements.find(browser.driver, selector, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [ + ("invalid", None), ("invalid", By.CSS_SELECTOR) +]) +def test_elements_finds_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(Exception): + browser.Elements.finds(browser.driver, selector, locator=locator) diff --git a/tests/browsers/suite_module_screenshots.py b/tests/browsers/modules/suite_module_screenshots.py similarity index 67% rename from tests/browsers/suite_module_screenshots.py rename to tests/browsers/modules/suite_module_screenshots.py index 6510e404..4b705368 100644 --- a/tests/browsers/suite_module_screenshots.py +++ b/tests/browsers/modules/suite_module_screenshots.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""Test Suite module for tests.browsers package""" +"""Test Suite module for tests.browsers.modules package""" import pytest diff --git a/tests/browsers/suite_module_waits.py b/tests/browsers/modules/suite_module_waits.py similarity index 66% rename from tests/browsers/suite_module_waits.py rename to tests/browsers/modules/suite_module_waits.py index 3f744cfc..76e6546d 100644 --- a/tests/browsers/suite_module_waits.py +++ b/tests/browsers/modules/suite_module_waits.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""Test Suite module for tests.browsers package""" +"""Test Suite module for tests.browsers.modules package""" import pytest diff --git a/tests/browsers/suite_module_elements.py b/tests/browsers/suite_module_elements.py deleted file mode 100644 index 3f744cfc..00000000 --- a/tests/browsers/suite_module_elements.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for tests.browsers package""" - - -import pytest - - -def test_mod_common_dummy(): - """TODO: doc method""" - pytest.fail("WIP: not developed yet") diff --git a/tests/loggers/__init__.py b/tests/loggers/__init__.py new file mode 100644 index 00000000..0d42adbd --- /dev/null +++ b/tests/loggers/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests.loggers""" diff --git a/tests/loggers/suite_loggers.py b/tests/loggers/suite_loggers.py new file mode 100644 index 00000000..d3f24f5f --- /dev/null +++ b/tests/loggers/suite_loggers.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for qacode.core.bots package""" + + +import pytest +from qacode.core.loggers.log import Log +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +def log_create(cfg, level=None): + """TODO: doc mehotd""" + cfg = cfg.get('log').copy() + if level is not None: + cfg.update({"level": level}) + return Log(**cfg) + + +@pytest.mark.dependency(name="log_create") +def test_log_create(): + """TODO: doc method""" + log = log_create(CFG) + ASSERT.is_instance(log, Log) + + +@pytest.mark.dependency(depends=['log_create']) +def test_log_debug(): + """TODO: doc method""" + log = log_create(CFG, level="DEBUG") + log.debug("Test DEBUG level") + + +@pytest.mark.dependency(depends=['log_create']) +def test_log_info(): + """TODO: doc method""" + log = log_create(CFG, level="INFO") + log.info("Test INFO level") + + +@pytest.mark.dependency(depends=['log_create']) +def test_log_warning(): + """TODO: doc method""" + log = log_create(CFG, level="WARNING") + log.warning("Test WARNING level") + + +@pytest.mark.dependency(depends=['log_create']) +def test_log_error(): + """TODO: doc method""" + log = log_create(CFG, level="ERROR") + log.error("Test ERROR level") + + +@pytest.mark.dependency(depends=['log_create']) +def test_log_critical(): + """TODO: doc method""" + log = log_create(CFG, level="CRITICAL") + log.critical("Test CRITICAL level") From 7a151c784db44f06a743f64cd0601d1daa6adc47 Mon Sep 17 00:00:00 2001 From: netzulo Date: Sun, 9 Feb 2020 19:44:02 +0100 Subject: [PATCH 17/43] [qacode] update elements coverage to 70% --- qacode/core/browsers/modules/elements.py | 54 +++++++--------- .../browsers/modules/suite_module_elements.py | 62 ++++++++++++++++++- .../modules/suite_module_elements_raises.py | 58 ++++++++++++++++- 3 files changed, 137 insertions(+), 37 deletions(-) diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py index b6cca87c..b8155cde 100644 --- a/qacode/core/browsers/modules/elements.py +++ b/qacode/core/browsers/modules/elements.py @@ -2,10 +2,6 @@ """TODO""" -from selenium.common.exceptions import ( - NoSuchElementException, - StaleElementReferenceException, -) from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC @@ -61,47 +57,41 @@ def finds_wait(cls, driver_wait, selector, locator=By.CSS_SELECTOR): return driver_wait.until(expectation) @classmethod - def find_child(cls, driver, element, child_selector, - locator=By.CSS_SELECTOR): + def find_child(cls, element, child_selector, locator=By.CSS_SELECTOR): """TODO: doc method""" - if element is None or not isinstance(element, WebElement): - raise Exception("Cant find child if not element") - try: - return element.find_element(locator, child_selector) - except (NoSuchElementException, StaleElementReferenceException) as err: - # at Java lang exist 1 expected condition - # named : visibilityOfNestedElementsLocatedBy - # doc : https://selenium-python.readthedocs.io/waits.html - # maybe must exist at python too - # then, create and use new method named: find_element_child_wait() - # raise NotImplementedError("TODO:open an issue at github please") - raise Exception(err) + if locator is None: + raise Exception("finds_wait: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + return element.find_element(locator, child_selector) @classmethod - def find_children(cls, driver, element, child_selector, - locator=By.CSS_SELECTOR): + def find_children(cls, element, child_selector, locator=By.CSS_SELECTOR): """TODO: doc method""" - if element is None or not isinstance(element, WebElement): - raise Exception("Cant find children if not element found") - try: - return element.find_elements(locator, child_selector) - except (NoSuchElementException, StaleElementReferenceException) as err: - # at Java lang exist 1 expected condition - # named : visibilityOfNestedElementsLocatedBy - # doc : https://selenium-python.readthedocs.io/waits.html - # maybe must exist at python too - # then, create and use new method named: find_element_child_wait() - # raise NotImplementedError("TODO:open an issue at github please") - raise Exception(err) + if locator is None: + raise Exception("finds_wait: Locator can't be None") + # Not found: NoSuchElementException, StaleElementReferenceException + return element.find_elements(locator, child_selector) @classmethod def finds_child(cls): """TODO: doc method""" + # at Java lang exist 1 expected condition + # named : visibilityOfNestedElementsLocatedBy + # doc : https://selenium-python.readthedocs.io/waits.html + # maybe must exist at python too + # then, create and use new method named: find_element_child_wait() + # raise NotImplementedError("TODO:open an issue at github please") raise NotImplementedError("TODO: open an issue at github please") @classmethod def finds_children(cls): """TODO: doc method""" + # at Java lang exist 1 expected condition + # named : visibilityOfNestedElementsLocatedBy + # doc : https://selenium-python.readthedocs.io/waits.html + # maybe must exist at python too + # then, create and use new method named: find_element_child_wait() + # raise NotImplementedError("TODO:open an issue at github please") raise NotImplementedError("TODO: open an issue at github please") @classmethod diff --git a/tests/browsers/modules/suite_module_elements.py b/tests/browsers/modules/suite_module_elements.py index 4ae9c19c..dbfe7a25 100644 --- a/tests/browsers/modules/suite_module_elements.py +++ b/tests/browsers/modules/suite_module_elements.py @@ -12,6 +12,23 @@ CFG = settings(file_path="qacode/configs/", file_name="settings.json") +def setup_selectors(): + """TODO: doc method""" + # setup parent + selector = CFG.get('bot').get('controls')[0].get('selector') + ASSERT.is_instance(selector, str) + ASSERT.greater(len(selector), 0, "invalid empty selector") + # setup child + child_sel = CFG.get('bot').get('controls')[1].get('selector') + ASSERT.is_instance(child_sel, str) + ASSERT.greater(len(child_sel), 0, "invalid empty selector") + # setup child + children_sel = "*" + ASSERT.is_instance(child_sel, str) + ASSERT.greater(len(child_sel), 0, "invalid empty selector") + return {"parent": selector, "child": child_sel, "children": children_sel} + + @pytest.mark.dependency(name="browser_open") def test_elements_browser_open(browser): """TODO: doc method""" @@ -25,9 +42,7 @@ def test_elements_browser_open(browser): @pytest.mark.dependency(depends=['browser_open']) def test_elements_find(browser): """TODO: doc method""" - selector = CFG.get('bot').get('controls')[0].get('selector') - ASSERT.is_instance(selector, str) - ASSERT.greater(len(selector), 0, "invalid empty selector") + selector = setup_selectors().get('parent') element = browser.Elements.find(browser.driver, selector) ASSERT.is_instance(element, WebElement) @@ -43,3 +58,44 @@ def test_elements_finds(browser): ASSERT.is_instance(elements, list) for element in elements: ASSERT.is_instance(element, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_findwait(browser): + """TODO: doc method""" + selector = setup_selectors().get('parent') + element = browser.Elements.find_wait(browser._driver_wait, selector) + ASSERT.is_instance(element, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_findswait(browser): + """TODO: doc method""" + selector = "{}{}".format(setup_selectors().get('parent'), " input") + elements = browser.Elements.finds_wait(browser._driver_wait, selector) + ASSERT.is_instance(elements, list) + for element in elements: + ASSERT.is_instance(element, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_findchild(browser): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('parent')) + ASSERT.is_instance(element, WebElement) + child = browser.Elements.find_child(element, selectors.get('child')) + ASSERT.is_instance(child, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_findchildren(browser): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('parent')) + ASSERT.is_instance(element, WebElement) + children = browser.Elements.find_children( + element, selectors.get('children')) + ASSERT.is_instance(children, list) + for child in children: + ASSERT.is_instance(child, WebElement) diff --git a/tests/browsers/modules/suite_module_elements_raises.py b/tests/browsers/modules/suite_module_elements_raises.py index 6a363dfe..4e9679c5 100644 --- a/tests/browsers/modules/suite_module_elements_raises.py +++ b/tests/browsers/modules/suite_module_elements_raises.py @@ -13,7 +13,7 @@ @pytest.mark.dependency(name="browser_open") -def test_elements_browser_open(browser): +def test_elements_raises_browser_open(browser): """TODO: doc method""" if browser.driver is None: browser.open() @@ -32,9 +32,63 @@ def test_elements_find_raises(browser, selector, locator): @pytest.mark.dependency(depends=['browser_open']) @pytest.mark.parametrize("selector, locator", [ - ("invalid", None), ("invalid", By.CSS_SELECTOR) + ("invalid", None), ("invalid", By.CSS_SELECTOR), ]) def test_elements_finds_raises(browser, selector, locator): """TODO: doc method""" with pytest.raises(Exception): browser.Elements.finds(browser.driver, selector, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [("invalid", None)]) +def test_elements_findwait_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(Exception): + browser.Elements.find_wait(browser.driver, selector, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [("invalid", None)]) +def test_elements_findswait_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(Exception): + browser.Elements.finds_wait(browser.driver, selector, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("parent_sel,child_sel,locator", [ + ("body", "invalid", None) +]) +def test_elements_findchild_raises(browser, parent_sel, child_sel, locator): + """TODO: doc method""" + element = browser.Elements.find(browser.driver, parent_sel) + with pytest.raises(Exception): + browser.Elements.find_child(element, child_sel, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("parent_sel,child_sel,locator", [ + ("body", "invalid", None) +]) +def test_elements_findchildren_raises(browser, parent_sel, child_sel, locator): + """TODO: doc method""" + element = browser.Elements.find(browser.driver, parent_sel) + with pytest.raises(Exception): + browser.Elements.find_children(element, child_sel, locator=locator) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [("invalid", None)]) +def test_elements_findschild_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(NotImplementedError): + browser.Elements.finds_child() + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("selector, locator", [("invalid", None)]) +def test_elements_findschildren_raises(browser, selector, locator): + """TODO: doc method""" + with pytest.raises(NotImplementedError): + browser.Elements.finds_children() From ae8dc22217863da0ca70475207dbe3bc6fb53d59 Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 10 Feb 2020 03:19:02 +0100 Subject: [PATCH 18/43] [qacode] added so much tests today read commit files --- qacode/core/browsers/modules/elements.py | 22 +++---- qacode/core/browsers/modules/screenshots.py | 8 +-- qacode/core/browsers/modules/waits.py | 59 +++++++------------ qacode/core/testing/asserts.py | 36 +---------- .../browsers/modules/suite_module_elements.py | 47 +++++++++------ .../modules/suite_module_elements_raises.py | 11 ++++ .../modules/suite_module_screenshots.py | 38 +++++++++++- tests/browsers/modules/suite_module_waits.py | 40 ++++++++++++- tests/utils.py | 27 +++++++++ 9 files changed, 180 insertions(+), 108 deletions(-) create mode 100644 tests/utils.py diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py index b8155cde..2c43fe64 100644 --- a/qacode/core/browsers/modules/elements.py +++ b/qacode/core/browsers/modules/elements.py @@ -3,7 +3,6 @@ from selenium.webdriver.common.by import By -from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC @@ -108,15 +107,18 @@ def ele_click(cls, element): def ele_write(cls, element, text=None): """Over element perform send_keys , if not sended will write empty over element + + Returns: + WebElement -- returns element clicked (to allow chaining) """ - if not isinstance(element, WebElement): - raise Exception("Param 'element' it's not WebElement") - if text is not None: - element.send_keys(text) + if not text: + # it's neccessary because some fields shows + # validation message and color just after + # try to send empty message + element.send_keys('') else: - # it's neccessary because some fields shows validation message and - # color after try to send empty message - element.send_keys() + element.send_keys(text) + return element @classmethod def ele_attribute(cls, element, attr_name): @@ -126,8 +128,8 @@ def ele_attribute(cls, element, attr_name): returns the value of the attribute with the same name. If there's no attribute with that name, None is returned. """ - value = str(element.get_attribute(attr_name)) - if value is None or value == attr_name: + value = element.get_attribute(attr_name) + if value is None: raise Exception("Attr '{}' not found".format(attr_name)) return value diff --git a/qacode/core/browsers/modules/screenshots.py b/qacode/core/browsers/modules/screenshots.py index b4e5e86d..47085bdd 100644 --- a/qacode/core/browsers/modules/screenshots.py +++ b/qacode/core/browsers/modules/screenshots.py @@ -6,14 +6,14 @@ class ModuleScreenshots(object): """TODO: doc class""" @classmethod - def get_screenshot_as_base64(cls, driver): + def as_base64(cls, driver): """Gets the screenshot of the current window as a base64 encoded string which is useful in embedded images in HTML """ return driver.get_screenshot_as_base64() @classmethod - def get_screenshot_as_file(cls, driver, file_name): + def as_file(cls, driver, file_name): """Gets the screenshot of the current window. Returns False if there is any IOError, else returns True. Use full paths in your filename. @@ -28,7 +28,7 @@ def get_screenshot_as_file(cls, driver, file_name): return driver.get_screenshot_as_file(file_name) @classmethod - def get_screenshot_as_png(cls, driver): + def as_png(cls, driver): """Gets the screenshot of the current window as a binary data. @@ -38,7 +38,7 @@ def get_screenshot_as_png(cls, driver): return driver.get_screenshot_as_png() @classmethod - def get_screenshot_save(cls, driver, file_name): + def save(cls, driver, file_name): """Gets the screenshot of the current window. Returns False if there is any IOError, else returns True. Use full paths in your filename. diff --git a/qacode/core/browsers/modules/waits.py b/qacode/core/browsers/modules/waits.py index 8fbca290..80caeea5 100644 --- a/qacode/core/browsers/modules/waits.py +++ b/qacode/core/browsers/modules/waits.py @@ -4,60 +4,41 @@ from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC -from selenium.webdriver.support.ui import WebDriverWait class ModuleWaits(object): """TODO: doc class""" @staticmethod - def ele_wait_invisible(driver, selector, locator=By.CSS_SELECTOR, - timeout=0): + def ele_invisible(driver_wait, selector, locator=By.CSS_SELECTOR): """Wait for invisible element (display:none), returns element""" if selector is None: - raise Exception( - "Can't wait invisible element if None selector given") - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(driver, timeout) - try: - element = driver_wait.until( - EC.invisibility_of_element_located(locator_tuple)) - except Exception: - raise Exception("Fails at wait for invisible element") - return element + raise Exception("Not selector provided") + expectation = EC.invisibility_of_element_located((locator, selector)) + return driver_wait.until(expectation) @staticmethod - def ele_wait_visible(driver, element, timeout=0): + def ele_visible(driver_wait, element): """Wait for visible condition element, returns self""" if element is None: - raise Exception("Can't wait visible if element is None") - driver_wait = WebDriverWait(driver, timeout) - try: - element = driver_wait.until(EC.visibility_of(element)) - except Exception: - raise Exception("Fails at wait for visible element") - return element + raise Exception("Not element provided") + expectation = EC.visibility_of(element) + return driver_wait.until(expectation) @staticmethod - def ele_wait_text(driver, selector, text, - locator=By.CSS_SELECTOR, timeout=0): + def ele_text(driver_wait, selector, text, locator=By.CSS_SELECTOR): """Wait if the given text is present in the specified element""" - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(driver, timeout) - try: - return driver_wait.until( - EC.text_to_be_present_in_element(locator_tuple, text)) - except Exception: - raise Exception("Fails at wait for element text") + if selector is None: + raise Exception("Not selector provided") + expectation = EC.text_to_be_present_in_element( + (locator, selector), text) + return driver_wait.until(expectation) @staticmethod - def ele_wait_value(driver, selector, value, - locator=By.CSS_SELECTOR, timeout=0): + def ele_value(driver_wait, selector, value, locator=By.CSS_SELECTOR): """Wait if the given value is present in the specified element""" - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(driver, timeout) - try: - return driver_wait.until( - EC.text_to_be_present_in_element_value(locator_tuple, value)) - except Exception: - raise Exception("Fails at wait for element value") + if selector is None: + raise Exception("Not selector provided") + expectation = EC.text_to_be_present_in_element_value( + (locator, selector), value) + return driver_wait.until(expectation) diff --git a/qacode/core/testing/asserts.py b/qacode/core/testing/asserts.py index c8091ce2..0bf18904 100644 --- a/qacode/core/testing/asserts.py +++ b/qacode/core/testing/asserts.py @@ -54,42 +54,11 @@ def not_equals(self, actual, expected, msg=None): raise AssertionError(actual, expected, _msg) return True - def equals_url(self, actual, expected, msg=None, wait=0): - """Allow to compare 2 urls and check if 1st it's equals to 2nd url - - Arguments: - actual {type} -- actual value - expected {type} -- expected value - - Keyword Arguments: - wait {int} -- Wait time on Runtime execution before execute - next lane of code (default: {0}) - - Raises: - AssertionError -- [description] - """ - _msg = self.message( - "assert_equals_url", actual, expected, msg=msg) - self.sleep(wait) - if actual != expected: - raise AssertionError(actual, expected, _msg) - return True - - def not_equals_url(self, actual, expected, msg=None, wait=0): - """Allow to compare 2 urls to check if 1st isn't equals to 2nd url""" - _msg = self.message( - "assert_not_equals_url", actual, expected, msg=msg) - self.sleep(wait) - if actual == expected: - raise AssertionError(actual, expected, _msg) - return True - def contains_url(self, actual, contains, msg=None, wait=0): """Allow to compare 2 urls and check if 1st contains 2nd url""" _msg = self.message( "assert_contains_url", actual, contains, msg=msg) - self.sleep(wait) - if actual not in contains: + if contains not in actual: raise AssertionError(actual, contains, _msg) return True @@ -97,8 +66,7 @@ def not_contains_url(self, actual, contains, msg=None, wait=0): """Allow to compare 2 urls and check if 1st not contains 2nd url""" _msg = self.message( "assert_not_contains_url", actual, contains, msg=msg) - self.sleep(wait) - if actual in contains: + if contains in actual: raise AssertionError(actual, contains, _msg) return True diff --git a/tests/browsers/modules/suite_module_elements.py b/tests/browsers/modules/suite_module_elements.py index dbfe7a25..5eb9da4a 100644 --- a/tests/browsers/modules/suite_module_elements.py +++ b/tests/browsers/modules/suite_module_elements.py @@ -6,29 +6,13 @@ from qacode.core.testing.asserts import Assert from qacode.utils import settings from selenium.webdriver.remote.webelement import WebElement +from tests.utils import setup_selectors ASSERT = Assert() CFG = settings(file_path="qacode/configs/", file_name="settings.json") -def setup_selectors(): - """TODO: doc method""" - # setup parent - selector = CFG.get('bot').get('controls')[0].get('selector') - ASSERT.is_instance(selector, str) - ASSERT.greater(len(selector), 0, "invalid empty selector") - # setup child - child_sel = CFG.get('bot').get('controls')[1].get('selector') - ASSERT.is_instance(child_sel, str) - ASSERT.greater(len(child_sel), 0, "invalid empty selector") - # setup child - children_sel = "*" - ASSERT.is_instance(child_sel, str) - ASSERT.greater(len(child_sel), 0, "invalid empty selector") - return {"parent": selector, "child": child_sel, "children": children_sel} - - @pytest.mark.dependency(name="browser_open") def test_elements_browser_open(browser): """TODO: doc method""" @@ -99,3 +83,32 @@ def test_elements_findchildren(browser): ASSERT.is_instance(children, list) for child in children: ASSERT.is_instance(child, WebElement) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_elements_eleclick(browser): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('child')) + ele = browser.Elements.ele_click(element) + ASSERT.equals(element, ele) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("text", [None, "write_something"]) +def test_elements_elewrite(browser, text): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('child')) + ele = browser.Elements.ele_write(element, text=text) + ASSERT.equals(element, ele) + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("attr_name", ["id"]) +def test_elements_eleattribute(browser, attr_name): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('child')) + attr = browser.Elements.ele_attribute(element, attr_name) + ASSERT.is_instance(attr, str) diff --git a/tests/browsers/modules/suite_module_elements_raises.py b/tests/browsers/modules/suite_module_elements_raises.py index 4e9679c5..79ad4311 100644 --- a/tests/browsers/modules/suite_module_elements_raises.py +++ b/tests/browsers/modules/suite_module_elements_raises.py @@ -6,6 +6,7 @@ from qacode.core.testing.asserts import Assert from qacode.utils import settings from selenium.webdriver.common.by import By +from tests.utils import setup_selectors ASSERT = Assert() @@ -92,3 +93,13 @@ def test_elements_findschildren_raises(browser, selector, locator): """TODO: doc method""" with pytest.raises(NotImplementedError): browser.Elements.finds_children() + + +@pytest.mark.dependency(depends=['browser_open']) +@pytest.mark.parametrize("attr_name", ["doesnotexist"]) +def test_elements_eleattribute_raises(browser, attr_name): + """TODO: doc method""" + selectors = setup_selectors() + element = browser.Elements.find(browser.driver, selectors.get('child')) + with pytest.raises(Exception): + browser.Elements.ele_attribute(element, attr_name) diff --git a/tests/browsers/modules/suite_module_screenshots.py b/tests/browsers/modules/suite_module_screenshots.py index 4b705368..5a7803da 100644 --- a/tests/browsers/modules/suite_module_screenshots.py +++ b/tests/browsers/modules/suite_module_screenshots.py @@ -3,8 +3,42 @@ import pytest +from qacode.core.testing.asserts import Assert +from qacode.utils import settings -def test_mod_screenshots_dummy(): +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +@pytest.mark.dependency(name="browser_open") +def test_screenshot_browser_open(browser): + """TODO: doc method""" + if browser.driver is None: + browser.open() + + +@pytest.mark.dependency(depends=['browser_open']) +def test_screenshot_asbase64(browser): + """TODO: doc method""" + base64 = browser.Screenshots.as_base64(browser.driver) + ASSERT.is_instance(base64, str) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_screenshot_asfile(browser): + """TODO: doc method""" + ASSERT.true(browser.Screenshots.as_file(browser.driver, "qacode.jpg")) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_screenshot_aspng(browser): + """TODO: doc method""" + _bytes = browser.Screenshots.as_png(browser.driver) + ASSERT.is_instance(_bytes, bytes) + + +@pytest.mark.dependency(depends=['browser_open']) +def test_screenshot_save(browser): """TODO: doc method""" - pytest.fail("WIP: not developed yet") + ASSERT.true(browser.Screenshots.save(browser.driver, "qacode.jpeg")) diff --git a/tests/browsers/modules/suite_module_waits.py b/tests/browsers/modules/suite_module_waits.py index 76e6546d..986d7ac8 100644 --- a/tests/browsers/modules/suite_module_waits.py +++ b/tests/browsers/modules/suite_module_waits.py @@ -3,8 +3,44 @@ import pytest +from qacode.core.testing.asserts import Assert +from qacode.utils import settings -def test_mod_common_dummy(): +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +@pytest.mark.dependency(name="browser_open") +def test_waits_browser_open(browser): + """TODO: doc method""" + if browser.driver is None: + browser.open() + + +@pytest.mark.dependency(depends=['browser_open']) +def test_waits_eleinvisible(browser): + """TODO: doc method""" + # browser.Waits.ele_invisible(browser._driver_wait) + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['browser_open']) +def test_waits_elevisible(browser): + """TODO: doc method""" + # browser.Waits.ele_visible(browser._driver_wait) + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['browser_open']) +def test_waits_eletext(browser): + """TODO: doc method""" + # browser.Waits.ele_text(browser._driver_wait) + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['browser_open']) +def test_waits_elevalue(browser): """TODO: doc method""" - pytest.fail("WIP: not developed yet") + # browser.Waits.ele_value(browser._driver_wait) + raise NotImplementedError("WIP: not developed yet") diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..4ded5f92 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for tests.utils package""" + + +from qacode.core.testing.asserts import Assert +from qacode.utils import settings + + +ASSERT = Assert() +CFG = settings(file_path="qacode/configs/", file_name="settings.json") + + +def setup_selectors(): + """TODO: doc method""" + # setup parent + selector = CFG.get('bot').get('controls')[0].get('selector') + ASSERT.is_instance(selector, str) + ASSERT.greater(len(selector), 0, "invalid empty selector") + # setup child + child_sel = CFG.get('bot').get('controls')[1].get('selector') + ASSERT.is_instance(child_sel, str) + ASSERT.greater(len(child_sel), 0, "invalid empty selector") + # setup child + children_sel = "*" + ASSERT.is_instance(child_sel, str) + ASSERT.greater(len(child_sel), 0, "invalid empty selector") + return {"parent": selector, "child": child_sel, "children": children_sel} From 4609a29167bfe1dcce0214fe7548fb3d971be2b6 Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 10 Feb 2020 03:21:58 +0100 Subject: [PATCH 19/43] [qacode] missclicked --- qacode/core/browsers/modules/elements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qacode/core/browsers/modules/elements.py b/qacode/core/browsers/modules/elements.py index 2c43fe64..ca39ad88 100644 --- a/qacode/core/browsers/modules/elements.py +++ b/qacode/core/browsers/modules/elements.py @@ -115,7 +115,7 @@ def ele_write(cls, element, text=None): # it's neccessary because some fields shows # validation message and color just after # try to send empty message - element.send_keys('') + element.send_keys() else: element.send_keys(text) return element From 3fb3ff0f67aec747e3767384be9576b99c96b900 Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 10 Feb 2020 03:27:22 +0100 Subject: [PATCH 20/43] [qacode] removed refactored files --- qacode_old/configs/__init__.py | 2 - qacode_old/core/bots/__init__.py | 9 - qacode_old/core/bots/bot_base.py | 375 --------- qacode_old/core/bots/modules/__init__.py | 8 - qacode_old/core/bots/modules/nav_base.py | 720 ------------------ qacode_old/core/testing/__init__.py | 9 - qacode_old/core/testing/test_info.py | 451 ----------- qacode_old/utils.py | 82 -- tests/testing/__init__.py | 2 + tests/testing/suite_asserts.py | 129 ++++ tests_old/000_unitaries/suite_001_config.py | 114 --- .../000_unitaries/suite_002_testinfobase.py | 53 -- .../suite_004_teststrictrules.py | 77 -- .../001_functionals/suite_001_botbase.py | 139 ---- .../001_functionals/suite_002_testinfobot.py | 36 - .../suite_003_testinfobotunique.py | 37 - .../001_functionals/suite_004_navbase.py | 422 ---------- 17 files changed, 131 insertions(+), 2534 deletions(-) delete mode 100644 qacode_old/configs/__init__.py delete mode 100644 qacode_old/core/bots/__init__.py delete mode 100644 qacode_old/core/bots/bot_base.py delete mode 100644 qacode_old/core/bots/modules/__init__.py delete mode 100644 qacode_old/core/bots/modules/nav_base.py delete mode 100644 qacode_old/core/testing/__init__.py delete mode 100644 qacode_old/core/testing/test_info.py delete mode 100644 qacode_old/utils.py create mode 100644 tests/testing/__init__.py create mode 100644 tests/testing/suite_asserts.py delete mode 100644 tests_old/000_unitaries/suite_001_config.py delete mode 100644 tests_old/000_unitaries/suite_002_testinfobase.py delete mode 100644 tests_old/000_unitaries/suite_004_teststrictrules.py delete mode 100644 tests_old/001_functionals/suite_001_botbase.py delete mode 100644 tests_old/001_functionals/suite_002_testinfobot.py delete mode 100644 tests_old/001_functionals/suite_003_testinfobotunique.py delete mode 100644 tests_old/001_functionals/suite_004_navbase.py diff --git a/qacode_old/configs/__init__.py b/qacode_old/configs/__init__.py deleted file mode 100644 index d83f2fff..00000000 --- a/qacode_old/configs/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.configs""" diff --git a/qacode_old/core/bots/__init__.py b/qacode_old/core/bots/__init__.py deleted file mode 100644 index ae8ab09b..00000000 --- a/qacode_old/core/bots/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.bots""" - - -from qacode.core.bots import bot_base -from qacode.core.bots import modules - - -__all__ = ['bot_base', 'modules'] diff --git a/qacode_old/core/bots/bot_base.py b/qacode_old/core/bots/bot_base.py deleted file mode 100644 index 99e14689..00000000 --- a/qacode_old/core/bots/bot_base.py +++ /dev/null @@ -1,375 +0,0 @@ -# -*- coding: utf-8 -*- -"""TODO""" - - -import os -import sys -from qacode.core.bots.modules.nav_base import NavBase -from qacode.core.exceptions.core_exception import CoreException -from qacode.core.loggers.logger_manager import Log -from qacode.utils import settings -from selenium import webdriver as WebDriver -from selenium.webdriver import DesiredCapabilities -from selenium.webdriver.chrome.options import Options as ChromeOptions -from selenium.webdriver.common.action_chains import ActionChains -from selenium.webdriver.common.touch_actions import TouchActions -from selenium.webdriver.firefox.options import Options as FirefoxOptions -from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver -from selenium.webdriver.support.ui import WebDriverWait - - -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] - 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) diff --git a/qacode_old/core/bots/modules/__init__.py b/qacode_old/core/bots/modules/__init__.py deleted file mode 100644 index c8877335..00000000 --- a/qacode_old/core/bots/modules/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.bots.modules""" - - -from qacode.core.bots.modules import nav_base - - -__all__ = ['nav_base'] diff --git a/qacode_old/core/bots/modules/nav_base.py b/qacode_old/core/bots/modules/nav_base.py deleted file mode 100644 index f2770469..00000000 --- a/qacode_old/core/bots/modules/nav_base.py +++ /dev/null @@ -1,720 +0,0 @@ -# -*- coding: utf-8 -*- -"""Created on 04 march 2017 - -@author: ntz -""" - - -import sys -from qacode.core.exceptions.core_exception import CoreException -from selenium.common.exceptions import ( - NoSuchElementException, - StaleElementReferenceException, - WebDriverException -) -from selenium.webdriver.common.by import By -from selenium.webdriver.remote.webelement import WebElement -from selenium.webdriver.support import expected_conditions as EC -from selenium.webdriver.support.ui import WebDriverWait - - -class NavBase(object): - """Main navigation methods to use on selenium scripts""" - - driver = None - log = None - driver_wait = None - driver_actions = None - driver_touch = None - - def __init__(self, driver, log, driver_wait=None, driver_actions=None, - driver_touch=None): - """Initialize self properties - - Arguments: - driver {WebDriver} -- instance of any browser type/mode - log {Log} -- Logger for methods usage - - Keyword Arguments: - driver_wait {selenium.webdriver.support.ui.WebDriverWait} - -- web driver wait for conditions (default: {None}) - driver_actions - {from selenium.webdriver.common.action_chains.ActionChains} - -- web driver for perform actions on elements - driver_touch - {selenium.webdriver.common.touch_actions.TouchActions} - -- web driver for perform touch actions on elements - """ - self.driver = driver - self.log = log - self.driver_wait = driver_wait - self.driver_actions = driver_actions - self.driver_touch = driver_touch - - def method_name(self): - """Returns a string with the name of the function it's called from""" - return sys._getframe(1).f_code.co_name - - def get_driver_wait(self, driver_wait=None): - """Allow to obatin an instance of WebDriverWait""" - if driver_wait is None and self.driver_wait is None: - raise CoreException("Nav instanced without driver_wait") - if driver_wait is None: - driver_wait = self.driver_wait - return driver_wait - - def get_url(self, url, wait_for_load=0): - """Do get_url including implicit wait for page load""" - if wait_for_load > 0: - self.driver.implicitly_wait(wait_for_load) - self.driver.get(url) - - def get_maximize_window(self): - """Maximize browser window""" - self.driver.maximize_window() - - def get_window_handle(self): - """Get window object to handle with selenium on scripts""" - return self.driver.current_window_handle - - def add_cookie(self, cookie_dict): - """Adds a cookie to your current session. - - Args: - cookie_dict: A dictionary object, with required - keys - "name" and "value" - optional keys - "path", "domain", "secure", "expiry" - Usage: - driver.add_cookie({ - "name" : "foo", - "value" : "bar"}) - driver.add_cookie({ - 'name' : 'foo', - 'value' : 'bar', - 'path' : '/', - 'secure':True, - 'domain': None}) - """ - method = self.method_name() - valid_keys = ["name", "value"] - if cookie_dict is None: - raise CoreException("Can't add None cookie") - for key in valid_keys: - if cookie_dict.get(key) is None: - msg = "Can't add new cookie without '{}'".format(key) - raise CoreException(msg) - try: - return self.driver.add_cookie(cookie_dict) - except WebDriverException as err: - bot_info = {"err": err, "method": method} - raise CoreException(bot_info=bot_info) - - def get_cookies(self): - """Returns a set of dictionaries, corresponding to cookies - visible in the current session. - """ - return self.driver.get_cookies() - - def delete_cookie_by_key(self, key_name): - """Deletes a single cookie with the given name""" - self.driver.delete_cookie(key_name) - - def delete_cookies(self): - """Delete all cookies in the scope of the session""" - self.driver.delete_all_cookies() - - def get_capabilities(self): - """Retrieve current capabilities applied to selenium driver""" - return self.driver.desired_capabilities - - def execute_js(self, script, *args): - """Execute arbitrary Javascript code - - Arguments: - script {str} -- JS code to be executed on WebDriver - *args {[type]} -- More arguments ( like element selector ) - - Returns: - str -- JS script returns - """ - return self.driver.execute_script(script, *args) - - def set_css_rule(self, css_selector, css_prop, css_value, - css_important=False, index=0): - """Set new value for given CSS property name - - Arguments: - css_selector {str} -- CSS selector to apply rule - css_prop {str} -- CSS property to be applied to rule - css_value {str} -- CSS property value to be applied to rule - - Keyword Arguments: - css_important {bool} -- Allow to include '!important' - to rule (default: {False}) - index {int} -- Position to insert new CSS rule - on first stylesheet (default: {0}) - - Returns: - str -- JS script returns - """ - css_important_text = '' - if css_important: - css_important_text = '!important' - css_rule = " {0!s} {{ {1!s} : {2!s} {3!s}; }}".format( - css_selector, - css_prop, - css_value, - css_important_text) - js_script = "document.styleSheets[0].insertRule(\"{0!s}\", {1:d});".format( # noqa: E501 - css_rule, index) - return self.execute_js(js_script) - - def find_element(self, selector, locator=By.CSS_SELECTOR): - """Just divided execution ways for search web element - throught selenium - - Arguments: - selector {str} -- string selector used to locate one - element or first obtained - - Keyword Arguments: - locator {By} -- locator strategy used to find - WebElement selector (default: {By.CSS_SELECTOR}) - - Raises: - CoreException -- If locator is None - CoreException -- Element selector+locator strategy raises - selenium NoSuchElementException - - Returns: - WebElement -- selenium representation for a web element - """ - method = self.method_name() - msg = "Locator not selected at find_element, selector={}".format( - selector) - if locator is None: - raise CoreException(msg) - try: - return self.driver.find_element(locator, selector) - except NoSuchElementException as err: - info_bot = {"err": err, "method": method} - raise CoreException(info_bot=info_bot) - - def find_elements(self, selector, locator=By.CSS_SELECTOR): - """Just divided execution ways for search web elements - throught selenium - - Arguments: - selector {str} -- string selector used to locate - one or more elements - - Keyword Arguments: - locator {By} -- locator strategy used to find - WebElement selector (default: {By.CSS_SELECTOR}) - - Raises: - CoreException -- If locator is None - CoreException -- Element selector+locator strategy raises - selenium NoSuchElementException - - Returns: - list(WebElement) -- selenium representation for a - list of web elements - """ - method = self.method_name() - msg = "Locator not selected at find_element, selector={}".format( - selector) - if locator is None: - raise CoreException(msg, info_bot={"method": method}) - try: - elements = self.driver.find_elements(locator, selector) - if len(elements) == 0: - raise CoreException( - "0 elements found", info_bot={"method": method}) - return elements - except NoSuchElementException as err: - info_bot = {"err": err, "method": method} - raise CoreException(info_bot=info_bot) - - def find_element_wait(self, selector, - locator=By.CSS_SELECTOR, driver_wait=None): - """Search element using WebDriverWait class - and ElementConditions presence_of_element_located - - Arguments: - selector {str} -- string selector used to locate one - element or first obtained - - Keyword Arguments: - locator {By} -- locator strategy used to find - WebElement selector (default: {By.CSS_SELECTOR}) - driver_wait {WebDriverWait} -- driver that supports - ExpectedConditions methods (default: {None}) - - Raises: - CoreException -- if NavBase instanced - without driver_wait - - Returns: - WebElement -- element through selenium - WebDriverWait class - """ - driver_wait = self.get_driver_wait(driver_wait=driver_wait) - try: - return driver_wait.until( - EC.presence_of_element_located((locator, selector))) - except (NoSuchElementException, StaleElementReferenceException): - return driver_wait.until( - EC.visibility_of_element_located((locator, selector))) - - def find_elements_wait(self, selector, - locator=By.CSS_SELECTOR, driver_wait=None): - """Search elements using WebDriverWait class - and ElementConditions presence_of_all_elements_located - - Arguments: - selector {str} -- string selector used to locate - multiple elements - - Keyword Arguments: - locator {By} -- locator strategy used to find - WebElement selector (default: {By.CSS_SELECTOR}) - driver_wait {WebDriverWait} -- driver that supports - ExpectedConditions methods (default: {None}) - - Raises: - CoreException -- if NavBase instanced - without driver_wait - - Returns: - WebElement -- element through selenium - WebDriverWait class - """ - driver_wait = self.get_driver_wait(driver_wait=driver_wait) - try: - return driver_wait.until( - EC.presence_of_all_elements_located((locator, selector))) - except (NoSuchElementException, StaleElementReferenceException): - return driver_wait.until( - EC.visibility_of_all_elements_located((locator, selector))) - - def find_element_child(self, element, child_selector, - locator=By.CSS_SELECTOR): - """TODO: doc method""" - method = self.method_name() - msg = "Cant find child if not element found" - if element is None or not isinstance(element, WebElement): - raise CoreException(msg, info_bot={"method": method}) - try: - return element.find_element(locator, child_selector) - except (NoSuchElementException, StaleElementReferenceException) as err: - # at Java lang exist 1 expected condition - # named : visibilityOfNestedElementsLocatedBy - # doc : https://selenium-python.readthedocs.io/waits.html - # maybe must exist at python too - # then, create and use new method named: find_element_child_wait() - # raise NotImplementedError("TODO:open an issue at github please") - info_bot = {"err": err, "method": method} - raise CoreException(msg, info_bot=info_bot) - - def find_element_children(self, element, child_selector, - locator=By.CSS_SELECTOR): - """TODO: doc method""" - method = self.method_name() - if element is None or not isinstance(element, WebElement): - raise CoreException("Cant find children if not element found") - try: - return element.find_elements(locator, child_selector) - except (NoSuchElementException, StaleElementReferenceException) as err: - # at Java lang exist 1 expected condition - # named : visibilityOfNestedElementsLocatedBy - # doc : https://selenium-python.readthedocs.io/waits.html - # maybe must exist at python too - # then, create and use new method named: find_element_child_wait() - # raise NotImplementedError("TODO:open an issue at github please") - info_bot = {"err": err, "method": method} - raise CoreException(info_bot=info_bot) - - def find_elements_child(self): - """TODO: doc method""" - raise NotImplementedError("TODO: open an issue at github please") - - def find_elements_children(self): - """TODO: doc method""" - raise NotImplementedError("TODO: open an issue at github please") - - def forward(self): - """Go forward using browser functionality""" - self.driver.forward() - - def reload(self): - """Go reload page using browser functionality""" - self.driver.refresh() - - def get_log(self, log_name='browser', raises=False): - """Get selenium log by name, this depends of - driver mode and browser what it's using each time - - Keyword Arguments: - log_name {str} -- get log type lanes (default: {'browser'}) - - Raises: - CoreException -- if log_name value not in list - of valid values : browser, driver, client, server - - Returns: - list() -- list of messages typed on a log_name - """ - method = self.method_name() - try: - return { - 'browser': self.driver.get_log, - 'driver': self.driver.get_log, - 'client': self.driver.get_log, - 'server': self.driver.get_log, - }[log_name](log_name) - except (KeyError, WebDriverException) as err: - if isinstance(err, KeyError): - raise CoreException( - "Can't use not valid value to get log", - info_bot={"err": err, "method": method}) - self.log.debug(("nav | get_log: Selenium, not all drivers will" - " be handled by them with all optionsvalues")) - self.log.warning("nav | get_log: log_name={}, err={}".format( - log_name, err.msg)) - return list() - - def get_screenshot_as_base64(self): - """Gets the screenshot of the current window as a base64 encoded string - which is useful in embedded images in HTML - """ - return self.driver.get_screenshot_as_base64() - - def get_screenshot_as_file(self, file_name): - """Gets the screenshot of the current window. Returns False - if there is any IOError, else returns True. Use full paths - in your filename. - - Arguments: - file_name {str} -- name of file path where - want to save screenshot - - Returns: - list(byte) -- file binary object of screenshot bytes - """ - return self.driver.get_screenshot_as_file(file_name) - - def get_screenshot_as_png(self): - """Gets the screenshot of the current window as a - binary data. - - Returns: - File -- file binary object of screenshot with PNG format - """ - return self.driver.get_screenshot_as_png() - - def get_screenshot_save(self, file_name): - """Gets the screenshot of the current window. Returns False - if there is any IOError, else returns True. - Use full paths in your filename. - - Arguments: - file_name {str} -- name of file path where - want to save screenshot - - Returns: - list(byte) -- file binary object of screenshot bytes - """ - return self.driver.save_screenshot(file_name) - - def js_set_timeout(self, timeout=60): - """Set the amount of time that the script should wait during an - execute_async_script call before throwing an error. - - Keyword Arguments: - timeout {int} -- seconds to raise script - wait (default: {60}) - """ - self.driver.set_script_timeout(timeout) - - def set_window_size(self, pos_x=800, pos_y=600): - """Sets the width and height of the current - window. (window.resizeTo) - - Keyword Arguments: - pos_x {int} -- width of new window size (default: {800}) - pos_y {int} -- height of new window size (default: {600}) - """ - self.driver.set_window_size(pos_x, pos_y) - - def get_title(self): - """Obtains the title of the current page and return it - - Returns: - str -- title of current page opened - """ - return self.driver.title - - def get_current_url(self): - """Return current url from opened bot - - Raises: - CoreException -- if can't obtains url with this - selenium driver - - Returns: - str -- string representation of current driver url - """ - msg = "Failed at obtain selenium driver property 'current_url'" - try: - return self.driver.current_url - except WebDriverException: - raise CoreException(msg) - - def is_url(self, url, ignore_raises=True): - """Check if url it's the same what selenium current and visible url - - Arguments: - url {str} -- string value used to verify url - - Keyword Arguments: - ignore_raises {bool} -- allows to ignore errors - when executes if raises errors (default: {True}) - - Raises: - exceptions -- [description] - CoreException -- [description] - - Returns: - bool -- if current driver url match with param url, - then returns True, False if not - """ - if self.get_current_url() != url: - if not ignore_raises: - raise CoreException("'Current url' is not 'param url'") - return False - return True - - def set_web_element(self, new_attr_id): - """Create web element using selenium adding to DOM - - Arguments: - new_attr_id {str} -- html attribute ID for - new web element - """ - self.driver.create_web_element(new_attr_id) - - def ele_click(self, element=None, selector=None, locator=By.CSS_SELECTOR): - """Perform click webelement with locator param or search it by default - CSS_SELECTOR value if element it's none but selector - it's not default value - - Keyword Arguments: - element {WebElement} -- selenium object, instance of WebElement - (default: {None}) - selector {str} -- selector to search and element to click - (default: {None}) - locator {By} -- locator selenium strategy - (default: {By.CSS_SELECTOR}) - - Raises: - CoreException -- Bad params combination, need element - or selector to search element - - Returns: - WebElement -- returns element clicked (to allow chaining) - """ - method = self.method_name() - curr_ele = element - curr_selector = selector - can_click = False - - if curr_ele is None and curr_selector is None: - msg = ("Bad arguments: curr_ele={}, curr_selector={}" - "".format(curr_ele, curr_selector)) - raise CoreException(msg, info_bot={"method": method}) - elif curr_ele is None: - curr_ele = self.find_element(curr_selector, locator=locator) - can_click = True - elif curr_ele is not None and isinstance(curr_ele, WebElement): - can_click = True - if can_click: - curr_ele.click() - return curr_ele - - def ele_write(self, element, text=None): - """ - Over element perform send_keys , if not sended text, then will write - empty over element - :param element: WebElement - :return: None - """ - method = self.method_name() - if not isinstance(element, WebElement): - msg = "Param 'element' it's not WebElement" - raise CoreException(msg, info_bot={"method": method}) - if text is not None: - element.send_keys(text) - else: - # it's neccessary because some fields shows validation message and - # color after try to send empty message - element.send_keys() - - def ele_is_displayed(self, element): - """Whether the element is visible to a user - - Webdriver spec to determine if element it's displayed: - https://w3c.github.io/webdriver/webdriver-spec.html#widl-WebElement-isDisplayed-boolean - - Arguments: - element {WebElement} -- selenium web element - - Returns: - bool -- Value based on selenium SPEC to determine if an element - is enabled - """ - return element.is_displayed() - - def ele_is_enabled(self, element): - """Returns whether the element is enabled - - Arguments: - element {WebElement} -- selenium web element - - Returns: - bool -- Value based on selenium SPEC to determine if an element - is enabled - """ - return element.is_enabled() - - def ele_is_selected(self, element): - """Returns whether the element is selected - - Arguments: - element {WebElement} -- selenium web element - - Returns: - bool -- Value based on selenium SPEC to determine if an element - is enabled - """ - return element.is_selected() - - def ele_text(self, element, on_screen=True): - """Get element content text. - If the isDisplayed() method can sometimes trip over when - the element is not really hidden but outside the viewport - get_text() returns an empty string for such an element. - - Keyword Arguments: - on_screen {bool} -- allow to obtain text if element - it not displayed to this element before - read text (default: {True}) - - Returns: - str -- Return element content text (innerText property) - """ - method = self.method_name() - if on_screen: - text = str(element.text) - else: - text = self.ele_attribute(element, 'innerText') - self.log.debug("text obtained from innerText") - if self.ele_is_displayed(element): - msg = ("on_screen param must use when" - "element it's not displayed") - raise CoreException(msg, info_bot={"method": method}) - return text - - def ele_input_value(self, element): - """Return value of value attribute, usefull for inputs""" - return self.ele_attribute(element, 'value') - - def ele_attribute(self, element, attr_name): - """Returns tuple with (attr, value) if founds - This method will first try to return the value of a property with - the given name. If a property with that name doesn't exist, it - returns the value of the attribute with the same name. If there's - no attribute with that name, None is returned. - """ - method = self.method_name() - value = str(element.get_attribute(attr_name)) - if value is None or value == attr_name: - msg = "Attr '{}' not found".format(attr_name) - raise CoreException(msg, info_bot={"method": method}) - return value - - def ele_tag(self, element): - """Returns element.tag_name value""" - return element.tag_name - - def ele_clear(self, element): - """Clear element text""" - return element.clear() - - def ele_css(self, element, prop_name): - """Allows to obtain CSS value based on CSS property name - - Arguments: - element {WebElement} -- WebElement to modify CSS property - prop_name {str} -- CSS property name - - Returns: - str -- Value of CSS property searched - """ - return element.value_of_css_property(prop_name) - - def ele_wait_invisible(self, selector, locator=By.CSS_SELECTOR, timeout=0): - """Wait for invisible element (display:none), returns element""" - if selector is None: - raise CoreException( - "Can't wait invisible element if None selector given") - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(self.driver, timeout) - try: - element = driver_wait.until( - EC.invisibility_of_element_located(locator_tuple)) - except Exception: - raise CoreException("Fails at wait for invisible element") - return element - - def ele_wait_visible(self, element, timeout=0): - """Wait for visible condition element, returns self""" - if element is None: - raise CoreException("Can't wait visible if element is None") - driver_wait = WebDriverWait(self.driver, timeout) - try: - element = driver_wait.until(EC.visibility_of(element)) - except Exception: - raise CoreException("Fails at wait for visible element") - return element - - def ele_wait_text(self, selector, text, - locator=By.CSS_SELECTOR, timeout=0): - """Wait if the given text is present in the specified element""" - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(self.driver, timeout) - try: - return driver_wait.until( - EC.text_to_be_present_in_element(locator_tuple, text)) - except Exception: - raise CoreException("Fails at wait for element text") - - def ele_wait_value(self, selector, value, - locator=By.CSS_SELECTOR, timeout=0): - """Wait if the given value is present in the specified element""" - locator_tuple = (locator, selector) - driver_wait = WebDriverWait(self.driver, timeout) - try: - return driver_wait.until( - EC.text_to_be_present_in_element_value(locator_tuple, value)) - except Exception: - raise CoreException("Fails at wait for element value") - - def __repr__(self): - """Show basic properties for this object""" - return ("ControlBase: drivers instanced are... \n" - " driver_wait={},\n driver_actions={},\n" - " driver_touch={}").format( - self.driver_wait, - self.driver_actions, - self.driver_touch) diff --git a/qacode_old/core/testing/__init__.py b/qacode_old/core/testing/__init__.py deleted file mode 100644 index 6a35e1c7..00000000 --- a/qacode_old/core/testing/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.testing""" - - -from qacode.core.testing import test_info -from qacode.core.testing import testlink - - -__all__ = ['test_info', 'testlink'] diff --git a/qacode_old/core/testing/test_info.py b/qacode_old/core/testing/test_info.py deleted file mode 100644 index 49480085..00000000 --- a/qacode_old/core/testing/test_info.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -"""Base module for inherit new Test Suites""" - - -import os -import re -import time -from qacode.core.bots.bot_base import BotBase -from qacode.core.exceptions.core_exception import CoreException -from qacode.core.loggers.logger_manager import Log -from qatestlink.core.testlink_manager import TLManager - - -ASSERT_MSG_DEFAULT = "Fails at '{}': actual={}, expected={}" -ASSERT_REGEX_URL = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" # noqa: E501 - - -class TestInfoBase(object): - """Base class for inherit new Test classes""" - - is_loaded = False - log = None - config = None - tlm = None # Testlink Manager class - - @classmethod - def load(cls, config): - """Load default config dict""" - if config is None and not cls.is_loaded: - raise CoreException("Bad param 'config' provided") - cls.add_property('config', value=config) - if cls.log is None: - config_bot = cls.config.get('bot') - log_path = "{}/".format( - config_bot.get('log_output_file')) - log = Log( - log_path=log_path, - log_name=config_bot.get('log_name'), - log_level=config_bot.get('log_level') - ) - cls.add_property('log', log) - tl_key = cls.config.get('testlink') - if cls.tlm is None and tl_key is not None: - cls.tlm = TLManager(settings=tl_key) - cls.is_loaded = True - - @classmethod - def bot_open(cls, config): - """Open browser using BotBase instance - - Returns: - BotBase -- wrapper browser handler for selenium - """ - return BotBase(**config) - - @classmethod - def bot_close(cls, bot): - """Close bot calling bot.close() from param""" - return bot.close() - - @classmethod - def cfg_apps(cls): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps' - """ - if cls.config is None: - raise CoreException("Call to cls.load() first") - return cls.config.get('tests').get('apps') - - @classmethod - def cfg_pages(cls): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps[i].pages' - """ - if cls.config is None: - raise CoreException("Call to cls.load() first") - pages = [] - for app in cls.cfg_apps(): - pages.extend(app.get('pages')) - return pages - - @classmethod - def cfg_controls(cls): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps[i].pages[j].controls' - """ - if cls.config is None: - raise CoreException("Call to cls.load() first") - controls = [] - for page in cls.cfg_pages(): - controls.extend(page.get('controls')) - return controls - - @classmethod - def cfg_app(cls, app_name): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps' filtering by 'app_name' param - """ - for app in cls.cfg_apps(): - if app.get('name') == app_name: - return app - raise Exception( - "Not found for: app_name={}".format( - app_name)) - - @classmethod - def cfg_page(cls, page_name, app_name=None): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps[i].pages' filtering by 'page_name' param - """ - apps = [] - if app_name is None: - apps.extend(cls.cfg_apps()) - else: - apps.append(cls.cfg_app(app_name)) - for app in apps: - for page in app.get('pages'): - if page.get('name') == page_name: - return page - - @classmethod - def cfg_control(cls, control_name, page_name=None, app_name=None): - """Obtain inherit dict from 'cls.config' dict named - 'config.tests.apps[i].pages[j].controls' filtering by - 'control_name' param - """ - controls = [] - if page_name is None: - controls.extend(cls.cfg_controls()) - else: - controls.extend(cls.cfg_page(page_name, app_name=app_name)) - for control in controls: - if control.get('name') == control_name: - return control - - @classmethod - def assert_message(cls, assert_name, actual, expected, msg=None): - """Generate assert message for method that calls for it - - Arguments: - assert_name {str} -- Assert method name that call - actual {any} -- Actual value to compare - expected {any} -- Expected value to compare - - Keyword Arguments: - msg {[type]} -- [description] (default: {None}) - - Returns: - str -- Message to be use on Assert method - """ - if msg is not None: - return msg - return ASSERT_MSG_DEFAULT.format( - assert_name, - actual, - expected) - - def setup_method(self, test_method, **kwargs): - """Configure self.attribute""" - self.load(kwargs.get('config')) - self.log.info("Started testcase named='{}'".format( - test_method.__name__)) - - def teardown_method(self, test_method): - """Unload self.attribute""" - self.log.info("Finished testcase named='{}'".format( - test_method.__name__)) - - @classmethod - def add_property(cls, name, value=None): - """Add property to test instance using param 'name', will setup - None if any value it's passed by param - """ - setattr(cls, name, value) - - def timer(self, wait=5, print_each=5): - """Timer to sleep browser on testcases - - Keyword Arguments: - wait {int} -- seconds to wait (default: {5}) - print_each {int} -- print message each seconds, must be divisible - by 5, negatives are accepted (default: {5}) - - Raises: - Exception -- [description] - """ - msg_err = "Timer can't works if print_each param isn't divisible by 1" - if (print_each % 1) != 0: - raise Exception(msg_err) - while wait > 0: - self.sleep(print_each) - wait -= print_each - - def sleep(self, wait=0): - """Just call to native python time.sleep method - - Keyword Arguments: - wait {int} -- Wait time on Runtime execution before execute - next lane of code (default: {0}) - """ - if wait > 0: - time.sleep(wait) - - def assert_equals(self, actual, expected, msg=None): - """Allow to compare 2 values and check if 1st it's equals to - 2nd value - """ - _msg = self.assert_message("assert_equals", actual, expected, msg=msg) - if actual != expected: - raise AssertionError(actual, expected, _msg) - return True - - def assert_not_equals(self, actual, expected, msg=None): - """Allow to compare 2 value to check if 1st isn't equals to - 2nd value - """ - _msg = self.assert_message( - "assert_not_equals", actual, expected, msg=msg) - if actual == expected: - raise AssertionError(actual, expected, _msg) - return True - - def assert_equals_url(self, actual, expected, msg=None, wait=0): - """Allow to compare 2 urls and check if 1st it's equals to 2nd url - - Arguments: - actual {type} -- actual value - expected {type} -- expected value - - Keyword Arguments: - wait {int} -- Wait time on Runtime execution before execute - next lane of code (default: {0}) - - Raises: - AssertionError -- [description] - """ - _msg = self.assert_message( - "assert_equals_url", actual, expected, msg=msg) - self.sleep(wait) - if actual != expected: - raise AssertionError(actual, expected, _msg) - return True - - def assert_not_equals_url(self, actual, expected, msg=None, wait=0): - """Allow to compare 2 urls to check if 1st isn't equals to 2nd url""" - _msg = self.assert_message( - "assert_not_equals_url", actual, expected, msg=msg) - self.sleep(wait) - if actual == expected: - raise AssertionError(actual, expected, _msg) - return True - - def assert_contains_url(self, actual, contains, msg=None, wait=0): - """Allow to compare 2 urls and check if 1st contains 2nd url""" - _msg = self.assert_message( - "assert_contains_url", actual, contains, msg=msg) - self.sleep(wait) - if actual not in contains: - raise AssertionError(actual, contains, _msg) - return True - - def assert_not_contains_url(self, actual, contains, msg=None, wait=0): - """Allow to compare 2 urls and check if 1st not contains 2nd url""" - _msg = self.assert_message( - "assert_not_contains_url", actual, contains, msg=msg) - self.sleep(wait) - if actual in contains: - raise AssertionError(actual, contains, _msg) - return True - - def assert_is_instance(self, instance, class_type, msg=None): - """Allow to encapsulate method assertIsInstance(obj, cls, msg='')""" - _msg = self.assert_message( - "assert_is_instance", instance, class_type, msg=msg) - if not isinstance(class_type, type): - class_type = type(class_type) - if not isinstance(instance, class_type): - raise AssertionError(instance, class_type, _msg) - return True - - def assert_greater(self, actual, greater, msg=None): - """Allow to encapsulate method assertGreater(a, b, msg=msg)""" - _msg = self.assert_message( - "assert_greater", actual, greater, msg=msg) - if actual < greater: - raise AssertionError(actual, greater, _msg) - return True - - def assert_lower(self, actual, lower, msg=None): - """Allow to encapsulate method assertLower(a, b, msg=msg)""" - _msg = self.assert_message( - "assert_lower", actual, lower, msg=msg) - if actual > lower: - raise AssertionError(actual, lower, _msg) - return True - - def assert_in(self, actual, valid_values, msg=None): - """Allow to compare if value it's in to 2nd list of values""" - _msg = self.assert_message( - "assert_in", actual, valid_values, msg=msg) - if actual not in valid_values: - raise AssertionError(actual, valid_values, _msg) - return True - - def assert_not_in(self, actual, invalid_values, msg=None): - """Allow to compare if value it's not in to 2nd list of values""" - _msg = self.assert_message( - "assert_not_in", actual, invalid_values, msg=msg) - if actual in invalid_values: - raise AssertionError(actual, invalid_values, _msg) - return True - - def assert_regex(self, actual, pattern, msg=None): - """Allow to compare if value match pattern""" - _msg = self.assert_message( - "assert_regex", actual, pattern, msg=msg) - is_match = re.match(pattern, actual) - if not is_match: - raise AssertionError(actual, pattern, _msg) - return True - - def assert_not_regex(self, actual, pattern, msg=None): - """Allow to compare if value not match pattern""" - _msg = self.assert_message( - "assert_not_regex", actual, pattern, msg=msg) - is_match = re.match(pattern, actual) - if is_match: - raise AssertionError(actual, pattern, _msg) - return True - - def assert_regex_url(self, actual, pattern=None, msg=None): - """Allow to compare if value match url pattern, can use - custom pattern - """ - if not pattern: - pattern = ASSERT_REGEX_URL - return self.assert_regex(actual, pattern, msg=msg) - - def assert_path_exist(self, actual, is_dir=True, msg=None): - """Allow to check if path exist, can check if is_dir also""" - _msg = self.assert_message( - "assert_path_exist", - actual, - "is_dir={}".format(is_dir), - msg=msg) - if not os.path.exists(actual): - raise AssertionError(actual, "PATH_NOT_EXIST", _msg) - _is_dir = os.path.isdir(actual) - if is_dir: - if not _is_dir: - raise AssertionError(actual, "PATH_NOT_DIR", _msg) - else: - if _is_dir: - raise AssertionError(actual, "PATH_IS_DIR_AND_MUST_NOT", _msg) - return True - - def assert_path_not_exist(self, actual, msg=None): - """Allow to check if path not exist, can check if is_dir also""" - _msg = self.assert_message( - "assert_path_not_exist", actual, "", msg=msg) - if os.path.exists(actual): - raise AssertionError(actual, "PATH_EXIST_AND_MUST_NOT", _msg) - return True - - def assert_true(self, actual, msg=None): - """Allow to compare and check if value it's equals to 'True'""" - self.assert_is_instance(actual, bool) - self.assert_equals(actual, True, msg=msg) - return True - - def assert_false(self, actual, msg=None): - """Allow to compare and check if value it's equals to 'False'""" - self.assert_is_instance(actual, bool) - self.assert_equals(actual, False, msg=msg) - return True - - def assert_none(self, actual, msg=None): - """Allow to compare and check if value it's equals to 'None'""" - return self.assert_equals(actual, None, msg=msg) - - def assert_not_none(self, actual, msg=None): - """Allow to compare and check if value it's not equals to 'None'""" - return self.assert_not_equals(actual, None, msg=msg) - - -class TestInfoBot(TestInfoBase): - """Inherit class what implements bot on each testcase""" - - bot = None - - def setup_method(self, test_method, **kwargs): - """Configure self.attribute. - If skipIf mark applied and True as first param for args tuple - then not open bot - """ - super(TestInfoBot, self).setup_method(test_method, **kwargs) - if 'skipIf' in dir(test_method) and test_method.skipIf.args[0]: - return False - if not isinstance(self.bot, BotBase): - self.add_property('bot', value=self.bot_open(self.config)) - - def teardown_method(self, test_method, close=True): - """Unload self.attribute, also close bot""" - super(TestInfoBot, self).teardown_method(test_method) - try: - if close: - self.bot_close(self.bot) - else: - self.log.debug( - "Not closing bot by optional param 'close'") - except Exception as err: - self.log.error( - "Fails at try to close bot: {}".format( - err)) - - -class TestInfoBotUnique(TestInfoBot): - """Inherit class what implements bot on each testcase""" - - @classmethod - def setup_class(cls, **kwargs): - """Configure 'cls.attribute'. If name start with 'test_' and have - decorator skipIf with value True, then not open bot - """ - tests_methods = [] - skip_methods = [] - skip_force = kwargs.get('skip_force') - for method_name in dir(cls): - if method_name.startswith("test_"): - method = getattr(cls, method_name) - tests_methods.append(method) - if 'skipIf' in dir(method) and method.skipIf.args[0]: - skip_methods.append(method) - if tests_methods == skip_methods or skip_force: - return False - else: - if not isinstance(cls.bot, BotBase): - cls.load(kwargs.get('config')) - cls.add_property( - 'bot', value=cls.bot_open(cls.config)) - - @classmethod - def teardown_class(cls): - """Unload self.attribute, closing bot from 'cls.bot' property""" - if cls.bot: - cls.bot_close(cls.bot) - - def teardown_method(self, test_method, close=False): - """Unload self.attribute, also disable closing bot from TestInfoBot""" - super(TestInfoBotUnique, self).teardown_method( - test_method, close=close) diff --git a/qacode_old/utils.py b/qacode_old/utils.py deleted file mode 100644 index bce09f71..00000000 --- a/qacode_old/utils.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -"""Utils tasks for files operations and settings operations""" - - -import json -from os import path -from sys import version_info - - -def path_format(file_path=None, file_name=None, is_abspath=False, - ignore_raises=False): - """ - Get path joined checking before if path and filepath exist, - if not, raise an Exception - if ignore_raise it's enabled, then file_path must include '/' at end lane - """ - path_formatted = "{}{}".format(file_path, file_name) - if ignore_raises: - return path_formatted - if file_path is None or not path.exists(file_path): - raise IOError("Path '{}' doesn't exists".format(file_path)) - if file_name is None or not path.exists(path_formatted): - raise IOError( - "File '{}{}' doesn't exists".format(file_path, file_name)) - if is_abspath: - return path.abspath(path.join(file_path, file_name)) - else: - return path.join(file_path, file_name) - - -def read_file(is_json=False, file_path=None, encoding='utf-8', - is_encoding=True, ignore_raises=False): - """Returns file object from file_path, - compatible with all py versiones - optionals: - can be use to return dict from json path - can modify encoding used to obtain file - """ - text = None - try: - if file_path is None: - raise Exception("File path received it's None") - if version_info.major >= 3: - if not is_encoding: - encoding = None - with open(file_path, encoding=encoding) as buff: - text = buff.read() - if version_info.major <= 2: - with open(file_path) as buff: - if is_encoding: - text = buff.read().decode(encoding) - else: - text = buff.read() - if is_json: - return json.loads(text) - except Exception as err: - if not ignore_raises: - raise Exception(err) - return text - - -def read(file_path='./', file_name=None, is_encoding=True, - ignore_raises=False): - """Read file""" - if file_name is None: - raise Exception("File name not provided") - return read_file( - is_encoding=is_encoding, - ignore_raises=ignore_raises, - file_path=path_format( - file_path=file_path, - file_name=file_name, - ignore_raises=ignore_raises)) - - -def settings(file_path='./', file_name='settings.json', - is_abspath=True): - """Returns file settings as a dict to be use on qacode lib""" - return read_file(is_json=True, - file_path=path_format(file_path=file_path, - file_name=file_name, - is_abspath=is_abspath)) diff --git a/tests/testing/__init__.py b/tests/testing/__init__.py new file mode 100644 index 00000000..a238508c --- /dev/null +++ b/tests/testing/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""package qacode.tests.testing""" diff --git a/tests/testing/suite_asserts.py b/tests/testing/suite_asserts.py new file mode 100644 index 00000000..a00b984f --- /dev/null +++ b/tests/testing/suite_asserts.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +"""Test Suite module for qacode.core.bots package""" + + +import pytest +from qacode.core.testing.asserts import Assert + + +def asserts_create(): + """TODO: doc mehotd""" + return Assert() + + +@pytest.mark.dependency(name="asserts_create") +def test_asserts_create(): + """TODO: doc method""" + asserts = asserts_create() + assert type(asserts) == Assert + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_equals(): + """TODO: doc method""" + asserts = asserts_create() + asserts.equals("equals", "equals") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_notequals(): + """TODO: doc method""" + asserts = asserts_create() + asserts.not_equals("equals", "notequals") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_containsurl(): + """TODO: doc method""" + asserts = asserts_create() + asserts.contains_url("http://equals.com", "equals.com") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_notcontainsurl(): + """TODO: doc method""" + asserts = asserts_create() + asserts.not_contains_url("http://equals.com", "notcontains") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_isinstance(): + """TODO: doc method""" + asserts = asserts_create() + asserts.is_instance("text", str) + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_greater(): + """TODO: doc method""" + asserts = asserts_create() + asserts.greater(1, 0) + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_lower(): + """TODO: doc method""" + asserts = asserts_create() + asserts.lower(0, 1) + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_inlist(): + """TODO: doc method""" + asserts = asserts_create() + asserts.in_list(0, [0, 1]) + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_notinlist(): + """TODO: doc method""" + asserts = asserts_create() + asserts.not_in_list(0, [1, 2]) + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_regex(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_regexurl(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_pathexist(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_pathnotexist(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_true(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_false(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_none(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") + + +@pytest.mark.dependency(depends=['asserts_create']) +def test_asserts_notnone(): + """TODO: doc method""" + raise NotImplementedError("WIP: not developed yet") diff --git a/tests_old/000_unitaries/suite_001_config.py b/tests_old/000_unitaries/suite_001_config.py deleted file mode 100644 index 13e875ab..00000000 --- a/tests_old/000_unitaries/suite_001_config.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for configs""" - - -import pytest -from qacode.core.testing.test_info import TestInfoBase -from qacode.utils import settings - - -SETTINGS = settings(file_path="qacode/configs/") -MSG_OBSOLETE = "Test obsolete, need new tests for key tests.functionals.pages" -SKIP_CONFIG = SETTINGS['tests']['skip']['test_configs'] -SKIP_CONFIG_MSG = 'test_configs DISABLED by config file' - - -class TestConfig(TestInfoBase): - """Testcases for class TestInfoBase""" - - def setup_method(self, test_method): - """TODO: doc method""" - super(TestConfig, self).setup_method( - test_method, - config=settings(file_path="qacode/configs/")) - - # Error Messages - ERR_KEY_NOT_FOUND = "Required key '{}', can't be None" - ERR_KEY_INVALID_VALUE = "Required key '{}', just can be in '{}'" - ERR_KEY_PATH_NOT_FOUND = "Required key '{}', not found for path '{}'" - ERR_KEY_EMPTY = "Required key '{}', can't be empty, value='{}'" - ERR_KEY_REGEX = "Optional key '{}', not provided or not matching regex: {}" - # Test constants - PATH_SETTINGS = "qacode/configs/settings.json" - REGEX_URL = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" # noqa: E501 - - def test_config_exist(self): - """Test : test_000_config_exist""" - self.assert_path_exist(self.PATH_SETTINGS, is_dir=False) - - @pytest.mark.parametrize("key_name", [ - "mode", "browser", "url_hub", "drivers_path", - "drivers_names", "log_output_file", "log_name", "log_level" - ]) - def test_config_bot_keys(self, key_name): - """Testcase: test_config_bot_keys""" - if SKIP_CONFIG: - pytest.skip(msg=SKIP_CONFIG_MSG) - key_value = self.config['bot'][key_name] - if key_name == 'mode': - valid_values = ["local", "remote"] - self.assert_in(key_value, valid_values) - if key_name == 'browser': - valid_values = [ - "firefox", "chrome", - "iexplorer", "phantomjs", - "edge", "iexplorer"] - self.assert_in(key_value, valid_values) - if key_name == 'url_hub': - self.assert_regex_url(key_value) - if key_name == 'drivers_path': - self.assert_path_exist(key_value) - if key_name == 'drivers_names': - drivers_path = '../qadrivers/{}' - for value in key_value: - driver_path = drivers_path.format(value) - self.assert_path_exist(driver_path, is_dir=False) - if key_name == 'log_name': - self.assert_not_equals(key_value, "") - if key_name == 'log_output_file': - self.assert_not_equals(key_value, "") - - @pytest.mark.parametrize("key_name", [ - "skip", "apps" - ]) - def test_config_tests_keys(self, key_name): - """Testcase: test_config_tests_keys""" - if SKIP_CONFIG: - pytest.skip(msg=SKIP_CONFIG_MSG) - key_value = self.config['tests'][key_name] - if key_name == 'skip': - self.assert_is_instance(key_value, dict) - self.assert_is_instance( - key_value.get('test_configs'), bool) - self.assert_is_instance( - key_value.get('browsers'), dict) - self.assert_is_instance( - key_value.get('bot_multiple'), bool) - self.assert_is_instance( - key_value.get('bot_unique'), bool) - self.assert_is_instance( - 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_pages'), bool) - self.assert_is_instance( - key_value.get('benchmarks'), bool) - if key_name == 'apps': - self.assert_is_instance(key_value, list) - for app_config in key_value: - self.assert_is_instance(app_config, dict) - self.assert_is_instance(app_config.get('name'), str) - self.assert_is_instance(app_config.get('pages'), list) - for page_config in app_config.get('pages'): - self.assert_is_instance(page_config.get('name'), str) - self.assert_is_instance(page_config.get('url'), str) - self.assert_is_instance(page_config.get('locator'), str) - self.assert_is_instance(page_config.get('go_url'), bool) - self.assert_is_instance(page_config.get('wait_url'), int) - 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_old/000_unitaries/suite_002_testinfobase.py b/tests_old/000_unitaries/suite_002_testinfobase.py deleted file mode 100644 index f180a6ec..00000000 --- a/tests_old/000_unitaries/suite_002_testinfobase.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for testing package""" - - -import logging -import pytest -from qacode.core.loggers.logger_manager import Log -from qacode.core.testing.test_info import TestInfoBase -from qacode.utils import settings -from qatestlink.core.testlink_manager import TLManager - - -class TestTestInfoBase(TestInfoBase): - """Testcases for class TestInfoBase""" - - def setup_method(self, test_method): - """TODO: doc method""" - super(TestTestInfoBase, self).setup_method( - test_method, config=settings(file_path="qacode/configs/")) - - def test_log_inheritance(self): - """Test: test_001_inheritance""" - self.assert_is_instance(self, object) - self.assert_is_instance(self, TestInfoBase) - self.assert_is_instance(self.log._logger, logging.Logger) - self.assert_is_instance(self.config, dict) - if self.config.get('testlink'): - self.assert_is_instance(self.tlm, TLManager) - - @pytest.mark.parametrize("log_level", [ - "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" - ]) - def test_log_levels(self, log_level): - """Testcase: test_002_log_levels""" - msg = "Unitary test, checking level type'{}'".format( - log_level) - if log_level == 'DEBUG': - self.log.debug(msg) - if log_level == 'INFO': - self.log.info(msg) - if log_level == 'WARNING': - self.log.warning(msg) - if log_level == 'ERROR': - self.log.error(msg) - if log_level == 'CRITICAL': - self.log.critical(msg) - - def test_log_notparams(self): - """Testcase: test_log_notlogname""" - log = Log(**{}) - self.assert_equals(log._name, "qacode") - self.assert_equals(log._name_file, "qacode.log") - self.assert_equals(log._path, "./logs/") diff --git a/tests_old/000_unitaries/suite_004_teststrictrules.py b/tests_old/000_unitaries/suite_004_teststrictrules.py deleted file mode 100644 index d532e15f..00000000 --- a/tests_old/000_unitaries/suite_004_teststrictrules.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for enums package""" - - -import pytest -from qacode.core.exceptions.core_exception import CoreException -from qacode.core.testing.test_info import TestInfoBase -from qacode.core.webs.css_properties import CssProperty -from qacode.core.webs.html_attrs import HtmlAttr -from qacode.core.webs.html_tags import HtmlTag -from qacode.core.webs.strict_rules import ( - StrictRule, StrictSeverity, StrictType) -from qacode.utils import settings - - -class Teststrictrules(TestInfoBase): - """Testcases for class TestInfoBase""" - - def setup_method(self, test_method): - """TODO: doc method""" - super(Teststrictrules, self).setup_method( - test_method, config=settings(file_path="qacode/configs/")) - - @pytest.mark.parametrize("name", ['select', 'table']) - @pytest.mark.parametrize("strict_type", [StrictType.TAG]) - @pytest.mark.parametrize("severity", [ - StrictSeverity.LOW, StrictSeverity.MEDIUM, StrictSeverity.HIGHT]) - def test_strictrule_tags(self, name, strict_type, severity): - """Test: test_strictrule_tags""" - strict_rule = StrictRule(name, strict_type, severity) - self.assert_is_instance(strict_rule, StrictRule) - self.assert_equals(strict_rule.enum_type, HtmlTag(name)) - self.assert_equals(strict_rule.name, name) - self.assert_equals(strict_rule.severity, severity) - - @pytest.mark.parametrize("name", ['id', 'class']) - @pytest.mark.parametrize("strict_type", [StrictType.HTML_ATTR]) - @pytest.mark.parametrize("severity", [ - StrictSeverity.LOW, StrictSeverity.MEDIUM, StrictSeverity.HIGHT]) - def test_strictrule_htmlattrs(self, name, strict_type, severity): - """Test: test_strictrule_htmlattrs""" - strict_rule = StrictRule(name, strict_type, severity) - self.assert_is_instance(strict_rule, StrictRule) - self.assert_equals(strict_rule.enum_type, HtmlAttr(name)) - self.assert_equals(strict_rule.name, name) - self.assert_equals(strict_rule.severity, severity) - - @pytest.mark.parametrize("name", ['display', 'visibility']) - @pytest.mark.parametrize("strict_type", [StrictType.CSS_PROP]) - @pytest.mark.parametrize("severity", [ - StrictSeverity.LOW, StrictSeverity.MEDIUM, StrictSeverity.HIGHT]) - def test_strictrule_cssprops(self, name, strict_type, severity): - """Test: test_strictrule_htmlattrs""" - strict_rule = StrictRule(name, strict_type, severity) - self.assert_is_instance(strict_rule, StrictRule) - self.assert_equals(strict_rule.enum_type, CssProperty(name)) - self.assert_equals(strict_rule.name, name) - self.assert_equals(strict_rule.severity, severity) - - @pytest.mark.parametrize("name", [None, 'select']) - @pytest.mark.parametrize("strict_type", [None, 'bad', StrictType.TAG]) - @pytest.mark.parametrize("severity", [None]) - def test_strictrule_instance_raises(self, name, strict_type, severity): - """Test: test_strictrule_instance_raises""" - with pytest.raises(CoreException): - StrictRule(name, strict_type, severity) - - @pytest.mark.parametrize("name", ['select']) - @pytest.mark.parametrize("strict_type", [ - StrictType.JS_EVENT, StrictType.BEHAVIOUR, - StrictType.USABILITY, StrictType.SEO]) - @pytest.mark.parametrize("severity", [ - StrictSeverity.LOW, StrictSeverity.MEDIUM, StrictSeverity.HIGHT]) - def test_strictrule_notimplementedtypes(self, name, strict_type, severity): - """Test: test_strictrule_instance_raises""" - with pytest.raises(NotImplementedError): - StrictRule(name, strict_type, severity) diff --git a/tests_old/001_functionals/suite_001_botbase.py b/tests_old/001_functionals/suite_001_botbase.py deleted file mode 100644 index d94643e7..00000000 --- a/tests_old/001_functionals/suite_001_botbase.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testsuite for package bots""" - - -import pytest -from qacode.core.bots.bot_base import BotBase -from qacode.core.exceptions.core_exception import CoreException -from qacode.core.loggers.logger_manager import Log -from qacode.core.testing.test_info import TestInfoBase -from qacode.utils import settings - - -SETTINGS = settings(file_path="qacode/configs/") -SKIP = SETTINGS['tests']['skip']['browsers'] -SKIP_MSG = 'browsers.{} DISABLED by config file' -# TODO: must be setteable from config JSON -WAIT_TO_CLOSE = int(3) -LOGGER_MANAGER = Log(log_level=SETTINGS['bot']['log_level']) - - -class TestBotBase(TestInfoBase): - """Testcases for class BotBase""" - - def setup_method(self, test_method): - """TODO: doc method""" - super(TestBotBase, self).setup_method( - test_method, config=settings(file_path="qacode/configs/")) - - def teardown_method(self, method): - """TODO: doc method""" - if method.__name__ == 'test_botbase_drivernamefilter_ok': - return True - self.try_bot_close() - - def try_bot_close(self): - """Utility method for tests""" - try: - if self.bot: - self.bot.close() - except Exception: - print("ERROR: Failed at try to close bot") - - @pytest.mark.skipIf(SKIP, SKIP_MSG) - @pytest.mark.parametrize("is_win", [True, False]) - @pytest.mark.parametrize("is_64bits", [True, False]) - @pytest.mark.parametrize("browser", ["chrome", "firefox"]) - def test_botbase_drivernamefilter_ok(self, browser, is_win, is_64bits): - """Testcase: test_botbase_drivernamefilter_ok""" - if 'bot' not in dir(self): - settings = SETTINGS.copy() - self.add_property('bot', BotBase(**settings)) - # end setup - self.bot.IS_WIN = is_win - self.bot.IS_64BITS = is_64bits - name_formatted = self.bot.driver_name_filter(browser) - if is_win and not is_64bits: - self.assert_equals( - name_formatted, "{}driver_32.exe".format(browser)) - if is_win and is_64bits: - self.assert_equals( - name_formatted, "{}driver_64.exe".format(browser)) - if not is_win and not is_64bits: - self.assert_equals( - name_formatted, "{}driver_32".format(browser)) - if not is_win and is_64bits: - self.assert_equals( - name_formatted, "{}driver_64".format(browser)) - self.try_bot_close() - - @pytest.mark.parametrize("browser_name", [ - "chrome", "firefox", "iexplorer", "edge"]) - @pytest.mark.parametrize("driver_mode", ["local", "remote"]) - def test_bot_modes_and_names(self, driver_mode, browser_name): - """Testcase: test_001_bot_local_chrome""" - if SKIP[browser_name][driver_mode]: - pytest.skip(SKIP_MSG.format(browser_name)) - settings = SETTINGS.copy() - settings.get('bot').update({ - 'browser': str(browser_name), - 'mode': str(driver_mode) - }) - if browser_name == 'edge': - browser_name = 'MicrosoftEdge' - pytest.skip(msg="Browser not configured") - if browser_name == 'iexplorer': - browser_name = 'internet explorer' - self.bot = BotBase(**settings) - self.timer(wait=WAIT_TO_CLOSE) - self.assert_is_instance(self.bot, BotBase) - self.assert_equals( - self.bot.settings.get('browser'), - settings.get('bot').get('browser')) - self.assert_equals(self.bot.settings.get('mode'), driver_mode) - self.assert_equals(self.bot.curr_caps['browserName'], browser_name) - - @pytest.mark.parametrize("browser_name", ["chrome", "firefox"]) - @pytest.mark.parametrize("driver_mode", ["local", "remote"]) - def test_bot_modes_headless(self, driver_mode, browser_name): - """Testcase: test_bot_modes_headless""" - if SKIP[browser_name][driver_mode]: - pytest.skip(SKIP_MSG.format(browser_name)) - settings = SETTINGS.copy() - settings.get('bot').update({ - 'browser': str(browser_name), - 'mode': str(driver_mode), - 'options': {"headless": True} - }) - self.bot = BotBase(**settings) - self.timer(wait=WAIT_TO_CLOSE) - self.assert_is_instance(self.bot, BotBase) - self.assert_equals( - self.bot.settings.get('browser'), - settings.get('bot').get('browser')) - self.assert_equals(self.bot.settings.get('mode'), driver_mode) - self.assert_equals(self.bot.curr_caps['browserName'], browser_name) - - @pytest.mark.skipIf(SKIP, SKIP_MSG) - def test_botbase_invalidsettingskey(self): - """Testcase: test_botbase_invalidsettingskey""" - settings = SETTINGS.copy() - settings.get('bot').update({"must_raises": "test"}) - with pytest.raises(CoreException): - BotBase(**settings) - - @pytest.mark.skipIf(SKIP, SKIP_MSG) - def test_botbase_invalidmode(self): - """Testcase: test_botbase_invalidmode""" - settings = SETTINGS.copy() - settings.get('bot').update({"mode": "must_raises"}) - with pytest.raises(CoreException): - self.bot = BotBase(**settings) - - @pytest.mark.skipIf(SKIP, SKIP_MSG) - def test_botbase_invalidbrowser(self): - """Testcase: test_botbase_invalidbrowser""" - settings = SETTINGS.copy() - settings.get('bot').update({"browser": "must_raises"}) - with pytest.raises(CoreException): - self.bot = BotBase(**settings) diff --git a/tests_old/001_functionals/suite_002_testinfobot.py b/tests_old/001_functionals/suite_002_testinfobot.py deleted file mode 100644 index 0cec6524..00000000 --- a/tests_old/001_functionals/suite_002_testinfobot.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for testing package""" - - -import logging -import pytest -from qacode.core.bots.bot_base import BotBase -from qacode.core.testing.test_info import TestInfoBot -from qacode.utils import settings -from qatestlink.core.testlink_manager import TLManager - - -SETTINGS = settings(file_path="qacode/configs/") -SKIP_BOT_MULTIPLE = SETTINGS['tests']['skip']['bot_multiple'] -SKIP_BOT_MULTIPLE_MSG = 'bot_multiple DISABLED by config file' - - -class TestTestInfoBot(TestInfoBot): - """Testcases for class TestInfoBot""" - - def setup_method(self, test_method): - """Setup class (suite) to be executed""" - super(TestTestInfoBot, self).setup_method( - test_method, config=settings(file_path="qacode/configs/")) - - @pytest.mark.parametrize('run_time', [1, 2]) - @pytest.mark.skipIf(SKIP_BOT_MULTIPLE, SKIP_BOT_MULTIPLE_MSG) - def test_multiple_bots(self, run_time): - """Testcase: test_multiple_bots""" - self.log.debug("TestInfoBotUnique, test='{}'".format(run_time)) - self.assert_is_instance(self, object) - self.assert_is_instance(self, TestInfoBot) - self.assert_is_instance(self.log._logger, logging.Logger) - self.assert_is_instance(self.bot, BotBase) - self.assert_is_instance(self.config, dict) - self.assert_is_instance(self.tlm, TLManager) diff --git a/tests_old/001_functionals/suite_003_testinfobotunique.py b/tests_old/001_functionals/suite_003_testinfobotunique.py deleted file mode 100644 index 3abec654..00000000 --- a/tests_old/001_functionals/suite_003_testinfobotunique.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test Suite module for testing package""" - - -import logging -import pytest -from qacode.core.bots.bot_base import BotBase -from qacode.core.testing.test_info import TestInfoBotUnique -from qacode.utils import settings -from qatestlink.core.testlink_manager import TLManager - - -SETTINGS = settings(file_path="qacode/configs/") -SKIP_BOT_UNIQUE = SETTINGS['tests']['skip']['bot_unique'] -SKIP_BOT_UNIQUE_MSG = 'bot_unique DISABLED by config file' - - -class TestTestInfoBotUnique(TestInfoBotUnique): - """Testcases for class TestInfoBot""" - - @classmethod - def setup_class(cls, **kwargs): - """Setup class (suite) to be executed""" - super(TestTestInfoBotUnique, cls).setup_class( - config=settings(file_path="qacode/configs/"), - skip_force=SKIP_BOT_UNIQUE) - - @pytest.mark.parametrize('run_time', [1, 2]) - @pytest.mark.skipIf(SKIP_BOT_UNIQUE, SKIP_BOT_UNIQUE_MSG) - def test_unique_bot_multiple_tests(self, run_time): - """Testcase: test_unique_bot_multiple_tests""" - self.log.debug("TestInfoBotUnique, test='{}'".format(run_time)) - self.assert_is_instance(self, object) - self.assert_is_instance(self, TestInfoBotUnique) - self.assert_is_instance(self.log._logger, logging.Logger) - self.assert_is_instance(self.bot, BotBase) - self.assert_is_instance(self.tlm, TLManager) diff --git a/tests_old/001_functionals/suite_004_navbase.py b/tests_old/001_functionals/suite_004_navbase.py deleted file mode 100644 index 9fe7e7fa..00000000 --- a/tests_old/001_functionals/suite_004_navbase.py +++ /dev/null @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package for suites and tests related to bots.modules package""" - - -import pytest -from qacode.core.bots.modules.nav_base import NavBase -from qacode.core.exceptions.core_exception import CoreException -from qacode.core.testing.test_info import TestInfoBotUnique -from qacode.utils import settings -from selenium.webdriver.remote.webelement import WebElement - - -SETTINGS = settings(file_path="qacode/configs/") -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 = None - - @classmethod - def setup_class(cls, **kwargs): - """Setup class (suite) to be executed""" - super(TestNavBase, cls).setup_class( - config=settings(file_path="qacode/configs/"), - 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.cfg_app('qadmin')) - self.add_property('page', self.cfg_page('qacode_login')) - self.add_property('txt_username', self.cfg_control('txt_username')) - self.add_property('txt_password', self.cfg_control('txt_password')) - self.add_property('btn_submit', self.cfg_control('btn_submit')) - self.add_property('lst_ordered', self.cfg_control('lst_ordered')) - self.add_property( - 'lst_ordered_child', self.cfg_control('lst_ordered_child')) - self.add_property('dd_menu_data', self.cfg_control('dd_menu_data')) - self.add_property( - 'dd_menu_data_lists', self.cfg_control('dd_menu_data_lists')) - self.add_property( - 'btn_click_invisible', self.cfg_control('btn_click_invisible')) - self.add_property( - 'btn_click_visible', self.cfg_control('btn_click_visible')) - self.add_property('title_buttons', self.cfg_control('title_buttons')) - - def setup_login_to_inputs(self): - """Do login before to exec some testcases""" - # setup_login - self.bot.navigation.get_url(self.page.get('url'), wait_for_load=10) - txt_username = self.bot.navigation.find_element( - self.txt_username.get("selector")) - txt_password = self.bot.navigation.find_element( - self.txt_password.get("selector")) - btn_submit = self.bot.navigation.find_element( - self.btn_submit.get("selector")) - self.bot.navigation.ele_write(txt_username, "admin") - self.bot.navigation.ele_write(txt_password, "admin") - self.bot.navigation.ele_click(btn_submit) - # end setup_login - - def setup_login_to_data(self): - """Do login before to exec some testcases""" - # setup_login - self.bot.navigation.get_url(self.page.get('url'), wait_for_load=10) - txt_username = self.bot.navigation.find_element( - self.txt_username.get("selector")) - txt_password = self.bot.navigation.find_element( - self.txt_password.get("selector")) - btn_submit = self.bot.navigation.find_element( - self.btn_submit.get("selector")) - self.bot.navigation.ele_write(txt_username, "admin") - self.bot.navigation.ele_write(txt_password, "admin") - self.bot.navigation.ele_click(btn_submit) - self.bot.navigation.ele_click( - self.bot.navigation.find_element_wait( - self.dd_menu_data.get("selector"))) - self.bot.navigation.ele_click( - self.bot.navigation.find_element_wait( - self.dd_menu_data_lists.get("selector"))) - # end setup_login - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_navbase_instance(self): # NO - """Testcase: test_navbase_instance""" - self.assert_is_instance(self.bot.navigation, NavBase) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gourl_withoutwaits(self): # YES - """Testcase: test_gourl_withoutwaits""" - self.bot.navigation.get_url(self.page.get('url')) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gourl_withwaits(self): # YES - """Testcase: test_gourl_withwaits""" - self.bot.navigation.get_url( - self.page.get('url'), wait_for_load=1) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getcurrenturl_ok(self): # YES - """Testcase: test_getcurrenturl_ok""" - self.assert_equals( - self.bot.navigation.get_current_url(), - self.page.get('url')) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_isurl_true(self): - """Testcase: test_isurl_true""" - self.assert_true( - self.bot.navigation.is_url( - self.bot.navigation.get_current_url())) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_isurl_false(self): - """Testcase: test_isurl_false""" - self.assert_false(self.bot.navigation.is_url("")) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_isurl_raiseswhenurlreturnfalse(self): - """Testcase: test_isurl_false""" - with pytest.raises(CoreException): - self.bot.navigation.is_url("", ignore_raises=False) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_reload_ok(self): - """Testcase: test_reload_ok""" - self.bot.navigation.reload() - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_forward_ok(self): - """Testcase: test_reload_ok""" - self.bot.navigation.forward() - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getmaximizewindow_ok(self): - """Testcase: test_getmaximizewindow_ok""" - self.bot.navigation.get_maximize_window() - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getcapabilities_ok(self): - """Testcase: test_getcapabilities_ok""" - caps = self.bot.navigation.get_capabilities() - self.assert_is_instance(caps, dict) - self.assert_is_instance(caps['chrome'], dict) - self.assert_equals(caps['browserName'], 'chrome') - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getlog_ok(self): - """Testcase: test_getlog_ok""" - 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_NAVS, SKIP_NAVS_MSG) - @pytest.mark.parametrize( - "log_name", [None, 'browser', 'driver', 'client', 'server']) - def test_getlog_lognames(self, log_name): - """Testcase: test_getlog_lognames""" - self.bot.navigation.get_url(self.page.get('url')) - if log_name is None: - with pytest.raises(CoreException): - self.bot.navigation.get_log(log_name=log_name) - return True - 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( - log_name, log_data) - self.log.debug(msg) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelement_ok(self): - """Testcase: test_findelement_ok""" - self.assert_is_instance( - self.bot.navigation.find_element("body"), - WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelement_notfound(self): - """Testcase: test_findelement_notfound""" - with pytest.raises(CoreException): - self.bot.navigation.find_element("article") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelement_notlocator(self): - """Testcase: test_findelement_notlocator""" - with pytest.raises(CoreException): - self.bot.navigation.find_element( - "body", locator=None) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelementwait_ok(self): - """Testcase: test_findelementwait_ok""" - self.assert_is_instance( - self.bot.navigation.find_element_wait("body"), - WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelementswait_ok(self): - """Testcase: test_findelementwait_ok""" - elements = self.bot.navigation.find_elements_wait("body>*") - self.assert_is_instance(elements, list) - for element in elements: - self.assert_is_instance(element, WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelements_ok(self): - """Testcase: test_findelement_ok""" - elements = self.bot.navigation.find_elements("body>*") - self.assert_is_instance(elements, list) - for element in elements: - self.assert_is_instance(element, WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelements_notfound(self): - """Testcase: test_findelements_notfound""" - with pytest.raises(CoreException): - self.bot.navigation.find_elements("article") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelements_notlocator(self): - """Testcase: test_findelements_notlocator""" - with pytest.raises(CoreException): - self.bot.navigation.find_elements( - "body", locator=None) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getwindowhandle_ok(self): - """Testcase: test_getwindowhandle_ok""" - self.assert_not_none( - self.bot.navigation.get_window_handle()) - - @pytest.mark.skipIf( - True, "Depends of remote+local webdrivers to get working") - def test_addcookie_ok(self): - """Testcase: test_addcookie_ok""" - cookie = {"name": "test_cookie", "value": "test_value"} - self.bot.navigation.add_cookie(cookie) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_addcookie_notparams(self): - """Testcase: test_addcookie_ok""" - with pytest.raises(CoreException): - self.bot.navigation.add_cookie(None) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_addcookie_badcookiekeys(self): - """Testcase: test_addcookie_ok""" - with pytest.raises(CoreException): - self.bot.navigation.add_cookie({}) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getcookies_ok(self): - """Testcase: test_getcookies_ok""" - self.assert_is_instance( - self.bot.navigation.get_cookies(), - list) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_deletecookiebykey_ok(self): - """Testcase: test_deleteallcookies_ok""" - self.bot.navigation.delete_cookie_by_key("") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_deleteallcookies_ok(self): - """Testcase: test_deleteallcookies_ok""" - self.bot.navigation.delete_cookies() - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_setwindowsize_ok(self): - """Testcase: test_setwindowsize_ok""" - self.bot.navigation.set_window_size( - pos_x=1024, pos_y=768) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_gettitle_ok(self): # YES - """Testcase: test_gettitle_ok""" - self.assert_not_none( - self.bot.navigation.get_title()) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_getscreenshotasbase64_ok(self): - """Testcase: test_getscreenshotasbase64_ok""" - self.assert_not_none( - self.bot.navigation.get_screenshot_as_base64()) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_jssettimeout_ok(self): - """Testcase: test_jssettimeout_ok""" - self.bot.navigation.js_set_timeout(1) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_eleclick_okbyselector(self): - """Testcase: test_eleclick_ok""" - self.bot.navigation.ele_click(selector="body") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_eleclick_okbyelement(self): - """Testcase: test_eleclick_ok""" - self.bot.navigation.ele_click( - element=self.bot.navigation.find_element("body")) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_eleclick_notparams(self): - """Testcase: test_eleclick_notparams""" - with pytest.raises(CoreException): - self.bot.navigation.ele_click() - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewrite_ok(self): - """Testcase: test_elewrite_ok""" - self.bot.navigation.ele_write( - self.bot.navigation.find_element("body"), - text="test") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewrite_okwithouttext(self): - """Testcase: test_elewrite_ok""" - self.bot.navigation.ele_write( - self.bot.navigation.find_element("body"), - text=None) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewrite_notparams(self): - """Testcase: test_elewrite_notparams""" - with pytest.raises(CoreException): - self.bot.navigation.ele_write(None) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_setwebelement_ok(self): - """Testcase: test_setwebelement_ok""" - self.bot.navigation.set_web_element("test-element") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelementchild_ok(self): - """Testcase: test_findelementchild_ok""" - self.setup_login_to_data() - ele_parent = self.bot.navigation.find_element_wait( - self.lst_ordered.get("selector")) - self.assert_is_instance(ele_parent, WebElement) - ele_child = self.bot.navigation.find_element_child( - ele_parent, self.lst_ordered_child.get("selector")) - self.assert_is_instance(ele_child, WebElement) - self.assert_equals( - "Item list01", self.bot.navigation.ele_text(ele_child)) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_findelementchildren_ok(self): - """Testcase: test_findelementchildren_ok""" - self.setup_login_to_data() - ele_parent = self.bot.navigation.find_element_wait( - self.lst_ordered.get("selector")) - self.assert_is_instance(ele_parent, WebElement) - ele_children = self.bot.navigation.find_element_children( - ele_parent, self.lst_ordered_child.get("selector")) - self.assert_is_instance(ele_children, list) - self.assert_greater(len(ele_children), 1) - self.assert_lower(len(ele_children), 5) - self.assert_equals( - "Item list01", - self.bot.navigation.ele_text(ele_children[0])) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewaitinvisible_ok(self): - """Testcase: test_elewaitinvisible_ok""" - self.setup_login_to_inputs() - selector = self.btn_click_invisible.get("selector") - ele = self.bot.navigation.find_element_wait(selector) - ele.click() - # end setup - ele = self.bot.navigation.ele_wait_invisible(selector, timeout=7) - self.assert_is_instance(ele, WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewaitvisible_ok(self): - """Testcase: test_elewaitvisible_ok""" - self.setup_login_to_inputs() - find_ele = self.bot.navigation.find_element_wait - ele = find_ele(self.btn_click_invisible.get("selector")) - ele.click() - ele_invisible = find_ele(self.btn_click_visible.get("selector")) - # end setup - ele_visible = self.bot.navigation.ele_wait_visible( - ele_invisible, timeout=7) - self.assert_is_instance(ele_visible, WebElement) - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewaittext_ok(self): - """Testcase: test_elewaitvalue_ok""" - self.setup_login_to_inputs() - selector = self.btn_click_invisible.get("selector") - selector_title = self.title_buttons.get("selector") - ele_text = self.bot.navigation.find_element_wait(selector) - ele_text.click() - # end setup - is_changed = self.bot.navigation.ele_wait_text( - selector_title, "Buttonss", timeout=12) - self.assert_true(is_changed) - self.assert_is_instance( - self.bot.navigation.ele_text(ele_text), - "Buttonss") - - @pytest.mark.skipIf(SKIP_NAVS, SKIP_NAVS_MSG) - def test_elewaitvalue_ok(self): - """Testcase: test_elewaitvalue_ok""" - self.setup_login_to_inputs() - selector = self.btn_click_invisible.get("selector") - ele_text = self.bot.navigation.find_element_wait(selector) - ele_text.click() - # end setup - is_changed = self.bot.navigation.ele_wait_value( - selector, "bad_text", timeout=12) - self.assert_true(is_changed) - self.assert_is_instance( - self.bot.navigation.ele_attribute(ele_text, "value"), - "bad_text") From 489774c36ec661de7b2062a70b49872a9bc2159c Mon Sep 17 00:00:00 2001 From: netzulo Date: Mon, 10 Feb 2020 03:31:37 +0100 Subject: [PATCH 21/43] [qacode] remove old files --- qacode_old/__init__.py | 12 - qacode_old/core/__init__.py | 12 - qacode_old/core/enums/__init__.py | 8 - qacode_old/core/enums/enum_base.py | 26 - qacode_old/core/exceptions/__init__.py | 10 - .../core/exceptions/control_exception.py | 25 - qacode_old/core/exceptions/core_exception.py | 53 -- qacode_old/core/exceptions/page_exception.py | 27 - qacode_old/core/loggers/__init__.py | 9 - qacode_old/core/loggers/logger_manager.py | 80 --- qacode_old/core/loggers/logger_messages.py | 65 --- qacode_old/core/testing/testlink/__init__.py | 8 - .../testing/testlink/reporter_testlink.py | 50 -- qacode_old/core/webs/__init__.py | 18 - qacode_old/core/webs/controls/__init__.py | 11 - qacode_old/core/webs/controls/control_base.py | 531 ------------------ .../core/webs/controls/control_dropdown.py | 130 ----- qacode_old/core/webs/controls/control_form.py | 150 ----- .../core/webs/controls/control_table.py | 137 ----- qacode_old/core/webs/css_properties.py | 185 ------ qacode_old/core/webs/html_attrs.py | 14 - qacode_old/core/webs/html_tags.py | 130 ----- qacode_old/core/webs/pages/__init__.py | 8 - qacode_old/core/webs/pages/page_base.py | 188 ------- qacode_old/core/webs/strict_rules.py | 95 ---- tests_old/000_unitaries/__init__.py | 2 - .../000_unitaries/suite_003_testenumbase.py | 45 -- tests_old/001_functionals/__init__.py | 2 - .../001_functionals/suite_005_controlbase.py | 355 ------------ .../001_functionals/suite_006_controlform.py | 158 ------ .../suite_007_controldropdown.py | 273 --------- .../001_functionals/suite_008_controltable.py | 168 ------ .../001_functionals/suite_009_pagebase.py | 125 ----- .../suite_010_reportertestlink.py | 31 - tests_old/002_benchmarks/__init__.py | 2 - .../002_benchmarks/suite_001_browsers.py | 102 ---- tests_old/__init__.py | 2 - 37 files changed, 3247 deletions(-) delete mode 100644 qacode_old/__init__.py delete mode 100644 qacode_old/core/__init__.py delete mode 100644 qacode_old/core/enums/__init__.py delete mode 100644 qacode_old/core/enums/enum_base.py delete mode 100644 qacode_old/core/exceptions/__init__.py delete mode 100644 qacode_old/core/exceptions/control_exception.py delete mode 100644 qacode_old/core/exceptions/core_exception.py delete mode 100644 qacode_old/core/exceptions/page_exception.py delete mode 100644 qacode_old/core/loggers/__init__.py delete mode 100644 qacode_old/core/loggers/logger_manager.py delete mode 100644 qacode_old/core/loggers/logger_messages.py delete mode 100644 qacode_old/core/testing/testlink/__init__.py delete mode 100644 qacode_old/core/testing/testlink/reporter_testlink.py delete mode 100644 qacode_old/core/webs/__init__.py delete mode 100644 qacode_old/core/webs/controls/__init__.py delete mode 100644 qacode_old/core/webs/controls/control_base.py delete mode 100644 qacode_old/core/webs/controls/control_dropdown.py delete mode 100644 qacode_old/core/webs/controls/control_form.py delete mode 100644 qacode_old/core/webs/controls/control_table.py delete mode 100644 qacode_old/core/webs/css_properties.py delete mode 100644 qacode_old/core/webs/html_attrs.py delete mode 100644 qacode_old/core/webs/html_tags.py delete mode 100644 qacode_old/core/webs/pages/__init__.py delete mode 100644 qacode_old/core/webs/pages/page_base.py delete mode 100644 qacode_old/core/webs/strict_rules.py delete mode 100644 tests_old/000_unitaries/__init__.py delete mode 100644 tests_old/000_unitaries/suite_003_testenumbase.py delete mode 100644 tests_old/001_functionals/__init__.py delete mode 100644 tests_old/001_functionals/suite_005_controlbase.py delete mode 100644 tests_old/001_functionals/suite_006_controlform.py delete mode 100644 tests_old/001_functionals/suite_007_controldropdown.py delete mode 100644 tests_old/001_functionals/suite_008_controltable.py delete mode 100644 tests_old/001_functionals/suite_009_pagebase.py delete mode 100644 tests_old/001_functionals/suite_010_reportertestlink.py delete mode 100644 tests_old/002_benchmarks/__init__.py delete mode 100644 tests_old/002_benchmarks/suite_001_browsers.py delete mode 100644 tests_old/__init__.py diff --git a/qacode_old/__init__.py b/qacode_old/__init__.py deleted file mode 100644 index 6b4ccef7..00000000 --- a/qacode_old/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode - Created on 04 march 2017 - @author: ntz -""" - - -from qacode import configs -from qacode import core -from qacode import utils - -__all__ = ['configs', 'core', 'utils'] diff --git a/qacode_old/core/__init__.py b/qacode_old/core/__init__.py deleted file mode 100644 index 0a595103..00000000 --- a/qacode_old/core/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core""" - - -from qacode.core import bots -from qacode.core import exceptions -from qacode.core import loggers -from qacode.core import testing -from qacode.core import webs - - -__all__ = ['bots', 'exceptions', 'loggers', 'testing', 'webs'] diff --git a/qacode_old/core/enums/__init__.py b/qacode_old/core/enums/__init__.py deleted file mode 100644 index 6ef30f2d..00000000 --- a/qacode_old/core/enums/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.enums""" - - -from qacode.core.enums import enum_base - - -__all__ = ['enum_base'] diff --git a/qacode_old/core/enums/enum_base.py b/qacode_old/core/enums/enum_base.py deleted file mode 100644 index 42238700..00000000 --- a/qacode_old/core/enums/enum_base.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.enums.enum_base""" - - -from enum import Enum - - -class EnumBase(Enum): - """Enum Class with base methods to be used - at inherit classes - """ - - @classmethod - def get_properties(cls): - """Return enum values""" - return list(cls.__members__.keys()) - - @classmethod - def has_property(cls, value): - """Returns True if enum have value""" - try: - cls(value) - except ValueError: - return False - else: - return True diff --git a/qacode_old/core/exceptions/__init__.py b/qacode_old/core/exceptions/__init__.py deleted file mode 100644 index c17625c7..00000000 --- a/qacode_old/core/exceptions/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.exceptions""" - - -from qacode.core.exceptions import control_exception -from qacode.core.exceptions import core_exception -from qacode.core.exceptions import page_exception - - -__all__ = ['control_exception', 'core_exception', 'page_exception'] diff --git a/qacode_old/core/exceptions/control_exception.py b/qacode_old/core/exceptions/control_exception.py deleted file mode 100644 index c0b73a12..00000000 --- a/qacode_old/core/exceptions/control_exception.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package qacode.core.exceptions""" - - -from qacode.core.exceptions.core_exception import CoreException - - -NOT_MSG_CONTROL = "Message Exception not defined for ControlException class" - - -class ControlException(CoreException): - """ControlBase and inherit classes can use this exception""" - - def __init__(self, msg=NOT_MSG_CONTROL, log=None, info_bot=None): - """Instance ControlException error to raise message from controls""" - super(ControlException, self).__init__( - msg=msg, log=log, info_bot=info_bot) - self.selector = info_bot.get("selector") or "" - - def __str__(self): - """Representation of class""" - msg = super(ControlException, self).__str__() - msg += "selector={}".format( - self.info_bot.get("selector")) - return msg diff --git a/qacode_old/core/exceptions/core_exception.py b/qacode_old/core/exceptions/core_exception.py deleted file mode 100644 index 51a53164..00000000 --- a/qacode_old/core/exceptions/core_exception.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -"""Main Exceptions for qacode library""" - - -from qacode.core.loggers.logger_manager import Log -from selenium.common.exceptions import WebDriverException - - -NOT_MSG = 'Exception without message' - - -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) diff --git a/qacode_old/core/exceptions/page_exception.py b/qacode_old/core/exceptions/page_exception.py deleted file mode 100644 index 3f56b07c..00000000 --- a/qacode_old/core/exceptions/page_exception.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package qacode.core.exceptions""" - -from qacode.core.exceptions.core_exception import CoreException - - -NOT_MSG_PAGE = "Message Exception not defined for PageException class" - - -class PageException(CoreException): - """Exception class that can be raise from Page classes""" - - def __init__(self, msg=NOT_MSG_PAGE, log=None, info_bot=None): - """This exception must be raised from PageBase or inherit classes""" - self.url = info_bot.get("url") or "" - super(PageException, self).__init__( - msg=msg, log=log, info_bot=info_bot) - - def __str__(self): - """Representation of class""" - return self.msg_info_bot(self.info_bot) - - def msg_info_bot(self, info_bot): - """Generate str message from param 'info_bot'""" - msg = super(PageException, self).msg_info_bot(info_bot) - msg += "url='{}' ".format(self.url) - return msg diff --git a/qacode_old/core/loggers/__init__.py b/qacode_old/core/loggers/__init__.py deleted file mode 100644 index b7d110a3..00000000 --- a/qacode_old/core/loggers/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -"""package qacode.core.loggers""" - - -from qacode.core.loggers import logger_manager -from qacode.core.loggers import logger_messages - - -__all__ = ['logger_manager', 'logger_messages'] diff --git a/qacode_old/core/loggers/logger_manager.py b/qacode_old/core/loggers/logger_manager.py deleted file mode 100644 index fd0e370f..00000000 --- a/qacode_old/core/loggers/logger_manager.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -"""Module related with all logging tasks""" - - -from logging import ( - FileHandler, Formatter, INFO, StreamHandler, getLogger) -from qacode.utils import path_format - - -class Log(object): - """Manager for logger""" - - # ATTRIBUTES - _name = None - _name_file = None - _path = None - _path_join = None - _level = None - _formatter = None - _logger = None - - def __init__(self, *args, **kwargs): - """TODO: doc method""" - self._name = kwargs.get('log_name') or "qacode" - self._name_file = "{}.log".format(self._name) - self._path = kwargs.get('log_path') or './logs/' - self._path_join = path_format( - file_path=self._path, file_name=self._name_file) - self._level = kwargs.get('log_level') or INFO - - self._formatter = Formatter( - ("[pid:%(process)d][%(asctime)s][%(name)s]" - "[%(levelname)s]: %(message)s")) - self._handlers = self.__handlers__() or {} - self.__logger__() - - def __logger__(self): - """TODO: doc method""" - self._logger = getLogger(self._name) - self._logger.setLevel(self._level) - # Remove handlers added to logging module - for old_handler in self._logger.handlers: - self._logger.removeHandler(old_handler) - # Add new handlers - if not self._logger.handlers: - self._logger.addHandler(self._handlers['console']) - self._logger.addHandler(self._handlers['file']) - - def __handlers__(self): - """TODO: doc method""" - handlers = [StreamHandler(), FileHandler(self._path_join)] - for handler in handlers: - handler.setFormatter(self._formatter) - handler.setLevel(self._level) - return { - "console": handlers[0], - "file": handlers[1], - } - - # PUBLIC METHODS - - def debug(self, msg): - """TODO: doc method""" - self._logger.debug(msg) - - def info(self, msg): - """TODO: doc method""" - self._logger.info(msg) - - def warning(self, msg): - """TODO: doc method""" - self._logger.warning(msg) - - def error(self, msg): - """TODO: doc method""" - self._logger.warning(msg) - - def critical(self, msg): - """TODO: doc method""" - self._logger.critical(msg) diff --git a/qacode_old/core/loggers/logger_messages.py b/qacode_old/core/loggers/logger_messages.py deleted file mode 100644 index 6484cafc..00000000 --- a/qacode_old/core/loggers/logger_messages.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -"""Module related with all logging messages""" - -# Commons -NOT_IMPLEMENTED = "Open an issue on github if raise here" # noqa:E501 -BAD_PARAM = "ctl_form | bad param '{}', invalid value" # noqa:E501 -# ControlBase -CB_SETTINGS_LOADING = "ctl | load_settings_keys: loading keys..." # noqa:E501 -CB_SETTINGS_LOADED = "ctl | load_settings_keys: loaded keys" # noqa:E501 -CB_SEARCH_DISABLED = "ctl | _load_search: Disabled element search" # noqa:E501 -CB_SEARCH_LOADING = "ctl | _load_search: searching element..." # noqa:E501 -CB_SEARCH_WAITING = "ctl | _load_search: waiting for element..." # noqa:E501 -CB_SEARCH_FOUND = "ctl | _load_search: element found!" # noqa:E501 -CB_SEARCH_FOUND_CHILD = "ctl | _load_search: element child found!" # noqa:E501 -CB_PROP_DISABLED = "ctl | _load_properties: disabled loading for properties" # noqa:E501 -CB_PROP_LOADING = "ctl | _load_properties: loading properties..." # noqa:E501 -CB_PROP_LOADED = "ctl | _load_properties: loaded properties" # noqa:E501 -CB_FINDCHILD_LOADING = "ctl | find_child: searching for selector='{}'" # noqa:E501 -CB_FINDCHILD_LOADED = "ctl | find_child: child element found" # noqa:E501 -CB_GETTAG_LOADING = "ctl | get_tag: searching for tag" # noqa:E501 -CB_GETTAG_LOADED = "ctl | get_tag: found same tag='{}'" # noqa:E501 -CB_TYPETEXT_LOADING = "ctl | type_text: typing text='{}'" # noqa:E501 -CB_CLEAR_LOADING = "ctl | clear: clearing text..." # noqa:E501 -CB_CLEAR_LOADED = "ctl | clear: cleared text" # noqa:E501 -CB_CLICK_LOADING = "ctl | click: clicking element..." # noqa:E501 -CB_CLICK_RETRY = "ctl | click: retry clicking element..." # noqa:E501 -CB_CLICK_LOADED = "ctl | click: clicked!" # noqa:E501 -CB_GETTEXT_LOADING = "ctl | get_text: obtaining text..." # noqa:E501 -CB_GETTEXT_FAILED = "ctl | get_text: failed at obtain text" # noqa:E501 -CB_GETTEXT_LOADED = "ctl | get_text: text obtained, text='{}'" # noqa:E501 -CB_GETATTRS_LOADING = "ctl | get_attrs: obtaining attrs..." # noqa:E501 -CB_GETATTRVALUE_LOADING = "ctl | get_attr_value: obtaining value for attr_name='{}'" # noqa:E501 -CB_GETATTRVALUE_LOADED = "ctl | get_attr_value: obtained attr_name='{}', value='{}'" # noqa:E501 -CB_GETATTRVALUE_FAILED = "ctl | get_attr_value: fail at obtain value" # noqa:E501 -CB_SETCSSRULE_LOADING = "ctl | set_css_value: setting new CSS rule, prop_name='{}', prop_value='{}'" # noqa:E501 -CB_SETCSSRULE_FAILED = "ctl | set_css_value: failed at set CSS rule" # noqa:E501 -CB_GETCSSRULE_LOADING = "ctl | get_css_value: obtaining css_value..." # noqa:E501 -CB_GETCSSRULE_LOADED = "ctl | get_css_value: css_value='{}'" # noqa:E501 -CB_RELOAD_LOADING = "{} | reload: reloading control..." # noqa:E501 -CB_RELOAD_LOADED = "{} | reload: reloaded control" # noqa:E501 -# ControlForm -CF_RULES_LOADING = "ctl_form | loading rules..." # noqa:E501 -CF_RULES_DISABLED = "ctl_form | disabled rules functionality for this control" # noqa:E501 -CF_RULES_PARSING = "ctl_form | parsing rules..." # noqa:E501 -CF_RULES_PARSED = "ctl_form | parsed rules" # noqa:E501 -CF_RULES_APPLYING = "ctl_form | applying rules..." # noqa:E501 -CF_RULES_APPLIED = "ctl_form | applied rules" # noqa:E501 -CF_RULES_APPLYING_TAG = "ctl_form | applying tag rule..." # noqa:E501 -CF_RULES_APPLIED_TAG = "ctl_form | applied tag rule" # noqa:E501 -CF_RELOAD_LOADED = "ctl_form | reload: reloaded ctl" # noqa:E501 -CF_BADTAG = "ctl_form | This tag can't be loaded due a check, element must contains tag equals to validation rule tag type" # noqa:E501 -# ControlDropdown -CDD_SELECT_LOADING = "ctl_dd | select: selecting..." # noqa:E501 -CDD_SELECT_LOADED = "ctl_dd | select: selected" # noqa:E501 -CDD_SELECT_LOADING = "ctl_dd | deselect: deselecting..." # noqa:E501 -CDD_DESESELECT_LOADED = "ctl_dd | select: deselected" # noqa:E501 -CDD_DESELECTALL_LOADING = "ctl_dd | dropdown_select: deselecting all..." # noqa:E501 -CDD_DESELECTALL_LOADED = "ctl_dd | dropdown_select: deselected all" # noqa:E501 -CDD_BADTAG = "ctl_dd | Can't use this for not