Skip to content

Commit

Permalink
[qacode] starting issue #248 , WIP control_table
Browse files Browse the repository at this point in the history
+ new class ControlTable
+ inherit of ControlForm
+ validate tag table tag at instantiation
  • Loading branch information
netzulo committed Apr 14, 2019
1 parent 500e9fe commit bc2a2ea
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 5 deletions.
3 changes: 2 additions & 1 deletion qacode/configs/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"web_controls": {
"control_base": false,
"control_form": false,
"control_dropdown": false
"control_dropdown": false,
"control_table": false
},
"web_pages": false,
"benchmarks": true
Expand Down
2 changes: 2 additions & 0 deletions qacode/core/loggers/logger_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@
CDD_DESELECTALL_LOADED = "ctl_form | dropdown_select: deselected all" # noqa:E501
CDD_LOADED = "ctl_form | ctl.dropdown property for <select>" # noqa:E501
CDD_BADTAG = "Can't use this for not <select> tag element" # noqa:E501
# ControlTable
CT_BADTAG = "Can't use this for not <table> tag element" # noqa:E501
5 changes: 4 additions & 1 deletion qacode/core/webs/controls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@


from qacode.core.webs.controls import control_base
from qacode.core.webs.controls import control_dropdown
from qacode.core.webs.controls import control_form
from qacode.core.webs.controls import control_table


