diff --git a/qacode/core/loggers/logger_messages.py b/qacode/core/loggers/logger_messages.py index 8f086861..427d6a4f 100644 --- a/qacode/core/loggers/logger_messages.py +++ b/qacode/core/loggers/logger_messages.py @@ -63,6 +63,7 @@ CF_PARSERULES_LOADED = "ctl_form | parse_rules: parsed" # noqa:E501 CF_RELOAD_LOADED = "ctl_form | reload: reloaded ctl" # noqa:E501 CF_STRICT_ATTRS_RAISES = "Validation raises for strict_attrs for this element: control={}, strict_attrs=[{}]" # noqa:E501 +CF_BADTAG = "ctl_form | This tag can't be loaded as strict_rule" # noqa:E501 # ControlDropdown CDD_SELECT_LOADING = "ctl_dd | select: selecting..." # noqa:E501 CDD_SELECT_LOADED = "ctl_dd | select: selected" # noqa:E501 @@ -72,7 +73,10 @@ CDD_DESELECTALL_LOADED = "ctl_dd | dropdown_select: deselected all" # noqa:E501 CDD_LOADED = "ctl_dd | ctl.dropdown property for tag element" # noqa:E501 +CDD_BADPARAMS = "ctl_dd | Can't use this function with all flags with True values" # noqa:E501 +CDD_BADINDEXTYPE = "ctl_dd | index must be an int value" # noqa:E501 # ControlTable CT_BADTAG = "ctl_tb | Can't use this for not tag element" # noqa:E501 CT_LOADED = "ctl_tb | ctl.table property for
" # noqa:E501 CT_TBLNOTCHILD = "ctl_tb | this table haven't got '{}' selector" # noqa:E501 +CT_TBL2ORMORETBODIES = "2 or more tbodys not supported, Open an issue on Github" # noqa:E501 diff --git a/qacode/core/webs/controls/control_dropdown.py b/qacode/core/webs/controls/control_dropdown.py index 4f9f512b..b9178e90 100644 --- a/qacode/core/webs/controls/control_dropdown.py +++ b/qacode/core/webs/controls/control_dropdown.py @@ -18,10 +18,11 @@ def __init__(self, bot, **kwargs): Some elements need to search False to be search at future """ kwargs.update({"instance": "ControlDropdown"}) - strict_rules = kwargs.get("strict_rules") + strict_rules = kwargs.get("strict_rules") or [] if not bool(strict_rules): strict_rules.append( {"tag": "select", "type": "tag", "severity": "hight"}) + kwargs.update({"strict_rules": strict_rules}) super(ControlDropdown, self).__init__(bot, **kwargs) if not self.IS_DROPDOWN and self.tag is not None: raise ControlException(msg=MSG.CDD_BADTAG) @@ -43,6 +44,16 @@ def reload(self, **kwargs): super(ControlDropdown, self).reload(**kwargs) self.dropdown = Select(self.element) + def __check_dropdown__(self, text, by_value=False, by_index=False): + """Internal funcionality for select/deselect methods""" + self.__check_reload__form__() + if self.dropdown is None: + raise ControlException(msg=MSG.CDD_BADTAG) + if by_value and by_index: + raise ControlException(msg=MSG.CDD_BADPARAMS) + if by_index and not isinstance(text, int): + raise ControlException(msg=MSG.CDD_BADINDEXTYPE) + def select(self, text, by_value=False, by_index=False): """The Select class only works with tags which have select tags. Using the Index of Dropdown (int) @@ -63,19 +74,12 @@ def select(self, text, by_value=False, by_index=False): ControlException -- if tag is not 'select' ControlException -- if all flags are 'True' """ + self.__check_dropdown__( + text, by_value=by_value, by_index=by_index) self.bot.log.debug(MSG.CDD_SELECT_LOADING) - self.__check_reload__form__() - if self.dropdown is None: - raise ControlException( - msg="Element must be dropdown, tag={})".format(self.tag)) - if by_value and by_index: - raise ControlException( - msg="Can't use this function with all flags with True values") if by_value: self.dropdown.select_by_value(text) elif by_index: - if not isinstance(text, int): - raise ControlException(msg="index must be an int value") self.dropdown.select_by_index(int(text)) else: self.dropdown.select_by_visible_text(text) @@ -102,15 +106,11 @@ def deselect(self, text, by_value=False, by_index=False): ControlException -- if all flags are 'True' """ self.bot.log.debug(MSG.CDD_SELECT_LOADING) - self.__check_reload__form__() - if by_value and by_index: - raise ControlException( - msg="Can't use this function with all flags with True values") + self.__check_dropdown__( + text, by_value=by_value, by_index=by_index) if by_value: self.dropdown.deselect_by_value(text) elif by_index: - if not isinstance(text, int): - raise ControlException(msg="index must be an int value") self.dropdown.deselect_by_index(int(text)) else: self.dropdown.deselect_by_visible_text(text) @@ -124,6 +124,6 @@ def deselect_all(self): ControlException -- if tag is not 'select' """ self.bot.log.debug(MSG.CDD_DESELECTALL_LOADING) - self.__check_reload__form__() + self.__check_dropdown__('') self.dropdown.deselect_all() self.bot.log.debug(MSG.CDD_DESELECTALL_LOADED) diff --git a/qacode/core/webs/controls/control_form.py b/qacode/core/webs/controls/control_form.py index 7ae8b670..cef675a6 100644 --- a/qacode/core/webs/controls/control_form.py +++ b/qacode/core/webs/controls/control_form.py @@ -56,7 +56,7 @@ def __load__rules__(self, enabled=False): """Validate strict rules for each type of StricRule""" self.bot.log.debug(MSG.CF_PARSERULES_LOADING) if not enabled: - self.warning(MSG.CF_STRICT_DISABLED) + self.bot.log.warning(MSG.CF_STRICT_DISABLED) return False typed_rules = list() # parsing rules > to enums > to instance @@ -104,8 +104,7 @@ def __load_strict_tag__(self, strict_tag): 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") + raise ControlException(msg=MSG.CF_BADTAG) if self.tag == HtmlTag.TAG_SELECT.value: self.IS_DROPDOWN = True if self.tag == HtmlTag.TAG_TABLE.value: diff --git a/qacode/core/webs/controls/control_table.py b/qacode/core/webs/controls/control_table.py index 6ac0c592..d7dbcf1b 100644 --- a/qacode/core/webs/controls/control_table.py +++ b/qacode/core/webs/controls/control_table.py @@ -28,10 +28,11 @@ def __init__(self, bot, **kwargs): Some elements need to search False to be search at future """ kwargs.update({"instance": "ControlTable"}) - strict_rules = kwargs.get("strict_rules") + strict_rules = kwargs.get("strict_rules") or [] if not bool(strict_rules): strict_rules.append( {"tag": "table", "type": "tag", "severity": "hight"}) + kwargs.update({"strict_rules": strict_rules}) super(ControlTable, self).__init__(bot, **kwargs) if not self.IS_TABLE and self.tag is not None: raise ControlException(msg=MSG.CT_BADTAG) @@ -54,17 +55,20 @@ def __load_table__(self, element=None): "element": element}) # Preload self.tbodies = self.__try__("find_children", "tbodies") - is_html5 = False if bool(self.tbodies): - is_html5 = True + # table html5 structure self.caption = self.__try__("find_child", "caption") self.thead = self.__try__("find_child", "thead") self.tfoot = self.__try__("find_child", "tfoot") - # Load column headers - if not is_html5: - columns = self._table.find_children("tr :not(td)") # noqa - for column in columns: - column.name = column.text + if len(self.tbodies) > 1: + raise ControlException(MSG.CT_TBL2ORMORETBODIES) + rows = [] + rows.append(self.__get_row__(self.thead.find_child("tr"), "th")) + for ctl_row in self.tbodies[0].find_children("tr"): + rows.append(self.__get_row__(ctl_row, "td")) + self._rows = rows + else: + # table (TR > TH)+(TR > TD) + self.assert_lower(len(ctl.rows), 3) for row in ctl.rows: self.assert_is_instance(row, list) + self.assert_lower(len(row), 2) for cell in row: self.assert_is_instance(cell, ControlBase) # Use case 2. html5:: TABLE > (THEAD > (TR > TH))+(TBODY > (TR > TH)) - # raise NotImplementedError("TODO: WIP zone") + + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) + @pytest.mark.parametrize("strict_rules", [None]) + def test_controltable_instance_raises(self, strict_rules): + """Testcase: test_controltable_instance_raises""" + self.setup_login_to_data() + cfg = self.tbl_ok + cfg.update({ + "instance": "ControlTable", + "strict_rules": strict_rules, + "selector": "span" + }) + # 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') + + @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) + def test_controltable_loadtable_ok(self): + """Testcase: test_controltable_loadtable""" + self.setup_login_to_data() + ctl = ControlTable(self.bot, **self.tbl_ok) + ctl.__load_table__()