From 1b9a246d9a97af7973cdab2c62aec3bca98384ab Mon Sep 17 00:00:00 2001 From: Vladimir Druzhinin <128374224+StateOf-Vlado@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:53:49 +0100 Subject: [PATCH] chore: Extra logs added for UI Elements (#235) #232 --- test/e2e/gui/elements/base_object.py | 46 ------------------------- test/e2e/gui/elements/button.py | 4 +++ test/e2e/gui/elements/check_box.py | 5 +++ test/e2e/gui/elements/list.py | 5 +++ test/e2e/gui/elements/object.py | 45 ++++++++++++++++++------ test/e2e/gui/elements/scroll.py | 4 ++- test/e2e/gui/elements/slider.py | 6 +++- test/e2e/gui/elements/text_edit.py | 6 ++++ test/e2e/gui/elements/text_label.py | 4 +++ test/e2e/gui/elements/window.py | 13 ++++--- test/e2e/gui/screens/settings_wallet.py | 16 ++++----- 11 files changed, 83 insertions(+), 71 deletions(-) delete mode 100644 test/e2e/gui/elements/base_object.py diff --git a/test/e2e/gui/elements/base_object.py b/test/e2e/gui/elements/base_object.py deleted file mode 100644 index c7f9330662..0000000000 --- a/test/e2e/gui/elements/base_object.py +++ /dev/null @@ -1,46 +0,0 @@ -import logging - -import allure - -import configs -import driver -from gui import objects_map - -_logger = logging.getLogger(__name__) - - -class BaseObject: - - def __init__(self, name: str, real_name: [str, dict] = None): - self.symbolic_name = name - if real_name: - self.real_name = real_name - else: - self.real_name = getattr(objects_map, name) - - def __str__(self): - return f'{type(self).__qualname__}({self.symbolic_name})' - - def __repr__(self): - return f'{type(self).__qualname__}({self.symbolic_name})' - - @property - def object(self): - raise NotImplementedError - - @property - def is_visible(self) -> bool: - raise NotImplementedError - - @allure.step('Wait until appears {0}') - def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): - assert driver.waitFor(lambda: self.is_visible, timeout_msec), f'Object {self} is not visible' - return self - - @allure.step('Wait until hidden {0}') - def wait_until_hidden(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): - assert driver.waitFor(lambda: not self.is_visible, timeout_msec), f'Object {self} is not hidden' - - @classmethod - def wait_for(cls, condition, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC) -> bool: - return driver.waitFor(lambda: condition, timeout_msec) diff --git a/test/e2e/gui/elements/button.py b/test/e2e/gui/elements/button.py index d838ee9b8c..56d81957fe 100644 --- a/test/e2e/gui/elements/button.py +++ b/test/e2e/gui/elements/button.py @@ -1,3 +1,4 @@ +import logging import typing import allure @@ -5,6 +6,8 @@ import allure import driver from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class Button(QObject): @@ -19,3 +22,4 @@ class Button(QObject): getattr(self.object, 'clicked')() else: super(Button, self).click(x, y, button) + _logger.info(f'{self}: clicked') diff --git a/test/e2e/gui/elements/check_box.py b/test/e2e/gui/elements/check_box.py index 49a21e5eaf..fcaf53d35c 100644 --- a/test/e2e/gui/elements/check_box.py +++ b/test/e2e/gui/elements/check_box.py @@ -1,9 +1,13 @@ +import logging + import allure import configs import driver from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class CheckBox(QObject): @@ -13,3 +17,4 @@ class CheckBox(QObject): self.click(x, y) assert driver.waitFor( lambda: self.is_checked is value, configs.timeouts.UI_LOAD_TIMEOUT_MSEC), 'Value not changed' + _logger.info(f'{self}: value changed to "{value}"') diff --git a/test/e2e/gui/elements/list.py b/test/e2e/gui/elements/list.py index 248f8ee4a3..419366487c 100644 --- a/test/e2e/gui/elements/list.py +++ b/test/e2e/gui/elements/list.py @@ -1,3 +1,4 @@ +import logging import time import typing @@ -7,6 +8,8 @@ import configs import driver from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class List(QObject): @@ -27,6 +30,7 @@ class List(QObject): @allure.step('Select item {1} in {0}') def select(self, value: str, attr_name: str): driver.mouseClick(self.wait_for_item(value, attr_name)) + _logger.info(f'{self}: {value} selected') @allure.step('Wait for item {1} in {0} with attribute {2}') def wait_for_item(self, value: str, attr_name: str, timeout_sec: int = configs.timeouts.UI_LOAD_TIMEOUT_SEC): @@ -36,6 +40,7 @@ class List(QObject): for index in range(self.object.count): cur_value = str(getattr(self.object.itemAtIndex(index), attr_name, '')) if cur_value == value: + _logger.info(f'{self}: "{value}" for attribute "{attr_name}" appeared') return self.object.itemAtIndex(index) values.append(cur_value) time.sleep(1) diff --git a/test/e2e/gui/elements/object.py b/test/e2e/gui/elements/object.py index 2fbbc39013..039f07f55f 100644 --- a/test/e2e/gui/elements/object.py +++ b/test/e2e/gui/elements/object.py @@ -6,21 +6,32 @@ import allure import configs import driver -from gui.elements.base_object import BaseObject +from gui import objects_map from scripts.tools.image import Image _logger = logging.getLogger(__name__) -class QObject(BaseObject): +class QObject: def __init__(self, name, real_name: [str, dict] = None): - super().__init__(name, real_name) + self.symbolic_name = name + if real_name: + self.real_name = real_name + else: + self.real_name = getattr(objects_map, name) self._image = Image(self.real_name) + def __getattr__(self, attr: str): + value = getattr(self.object, attr) + return value + def __str__(self): return f'{type(self).__qualname__}({self.symbolic_name})' + def __repr__(self): + return f'{type(self).__qualname__}({self.symbolic_name})' + @property @allure.step('Get object {0}') def object(self): @@ -51,10 +62,6 @@ class QObject(BaseObject): def width(self) -> int: return int(self.bounds.width) - @allure.step('Get attribute {0}') - def get_object_attribute(self, attr: str): - return getattr(self.object, attr) - @property @allure.step('Get height {0}') def height(self) -> int: @@ -68,17 +75,17 @@ class QObject(BaseObject): @property @allure.step('Get enabled {0}') def is_enabled(self) -> bool: - return self.object.enabled + return getattr(self, 'enabled') @property @allure.step('Get selected {0}') def is_selected(self) -> bool: - return self.object.selected + return getattr(self, 'selected') @property @allure.step('Get checked {0}') def is_checked(self) -> bool: - return self.object.checked + return getattr(self, 'checked') @property @allure.step('Get visible {0}') @@ -107,12 +114,14 @@ class QObject(BaseObject): y or self.height // 2, button or driver.Qt.LeftButton ) + _logger.info(f'{self}: clicked') @allure.step('Hover {0}') def hover(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): def _hover(): try: driver.mouseMove(self.object) + _logger.info(f'{self}: mouse hovered') return getattr(self.object, 'hovered', True) except RuntimeError as err: _logger.debug(err) @@ -133,3 +142,19 @@ class QObject(BaseObject): y or self.height // 2, driver.Qt.RightButton ) + _logger.info(f'{self}: clicked via Right Mouse Button') + + @allure.step('Wait until appears {0}') + def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): + assert driver.waitFor(lambda: self.is_visible, timeout_msec), f'Object {self} is not visible' + _logger.info(f'{self}: is visible') + return self + + @allure.step('Wait until hidden {0}') + def wait_until_hidden(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): + assert driver.waitFor(lambda: not self.is_visible, timeout_msec), f'Object {self} is not hidden' + _logger.info(f'{self}: is hidden') + + @classmethod + def wait_for(cls, condition, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC) -> bool: + return driver.waitFor(lambda: condition, timeout_msec) diff --git a/test/e2e/gui/elements/scroll.py b/test/e2e/gui/elements/scroll.py index 9f7d30ad0d..db817fb201 100644 --- a/test/e2e/gui/elements/scroll.py +++ b/test/e2e/gui/elements/scroll.py @@ -11,7 +11,7 @@ _logger = logging.getLogger(__name__) class Scroll(QObject): - @allure.step('Scroll vertical to object') + @allure.step('Scroll vertical to object {1}') def vertical_scroll_to(self, element: QObject, timeout_sec: int = 5): started_at = time.monotonic() step = 10 @@ -29,6 +29,7 @@ class Scroll(QObject): if hasattr(element.object, 'height'): y += int(element.object.height) driver.flick(self.object, 0, y) + _logger.info(f'{self}: scrolled to {element}') except LookupError as err: _logger.debug(err) @@ -40,3 +41,4 @@ class Scroll(QObject): driver.flick(self.object, 0, step) if time.monotonic() - started_at > timeout_sec: raise LookupError(f'Object not found: {element}') + _logger.info(f'{self}: scrolled down to {element}') diff --git a/test/e2e/gui/elements/slider.py b/test/e2e/gui/elements/slider.py index 613697bc27..9b60c5c1bb 100644 --- a/test/e2e/gui/elements/slider.py +++ b/test/e2e/gui/elements/slider.py @@ -1,7 +1,10 @@ +import logging import allure from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class Slider(QObject): @@ -21,7 +24,7 @@ class Slider(QObject): return int(self.object.value) @value.setter - @allure.step('Set value {1} {0}') + @allure.step('Set value {1} in {0}') def value(self, value: int): if value != self.value: if self.min <= value <= self.max: @@ -31,3 +34,4 @@ class Slider(QObject): if self.value > value: while self.value > value: self.object.decrease() + _logger.info(f'{self}: value changed to "{value}"') diff --git a/test/e2e/gui/elements/text_edit.py b/test/e2e/gui/elements/text_edit.py index ddd5151dae..af9c3b4b2f 100644 --- a/test/e2e/gui/elements/text_edit.py +++ b/test/e2e/gui/elements/text_edit.py @@ -1,9 +1,13 @@ +import logging + import allure import configs import driver from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class TextEdit(QObject): @@ -23,6 +27,7 @@ class TextEdit(QObject): @allure.step('Type: {1} in {0}') def type_text(self, value: str): driver.type(self.object, value) + _logger.info(f'{self}: value changed to "{value}"') return self @allure.step('Clear {0}') @@ -31,4 +36,5 @@ class TextEdit(QObject): if verify: assert driver.waitFor(lambda: not self.text), \ f'Clear text field failed, value in field: "{self.text}"' + _logger.info(f'{self}: cleared') return self diff --git a/test/e2e/gui/elements/text_label.py b/test/e2e/gui/elements/text_label.py index e8b605298f..59eac9f919 100644 --- a/test/e2e/gui/elements/text_label.py +++ b/test/e2e/gui/elements/text_label.py @@ -1,7 +1,11 @@ +import logging + import allure from gui.elements.object import QObject +_logger = logging.getLogger(__name__) + class TextLabel(QObject): diff --git a/test/e2e/gui/elements/window.py b/test/e2e/gui/elements/window.py index 32071e6ef9..021ee1576e 100644 --- a/test/e2e/gui/elements/window.py +++ b/test/e2e/gui/elements/window.py @@ -20,36 +20,39 @@ class Window(QObject): @allure.step("Maximize {0}") def maximize(self): assert driver.toplevel_window.maximize(self.real_name), 'Maximize failed' - _logger.info(f'Window {getattr(self.object, "title", "")} is maximized') + _logger.info(f'Window {getattr(self, "title", "")} is maximized') @allure.step("Minimize {0}") def minimize(self): assert driver.toplevel_window.minimize(self.real_name), 'Minimize failed' - _logger.info(f'Window {getattr(self.object, "title", "")} is minimized') + _logger.info(f'Window {getattr(self, "title", "")} is minimized') @allure.step("Set focus on {0}") def set_focus(self): assert driver.toplevel_window.set_focus(self.real_name), 'Set focus failed' - _logger.info(f'Window {getattr(self.object, "title", "")} in focus') + _logger.info(f'Window {getattr(self, "title", "")} in focus') @allure.step("Move {0} on top") def on_top_level(self): assert driver.toplevel_window.on_top_level(self.real_name), 'Set on top failed' - _logger.info(f'Window {getattr(self.object, "title", "")} moved on top') + _logger.info(f'Window {getattr(self, "title", "")} moved on top') @allure.step("Close {0}") def close(self): driver.toplevel_window.close(self.real_name) + _logger.info(f'Window {getattr(self, "title", "")} closed') @allure.step("Show {0}") def show(self): driver.waitForObjectExists(self.real_name).setVisible(True) + _logger.info(f'Window {getattr(self, "title", "")} is visible') @allure.step("Hide {0}") def hide(self): driver.waitForObjectExists(self.real_name).setVisible(False) + _logger.info(f'Window {getattr(self, "title", "")} hidden') def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): super().wait_until_appears(timeout_msec) - _logger.info(f'Window {getattr(self.object, "title", "")} appears') + _logger.info(f'Window {getattr(self, "title", "")} appears') return self diff --git a/test/e2e/gui/screens/settings_wallet.py b/test/e2e/gui/screens/settings_wallet.py index 4d99aa3efd..a6c7e439d8 100644 --- a/test/e2e/gui/screens/settings_wallet.py +++ b/test/e2e/gui/screens/settings_wallet.py @@ -103,31 +103,31 @@ class AccountDetailsView(WalletSettingsView): @allure.step("Get account address value") def get_account_address_value(self): - raw_value = str(self._wallet_account_address.get_object_attribute('subTitle')) + raw_value = str(getattr(self._wallet_account_address, 'subTitle')) address = raw_value.split(">")[-1] return address @allure.step('Get account color value') def get_account_color_value(self): - color_name = str(self._wallet_account_title.get_object_attribute('color')['name']) + color_name = str(getattr(self._wallet_account_title, 'color')['name']) return color_name @allure.step('Get account emoji id') def get_account_emoji_id(self): - emoji_id = str(self._wallet_account_emoji.get_object_attribute('emojiId')) + emoji_id = str(getattr(self._wallet_account_emoji, 'emojiId')) return emoji_id @allure.step('Get account origin value') def get_account_origin_value(self): - return str(self._wallet_account_origin.get_object_attribute('subTitle')) + return str(getattr(self._wallet_account_origin, 'subTitle')) @allure.step('Get account derivation path value') def get_account_derivation_path_value(self): - return str(self._wallet_account_derivation_path.get_object_attribute('subTitle')) + return str(getattr(self._wallet_account_derivation_path, 'subTitle')) @allure.step('Get account storage value') def get_account_storage_value(self): - raw_value = str(self._wallet_account_stored.get_object_attribute('subTitle')) + raw_value = str(getattr(self._wallet_account_stored, 'subTitle')) storage = raw_value.split(">")[-1] return storage @@ -155,7 +155,7 @@ class NetworkWalletSettings(WalletSettingsView): def get_network_item_attribute_by_id_and_attr_name(self, attribute_name, network_id): self._wallet_network_item_template.real_name['objectName'] = RegularExpression( f'walletNetworkDelegate_.*_{network_id}') - return self._wallet_network_item_template.get_object_attribute(attribute_name) + return getattr(self._wallet_network_item_template, attribute_name) @allure.step('Open network to check the details') def click_network_item_to_open_edit_view(self, network_id): @@ -329,7 +329,7 @@ class EditNetworkSettings(WalletSettingsView): @allure.step('Get the text for consent when changing RPC urls') def get_acknowledgement_checkbox_text(self, attr): - text = str(self._network_acknowledgment_checkbox.get_object_attribute(attr)) + text = str(getattr(self._network_acknowledgment_checkbox, attr)) return text @allure.step('Get error message for Main RPC URL input')