__all__ = ['control_base', 'control_form']
__all__ = [
'control_base', 'control_dropdown', 'control_form', 'control_table']
4 changes: 2 additions & 2 deletions qacode/core/webs/controls/control_dropdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def __check_reload__form__(self):
if it's neccessary reload element properties
"""
super(ControlDropdown, self).__check_reload__form__()
reload_dropdown_needed = not self.element or not self.dropdown
if reload_dropdown_needed:
reload_needed = not self.element or not self.dropdown
if reload_needed:
self.reload(**self.settings)

def reload(self, **kwargs):
Expand Down
7 changes: 6 additions & 1 deletion qacode/core/webs/controls/control_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ControlForm(ControlBase):
strict_tag = None
# tag=select
IS_DROPDOWN = None
# tag=select
IS_TABLE = None

def __init__(self, bot, **kwargs):
"""Instance of ControlForm. Load properties from settings dict.
Expand Down Expand Up @@ -97,14 +99,17 @@ def __load_strict_tag__(self, strict_tag):
instance ControlForm specific properties
"""
self.IS_DROPDOWN = False
self.IS_TABLE = False
self.strict_tag = strict_tag
valid_tags = ['select']
valid_tags = ['select', 'table']
self.bot.log.debug(MSG.CF_STRICTTAG_LOADING)
if self.strict_tag.value not in valid_tags:
raise ControlException(
msg="This tag can be loaded as strict_rule")
if self.tag == HtmlTag.TAG_SELECT.value:
self.IS_DROPDOWN = True
if self.tag == HtmlTag.TAG_TABLE.value:
self.IS_TABLE = True
self.bot.log.debug(MSG.CF_STRICTTAG_LOADED)
return True

Expand Down
77 changes: 77 additions & 0 deletions qacode/core/webs/controls/control_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
"""Package module qacode.core.webs.control_form"""


from qacode.core.exceptions.control_exception import ControlException
from qacode.core.loggers import logger_messages as MSG
from qacode.core.webs.controls.control_base import ControlBase
from qacode.core.webs.controls.control_form import ControlForm


class ControlTable(ControlForm):
"""TODO: doc class"""

_table = None

def __init__(self, bot, **kwargs):
"""Instance of ControlForm. Load properties from settings dict.
Some elements need to search False to be search at future
"""
kwargs.update({"instance": "ControlTable"})
strict_rules = kwargs.get("strict_rules")
if not bool(strict_rules):
strict_rules.append(
{"tag": "table", "type": "tag", "severity": "hight"})
super(ControlTable, self).__init__(bot, **kwargs)
if not self.IS_TABLE and self.tag is not None:
raise ControlException(msg=MSG.CT_BADTAG)
self.bot.log.debug(MSG.CDD_LOADED)

def __load_table__(self, element=None):
"""Allow to load all TR > TD items from a TABLE element
Examples:
Use case 1. TABLE > (TR > TH)+(TR > TD)
Use case 2. TABLE > (THEAD > (TR > TH))+(TBODY > (TR > TH))
"""
if element is None:
element = self.element
self._table = ControlBase(self.bot, **{
"selector": self.selector,
"element": element})
# Load rows
# thead = self._table.find_child("thead")
# tbody = self._table.find_child("tbody")
# Load columns
# Load cells
# raise NotImplementedError("TODO: WIP zone")

def __check_reload__form__(self):
"""Allow to check before methods calls to ensure
if it's neccessary reload element properties
"""
super(ControlTable, self).__check_reload__form__()
reload_needed = not self.element or not self.table
if reload_needed:
self.reload(**self.settings)
if not self.IS_TABLE and self.tag is not None:
raise ControlException(msg=MSG.CT_BADTAG)

def reload(self, **kwargs):
"""Reload 'self.settings' property:dict and call to instance
logic with new configuration
"""
super(ControlTable, self).reload(**kwargs)
self.__load_table__(element=self.element)

@property
def table(self):
"""GETTER for 'table' property"""
return self._table

@table.setter
def table(self, value):
"""SETTER for 'table' property"""
if value is None or not isinstance(value, ControlBase):
raise ControlException("Can't set not 'Control' instance")
self.__load_table__(element=value)
125 changes: 125 additions & 0 deletions tests/001_functionals/suite_008_controltable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
"""Testsuite for package qacode.core.webs.controls"""


import pytest
from qacode.core.exceptions.control_exception import ControlException
from qacode.core.testing.test_info import TestInfoBotUnique
from qacode.core.webs.controls.control_base import ControlBase
from qacode.core.webs.controls.control_table import ControlTable
from qautils.files import settings
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.ui import Select


SETTINGS = settings(file_path="qacode/configs/")
SKIP_CONTROLS = SETTINGS['tests']['skip']['web_controls']['control_table']
SKIP_CONTROLS_MSG = 'web_controls DISABLED by config file'


class TestControlDropdown(TestInfoBotUnique):
"""Test Suite for ControlBase class"""

# app from config
app = None
# page from config: app
page = None
url = None
# page from config: app
page_inputs = None
url_inputs = None
# elements from config: page
form_login = None
txt_username = None
txt_password = None
btn_submit = None
# elements from config: page_data
dd_base = None
dd_menu_data = None
dd_menu_data_lists = None
tbl_ok = None

@classmethod
def setup_class(cls, **kwargs):
"""TODO: doc method"""
super(TestControlDropdown, cls).setup_class(
config=settings(file_path="qacode/configs/"),
skip_force=SKIP_CONTROLS)
cls.add_property('app', cls.settings_app('qadmin'))
# page
cls.add_property('page', cls.settings_page('qacode_login'))
cls.add_property('url', cls.page.get('url'))
cls.add_property('form_login', cls.settings_control('form_login'))
cls.add_property('txt_username', cls.settings_control('txt_username'))
cls.add_property('txt_password', cls.settings_control('txt_password'))
cls.add_property('btn_submit', cls.settings_control('btn_submit'))
# page_inputs
cls.add_property('page_inputs', cls.settings_page('qacode_inputs'))
cls.add_property('url_inputs', cls.page_inputs.get('url'))
cls.add_property('dd_base', cls.settings_control('dd_base'))
cls.add_property('dd_menu_data', cls.settings_control('dd_menu_data'))
cls.add_property(
'dd_menu_data_lists', cls.settings_control('dd_menu_data_lists'))
cls.add_property('tbl_ok', cls.settings_control('tbl_ok'))

def setup_method(self, test_method):
"""Configure self.attribute"""
super(TestControlDropdown, self).setup_method(
test_method, config=settings(file_path="qacode/configs/"))

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_CONTROLS, SKIP_CONTROLS_MSG)
@pytest.mark.parametrize("on_instance_search", [True, False])
@pytest.mark.parametrize("auto_reload", [True, False])
@pytest.mark.parametrize("strict_rules", [
[{"tag": "table", "type": "tag", "severity": "hight"}]
])
def test_controltable_instance(self, on_instance_search,
strict_rules, auto_reload):
"""Testcase: test_controltable_instance"""
self.setup_login_to_data()
cfg = self.tbl_ok
cfg.update({
"instance": "ControlTable",
"on_instance_search": on_instance_search,
"auto_reload": auto_reload,
"strict_rules": strict_rules
})
# functional testcases
ctl = ControlTable(self.bot, **cfg)
self.assert_is_instance(ctl, ControlTable)
self.assert_equals(ctl.selector, cfg.get('selector'))
self.assert_equals(ctl.instance, cfg.get('instance'))
self.assert_equals(ctl.name, cfg.get('name'))
self.assert_equals(ctl.locator, 'css selector')
self.assert_equals(
ctl.on_instance_search, cfg.get('on_instance_search'))
self.assert_equals(ctl.auto_reload, cfg.get('auto_reload'))
self.assert_equals(
len(ctl.strict_rules), len(cfg.get('strict_rules')))
if on_instance_search:
self.assert_is_instance(ctl.element, WebElement)
if auto_reload is not None:
self.assert_none(ctl.table)
ctl.reload(**ctl.settings)
self.assert_is_instance(ctl.table, ControlBase)
File renamed without changes.

0 comments on commit bc2a2ea

Please sign in to comment.