Skip to content

Commit

Permalink
[qacode] fix for issue #258 (#263)
Browse files Browse the repository at this point in the history
+ control base,form removed useless load methods
+ control base,form, updated some methods to internal
+ moved methods from control form to new control group class
+ tests moved to new class control group
+ update autodoc
  • Loading branch information
netzulo committed Apr 14, 2019
1 parent 06fd9c9 commit 500e9fe
Show file tree
Hide file tree
Showing 11 changed files with 473 additions and 306 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- New module at 'qacode.core.loggers' named 'logger_messages' #untracked
- New nav_base method named ele_wait_value #untracked
- Move dropdown methods to new control dropdown class #258

### Changed
- Separate benchmark test from all functional tests at tox -e coverage #251
- Moved log messages to new class to centralize them #untracked
- Refactor for control suites after changes from #247 , #untracked
- Updated USAGE.rst documentation #untracked
- Updated USAGE.rst documentation #258
- Now get_text check for input tag #untracked

### Fixed
Expand Down
22 changes: 14 additions & 8 deletions USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,8 @@ It's base control to load web element from ``WebDriver + browser session`` , *th
- Methods for **ControlBase**

+ method **load** : Load properties from settings dict. Some elements need to search False to be search at future
+ method **load_settings_keys** : Load default setting for ControlBase instance
+ method **_load_properties** : Load default properties for base element
+ method **_load_search** : Load element searching at selenium WebDriver
+ method **__load_settings_keys__** : Load default setting for ControlBase instance and default properties for base element
+ method **__load_search__** : Load element searching at selenium WebDriver
+ method **clear** : Clear input element text value
+ method **click** : Click on element
+ method **find_child** : Find child element using bot with default By.CSS_SELECTOR strategy for internal element trought selenium WebElement
Expand Down Expand Up @@ -135,20 +134,27 @@ Example of usage
ControlForm
~~~~~~~~~~~

+ Param **on_instance_strict** : by default it's disabled, at enable raises when strict_rules type warning logs message with 'hight severity' or when type error log messages with 'medium or more severity'
+ Param **strict_rules** : Allow to add strict_rules configuration to laod StrictRule class for each rule ( example: ``strict_rule = StrictRule('my_named_rule', StrictType.TAG, StrictSeverity.HIGHT)`` )

- Methods for **ControlForm**

+ method **__load__** : Load properties from settings dict. Some elements need to search False to be search at future
+ method **load_settings_keys** : Load default setting for ControlForm instance
+ method **__load_settings_keys__** : Load default setting for ControlForm instance
+ method **__load__rules__** : Parse array of configurations dicts of strict_rules to instances list of StrictRule
+ method **__load_strict_tag__** : alidate if element.tag is in list of strict_tags and instance ControlForm specific properties
+ method **__check_reload__form__** : Allow to check before methods calls to ensure if it's neccessary reload element properties
+ method **reload** : Reload 'self.settings' property:dict and call to instance logic with new configuration
+ method **dropdown_select** : The Select class only works with tags which have select tags
+ method **dropdown_deselect** : The Select class only works with tags which have select tags
+ method **dropdown_deselect_all** : The Select class only works with tags which have select tags with multiple="multiple" attribute.

ControlDropdown
~~~~~~~~~~~~~~~

- Methods for **ControlDropdown**

+ method **__check_reload__form__** : Allow to check before methods calls to ensure if it's neccessary reload element properties
+ method **reload** : Reload 'self.settings' property:dict and call to instance logic with new configuration
+ method **select** : The Select class only works with tags which have select tags
+ method **deselect** : The Select class only works with tags which have select tags
+ method **deselect_all** : The Select class only works with tags which have select tags with multiple="multiple" attribute.

Pages
-----
Expand Down
2 changes: 1 addition & 1 deletion qacode/configs/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"web_controls": {
"control_base": false,
"control_form": false,
"control_group": false
"control_dropdown": false
},
"web_pages": false,
"benchmarks": true
Expand Down
16 changes: 9 additions & 7 deletions qacode/core/loggers/logger_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@
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_DROPDOWNSELECT_LOADING = "ctl_form | dropdown_select: selecting..." # noqa:E501
CF_DROPDOWNSELECT_LOADED = "ctl_form | dropdown_select: selected" # noqa:E501
CF_DROPDOWNDESELECT_LOADING = "ctl_form | dropdown_select: deselecting..." # noqa:E501
CF_DROPDOWNDESELECT_LOADED = "ctl_form | dropdown_select: deselected" # noqa:E501
CF_DROPDOWNDESELECTALL_LOADING = "ctl_form | dropdown_select: deselecting all..." # noqa:E501
CF_DROPDOWNDESELECTALL_LOADED = "ctl_form | dropdown_select: deselected all" # noqa:E501
CF_DROPDOWN_LOADED = "ctl_form | ctl.dropdown property for <select>" # 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_form | dropdown_select: deselecting all..." # noqa:E501
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
24 changes: 8 additions & 16 deletions qacode/core/webs/controls/control_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
from qacode.core.bots.bot_base import BotBase
from qacode.core.exceptions.control_exception import ControlException
from qacode.core.exceptions.core_exception import CoreException
from qacode.core.loggers import logger_messages
from qacode.core.loggers import logger_messages as MSG
from selenium.common.exceptions import (
ElementNotVisibleException, NoSuchElementException
)
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement


