diff --git a/test/e2e/constants/user.py b/test/e2e/constants/user.py index c2e0452291..6a59a0119d 100644 --- a/test/e2e/constants/user.py +++ b/test/e2e/constants/user.py @@ -21,3 +21,5 @@ default_community_params = { UserCommunityInfo = namedtuple('CommunityInfo', ['name', 'description', 'members', 'image']) UserChannel = namedtuple('Channel', ['name', 'image', 'selected']) + +account_list_item = namedtuple('AccountListItem', ['name', 'color', 'emoji']) \ No newline at end of file diff --git a/test/e2e/gui/components/wallet/remove_wallet_account_popup.py b/test/e2e/gui/components/wallet/remove_wallet_account_popup.py new file mode 100644 index 0000000000..a28a061777 --- /dev/null +++ b/test/e2e/gui/components/wallet/remove_wallet_account_popup.py @@ -0,0 +1,25 @@ +import allure + +import configs +from gui.components.base_popup import BasePopup +from gui.elements.qt.button import Button +from gui.elements.qt.check_box import CheckBox + + +class RemoveWalletAccountPopup(BasePopup): + + def __init__(self): + super(RemoveWalletAccountPopup, self).__init__() + self._confirm_button = Button('mainWallet_Remove_Account_Popup_ConfirmButton') + self._cancel_button = Button('mainWallet_Remove_Account_Popup_CancelButton') + self._have_pen_paper_checkbox = CheckBox('mainWallet_Remove_Account_Popup_HavePenPaperCheckBox') + + @allure.step('Wait until appears {0}') + def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): + self._cancel_button.wait_until_appears(timeout_msec) + return self + + @allure.step('Confirm removing account') + def confirm(self): + self._confirm_button.click() + self._confirm_button.wait_until_hidden() \ No newline at end of file diff --git a/test/e2e/gui/components/wallet/wallet_account_popups.py b/test/e2e/gui/components/wallet/wallet_account_popups.py new file mode 100644 index 0000000000..06a0cc9ea6 --- /dev/null +++ b/test/e2e/gui/components/wallet/wallet_account_popups.py @@ -0,0 +1,72 @@ +import allure + +import driver +from gui.components.base_popup import BasePopup +from gui.components.emoji_popup import EmojiPopup +from gui.elements.qt.button import Button +from gui.elements.qt.check_box import CheckBox +from gui.elements.qt.text_edit import TextEdit +from gui.elements.qt.scroll import Scroll +from gui.elements.qt.object import QObject + + +class AccountPopup(BasePopup): + def __init__(self): + super(AccountPopup, self).__init__() + self._scroll = Scroll('scrollView_StatusScrollView') + self._name_text_edit = TextEdit('mainWallet_AddEditAccountPopup_AccountName') + self._emoji_button = Button('mainWallet_AddEditAccountPopup_AccountEmojiPopupButton') + self._color_radiobutton = QObject('color_StatusColorRadioButton') + # origin + self._origin_combobox = QObject('mainWallet_AddEditAccountPopup_SelectedOrigin') + self._watch_only_account_origin_item = QObject("mainWallet_AddEditAccountPopup_OriginOptionWatchOnlyAcc") + self._new_master_key_origin_item = QObject('mainWallet_AddEditAccountPopup_OriginOptionNewMasterKey') + self._existing_origin_item = QObject('addAccountPopup_OriginOption_StatusListItem') + # derivation + self._address_text_edit = TextEdit('mainWallet_AddEditAccountPopup_AccountWatchOnlyAddress') + self._add_account_button = Button('mainWallet_AddEditAccountPopup_PrimaryButton') + self._edit_derivation_path_button = Button('mainWallet_AddEditAccountPopup_EditDerivationPathButton') + self._derivation_path_combobox_button = Button('mainWallet_AddEditAccountPopup_PreDefinedDerivationPathsButton') + self._derivation_path_list_item = QObject('mainWallet_AddEditAccountPopup_derivationPath') + self._reset_derivation_path_button = Button('mainWallet_AddEditAccountPopup_ResetDerivationPathButton') + self._derivation_path_text_edit = TextEdit('mainWallet_AddEditAccountPopup_DerivationPathInput') + self._address_combobox_button = Button('mainWallet_AddEditAccountPopup_GeneratedAddressComponent') + self._non_eth_checkbox = CheckBox('mainWallet_AddEditAccountPopup_NonEthDerivationPathCheckBox') + + @allure.step('Set name for account') + def set_name(self, value: str): + self._name_text_edit.text = value + return self + + @allure.step('Set color for account') + def set_color(self, value: str): + if 'radioButtonColor' in self._color_radiobutton.real_name.keys(): + del self._color_radiobutton.real_name['radioButtonColor'] + colors = [str(item.radioButtonColor) for item in driver.findAllObjects(self._color_radiobutton.real_name)] + assert value in colors, f'Color {value} not found in {colors}' + self._color_radiobutton.real_name['radioButtonColor'] = value + self._color_radiobutton.click() + return self + + @allure.step('Set emoji for account') + def set_emoji(self, value: str): + self._emoji_button.click() + EmojiPopup().wait_until_appears().select(value) + return self + + @allure.step('Set eth address for account added from context menu') + def set_eth_address(self, value: str): + self._address_text_edit.text = value + return self + + @allure.step('Set eth address for account added from plus button') + def set_origin_eth_address(self, value: str): + self._origin_combobox.click() + self._watch_only_account_origin_item.click() + self._address_text_edit.text = value + return self + + @allure.step('Save added account') + def save(self): + self._add_account_button.wait_until_appears().click() + return self \ No newline at end of file diff --git a/test/e2e/gui/elements/qt/object.py b/test/e2e/gui/elements/qt/object.py index 88044240e8..9337a7f1b2 100644 --- a/test/e2e/gui/elements/qt/object.py +++ b/test/e2e/gui/elements/qt/object.py @@ -1,5 +1,6 @@ import logging import time +import typing import allure @@ -115,3 +116,15 @@ class QObject(BaseObject): return False assert driver.waitFor(lambda: _hover(), timeout_msec) + + @allure.step('Open context menu') + def open_context_menu( + self, + x: typing.Union[int, driver.UiTypes.ScreenPoint] = None, + y: typing.Union[int, driver.UiTypes.ScreenPoint] = None, + ): + self.click( + x or self.width // 2, + y or self.height // 2, + driver.Qt.RightButton + ) diff --git a/test/e2e/gui/objects_map/component_names.py b/test/e2e/gui/objects_map/component_names.py index 8684ab413e..5fb100199c 100644 --- a/test/e2e/gui/objects_map/component_names.py +++ b/test/e2e/gui/objects_map/component_names.py @@ -1,5 +1,6 @@ from objectmaphelper import * +from .main_names import statusDesktop_mainWindow from .main_names import statusDesktop_mainWindow_overlay # Scroll @@ -109,6 +110,14 @@ confirm_Community_Tags_StatusButton = {"checkable": False, "container": statusDe # Signing phrase popup signPhrase_Ok_Button = {"container": statusDesktop_mainWindow, "type": "StatusFlatButton", "objectName": "signPhraseModalOkButton", "visible": True} +# Remove account popup: +mainWallet_Remove_Account_Popup_Account_Notification = {"container": statusDesktop_mainWindow, "objectName": "RemoveAccountPopup-Notification", "type": "StatusBaseText", "visible": True} +mainWallet_Remove_Account_Popup_Account_Path_Component = {"container": statusDesktop_mainWindow, "objectName": "RemoveAccountPopup-DerivationPath", "type": "StatusInput", "visible": True} +mainWallet_Remove_Account_Popup_Account_Path = {"container": mainWallet_Remove_Account_Popup_Account_Path_Component, "type": "TextEdit", "unnamed": 1, "visible": True} +mainWallet_Remove_Account_Popup_HavePenPaperCheckBox = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "RemoveAccountPopup-HavePenPaper", "type": "StatusCheckBox", "visible": True} +mainWallet_Remove_Account_Popup_ConfirmButton = {"container": statusDesktop_mainWindow, "objectName": "RemoveAccountPopup-ConfirmButton", "type": "StatusButton", "visible": True} +mainWallet_Remove_Account_Popup_CancelButton = {"container": statusDesktop_mainWindow, "objectName": "RemoveAccountPopup-CancelButton", "type": "StatusFlatButton", "visible": True} + # Add saved address popup mainWallet_Saved_Addreses_Popup_Name_Input = {"container": statusDesktop_mainWindow, "objectName": "savedAddressNameInput", "type": "TextEdit"} mainWallet_Saved_Addreses_Popup_Address_Input = {"container": statusDesktop_mainWindow, "objectName": "savedAddressAddressInput", "type": "StatusInput"} @@ -143,4 +152,36 @@ mainWallet_AddEditAccountPopup_AccountEmoji = {"container": statusDesktop_mainWi # Delete Popup o_StatusDialogBackground = {"container": statusDesktop_mainWindow_overlay, "type": "StatusDialogBackground", "unnamed": 1, "visible": True} -delete_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "deleteChatConfirmationDialogDeleteButton", "type": "StatusButton", "visible": True} \ No newline at end of file +delete_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "deleteChatConfirmationDialogDeleteButton", "type": "StatusButton", "visible": True} + +# Wallet Account Popup +mainWallet_AddEditAccountPopup_derivationPath = {"container": statusDesktop_mainWindow, "objectName": RegularExpression("AddAccountPopup-PreDefinedDerivationPath*"), "type": "StatusListItem", "visible": True} +mainWallet_Address_Panel = {"container": statusDesktop_mainWindow, "objectName": "addressPanel", "type": "StatusAddressPanel", "visible": True} + +# Add/Edit account popup: +grid_Grid = {"container": statusDesktop_mainWindow_overlay, "id": "grid", "type": "Grid", "unnamed": 1, "visible": True} +color_StatusColorRadioButton = {"checkable": True, "container": statusDesktop_mainWindow_overlay, "type": "StatusColorRadioButton", "unnamed": 1, "visible": True} + +mainWallet_AddEditAccountPopup_Content = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-Content", "type": "Item", "visible": True} +mainWallet_AddEditAccountPopup_PrimaryButton = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-PrimaryButton", "type": "StatusButton", "visible": True} +mainWallet_AddEditAccountPopup_BackButton = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-BackButton", "type": "StatusBackButton", "visible": True} +mainWallet_AddEditAccountPopup_AccountNameComponent = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-AccountName", "type": "StatusInput", "visible": True} +mainWallet_AddEditAccountPopup_AccountName = {"container": mainWallet_AddEditAccountPopup_AccountNameComponent, "type": "TextEdit", "unnamed": 1, "visible": True} +mainWallet_AddEditAccountPopup_AccountColorComponent = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-AccountColor", "type": "StatusColorSelectorGrid", "visible": True} +mainWallet_AddEditAccountPopup_AccountColorSelector = {"container": mainWallet_AddEditAccountPopup_AccountColorComponent, "type": "Repeater", "objectName": "statusColorRepeater", "visible": True, "enabled": True} +mainWallet_AddEditAccountPopup_AccountEmojiPopupButton = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-AccountEmoji", "type": "StatusFlatRoundButton", "visible": True} +mainWallet_AddEditAccountPopup_SelectedOrigin = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-SelectedOrigin", "type": "StatusListItem", "visible": True} +mainWallet_AddEditAccountPopup_OriginOption_Placeholder = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-OriginOption-%NAME%", "type": "StatusListItem", "visible": True} +mainWallet_AddEditAccountPopup_OriginOptionNewMasterKey = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-OriginOption-LABEL-OPTION-ADD-NEW-MASTER-KEY", "type": "StatusListItem", "visible": True} +addAccountPopup_OriginOption_StatusListItem = {"container": statusDesktop_mainWindow_overlay, "type": "StatusListItem", "visible": True} + +mainWallet_AddEditAccountPopup_OriginOptionWatchOnlyAcc = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-OriginOption-LABEL-OPTION-ADD-WATCH-ONLY-ACC", "type": "StatusListItem", "visible": True} +mainWallet_AddEditAccountPopup_AccountWatchOnlyAddressComponent = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-WatchOnlyAddress", "type": "StatusInput", "visible": True} +mainWallet_AddEditAccountPopup_AccountWatchOnlyAddress = {"container": mainWallet_AddEditAccountPopup_AccountWatchOnlyAddressComponent, "type": "TextEdit", "unnamed": 1, "visible": True} +mainWallet_AddEditAccountPopup_EditDerivationPathButton = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-EditDerivationPath", "type": "StatusButton", "visible": True} +mainWallet_AddEditAccountPopup_ResetDerivationPathButton = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-ResetDerivationPath", "type": "StatusLinkText", "enabled": True, "visible": True} +mainWallet_AddEditAccountPopup_DerivationPathInputComponent = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-DerivationPathInput", "type": "DerivationPathInput", "visible": True} +mainWallet_AddEditAccountPopup_DerivationPathInput = {"container": mainWallet_AddEditAccountPopup_DerivationPathInputComponent, "type": "TextEdit", "unnamed": 1, "visible": True} +mainWallet_AddEditAccountPopup_PreDefinedDerivationPathsButton = {"container": mainWallet_AddEditAccountPopup_DerivationPathInputComponent, "objectName": "chevron-down-icon", "type": "StatusIcon", "visible": True} +mainWallet_AddEditAccountPopup_GeneratedAddressComponent = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-GeneratedAddress", "type": "StatusListItem", "visible": True} +mainWallet_AddEditAccountPopup_NonEthDerivationPathCheckBox = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-ConfirmAddingNonEthDerivationPath", "type": "StatusCheckBox", "visible": True} \ No newline at end of file diff --git a/test/e2e/gui/objects_map/main_names.py b/test/e2e/gui/objects_map/main_names.py index 3ccda13a72..3fcb63e51d 100644 --- a/test/e2e/gui/objects_map/main_names.py +++ b/test/e2e/gui/objects_map/main_names.py @@ -1,5 +1,6 @@ statusDesktop_mainWindow = {"name": "mainWindow", "type": "StatusWindow", "visible": True} statusDesktop_mainWindow_overlay = {"container": statusDesktop_mainWindow, "type": "Overlay", "unnamed": 1, "visible": True} +scrollView_StatusScrollView = {"container": statusDesktop_mainWindow_overlay, "id": "scrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True} splashScreen = {"container": statusDesktop_mainWindow, "objectName": "splashScreen", "type": "DidYouKnowSplashScreen"} # Main right panel diff --git a/test/e2e/gui/objects_map/wallet_names.py b/test/e2e/gui/objects_map/wallet_names.py index 1e209a7a08..7001ec3081 100644 --- a/test/e2e/gui/objects_map/wallet_names.py +++ b/test/e2e/gui/objects_map/wallet_names.py @@ -18,3 +18,7 @@ mainWallet_Saved_Addreses_List = {"container": mainWindow_SavedAddressesView, "o savedAddressView_Delegate = {"container": mainWallet_Saved_Addreses_List, "objectName": RegularExpression("savedAddressView_Delegate*"), "type": "SavedAddressesDelegate", "visible": True} send_StatusRoundButton = {"container": "", "type": "StatusRoundButton", "unnamed": 1, "visible": True} savedAddressView_Delegate_menuButton = {"container": mainWindow_SavedAddressesView, "objectName": RegularExpression("savedAddressView_Delegate_menuButton*"), "type": "StatusRoundButton", "visible": True} + +# Wallet Account View +mainWindow_StatusSectionLayout_ContentItem = {"container": statusDesktop_mainWindow, "objectName": "StatusSectionLayout", "type": "ContentItem", "visible": True} +mainWallet_Account_Name = {"container": mainWindow_StatusSectionLayout_ContentItem, "objectName": "accountName", "type": "StatusBaseText", "visible": True} diff --git a/test/e2e/gui/screens/wallet.py b/test/e2e/gui/screens/wallet.py index 322ccdaf30..96073703b8 100644 --- a/test/e2e/gui/screens/wallet.py +++ b/test/e2e/gui/screens/wallet.py @@ -1,13 +1,20 @@ +import typing + import allure +import configs +import constants.user import driver - +from driver.objects_access import walk_children from gui.components.base_popup import BasePopup from gui.components.wallet.add_saved_address_popup import AddressPopup, EditSavedAddressPopup from gui.components.wallet.confirmation_popup import ConfirmationPopup +from gui.components.wallet.remove_wallet_account_popup import RemoveWalletAccountPopup +from gui.components.wallet.wallet_account_popups import AccountPopup from gui.components.context_menu import ContextMenu from gui.elements.qt.button import Button from gui.elements.qt.object import QObject +from gui.elements.qt.text_label import TextLabel from scripts.utils.decorators import close_exists @@ -26,12 +33,97 @@ class LeftPanel(QObject): self._add_account_button = Button('mainWallet_Add_Account_Button') self._all_accounts_button = Button('mainWallet_All_Accounts_Button') + @property + @allure.step('Get all accounts from list') + def accounts(self) -> typing.List[constants.user.account_list_item]: + if 'title' in self._wallet_account_item.real_name.keys(): + del self._wallet_account_item.real_name['title'] + + accounts = [] + for account_item in driver.findAllObjects(self._wallet_account_item.real_name): + try: + name = str(account_item.title) + color = str(account_item.asset.color.name).lower() + emoji = '' + for child in walk_children(account_item): + if hasattr(child, 'emojiId'): + emoji = str(child.emojiId) + break + accounts.append(constants.user.account_list_item(name, color, emoji)) + except (AttributeError, RuntimeError): + continue + + return accounts + @allure.step('Choose saved addresses on left wallet panel') @close_exists(BasePopup()) def open_saved_addresses(self) -> 'SavedAddressesView': self._saved_addresses_button.click() return SavedAdressesView().wait_until_appears() + @allure.step('Select account from list') + @close_exists(BasePopup()) + def select_account(self, account_name: str) -> 'WalletAccountView': + self._wallet_account_item.real_name['title'] = account_name + self._wallet_account_item.click() + return WalletAccountView().wait_until_appears() + + @allure.step('Open context menu from left wallet panel') + @close_exists(BasePopup()) + def _open_context_menu(self) -> ContextMenu: + super(LeftPanel, self).open_context_menu() + return ContextMenu().wait_until_appears() + + @allure.step('Open context menu for account') + @close_exists(BasePopup()) + def _open_context_menu_for_account(self, account_name: str) -> ContextMenu: + self._wallet_account_item.real_name['title'] = account_name + self._wallet_account_item.wait_until_appears().open_context_menu() + return ContextMenu().wait_until_appears() + + @allure.step('Open account popup for editing') + def open_edit_account_popup(self, account_name: str, attempt: int = 2) -> AccountPopup: + try: + self._open_context_menu_for_account(account_name).select('Edit') + return AccountPopup().wait_until_appears() + except: + if attempt: + return self.open_edit_account_popup(account_name, attempt - 1) + else: + raise + + @allure.step('Open account popup') + def open_add_account_popup(self, attempt: int = 2): + self._add_account_button.click() + try: + return AccountPopup().wait_until_appears() + except AssertionError as err: + if attempt: + self.open_add_account_popup(attempt-1) + else: + raise err + + @allure.step('Open account popup for watch only account') + def open_add_watch_only_account_popup(self, attempt: int = 2) -> AccountPopup: + try: + self._open_context_menu().select('Add watch-only account') + return AccountPopup().wait_until_appears() + except: + if attempt: + return self.open_add_watch_anly_account_popup(attempt - 1) + else: + raise + + @allure.step('Delete account from list') + def delete_account(self, account_name: str, attempt: int = 2) -> RemoveWalletAccountPopup: + try: + self._open_context_menu_for_account(account_name).select('Delete') + return RemoveWalletAccountPopup().wait_until_appears() + except: + if attempt: + return self.delete_account(account_name, attempt - 1) + else: + raise class SavedAdressesView(QObject): @@ -73,4 +165,27 @@ class SavedAdressesView(QObject): def open_context_menu(self, name) -> ContextMenu: self._open_menu_button.real_name['objectName'] = 'savedAddressView_Delegate_menuButton' + '_' + name self._open_menu_button.click() - return ContextMenu().wait_until_appears() \ No newline at end of file + return ContextMenu().wait_until_appears() + + +class WalletAccountView(QObject): + + def __init__(self): + super(WalletAccountView, self).__init__('mainWindow_StatusSectionLayout_ContentItem') + self._account_name_text_label = TextLabel('mainWallet_Account_Name') + self._addresses_panel = QObject('mainWallet_Address_Panel') + + @property + @allure.step('Get name of account') + def name(self) -> str: + return self._account_name_text_label.text + + @property + @allure.step('Get address of account') + def address(self) -> str: + return str(self._addresses_panel.object.value) + + @allure.step('Wait until appears {0}') + def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC): + self._account_name_text_label.wait_until_appears(timeout_msec) + return self \ No newline at end of file diff --git a/test/e2e/tests/test_wallet.py b/test/e2e/tests/test_wallet.py index 125289806e..2a0cdb06d7 100644 --- a/test/e2e/tests/test_wallet.py +++ b/test/e2e/tests/test_wallet.py @@ -5,6 +5,7 @@ import pytest from allure import step import configs.timeouts +import constants import driver from gui.components.signing_phrase_popup import SigningPhrasePopup from gui.main_window import MainWindow @@ -43,4 +44,76 @@ def test_manage_saved_address(main_screen: MainWindow, name: str, address: str, with step('Verify that saved address with new name is not in the list of saved addresses'): assert driver.waitFor( lambda: new_name not in wallet.left_panel.open_saved_addresses().address_names, - configs.timeouts.UI_LOAD_TIMEOUT_MSEC), f'Address: {new_name} not found' \ No newline at end of file + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), f'Address: {new_name} not found' + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703022', 'Edit default wallet account') +@pytest.mark.case(703022) +@pytest.mark.parametrize('name, new_name, new_color, new_emoji, new_emoji_unicode', [ + pytest.param('Status account', 'MyPrimaryAccount', '#216266', 'sunglasses', '1f60e') +]) +def test_edit_default_wallet_account(main_screen: MainWindow, name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str): + with step('Select wallet account'): + wallet = main_screen.left_panel.open_wallet() + SigningPhrasePopup().wait_until_appears().confirm_phrase() + wallet.left_panel.select_account(name) + + with step('Edit wallet account'): + account_popup = wallet.left_panel.open_edit_account_popup(name) + account_popup.set_name(new_name).set_emoji(new_emoji).set_color(new_color).save() + + with step('Verify that the account is correctly displayed in accounts list'): + expected_account = constants.user.account_list_item(new_name, new_color.lower(), new_emoji_unicode) + started_at = time.monotonic() + while expected_account not in wallet.left_panel.accounts: + time.sleep(1) + if time.monotonic() - started_at > 15: + raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}') + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703026', 'Manage a watch-only account') +@pytest.mark.case(703026) +@pytest.mark.parametrize('address, name, color, emoji, emoji_unicode, new_name, ' + 'new_color, new_emoji, new_emoji_unicode', [ + pytest.param('0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A', 'AccWatch1', '#2a4af5', 'sunglasses', '1f60e', + 'AccWatch1edited', '#216266', 'thumbsup', '1f44d') +]) +def test_manage_watch_only_account(main_screen: MainWindow, address: str, color: str, emoji:str, emoji_unicode: str, name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str): + with step('Create watch-only wallet account'): + wallet = main_screen.left_panel.open_wallet() + SigningPhrasePopup().wait_until_appears().confirm_phrase() + account_popup = wallet.left_panel.open_add_account_popup() + account_popup.set_name(name).set_emoji(emoji).set_color(color).set_origin_eth_address(address).save() + account_popup.wait_until_hidden() + + with step('Verify that the account is correctly displayed in accounts list'): + expected_account = constants.user.account_list_item(name, color.lower(), emoji_unicode) + started_at = time.monotonic() + while expected_account not in wallet.left_panel.accounts: + time.sleep(1) + if time.monotonic() - started_at > 15: + raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}') + + with step('Delete wallet account'): + wallet.left_panel.delete_account(name).confirm() + + with step('Verify that the account is not displayed in accounts list'): + assert driver.waitFor(lambda: name not in [account.name for account in wallet.left_panel.accounts], 10000), \ + f'Account with {name} is still displayed even it should not be' + + with step('Create watch-only wallet account via context menu'): + account_popup = wallet.left_panel.open_add_watch_only_account_popup() + account_popup.set_name(name).set_emoji(emoji).set_color(color).set_eth_address(address).save() + account_popup.wait_until_hidden() + + with step('Edit wallet account'): + account_popup = wallet.left_panel.open_edit_account_popup(name) + account_popup.set_name(new_name).set_emoji(new_emoji).set_color(new_color).save() + + with step('Verify that the account is correctly displayed in accounts list'): + expected_account = constants.user.account_list_item(new_name, new_color.lower(), new_emoji_unicode) + started_at = time.monotonic() + while expected_account not in wallet.left_panel.accounts: + time.sleep(1) + if time.monotonic() - started_at > 15: + raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}') \ No newline at end of file