diff --git a/CHANGELOG.md b/CHANGELOG.md index fad6ddf4..55a8c00b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added +- Implemented pytests fixture: 1 browser by session #143 +- Check staled elements at control base, wip dev #143 + ### Changed - Moved asserts to own class + add greater/lower_or_equals #279 diff --git a/conftest.py b/conftest.py index e69de29b..35ed78b4 100644 --- a/conftest.py +++ b/conftest.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +"""Tests fixtures""" + +import pytest +import sys +from qacode.core.bots.bot_base import BotBase +from qacode.utils import settings + + +sys.dont_write_bytecode = True + + +@pytest.fixture(scope="session") +def browser(): + CFG = settings(file_path="qacode/configs/", file_name="settings.json") + bot = None + try: + bot = BotBase(**CFG) + yield bot + except Exception as err: + raise err + finally: + if bot: + bot.close() diff --git a/qacode/core/webs/controls/control_base.py b/qacode/core/webs/controls/control_base.py index 0eceec76..99a5a706 100644 --- a/qacode/core/webs/controls/control_base.py +++ b/qacode/core/webs/controls/control_base.py @@ -41,11 +41,7 @@ def __init__(self, bot, **kwargs): self._auto_reload = None # __search__, step 2 self._text = None - self._is_displayed = None - self._is_enabled = None - self._is_selected = None - self._attr_id = None - self._attr_class = None + self._id = None # Raises self._info_bot = {} self._bot.log.debug( @@ -127,11 +123,6 @@ def __search__(self): # Step 2 load minimal properties defined by qacode self.bot.log.debug(MSG.CB_PROP_LOADING) self._text = self.get_text() - self._is_displayed = nav.ele_is_displayed(self.element) - self._is_enabled = nav.ele_is_enabled(self.element) - self._is_selected = nav.ele_is_selected(self.element) - self._attr_id = self.get_attr_value('id') - self._attr_class = self.get_attr_value('class').split() self.bot.log.debug(MSG.CB_PROP_LOADED) def __check_reload__(self): @@ -143,6 +134,17 @@ def __check_reload__(self): return True return False + def __is_staled__(self): + """TODO: doc method""" + if not self._element: + raise Exception("Not web element, search it first") + return self._id != self._element._id + + def __check_element_ready__(self): + """TODO: doc method""" + if self.__is_staled__(): + raise Exception("Staled element, disappeared from the DOM") + def find_child(self, selector, locator=By.CSS_SELECTOR): """Find child element using bot with default By.CSS_SELECTOR strategy for internal element trought selenium WebElement @@ -406,17 +408,12 @@ def __repr__(self): """Show basic properties for this object""" return ("{}: name={}, " "bot.browser={}, bot.mode={} \n" - "settings={} \n" - "is_displayed={}, " - "is_enabled={}, is_selected={}").format( + "settings={}").format( self.__class__.__name__, self.name, self.bot.settings.get('browser'), self.bot.settings.get('mode'), - self.settings, - self.is_displayed, - self.is_enabled, - self.is_selected) + self.settings) @property def bot(self): @@ -491,6 +488,12 @@ def auto_reload(self): """GET for _auto_reload attribute""" return self._auto_reload + @property + def id(self): + """TODO: doc method""" + self.__check_element_ready__() + return self._element._id + @property def tag(self): """GET for _tag attribute. Returns from Webelement directly""" @@ -502,30 +505,20 @@ def tag(self): @property def text(self): - """GET for _text attribute""" + """GET for element text attribute""" return self._text @property def is_displayed(self): - """GET for _is_displayed attribute""" - return self._is_displayed + """TODO: doc method""" + return self.bot.navigation.ele_is_displayed(self.element) or None @property def is_enabled(self): - """GET for _is_enabled attribute""" - return self._is_enabled + """TODO: doc method""" + return self.bot.navigation.ele_is_enabled(self.element) or None @property def is_selected(self): - """GET for _is_selected attribute""" - return self._is_selected - - @property - def attr_id(self): - """GET for _attr_id attribute""" - return self._attr_id - - @property - def attr_class(self): - """GET for _attr_class attribute""" - return self._attr_class + """TODO: doc method""" + return self.bot.navigation.ele_is_selected(self.element) or None diff --git a/tests/001_functionals/suite_005_controlbase.py b/tests/001_functionals/suite_005_controlbase.py index ab9ef1fa..50664b4f 100644 --- a/tests/001_functionals/suite_005_controlbase.py +++ b/tests/001_functionals/suite_005_controlbase.py @@ -157,22 +157,6 @@ def test_method_gettext(self): control = ControlBase(self.bot, **cfg_btn) ASSERT.equals(control.get_text(), 'Login') - @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - def test_property_attr_id(self): - """Testcase: test_property_attr_id""" - cfg_input = self.txt_username.copy() - cfg_input.update({"on_instance_search": True}) - control = ControlBase(self.bot, **cfg_input) - ASSERT.not_none(control.attr_id) - - @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) - def test_property_attr_class(self): - """Testcase: test_property_attr_class""" - cfg_form = self.form_login.copy() - cfg_form.update({"on_instance_search": True}) - control = ControlBase(self.bot, **cfg_form) - ASSERT.in_list('ember-view', control.attr_class) - @pytest.mark.skipIf(SKIP_CONTROLS, SKIP_CONTROLS_MSG) def test_method_getattrvalue(self): """Testcase: test_method_getattrvalue"""