MSG = logger_messages


class ControlBase(object):
"""Requirements: #35, #70"""

Expand Down Expand Up @@ -51,20 +48,15 @@ def __init__(self, bot, **kwargs):
raise ControlException(msg="Bad param 'bot'")
self.bot = bot
# load settings before try to instance
self.load(**kwargs)

def load(self, **kwargs):
"""Load properties from settings dict.
Some elements need to search False to be search at future
"""
# needed for self._load_* functions
self.load_settings_keys(kwargs.copy(), update=True)
self.__load_settings_keys__(kwargs.copy(), update=True)
# instance logic
self._load_search(
self.__load_search__(
enabled=self.on_instance_search,
element=self.settings.get("element"))

def load_settings_keys(self, settings, update=False, default_keys=None):
def __load_settings_keys__(self, settings,
update=False, default_keys=None):
"""Load default setting for ControlBase instance"""
self.bot.log.debug(MSG.CB_SETTINGS_LOADING)
# generate default dict
Expand Down Expand Up @@ -100,7 +92,7 @@ def load_settings_keys(self, settings, update=False, default_keys=None):
self.settings = updated_settings
self.bot.log.debug(MSG.CB_SETTINGS_LOADED)

def _load_search(self, enabled=False, element=None):
def __load_search__(self, enabled=False, element=None):
"""Load element searching at selenium WebDriver"""
if enabled is None or not enabled:
self.bot.log.debug(MSG.CB_SEARCH_DISABLED)
Expand Down Expand Up @@ -370,9 +362,9 @@ def reload(self, **kwargs):
config = self.settings.copy()
config.update({"on_instance_search": True})
# needed for self._load_* functions
self.load_settings_keys(config, update=True)
self.__load_settings_keys__(config, update=True)
# instance logic
self._load_search(
self.__load_search__(
enabled=self.on_instance_search,
element=self.element)
if class_name == 'ControlBase':
Expand Down
129 changes: 129 additions & 0 deletions qacode/core/webs/controls/control_dropdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# -*- 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_form import ControlForm
from selenium.webdriver.support.ui import Select


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

dropdown = 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": "ControlDropdown"})
strict_rules = kwargs.get("strict_rules")
if not bool(strict_rules):
strict_rules.append(
{"tag": "select", "type": "tag", "severity": "hight"})
super(ControlDropdown, self).__init__(bot, **kwargs)
if not self.IS_DROPDOWN and self.tag is not None:
raise ControlException(msg=MSG.CDD_BADTAG)
self.bot.log.debug(MSG.CDD_LOADED)

def __check_reload__form__(self):
"""Allow to check before methods calls to ensure
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:
self.reload(**self.settings)

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

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)
Using the Value of Dropdown (str)
Using the Text of Dropdown (str)
Arguments:
text {str|int} -- Probably the easiest way of doing it. You
have to match the text which is displayed in the drop down.
Keyword Arguments:
by_value {bool} -- We can use to select an option using the
value attribute. (default: {False})
by_index {bool} -- We can use to select an option using the
index attribute. (default: {False})
Raises:
ControlException -- if tag is not 'select'
ControlException -- if all flags are 'True'
"""
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)
self.bot.log.debug(MSG.CDD_SELECT_LOADED)

def deselect(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)
Using the Value of Dropdown (str)
Using the Text of Dropdown (str)
Arguments:
text {str|int} -- Probably the easiest way of doing it. You
have to match the text which is displayed in the drop down.
Keyword Arguments:
by_value {bool} -- We can use to select an option using the
value attribute. (default: {False})
by_index {bool} -- We can use to select an option using the
index attribute. (default: {False})
Raises:
ControlException -- if tag is not 'select'
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")
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)
self.bot.log.debug(MSG.CDD_DESELECTALL_LOADING)

def deselect_all(self):
"""The Select class only works with tags which have select
tags with multiple="multiple" attribute.
Raises:
ControlException -- if tag is not 'select'
"""
self.bot.log.debug(MSG.CDD_DESELECTALL_LOADING)
self.__check_reload__form__()
self.dropdown.deselect_all()
self.bot.log.debug(MSG.CDD_DESELECTALL_LOADED)

0 comments on commit 500e9fe

Please sign in to comment.