Test/10287 suite wallet (#10675)

* test(suite_wallet): tests fix
#10287
This commit is contained in:
Vladimir Druzhinin 2023-05-17 16:39:58 +02:00 committed by GitHub
parent 684d17d968
commit 0d38f7acdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1200 additions and 690 deletions

View File

@ -0,0 +1,2 @@
from . import user_account
from . import wallet

View File

@ -0,0 +1,2 @@
LOGIN = ''
PASSWORD = 'TesTEr16843/!@00'

View File

@ -0,0 +1,14 @@
from collections import namedtuple
from enum import Enum
DEFAULT_ACCOUNT_NAME = 'Status account'
account_list_item = namedtuple('AccountListItem', ['name', 'color', 'emoji'])
class DerivationPath(Enum):
CUSTOM = 'Custom'
ETHEREUM = 'Ethereum'
ETHEREUM_ROPSTEN = 'Ethereum Testnet (Ropsten)'
ETHEREUM_LEDGER = 'Ethereum (Ledger)'
ETHEREUM_LEDGER_LIVE = 'Ethereum (Ledger Live/KeepKey)'

View File

@ -12,8 +12,10 @@ import sys
import test
import time
import configs
import names
import object
import objectMap
# IMPORTANT: It is necessary to import manually the Squish drivers module by module.
# More info in: https://kb.froglogic.com/display/KB/Article+-+Using+Squish+functions+in+your+own+Python+modules+or+packages
import squish
@ -503,9 +505,13 @@ def sleep_test(seconds: float):
squish.snooze(seconds)
def wait_for(py_condition_to_check: str, timeout_msec: int = 500) -> bool:
def wait_for(py_condition_to_check, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC) -> bool:
return squish.waitFor(lambda: py_condition_to_check, timeout_msec)
def wait_until_hidden(object_name: str, timeout_msec: int = _MAX_WAIT_OBJ_TIMEOUT) -> bool:
return squish.waitFor(lambda: not is_displayed(object_name), timeout_msec)
def get_real_name(obj):
return objectMap.realName(obj)

View File

@ -1,5 +1,8 @@
from .base_element import BaseElement
from .button import Button
from .checkbox import CheckBox
from .list import List
from .menu import Menu
from .scroll import Scroll
from .text_edit import TextEdit
from .text_label import TextLabel

View File

@ -4,24 +4,26 @@ import configs
import names
import object
import squish
from utils.decorators import attempt
class BaseElement:
def __init__(self, object_name):
self.symbolic_name = object_name
self.object_name = getattr(names, object_name)
def __str__(self):
return f'{type(self).__qualname__}({self.symbolic_name})'
self.object_name = getattr(names, object_name, object_name)
self._object_name_updates = {}
def __str__(self):
return f'{type(self).__qualname__}({self.symbolic_name})'
@property
def object(self):
return squish.waitForObject(self.object_name)
return squish.waitForObject(self.object_name, configs.squish.UI_LOAD_TIMEOUT_MSEC)
@property
def existent(self):
return squish.waitForObjectExists(self.object_name)
return squish.waitForObjectExists(self.object_name, configs.squish.UI_LOAD_TIMEOUT_MSEC)
@property
def bounds(self) -> squish.UiTypes.ScreenRectangle:
@ -43,6 +45,10 @@ class BaseElement:
def is_selected(self) -> bool:
return self.object.selected
@property
def is_checked(self) -> bool:
return self.object.checked
@property
def is_visible(self) -> bool:
try:
@ -50,6 +56,7 @@ class BaseElement:
except (AttributeError, LookupError, RuntimeError):
return False
@attempt(2)
def click(
self,
x: typing.Union[int, squish.UiTypes.ScreenPoint] = None,
@ -60,12 +67,26 @@ class BaseElement:
self.object,
x or self.width // 2,
y or self.height // 2,
button or squish.MouseButton.LeftButton
button or squish.Qt.LeftButton
)
def hover(self):
squish.mouseMove(self.center.x, self.center.y)
def open_context_menu(
self,
x: typing.Union[int, squish.UiTypes.ScreenPoint] = None,
y: typing.Union[int, squish.UiTypes.ScreenPoint] = None,
):
self.click(
x or self.width // 2,
y or self.height // 2,
squish.Qt.RightButton
)
@property
def is_enabled(self) -> bool:
return self.object.enabled
return self.object.enabled
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
assert squish.waitFor(lambda: self.is_visible, timeout_msec), f'Object {self} is not visible'

View File

@ -0,0 +1,13 @@
import configs
import squish
from .base_element import BaseElement
class CheckBox(BaseElement):
def set(self, value: bool, x: int = None, y: int = None):
if self.is_checked is not value:
self.click(x, y)
assert squish.waitFor(
lambda: self.is_checked is value, configs.squish.UI_LOAD_TIMEOUT_MSEC), 'Value not changed'

View File

@ -0,0 +1,18 @@
import squish
from .base_element import BaseElement
class List(BaseElement):
@property
def items(self):
return [self.object.itemAtIndex(index) for index in range(self.object.count)]
def select(self, attribute_value: str, attribute_name: str = 'text'):
for index in range(self.object.count):
list_item = self.object.itemAt(index)
if str(getattr(list_item, attribute_value, '')) == attribute_name:
squish.mouseClick(list_item)
return
raise LookupError(f'List item: {attribute_value}:{attribute_name} not found in {self.items}')

View File

@ -0,0 +1,11 @@
import configs
import squish
from .base_element import BaseElement
class Menu(BaseElement):
def select(self, menu_item: str):
squish.activateItem(squish.waitForObjectItem(self.object_name, menu_item, configs.squish.UI_LOAD_TIMEOUT_MSEC))
self.wait_until_hidden()

View File

@ -18,3 +18,11 @@ class Scroll(BaseElement):
time.sleep(0.1)
if time.monotonic() - started_at > timeout_sec:
raise LookupError(f'Object not found: {element.object_name}')
def vertical_down_to(self, element: BaseElement, timeout_sec: int = 5):
started_at = time.monotonic()
step = 100
while not element.is_visible:
squish.flick(self.object, 0, step)
if time.monotonic() - started_at > timeout_sec:
raise LookupError(f'Object not found: {element.object_name}')

View File

@ -1,3 +1,4 @@
import configs
import squish
from .base_element import BaseElement
@ -13,17 +14,17 @@ class TextEdit(BaseElement):
def text(self, value: str):
self.clear()
self.type_text(value)
assert squish.waitFor(lambda: self.text == value)
assert squish.waitFor(lambda: self.text == value, configs.squish.UI_LOAD_TIMEOUT_MSEC), \
f'Type text failed, value in field: "{self.text}", expected: {value}'
def type_text(self, value: str):
self.click()
squish.type(self.object, value)
assert squish.waitFor(lambda: self.text == value), \
f'Type text failed, value in field: "{self.text}", expected: {value}'
return self
def clear(self):
def clear(self, verify: bool = True):
self.object.clear()
assert squish.waitFor(lambda: not self.text), \
f'Field did not cleared, value in field: "{self.text}"'
if verify:
assert squish.waitFor(lambda: not self.text, configs.squish.UI_LOAD_TIMEOUT_MSEC), \
f'Field did not cleared, value in field: "{self.text}"'
return self

View File

@ -1,66 +1,282 @@
import time
import typing
from ast import Tuple
from enum import Enum
import time
import os
import sys
import common.Common as common
import configs
import constants
import squish
from common.SeedUtils import *
from .StatusMainScreen import StatusMainScreen
from .StatusMainScreen import authenticate_popup_enter_password
from drivers.SquishDriver import *
from objectmaphelper import *
from utils.ObjectAccess import *
from utils.decorators import close_exists
from .SettingsScreen import SidebarComponents
from drivers.SquishDriver import type_text as type_text
from .StatusMainScreen import authenticate_popup_enter_password
from .components.base_popup import BasePopup
from .components.confirmation_popup import ConfirmationPopup
from .components.context_menu import ContextMenu
from .components.remove_wallet_account_popup import RemoveWalletAccountPopup
from .components.saved_address_popup import AddSavedAddressPopup, EditSavedAddressPopup
from .components.wallet_account_popups import AccountPopup
NOT_APPLICABLE = "N/A"
VALUE_YES = "yes"
VALUE_NO = "no"
class MainWalletContextMenu(ContextMenu):
def __init__(self):
super(MainWalletContextMenu, self).__init__()
self._copy_address_menu_item = BaseElement('mainWallet_CopyAddress_MenuItem')
self._edit_account_menu_item = BaseElement('mainWallet_EditAccount_MenuItem')
self._add_new_account_menu_item = BaseElement('mainWallet_AddNewAccount_MenuItem')
self._add_watch_only_account_menu_item = BaseElement('mainWallet_AddWatchOnlyAccount_MenuItem')
self._delete_menu_item = BaseElement('mainWallet_DeleteAccount_MenuItem')
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
self._add_new_account_menu_item.wait_until_appears(timeout_msec)
return self
def select(self, menu_item: BaseElement):
menu_item.wait_until_appears()
menu_item.click()
menu_item.wait_until_hidden()
def select_copy_address(self):
self.select(self._copy_address_menu_item)
def select_edit_account(self):
self.select(self._edit_account_menu_item)
def select_add_new_account(self):
self.select(self._add_new_account_menu_item)
def select_add_watch_anly_account(self):
self.select(self._add_watch_only_account_menu_item)
def select_delete(self):
self.select(self._delete_menu_item)
class LeftPanel(BaseElement):
def __init__(self):
super(LeftPanel, self).__init__('mainWallet_LeftTab')
self._saved_addresses_button = BaseElement('mainWallet_Saved_Addresses_Button')
self._wallet_account_item = BaseElement('walletAccount_StatusListItem')
self._add_account_button = Button('mainWallet_Add_Account_Button')
@property
def accounts(self) -> typing.List[constants.wallet.account_list_item]:
if 'title' in self._wallet_account_item.object_name.keys():
del self._wallet_account_item.object_name['title']
accounts = []
for account_item in squish.findAllObjects(self._wallet_account_item.object_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.wallet.account_list_item(name, color, emoji))
except (AttributeError, RuntimeError):
continue
return accounts
@close_exists(BasePopup())
def open_saved_addresses(self) -> 'AddressesView':
self._saved_addresses_button.click()
return AddressesView().wait_until_appears()
@close_exists(BasePopup())
def select_account(self, account_name: str) -> 'WalletAccountView':
self._wallet_account_item.object_name['title'] = account_name
self._wallet_account_item.click()
return WalletAccountView().wait_until_appears()
@close_exists(BasePopup())
def _open_context_menu(self) -> MainWalletContextMenu:
super(LeftPanel, self).open_context_menu()
return MainWalletContextMenu().wait_until_appears()
@close_exists(BasePopup())
def _open_context_menu_for_account(self, account_name: str) -> MainWalletContextMenu:
self._wallet_account_item.object_name['title'] = account_name
self._wallet_account_item.wait_until_appears().open_context_menu()
return MainWalletContextMenu().wait_until_appears()
def open_edit_account_popup(self, account_name: str, attempt: int = 2) -> AccountPopup:
try:
self._open_context_menu_for_account(account_name).select_edit_account()
return AccountPopup().wait_until_appears()
except:
if attempt:
return self.open_edit_account_popup(account_name, attempt - 1)
else:
raise
def open_add_watch_anly_account_popup(self, attempt: int = 2) -> AccountPopup:
try:
self._open_context_menu().select_add_watch_anly_account()
return AccountPopup().wait_until_appears()
except:
if attempt:
return self.open_add_watch_anly_account_popup(attempt - 1)
else:
raise
def open_add_new_account_popup(self, attempt: int = 2):
try:
self._open_context_menu().select_add_new_account()
return AccountPopup().wait_until_appears()
except:
if attempt:
return self.open_add_new_account_popup(attempt - 1)
else:
raise
def open_add_account_popup(self):
self._add_account_button.click()
return AccountPopup().wait_until_appears()
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 SavedAddressListItem(BaseElement):
def __init__(self, object_name: str):
super(SavedAddressListItem, self).__init__(object_name)
self._send_button = Button('send_StatusRoundButton')
self._open_menu_button = Button('savedAddressView_Delegate_menuButton')
@property
def name(self) -> str:
return self.object.name
@property
def address(self) -> str:
return self.object.address
def open_send_popup(self):
self._send_button.object_name['container'] = self.object_name
self._send_button.click()
# TODO: return popup)
def open_context_menu(self) -> ContextMenu:
self._open_menu_button.object_name['container'] = self.object_name
self._open_menu_button.click()
return ContextMenu().wait_until_appears()
class AddressesView(BaseElement):
def __init__(self):
super(AddressesView, self).__init__('mainWindow_SavedAddressesView')
self._add_new_address_button = Button('mainWallet_Saved_Addreses_Add_Buttton')
self._address_list_item = BaseElement('savedAddressView_Delegate')
@property
def saved_addresses(self):
items = get_objects(self._address_list_item.symbolic_name)
addresses = [SavedAddressListItem(get_real_name(item)) for item in items]
return addresses
@property
def address_names(self):
names = [address.name for address in get_objects(self._address_list_item.symbolic_name)]
return names
def _get_saved_address_by_name(self, name):
for address in self.saved_addresses:
if address.name == name:
return address
raise LookupError(f'Address: {name} not found ')
def open_add_address_popup(self, attempt=2) -> 'AddSavedAddressPopup':
self._add_new_address_button.click()
try:
return AddSavedAddressPopup().wait_until_appears()
except AssertionError as err:
if attempt:
self.open_add_address_popup(attempt - 1)
else:
raise err
def open_edit_address_popup(self, address_name: str) -> 'EditSavedAddressPopup':
address = self._get_saved_address_by_name(address_name)
address.open_context_menu().select('Edit')
return EditSavedAddressPopup().wait_until_appears()
def delete_saved_address(self, address_name):
address = self._get_saved_address_by_name(address_name)
address.open_context_menu().select('Delete')
ConfirmationPopup().wait_until_appears().confirm()
class WalletAccountView(BaseElement):
def __init__(self):
super(WalletAccountView, self).__init__('mainWindow_StatusSectionLayout_ContentItem')
self._account_name_text_label = TextLabel('mainWallet_Account_Name')
self._addresses_panel = BaseElement('mainWallet_Address_Panel')
@property
def name(self) -> str:
return self._account_name_text_label.text
@property
def address(self) -> str:
return str(self._addresses_panel.object.value)
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
self._account_name_text_label.wait_until_appears(timeout_msec)
return self
class Tokens(Enum):
ETH: str = "ETH"
class SigningPhrasePopUp(Enum):
OK_GOT_IT_BUTTON: str = "signPhrase_Ok_Button"
class MainWalletScreen(Enum):
WALLET_LEFT_TAB: str = "mainWallet_LeftTab"
ADD_ACCOUNT_BUTTON: str = "mainWallet_Add_Account_Button"
ACCOUNT_NAME: str = "mainWallet_Account_Name"
ACCOUNT_ADDRESS_PANEL: str = "mainWallet_Address_Panel"
SEND_BUTTON_FOOTER: str = "mainWallet_Footer_Send_Button"
SAVED_ADDRESSES_BUTTON: str = "mainWallet_Saved_Addresses_Button"
NETWORK_SELECTOR_BUTTON: str = "mainWallet_Network_Selector_Button"
RIGHT_SIDE_TABBAR: str = "mainWallet_Right_Side_Tab_Bar"
WALLET_ACCOUNTS_LIST: str = "walletAccounts_StatusListView"
WALLET_ACCOUNT_ITEM_PLACEHOLDER = "walletAccounts_WalletAccountItem_Placeholder"
EPHEMERAL_NOTIFICATION_LIST: str = "mainWallet_Ephemeral_Notification_List"
TOTAL_CURRENCY_BALANCE: str = "mainWallet_totalCurrencyBalance"
class MainWalletRightClickMenu(Enum):
COPY_ADDRESS_ACTION_PLACEHOLDER: str = "mainWallet_RightClick_CopyAddress_MenuItem_Placeholder"
EDIT_ACCOUNT_ACTION_PLACEHOLDER: str = "mainWallet_RightClick_EditAccount_MenuItem_Placeholder"
DELETE_ACCOUNT_ACTION_PLACEHOLDER: str = "mainWallet_RightClick_DeleteAccount_MenuItem_Placeholder"
ADD_NEW_ACCOUNT_ACTION_PLACEHOLDER: str = "mainWallet_RightClick_AddNewAccount_MenuItem_Placeholder"
ADD_WATCH_ONLY_ACCOUNT_ACTION_PLACEHOLDER: str = "mainWallet_RightClick_AddWatchOnlyAccount_MenuItem_Placeholder"
class AssetView(Enum):
LIST: str = "mainWallet_Assets_View_List"
class NetworkSelectorPopup(Enum):
LAYER_1_REPEATER: str = "mainWallet_Network_Popup_Chain_Repeater_1"
class SavedAddressesScreen(Enum):
ADD_BUTTON: str = "mainWallet_Saved_Addreses_Add_Buttton"
SAVED_ADDRESSES_LIST: str = "mainWallet_Saved_Addreses_List"
EDIT: str = "mainWallet_Saved_Addreses_More_Edit"
DELETE: str = "mainWallet_Saved_Addreses_More_Delete"
CONFIRM_DELETE: str = "mainWallet_Saved_Addreses_More_Confirm_Delete"
DELEGATE_MENU_BUTTON_OBJECT_NAME: str = "savedAddressView_Delegate_menuButton"
DELEGATE_FAVOURITE_BUTTON_OBJECT_NAME: str = "savedAddressView_Delegate_favouriteButton"
class AddSavedAddressPopup(Enum):
NAME_INPUT: str = "mainWallet_Saved_Addreses_Popup_Name_Input"
ADDRESS_INPUT: str = "mainWallet_Saved_Addreses_Popup_Address_Input"
ADDRESS_INPUT_EDIT: str = "mainWallet_Saved_Addreses_Popup_Address_Input_Edit"
ADD_BUTTON: str = "mainWallet_Saved_Addreses_Popup_Address_Add_Button"
class SendPopup(Enum):
SCROLL_BAR: str = "mainWallet_Send_Popup_Main"
@ -74,69 +290,27 @@ class SendPopup(Enum):
ASSET_LIST: str = "mainWallet_Send_Popup_Asset_List"
HIGH_GAS_BUTTON: str = "mainWallet_Send_Popup_GasSelector_HighGas_Button"
class AddEditAccountPopup(Enum):
CONTENT = "mainWallet_AddEditAccountPopup_Content"
ACCOUNT_NAME = "mainWallet_AddEditAccountPopup_AccountName"
ACCOUNT_COLOR_SELECTOR = "mainWallet_AddEditAccountPopup_AccountColorSelector"
SELECTED_ORIGIN = "mainWallet_AddEditAccountPopup_SelectedOrigin"
EMOJI_PUPUP_BUTTON = "mainWallet_AddEditAccountPopup_AccountEmojiPopupButton"
EMOJI_PUPUP_SEARCH = "mainWallet_AddEditAccountPopup_AccountEmojiSearchBox"
EMOJI_PUPUP_EMOJI = "mainWallet_AddEditAccountPopup_AccountEmoji"
ORIGIN_OPTION_PLACEHOLDER = "mainWallet_AddEditAccountPopup_OriginOption_Placeholder"
ORIGIN_OPTION_NEW_MASTER_KEY = "mainWallet_AddEditAccountPopup_OriginOptionNewMasterKey"
ORIGIN_OPTION_WATCH_ONLY_ACC = "mainWallet_AddEditAccountPopup_OriginOptionWatchOnlyAcc"
WATCH_ONLY_ADDRESS = "mainWallet_AddEditAccountPopup_AccountWatchOnlyAddress"
PRIMARY_BUTTON = "mainWallet_AddEditAccountPopup_PrimaryButton"
BACK_BUTTON = "mainWallet_AddEditAccountPopup_BackButton"
EDIT_DERIVATION_PATH_BUTTON = "mainWallet_AddEditAccountPopup_EditDerivationPathButton"
RESET_DERIVATION_PATH_BUTTON = "mainWallet_AddEditAccountPopup_ResetDerivationPathButton"
DERIVATION_PATH = "mainWallet_AddEditAccountPopup_DerivationPathInput"
PREDEFINED_DERIVATION_PATHS_BUTTON = "mainWallet_AddEditAccountPopup_PreDefinedDerivationPathsButton"
PREDEFINED_TESTNET_ROPSTEN_PATH = "mainWallet_AddEditAccountPopup_PreDefinedPathsOptionTestnetRopsten"
SELECTED_GENERATED_ADDRESS = "mainWallet_AddEditAccountPopup_GeneratedAddressComponent"
GENERATED_ADDDRESS_99 = "mainWallet_AddEditAccountPopup_GeneratedAddress_99"
GENERATED_ADDRESSES_PAGE_20 = "mainWallet_AddEditAccountPopup_PageIndicatorPage_20"
NON_ETH_DERIVATION_PATH = "mainWallet_AddEditAccountPopup_NonEthDerivationPathCheckBox"
MASTER_KEY_IMPORT_PRIVATE_KEY_OPTION = "mainWallet_AddEditAccountPopup_MasterKey_ImportPrivateKeyOption"
MASTER_KEY_IMPORT_SEED_PHRASE_OPTION = "mainWallet_AddEditAccountPopup_MasterKey_ImportSeedPhraseOption"
MASTER_KEY_GENERATE_SEED_PHRASE_OPTION = "mainWallet_AddEditAccountPopup_MasterKey_GenerateSeedPhraseOption"
MASTER_KEY_GO_TO_KEYCARD_SETTINGS_OPTION = "mainWallet_AddEditAccountPopup_MasterKey_GoToKeycardSettingsOption"
PRIVATE_KEY = "mainWallet_AddEditAccountPopup_PrivateKey"
PRIVATE_KEY_KEY_NAME = "mainWallet_AddEditAccountPopup_PrivateKeyName"
IMPORTED_SEED_PHRASE_KEY_NAME = "mainWallet_AddEditAccountPopup_ImportedSeedPhraseKeyName"
GENERATED_SEED_PHRASE_KEY_NAME = "mainWallet_AddEditAccountPopup_GeneratedSeedPhraseKeyName"
SEED_PHRASE_12_WORDS: str = "mainWallet_AddEditAccountPopup_12WordsButton"
SEED_PHRASE_18_WORDS: str = "mainWallet_AddEditAccountPopup_18WordsButton"
SEED_PHRASE_24_WORDS: str = "mainWallet_AddEditAccountPopup_24WordsButton"
SEED_PHRASE_WORD_PATTERN: str = "mainWallet_AddEditAccountPopup_SPWord_"
HAVE_PEN_AND_PAPER = "mainWallet_AddEditAccountPopup_HavePenAndPaperCheckBox"
SEED_PHRASE_WRITTEN = "mainWallet_AddEditAccountPopup_SeedPhraseWrittenCheckBox"
STORING_SEED_PHRASE_CONFIRMED = "mainWallet_AddEditAccountPopup_StoringSeedPhraseConfirmedCheckBox"
SEED_BACKUP_ACKNOWLEDGE = "mainWallet_AddEditAccountPopup_SeedBackupAknowledgeCheckBox"
REVEAL_SEED_PHRASE_BUTTON = "mainWallet_AddEditAccountPopup_RevealSeedPhraseButton"
SEED_PHRASE_WORD_AT_INDEX_PLACEHOLDER = "mainWallet_AddEditAccountPopup_SeedPhraseWordAtIndex_Placeholder"
ENTER_SEED_PHRASE_WORD_COMPONENT = "mainWallet_AddEditAccountPopup_EnterSeedPhraseWordComponent"
ENTER_SEED_PHRASE_WORD = "mainWallet_AddEditAccountPopup_EnterSeedPhraseWord"
class RemoveAccountPopup(Enum):
ACCOUNT_NOTIFICATION = "mainWallet_Remove_Account_Popup_Account_Notification"
ACCOUNT_PATH = "mainWallet_Remove_Account_Popup_Account_Path"
HAVE_PEN_PAPER = "mainWallet_Remove_Account_Popup_HavePenPaperCheckBox"
CONFIRM_BUTTON = "mainWallet_Remove_Account_Popup_ConfirmButton"
CANCEL_BUTTON = "mainWallet_Remove_Account_Popup_CancelButton"
class AddEditAccountPopup(Enum):
ORIGIN_OPTION_NEW_MASTER_KEY = "mainWallet_AddEditAccountPopup_OriginOptionNewMasterKey"
MASTER_KEY_GO_TO_KEYCARD_SETTINGS_OPTION = "mainWallet_AddEditAccountPopup_MasterKey_GoToKeycardSettingsOption"
class CollectiblesView(Enum):
COLLECTIONS_REPEATER: str = "mainWallet_Collections_Repeater"
COLLECTIBLES_REPEATER: str = "mainWallet_Collectibles_Repeater"
COLLECTIONS_REPEATER: str = "mainWallet_Collections_Repeater"
COLLECTIBLES_REPEATER: str = "mainWallet_Collectibles_Repeater"
class WalletTabBar(Enum):
ASSET_TAB = 0
COLLECTION_TAB = 1
ASSET_TAB = 0
COLLECTION_TAB = 1
ACTIVITY_TAB = 2
class TransactionsView(Enum):
TRANSACTIONS_LISTVIEW: str = "mainWallet_Transactions_List"
TRANSACTIONS_DETAIL_VIEW_HEADER: str = "mainWallet_Transactions_Detail_View_Header"
TRANSACTIONS_LISTVIEW: str = "mainWallet_Transactions_List"
TRANSACTIONS_DETAIL_VIEW_HEADER: str = "mainWallet_Transactions_Detail_View_Header"
class StatusWalletScreen:
@ -144,225 +318,25 @@ class StatusWalletScreen:
### Screen actions region:
#####################################
def __init__(self):
super(StatusWalletScreen, self).__init__()
self.left_panel: LeftPanel = LeftPanel()
def accept_signing_phrase(self):
click_obj_by_name(SigningPhrasePopUp.OK_GOT_IT_BUTTON.value)
def open_add_account_popup(self):
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
def add_account_popup_do_primary_action(self, password: str = NOT_APPLICABLE):
click_obj_by_name(AddEditAccountPopup.PRIMARY_BUTTON.value)
if password != NOT_APPLICABLE:
authenticate_popup_enter_password(password)
def add_account_popup_open_edit_derivation_path_section(self, password: str):
click_obj_by_name(AddEditAccountPopup.EDIT_DERIVATION_PATH_BUTTON.value)
authenticate_popup_enter_password(password)
def add_account_popup_change_account_name(self, name: str):
is_loaded_visible_and_enabled(AddEditAccountPopup.ACCOUNT_NAME.value, 1000)
setText(AddEditAccountPopup.ACCOUNT_NAME.value, name)
def add_account_popup_change_account_color(self, color: str):
colorList = get_obj(AddEditAccountPopup.ACCOUNT_COLOR_SELECTOR.value)
for index in range(colorList.count):
c = colorList.itemAt(index)
if(c.radioButtonColor == color):
click_obj(colorList.itemAt(index))
def add_account_popup_change_origin(self, origin_object_name: str):
click_obj_by_name(AddEditAccountPopup.SELECTED_ORIGIN.value)
click_obj_by_name(origin_object_name)
def add_account_popup_change_origin_by_keypair_name(self, keypair_name):
click_obj_by_name(AddEditAccountPopup.SELECTED_ORIGIN.value)
originObj = wait_by_wildcards(AddEditAccountPopup.ORIGIN_OPTION_PLACEHOLDER.value, "%NAME%", keypair_name)
click_obj(originObj)
def add_account_popup_change_derivation_path(self, index: str, order: str, is_ethereum_root: str):
# initially we set derivation path to other than default eth path, in order to test reset button functionality
click_obj_by_name(AddEditAccountPopup.PREDEFINED_DERIVATION_PATHS_BUTTON.value)
hover_and_click_object_by_name(AddEditAccountPopup.PREDEFINED_TESTNET_ROPSTEN_PATH.value)
if is_ethereum_root == VALUE_YES:
click_obj_by_name(AddEditAccountPopup.RESET_DERIVATION_PATH_BUTTON.value)
else:
scroll_item_until_item_is_visible(AddEditAccountPopup.CONTENT.value, AddEditAccountPopup.NON_ETH_DERIVATION_PATH.value)
click_obj_by_name(AddEditAccountPopup.NON_ETH_DERIVATION_PATH.value)
[compLoaded, selectedAccount] = is_loaded(AddEditAccountPopup.SELECTED_GENERATED_ADDRESS.value)
if not compLoaded:
verify_failure("cannot find selected address")
return
if index != NOT_APPLICABLE or order != NOT_APPLICABLE:
click_obj_by_name(AddEditAccountPopup.DERIVATION_PATH.value)
common.clear_input_text(AddEditAccountPopup.DERIVATION_PATH.value)
if index != NOT_APPLICABLE:
type_text(AddEditAccountPopup.DERIVATION_PATH.value, index)
elif order != NOT_APPLICABLE:
do_until_validation_with_timeout(
lambda: time.sleep(0.5),
lambda: not selectedAccount.loading,
"generating addresses to offer after path is cleared",
5000)
click_obj(selectedAccount)
is_loaded_visible_and_enabled(AddEditAccountPopup.GENERATED_ADDRESSES_PAGE_20.value)
click_obj_by_name(AddEditAccountPopup.GENERATED_ADDRESSES_PAGE_20.value)
is_loaded_visible_and_enabled(AddEditAccountPopup.GENERATED_ADDDRESS_99.value)
click_obj_by_name(AddEditAccountPopup.GENERATED_ADDDRESS_99.value)
do_until_validation_with_timeout(
lambda: time.sleep(0.5),
lambda: not selectedAccount.loading,
"resolving an address after path is finally chosen",
5000)
def add_account_popup_change_account_emoji(self, emoji: str):
click_obj_by_name(AddEditAccountPopup.EMOJI_PUPUP_BUTTON.value)
wait_for_object_and_type(AddEditAccountPopup.EMOJI_PUPUP_SEARCH.value, emoji)
click_obj(wait_by_wildcards(AddEditAccountPopup.EMOJI_PUPUP_EMOJI.value, "%NAME%", "*"))
def add_account_popup_set_watch_only_account_as_selected_origin(self, address: str):
self.add_account_popup_change_origin(AddEditAccountPopup.ORIGIN_OPTION_WATCH_ONLY_ACC.value)
wait_for_object_and_type(AddEditAccountPopup.WATCH_ONLY_ADDRESS.value, address)
def add_account_popup_set_new_private_key_as_selected_origin(self, private_key: str, keypair_name: str):
self.add_account_popup_change_origin(AddEditAccountPopup.ORIGIN_OPTION_NEW_MASTER_KEY.value)
is_loaded_visible_and_enabled(AddEditAccountPopup.MASTER_KEY_IMPORT_PRIVATE_KEY_OPTION.value)
click_obj_by_name(AddEditAccountPopup.MASTER_KEY_IMPORT_PRIVATE_KEY_OPTION.value)
type_text(AddEditAccountPopup.PRIVATE_KEY.value, private_key)
wait_for_object_and_type(AddEditAccountPopup.PRIVATE_KEY_KEY_NAME.value, keypair_name)
self.add_account_popup_do_primary_action()
def add_account_popup_set_new_seed_phrase_as_selected_origin(self, seed_phrase: str, keypair_name: str):
self.add_account_popup_change_origin(AddEditAccountPopup.ORIGIN_OPTION_NEW_MASTER_KEY.value)
is_loaded_visible_and_enabled(AddEditAccountPopup.MASTER_KEY_IMPORT_SEED_PHRASE_OPTION.value)
click_obj_by_name(AddEditAccountPopup.MASTER_KEY_IMPORT_SEED_PHRASE_OPTION.value)
sp_words = seed_phrase.split()
if len(sp_words) == 12:
click_obj_by_name(AddEditAccountPopup.SEED_PHRASE_12_WORDS.value)
elif len(sp_words) == 18:
click_obj_by_name(AddEditAccountPopup.SEED_PHRASE_18_WORDS.value)
elif len(sp_words) == 24:
click_obj_by_name(AddEditAccountPopup.SEED_PHRASE_24_WORDS.value)
else:
test.fail("Wrong amount of seed words", len(words))
input_seed_phrase(AddEditAccountPopup.SEED_PHRASE_WORD_PATTERN.value, sp_words)
wait_for_object_and_type(AddEditAccountPopup.IMPORTED_SEED_PHRASE_KEY_NAME.value, keypair_name)
self.add_account_popup_do_primary_action()
def add_account_popup_set_generated_seed_phrase_as_selected_origin(self, keypair_name: str):
self.add_account_popup_change_origin(AddEditAccountPopup.ORIGIN_OPTION_NEW_MASTER_KEY.value)
is_loaded_visible_and_enabled(AddEditAccountPopup.MASTER_KEY_IMPORT_SEED_PHRASE_OPTION.value)
click_obj_by_name(AddEditAccountPopup.MASTER_KEY_GENERATE_SEED_PHRASE_OPTION.value)
click_obj_by_name(AddEditAccountPopup.HAVE_PEN_AND_PAPER.value)
click_obj_by_name(AddEditAccountPopup.SEED_PHRASE_WRITTEN.value)
click_obj_by_name(AddEditAccountPopup.STORING_SEED_PHRASE_CONFIRMED.value)
self.add_account_popup_do_primary_action()
click_obj_by_name(AddEditAccountPopup.REVEAL_SEED_PHRASE_BUTTON.value)
seed_phrase = [wait_by_wildcards(AddEditAccountPopup.SEED_PHRASE_WORD_AT_INDEX_PLACEHOLDER.value, "%WORD-INDEX%", str(i + 1)).textEdit.input.edit.text for i in range(12)]
self.add_account_popup_do_primary_action()
enterWordObj = wait_and_get_obj(AddEditAccountPopup.ENTER_SEED_PHRASE_WORD_COMPONENT.value)
label = str(enterWordObj.label)
index = int(label[len("Word #"):len(label)]) - 1
wordToEnter = str(seed_phrase[index])
wait_for_object_and_type(AddEditAccountPopup.ENTER_SEED_PHRASE_WORD.value, wordToEnter)
self.add_account_popup_do_primary_action()
enterWordObj = wait_and_get_obj(AddEditAccountPopup.ENTER_SEED_PHRASE_WORD_COMPONENT.value)
label = str(enterWordObj.label)
index = int(label[len("Word #"):len(label)]) - 1
wordToEnter = str(seed_phrase[index])
wait_for_object_and_type(AddEditAccountPopup.ENTER_SEED_PHRASE_WORD.value, wordToEnter)
self.add_account_popup_do_primary_action()
click_obj_by_name(AddEditAccountPopup.SEED_BACKUP_ACKNOWLEDGE.value)
self.add_account_popup_do_primary_action()
wait_for_object_and_type(AddEditAccountPopup.GENERATED_SEED_PHRASE_KEY_NAME.value, keypair_name)
self.add_account_popup_do_primary_action()
def add_account_popup_go_to_keycard_settings(self):
self.add_account_popup_change_origin(AddEditAccountPopup.ORIGIN_OPTION_NEW_MASTER_KEY.value)
is_loaded_visible_and_enabled(AddEditAccountPopup.MASTER_KEY_GO_TO_KEYCARD_SETTINGS_OPTION.value)
click_obj_by_name(AddEditAccountPopup.MASTER_KEY_GO_TO_KEYCARD_SETTINGS_OPTION.value)
def remove_account_popup_do_cancel_action(self):
click_obj_by_name(RemoveAccountPopup.CANCEL_BUTTON.value)
def remove_account_popup_do_remove_action(self, confirmHavingPenAndPaper, password: str):
if confirmHavingPenAndPaper:
click_obj_by_name(RemoveAccountPopup.HAVE_PEN_PAPER.value)
click_obj_by_name(RemoveAccountPopup.CONFIRM_BUTTON.value)
if password != NOT_APPLICABLE:
authenticate_popup_enter_password(password)
def click_option_from_left_part_right_click_menu(self, option: str):
right_click_obj_by_name(MainWalletScreen.WALLET_LEFT_TAB.value)
optionObj = wait_by_wildcards(option, "%NAME%", "wallet-background")
hover_obj(optionObj)
click_obj(optionObj)
def click_option_from_right_click_menu_of_account_with_name(self, option: str, name: str):
time.sleep(2)
##########################################
# Sometimes this function fails to open right click menu on form the wallet account item,
# or because of missed option from the right click menu
#
# NEEDS SOME INSPECTION WHAT'S REALLY HAPPENING
#
##########################################
# OPTION-1
# accounts = wait_and_get_obj(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
# for index in range(accounts.count):
# accountObj = accounts.itemAtIndex(index)
# if(accountObj.objectName == "walletAccount-" + name):
# right_click_obj(accountObj)
# do_until_validation_with_timeout(
# lambda: time.sleep(1),
# lambda: accountObj.itemLoaded,
# "loading address",
# 5000)
# optionObj = wait_by_wildcards(option, "%NAME%", name)
# hover_obj(optionObj)
# click_obj(optionObj)
# return
# OPTION-2
accountObj = wait_by_wildcards(MainWalletScreen.WALLET_ACCOUNT_ITEM_PLACEHOLDER.value, "%NAME%", name)
if accountObj is None:
objName = copy.deepcopy(getattr(names, MainWalletScreen.WALLET_ACCOUNT_ITEM_PLACEHOLDER.value))
realObjName = objName["objectName"].replace("%NAME%", name)
[compLoaded, accountObj] = is_loaded_visible_and_enabled(realObjName)
if not compLoaded:
verify_failure("cannot find wallet account component with objectName = " + realObjName)
return
if accountObj is None:
verify_failure("cannot find wallet account component with name = " + name)
return
do_until_validation_with_timeout(
lambda: time.sleep(0.5),
lambda: false if accountObj is None else accountObj.itemLoaded,
"loading address",
5000)
right_click_obj(accountObj)
time.sleep(1)
optionObj = wait_by_wildcards(option, "%NAME%", name)
if optionObj is None:
verify_failure("cannot find option in wallet account right click menu with name = " + name)
return
hover_obj(optionObj)
click_obj(optionObj)
def send_transaction(self, account_name, amount, token, chain_name, password):
is_loaded_visible_and_enabled(AssetView.LIST.value, 2000)
list = get_obj(AssetView.LIST.value)
# LoadingTokenDelegate will be visible until the balance is loaded verify_account_balance_is_positive checks for TokenDelegate
do_until_validation_with_timeout(lambda: time.sleep(0.1), lambda: self.verify_account_balance_is_positive(list, "ETH")[0], "Wait for tokens to load", 10000)
do_until_validation_with_timeout(lambda: time.sleep(0.1),
lambda: self.verify_account_balance_is_positive(list, "ETH")[0],
"Wait for tokens to load", 10000)
click_obj_by_name(MainWalletScreen.SEND_BUTTON_FOOTER.value)
@ -374,7 +348,7 @@ class StatusWalletScreen:
asset_list = get_obj(SendPopup.ASSET_LIST.value)
for index in range(asset_list.count):
tokenObj = asset_list.itemAtIndex(index)
if(not is_null(tokenObj) and tokenObj.objectName == "AssetSelector_ItemDelegate_" + token):
if (not is_null(tokenObj) and tokenObj.objectName == "AssetSelector_ItemDelegate_" + token):
click_obj(asset_list.itemAtIndex(index))
break
@ -382,7 +356,7 @@ class StatusWalletScreen:
accounts = get_obj(SendPopup.MY_ACCOUNTS_LIST.value)
for index in range(accounts.count):
if(accounts.itemAtIndex(index).objectName == account_name):
if (accounts.itemAtIndex(index).objectName == account_name):
print("WE FOUND THE ACCOUNT")
click_obj(accounts.itemAtIndex(index))
break
@ -396,54 +370,18 @@ class StatusWalletScreen:
def _click_repeater(self, repeater_object_name: str, object_name: str):
repeater = get_obj(repeater_object_name)
for index in range(repeater.count):
if(repeater.itemAt(index).objectName == object_name):
if (repeater.itemAt(index).objectName == object_name):
click_obj(repeater.itemAt(index))
break
def add_saved_address(self, name: str, address: str):
click_obj_by_name(MainWalletScreen.SAVED_ADDRESSES_BUTTON.value)
click_obj_by_name(SavedAddressesScreen.ADD_BUTTON.value)
type_text(AddSavedAddressPopup.NAME_INPUT.value, name)
type_text(AddSavedAddressPopup.ADDRESS_INPUT_EDIT.value, address)
addressInput = get_obj(AddSavedAddressPopup.ADDRESS_INPUT.value)
verify_equal(addressInput.plainText, address)
is_loaded_visible_and_enabled(AddSavedAddressPopup.ADD_BUTTON.value)
click_obj_by_name(AddSavedAddressPopup.ADD_BUTTON.value)
def _get_saved_address_delegate_item(self, name: str):
list = wait_and_get_obj(SavedAddressesScreen.SAVED_ADDRESSES_LIST.value)
found = -1
for index in range(list.count):
if list.itemAtIndex(index).objectName == f"savedAddressView_Delegate_{name}":
found = index
assert found != -1, "saved address not found"
return list.itemAtIndex(found)
def _find_saved_address_and_open_menu(self, name: str):
item = self._get_saved_address_delegate_item(name)
menuButton = get_child_item_with_object_name(item, f"{SavedAddressesScreen.DELEGATE_MENU_BUTTON_OBJECT_NAME.value}_{name}")
is_object_loaded_visible_and_enabled(menuButton)
click_obj(menuButton)
self.left_panel.open_saved_addresses().open_add_address_popup().add_saved_address(name, address)
def edit_saved_address(self, name: str, new_name: str):
self._find_saved_address_and_open_menu(name)
click_obj_by_name(SavedAddressesScreen.EDIT.value)
# Delete existing text
type_text(AddSavedAddressPopup.NAME_INPUT.value, "<Ctrl+A>")
type_text(AddSavedAddressPopup.NAME_INPUT.value, "<Del>")
type_text(AddSavedAddressPopup.NAME_INPUT.value, new_name)
click_obj_by_name(AddSavedAddressPopup.ADD_BUTTON.value)
self.left_panel.open_saved_addresses().open_edit_address_popup(name).edit_saved_address(new_name)
def delete_saved_address(self, name: str):
self._find_saved_address_and_open_menu(name)
click_obj_by_name(SavedAddressesScreen.DELETE.value)
click_obj_by_name(SavedAddressesScreen.CONFIRM_DELETE.value)
self.left_panel.open_saved_addresses().delete_saved_address(name)
def toggle_favourite_for_saved_address(self, name: str):
# Find the saved address and click favourite to toggle
@ -473,103 +411,58 @@ class StatusWalletScreen:
assert False, "network name not found"
def click_default_wallet_account(self):
accounts = get_obj(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
click_obj(accounts.itemAtIndex(0))
def click_wallet_account(self, account_name: str):
accounts = get_obj(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
for index in range(accounts.count):
if(accounts.itemAtIndex(index).objectName == "walletAccount-" + account_name):
click_obj(accounts.itemAtIndex(index))
return
#####################################
### Verifications region:
#####################################
def remove_account_popup_verify_account_account_to_be_removed(self, name: str, path: str):
objNotification = wait_and_get_obj(RemoveAccountPopup.ACCOUNT_NOTIFICATION.value)
displayedNotification = str(objNotification.text)
if name not in displayedNotification:
verify_failure("Remove account popup doesn't refer to an account with name: " + name)
if path != NOT_APPLICABLE:
objPath = get_obj(RemoveAccountPopup.ACCOUNT_PATH.value)
if path != objPath.text:
verify_failure("Remove account popup doesn't refer to an account with path: " + path)
def verify_account_existence(self, name: str, color: str, emoji_unicode: str):
[compLoaded, accNameObj] = is_loaded_visible_and_enabled(MainWalletScreen.ACCOUNT_NAME.value)
if not compLoaded:
verify_failure("cannot find account name on the right, most likely the account we're searching for is not selected")
return
do_until_validation_with_timeout(
lambda: time.sleep(0.5),
lambda: accNameObj.text == name,
"selected account match",
5000)
expected_account = constants.wallet.account_list_item(name, color.lower(), emoji_unicode)
started_at = time.monotonic()
while not expected_account in self.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 5:
raise LookupError(f'Account {expected_account} not found in {self.left_panel.accounts}')
is_loaded_visible_and_enabled(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
accounts = get_obj(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
for index in range(accounts.count):
acc = accounts.itemAtIndex(index)
if(acc.objectName == "walletAccount-" + name):
verify_equal(str(acc.title), name, "Account displays the expected name")
verify_equal(str(acc.asset.color.name), str(color.lower()), "Account displays the expected color")
verify_equal((True if emoji_unicode in str(acc.asset.emoji) else False), True, "Account displays the expected emoji")
return
def verify_account_doesnt_exist(self, name: str):
is_loaded_visible_and_enabled(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
accounts = get_obj(MainWalletScreen.WALLET_ACCOUNTS_LIST.value)
for index in range(accounts.count):
acc = accounts.itemAtIndex(index)
if(acc.objectName == "walletAccount-" + name):
verify_failure("Account with " + name + " is still displayed even it should not be")
assert name not in [account.name for account in self.left_panel.accounts], \
f'Account with {name} is still displayed even it should not be'
def verify_account_address_correct(self, account_name: str, address: str):
actual_address = self.left_panel.select_account(account_name).address
assert actual_address.lower() == address.lower(), f'Account {account_name} has unexpected address {actual_address}'
def verify_keycard_settings_is_opened(self):
[compLoaded, accNameObj] = is_loaded_visible_and_enabled(SidebarComponents.KEYCARD_OPTION.value)
if not compLoaded:
verify_failure("keycard option from the app settings cannot be found")
return
verify(bool(accNameObj.selected), "keycard option from the app settings is displayed")
def verify_account_balance_is_positive(self, list, symbol: str) -> Tuple(bool, ):
if list is None:
return (False, )
return (False,)
for index in range(list.count):
tokenListItem = list.itemAtIndex(index)
if tokenListItem != None and tokenListItem.item != None and tokenListItem.item.objectName == "AssetView_LoadingTokenDelegate_"+str(index):
return (False, )
if tokenListItem != None and tokenListItem.item != None and tokenListItem.item.objectName == "AssetView_LoadingTokenDelegate_" + str(
index):
return (False,)
if tokenListItem != None and tokenListItem.item != None and tokenListItem.item.objectName == "AssetView_TokenListItem_" + symbol and tokenListItem.item.balance != "0":
return (True, tokenListItem)
return (False, )
return (False,)
def verify_positive_balance(self, symbol: str):
is_loaded_visible_and_enabled(AssetView.LIST.value, 5000)
list = get_obj(AssetView.LIST.value)
do_until_validation_with_timeout(lambda: time.sleep(0.1), lambda: self.verify_account_balance_is_positive(list, symbol)[0], "Symbol " + symbol + " not found in the asset list", 5000)
do_until_validation_with_timeout(lambda: time.sleep(0.1),
lambda: self.verify_account_balance_is_positive(list, symbol)[0],
"Symbol " + symbol + " not found in the asset list", 5000)
def verify_saved_address_exists(self, name: str):
list = wait_and_get_obj(SavedAddressesScreen.SAVED_ADDRESSES_LIST.value)
for index in range(list.count):
if list.itemAtIndex(index).objectName == f"savedAddressView_Delegate_{name}":
return
verify_failure(f'FAIL: saved address {name} not found"')
assert wait_for(name in self.left_panel.open_saved_addresses().address_names), f'Address: {name} not found'
def verify_saved_address_doesnt_exist(self, name: str):
# The list should be hidden when there are no saved addresses
try:
list = wait_and_get_obj(SavedAddressesScreen.SAVED_ADDRESSES_LIST.value, 250)
except LookupError:
return
list = wait_and_get_obj(SavedAddressesScreen.SAVED_ADDRESSES_LIST.value)
for index in range(list.count):
if list.itemAtIndex(index).objectName == f"savedAddressView_Delegate_{name}":
verify_failure(f'FAIL: saved address {name} exists')
assert wait_for(name not in self.left_panel.open_saved_addresses().address_names), f'Address: {name} found'
def verify_transaction(self):
pass
@ -582,7 +475,7 @@ class StatusWalletScreen:
tabbar = get_obj(MainWalletScreen.RIGHT_SIDE_TABBAR.value)
click_obj(tabbar.itemAt(WalletTabBar.COLLECTION_TAB.value))
collectionsRepeater = get_obj(CollectiblesView.COLLECTIONS_REPEATER.value)
if(collectionsRepeater.count > 0):
if (collectionsRepeater.count > 0):
collectionsRepeater.itemAt(0).expanded = True
collectiblesRepeater = get_obj(CollectiblesView.COLLECTIBLES_REPEATER.value)
verify(collectiblesRepeater.count > 0, "Collectibles not retrieved for the account")
@ -593,7 +486,7 @@ class StatusWalletScreen:
transaction_list_view = get_obj(TransactionsView.TRANSACTIONS_LISTVIEW.value)
wait_for("transaction_list_view.count > 0", 60*1000)
wait_for("transaction_list_view.count > 0", 60 * 1000)
verify(transaction_list_view.count > 1, "Transactions not retrieved for the account")
transaction_item = transaction_list_view.itemAtIndex(1)
@ -606,4 +499,3 @@ class StatusWalletScreen:
verify_equal(transaction_item.item.shortTimeStamp, transaction_detail_header.shortTimeStamp)
verify_equal(transaction_item.item.fiatValue, transaction_detail_header.fiatValue)
verify_equal(transaction_item.item.symbol, transaction_detail_header.symbol)

View File

@ -0,0 +1,20 @@
import constants
from drivers.SquishDriver import *
class AuthenticatePopup(BaseElement):
def __init__(self):
super(AuthenticatePopup, self).__init__('contextMenu_PopupItem')
self._password_text_edit = TextEdit('sharedPopup_Password_Input')
self._primary_button = Button('sharedPopup_Primary_Button')
self._cancel_buttom = Button('sharedPopup_Cancel_Button')
def authenticate(self, password: str = constants.user_account.PASSWORD):
self._password_text_edit.text = password
self._primary_button.click()
self._primary_button.wait_until_hidden()
def cancel(self):
self._cancel_buttom.click()
self._cancel_buttom.wait_until_hidden()

View File

@ -0,0 +1,79 @@
import typing
import configs
from drivers.SquishDriver import *
from .base_popup import BasePopup
class BackUpYourSeedPhrasePopUp(BasePopup):
def __init__(self):
super(BackUpYourSeedPhrasePopUp, self).__init__()
self._i_have_a_pen_and_paper_check_box = CheckBox('mainWallet_AddEditAccountPopup_HavePenAndPaperCheckBox')
self._i_know_where_i_ll_store_it_check_box = CheckBox(
'mainWallet_AddEditAccountPopup_StoringSeedPhraseConfirmedCheckBox')
self._i_am_ready_to_write_down_seed_phrase_check_box = CheckBox(
'mainWallet_AddEditAccountPopup_SeedPhraseWrittenCheckBox')
self._primary_button = Button('mainWallet_AddEditAccountPopup_PrimaryButton')
self._reveal_seed_phrase_button = Button('mainWallet_AddEditAccountPopup_RevealSeedPhraseButton')
self._seed_phrase_panel = BaseElement('confirmSeedPhrasePanel_StatusSeedPhraseInput')
self._seed_phrase_word_component = BaseElement('mainWallet_AddEditAccountPopup_EnterSeedPhraseWordComponent')
self._prove_word_seed_phrase_text_edit = TextEdit('mainWallet_AddEditAccountPopup_EnterSeedPhraseWord')
self._acknowledge_check_box = CheckBox('mainWallet_AddEditAccountPopup_SeedBackupAknowledgeCheckBox')
self._seed_phrase_name_text_edit = TextEdit('mainWallet_AddEditAccountPopup_GeneratedSeedPhraseKeyName')
def set_have_pen_and_paper(self, value: bool):
self._i_have_a_pen_and_paper_check_box.set(value)
return self
def set_ready_to_write_seed_phrase(self, value: bool):
self._i_am_ready_to_write_down_seed_phrase_check_box.set(value)
return self
def set_know_where_store_it(self, value: bool):
self._i_know_where_i_ll_store_it_check_box.set(value)
return self
def next(self):
self._primary_button.click()
return self
def reveal_seed_phrase(self):
self._reveal_seed_phrase_button.click()
return self
def get_seed_phrases(self):
phrases = []
for phrase_n in range(1, 13):
object_name = f'SeedPhraseWordAtIndex-{phrase_n}'
self._seed_phrase_panel.object_name['objectName'] = object_name
phrases.append(str(self._seed_phrase_panel.object.textEdit.input.edit.text))
return phrases
def confirm_word(self, seed_phrase: typing.List[str]):
word_index = int(str(self._seed_phrase_word_component.object.label).split('Word #')[1])
seed_word = seed_phrase[word_index - 1]
self._prove_word_seed_phrase_text_edit.text = seed_word
return self
def set_acknowledge(self, value: bool):
self._acknowledge_check_box.set(value)
return self
def set_seed_phrase_name(self, value: str):
self._seed_phrase_name_text_edit.text = value
return self
def wait_until_hidden(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
self._seed_phrase_name_text_edit.wait_until_hidden()
def generate_seed_phrase(self, name: str):
self.set_have_pen_and_paper(True).set_ready_to_write_seed_phrase(True).set_know_where_store_it(True)
self.next().reveal_seed_phrase()
seed_phrases = self.get_seed_phrases()
self.next().confirm_word(seed_phrases)
self.next().confirm_word(seed_phrases)
self.next().set_acknowledge(True)
self.next().set_seed_phrase_name(name)
self.next().wait_until_hidden()

View File

@ -0,0 +1,11 @@
from drivers.SquishDriver import *
class BasePopup(BaseElement):
def __init__(self):
super(BasePopup, self).__init__('statusDesktop_mainWindow_overlay')
def close(self):
squish.nativeType('<Escape>')
self.wait_until_hidden()

View File

@ -1,10 +1,12 @@
from drivers.SquishDriver import *
from .base_popup import BasePopup
class ChangePasswordPopup(BaseElement):
class ChangePasswordPopup(BasePopup):
def __init__(self):
super(ChangePasswordPopup, self).__init__('statusDesktop_mainWindow_overlay')
super(ChangePasswordPopup, self).__init__()
self._current_password_text_field = TextEdit('change_password_menu_current_password')
self._new_password_text_field = TextEdit('change_password_menu_new_password')
self._confirm_password_text_field = TextEdit('change_password_menu_new_password_confirm')
@ -16,4 +18,4 @@ class ChangePasswordPopup(BaseElement):
self._new_password_text_field.text = new_pwd
self._confirm_password_text_field.text = new_pwd
self._submit_button.click()
self._quit_button.wait_until_appears(15000).click()
self._quit_button.wait_until_appears(15000).click()

View File

@ -0,0 +1,12 @@
from drivers.SquishDriver import *
class ConfirmationPopup(BaseElement):
def __init__(self):
super(ConfirmationPopup, self).__init__('contextMenu_PopupItem')
self._confirm_button = Button('confirmButton')
def confirm(self):
self._confirm_button.click()
self.wait_until_hidden()

View File

@ -0,0 +1,12 @@
from drivers.SquishDriver import *
class ContextMenu(BaseElement):
def __init__(self):
super(ContextMenu, self).__init__('contextMenu_PopupItem')
self._menu_item = BaseElement('contextMenuItem')
def select(self, value: str):
self._menu_item.object_name['text'] = value
self._menu_item.click()

View File

@ -0,0 +1,21 @@
import configs
from drivers.SquishDriver import *
from .base_popup import BasePopup
class EmojiPopup(BasePopup):
def __init__(self):
super(EmojiPopup, self).__init__()
self._search_text_edit = TextEdit('mainWallet_AddEditAccountPopup_AccountEmojiSearchBox')
self._emoji_item = BaseElement('mainWallet_AddEditAccountPopup_AccountEmoji')
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
self._search_text_edit.wait_until_appears(timeout_msec)
return self
def select(self, name: str):
self._search_text_edit.text = name
self._emoji_item.object_name['objectName'] = 'statusEmoji_' + name
self._emoji_item.click()
self._search_text_edit.wait_until_hidden()

View File

@ -0,0 +1,29 @@
from drivers.SquishDriver import *
from .authenticate_popup import AuthenticatePopup
from .base_popup import BasePopup
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')
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
self._cancel_button.wait_until_appears(timeout_msec)
return self
def confirm(self):
self._confirm_button.click()
self._confirm_button.wait_until_hidden()
def cancel(self):
self._cancel_button.click()
self._cancel_button.wait_until_hidden()
def agree_and_confirm(self):
self._have_pen_paper_checkbox.wait_until_appears().set(True)
self.confirm()

View File

@ -0,0 +1,35 @@
from drivers.SquishDriver import *
from .base_popup import BasePopup
class SavedAddressPopup(BasePopup):
def __init__(self):
super(SavedAddressPopup, self).__init__()
self._name_text_edit = TextEdit('mainWallet_Saved_Addreses_Popup_Name_Input')
self._save_add_address_button = Button('mainWallet_Saved_Addreses_Popup_Address_Add_Button')
class AddSavedAddressPopup(SavedAddressPopup):
def __init__(self):
super(AddSavedAddressPopup, self).__init__()
self._address_text_edit = TextEdit('mainWallet_Saved_Addreses_Popup_Address_Input_Edit')
def add_saved_address(self, name: str, address: str):
self._name_text_edit.text = name
self._address_text_edit.clear(verify=False)
self._address_text_edit.type_text(address)
self._save_add_address_button.click()
self.wait_until_hidden()
class EditSavedAddressPopup(SavedAddressPopup):
def __init__(self):
super(EditSavedAddressPopup, self).__init__()
self._address_text_label = TextLabel('mainWallet_Saved_Addreses_Popup_Address_Input_Edit')
def edit_saved_address(self, name: str):
self._name_text_edit.text = name
self._save_add_address_button.click()
self.wait_until_hidden()

View File

@ -2,11 +2,13 @@ import typing
from drivers.SquishDriver import *
from .base_popup import BasePopup
class SocialLinksPopup(BaseElement):
class SocialLinksPopup(BasePopup):
def __init__(self):
super(SocialLinksPopup, self).__init__('statusDesktop_mainWindow_overlay')
super(SocialLinksPopup, self).__init__()
self._add_social_link_list_item = BaseElement('socialLink_StatusListItem')
self._social_link_text_field = TextEdit('edit_TextEdit')
self._add_button = Button('add_StatusButton')

View File

@ -0,0 +1,195 @@
import typing
import configs
import constants
import squish
from drivers.SquishDriver import *
from .authenticate_popup import AuthenticatePopup
from .back_up_your_seed_phrase_popup import BackUpYourSeedPhrasePopUp
from .base_popup import BasePopup
from .emoji_popup import EmojiPopup
GENERATED_LPAGES_LIMIT = 20
class GeneratedAddressesList(BaseElement):
def __init__(self):
super(GeneratedAddressesList, self).__init__('statusDesktop_mainWindow_overlay_popup2')
self._address_list_item = BaseElement('addAccountPopup_GeneratedAddress')
self._paginator_page = BaseElement('page_StatusBaseButton')
@property
def is_paginator_load(self) -> bool:
try:
return str(squish.findAllObjects(self._paginator_page.object_name)[0].text) == '1'
except IndexError:
return False
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
if 'text' in self._paginator_page.object_name:
del self._paginator_page.object_name['text']
assert squish.waitFor(lambda: self.is_paginator_load, timeout_msec), 'Generated address list not load'
return self
def select(self, index: int):
self._address_list_item.object_name['objectName'] = f'AddAccountPopup-GeneratedAddress-{index}'
selected_page_number = 1
while selected_page_number != GENERATED_LPAGES_LIMIT:
if self._address_list_item.is_visible:
self._address_list_item.click()
self._paginator_page.wait_until_hidden()
break
else:
selected_page_number += 1
self._paginator_page.object_name['text'] = selected_page_number
self._paginator_page.click()
class AddNewAccountPopup(BasePopup):
def __init__(self):
super(AddNewAccountPopup, self).__init__()
self._import_private_key_button = Button('mainWallet_AddEditAccountPopup_MasterKey_ImportPrivateKeyOption')
self._import_seed_phrase_button = Button('mainWallet_AddEditAccountPopup_MasterKey_ImportSeedPhraseOption')
self._private_key_text_edit = TextEdit('mainWallet_AddEditAccountPopup_PrivateKey')
self._private_key_name_text_edit = TextEdit('mainWallet_AddEditAccountPopup_PrivateKeyName')
self._generate_master_key_button = Button('mainWallet_AddEditAccountPopup_MasterKey_GenerateSeedPhraseOption')
self._continue_button = Button('mainWallet_AddEditAccountPopup_PrimaryButton')
self._seed_phrase_12_words_button = Button("mainWallet_AddEditAccountPopup_12WordsButton")
self._seed_phrase_18_words_button = Button("mainWallet_AddEditAccountPopup_18WordsButton")
self._seed_phrase_24_words_button = Button("mainWallet_AddEditAccountPopup_24WordsButton")
self._seed_phrase_word_text_edit = TextEdit('mainWallet_AddEditAccountPopup_SPWord')
self._seed_phrase_phrase_key_name_text_edit = TextEdit(
'mainWallet_AddEditAccountPopup_ImportedSeedPhraseKeyName')
def import_private_key(self, private_key: str) -> str:
self._import_private_key_button.click()
self._private_key_text_edit.text = private_key
self._private_key_name_text_edit.text = private_key[:5]
self._continue_button.click()
return private_key[:5]
def import_new_seed_phrase(self, seed_phrase_words: list) -> str:
self._import_seed_phrase_button.click()
if len(seed_phrase_words) == 12:
self._seed_phrase_12_words_button.click()
elif len(seed_phrase_words) == 18:
self._seed_phrase_18_words_button.click()
elif len(seed_phrase_words) == 24:
self._seed_phrase_24_words_button.click()
else:
raise RuntimeError("Wrong amount of seed words", len(seed_phrase_words))
for count, word in enumerate(seed_phrase_words, start=1):
self._seed_phrase_word_text_edit.object_name['objectName'] = f'statusSeedPhraseInputField{count}'
self._seed_phrase_word_text_edit.text = word
seed_phrase_name = ''.join([word[0] for word in seed_phrase_words[:10]])
self._seed_phrase_phrase_key_name_text_edit.text = seed_phrase_name
self._continue_button.click()
return seed_phrase_name
def generate_new_master_key(self, name: str):
self._generate_master_key_button.click()
BackUpYourSeedPhrasePopUp().wait_until_appears().generate_seed_phrase(name)
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 = BaseElement('color_StatusColorRadioButton')
# origin
self._origin_combobox = BaseElement('mainWallet_AddEditAccountPopup_SelectedOrigin')
self._watch_only_account_origin_item = BaseElement("mainWallet_AddEditAccountPopup_OriginOptionWatchOnlyAcc")
self._new_master_key_origin_item = BaseElement('mainWallet_AddEditAccountPopup_OriginOptionNewMasterKey')
self._existing_origin_item = BaseElement('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 = BaseElement('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')
def set_name(self, value: str):
self._name_text_edit.text = value
return self
def set_color(self, value: str):
if 'radioButtonColor' in self._color_radiobutton.object_name.keys():
del self._color_radiobutton.object_name['radioButtonColor']
colors = [str(item.radioButtonColor) for item in squish.findAllObjects(self._color_radiobutton.object_name)]
assert value in colors, f'Color {value} not found in {colors}'
self._color_radiobutton.object_name['radioButtonColor'] = value
self._color_radiobutton.click()
return self
def set_emoji(self, value: str):
self._emoji_button.click()
EmojiPopup().wait_until_appears().select(value)
return self
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
def set_origin_keypair(self, value: str):
self._origin_combobox.click()
self._existing_origin_item.object_name['objectName'] = f'AddAccountPopup-OriginOption-{value}'
self._existing_origin_item.click()
return self
def set_origin_seed_phrase(self, value: typing.List[str]):
self._origin_combobox.click()
self._new_master_key_origin_item.click()
AddNewAccountPopup().wait_until_appears().import_new_seed_phrase(value)
return self
def set_origin_new_seed_phrase(self, value: str):
self._origin_combobox.click()
self._new_master_key_origin_item.click()
AddNewAccountPopup().wait_until_appears().generate_new_master_key(value)
return self
def set_origin_private_key(self, value: str):
self._origin_combobox.click()
self._new_master_key_origin_item.click()
AddNewAccountPopup().wait_until_appears().import_private_key(value)
return self
def set_derivation_path(self, value: str, index: int):
self._edit_derivation_path_button.click()
AuthenticatePopup().wait_until_appears().authenticate()
if value in [_.value for _ in constants.wallet.DerivationPath]:
self._derivation_path_combobox_button.click()
self._derivation_path_list_item.object_name['title'] = value
self._derivation_path_list_item.click()
del self._derivation_path_list_item.object_name['title']
self._address_combobox_button.click()
GeneratedAddressesList().wait_until_appears().select(index)
if value != constants.wallet.DerivationPath.ETHEREUM.value:
self._scroll.vertical_down_to(self._non_eth_checkbox)
self._non_eth_checkbox.set(True)
else:
self._derivation_path_text_edit.type_text(str(index))
return self
def save(self):
self._add_account_button.click()
return self
def wait_until_appears(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
assert squish.waitFor(lambda: self._name_text_edit.is_visible, timeout_msec), f'Object {self} is not visible'
return self
def wait_until_hidden(self, timeout_msec: int = configs.squish.UI_LOAD_TIMEOUT_MSEC):
assert squish.waitFor(lambda: not self._name_text_edit.is_visible, timeout_msec), f'Object {self} is visible'

View File

@ -0,0 +1,40 @@
import time
count = 2
def attempt(count):
_count = count
def _wrapper(method_to_decorate):
def wrapper(*args, **kwargs):
try:
return method_to_decorate(*args, **kwargs)
except:
global count
if count:
count -= 1
time.sleep(1)
return wrapper(*args, **kwargs)
else:
raise
return wrapper
return _wrapper
def close_exists(element):
def _wrapper(method_to_decorate):
def wrapper(*args, **kwargs):
if element.is_visible:
element.close()
return method_to_decorate(*args, **kwargs)
return wrapper
return _wrapper

View File

@ -1,6 +1,6 @@
import drivers.SquishDriverVerification as verifier
import os
from typing import Dict, Any
from .global_names import mainWindow_RighPanel
@ -8,11 +8,12 @@ def verify_screenshot(func, obj: Dict[str, Any] = mainWindow_RighPanel):
def inner(*args, **kwargs):
context = args[0]
func(*args, **kwargs)
scenario = context.userData["feature_name"].lower().replace(" ", "_")
step = context.userData["step_name"].lower().replace(" ", "_")
step = getattr(context.userData, "step_name", '').lower().replace(" ", "_")
filename = f"{step}_{'_'.join(args[1:])}"
path = os.path.join(scenario, filename)
# verifier.verify_or_create_screenshot(path, obj)
# verifier.verify_or_create_screenshot(path, obj)
return inner

View File

@ -1,6 +1,10 @@
from objectmaphelper import *
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}
statusDesktop_mainWindow_overlay_popup = {"container": statusDesktop_mainWindow_overlay, "type": "PopupItem", "unnamed": 1, "visible": True}
statusDesktop_mainWindow_overlay_popup2 = {"container": statusDesktop_mainWindow_overlay, "occurrence": 2, "type": "PopupItem", "unnamed": 1, "visible": True}
mainWindow_navBarListView_ListView = {"container": statusDesktop_mainWindow, "objectName": "statusMainNavBarListView", "type": "ListView", "visible": True}
mainWindow_communityNavBarListView_ListView = {"container": statusDesktop_mainWindow, "objectName": "statusCommunityMainNavBarListView", "type": "ListView", "visible": True}
chatView_log = {"container": statusDesktop_mainWindow, "objectName": "chatLogView", "type": "StatusListView", "visible": True}
@ -18,7 +22,7 @@ viewProfile_MenuItem = {"container": statusDesktop_mainWindow_overlay, "objectNa
mainWindow_ContactsColumn_Messages_Headline = {"container": statusDesktop_mainWindow, "objectName": "ContactsColumnView_MessagesHeadline", "type": "StatusNavigationPanelHeadline"}
# main right panel
mainWindow_RighPanel= {"container": statusDesktop_mainWindow, "type": "ColumnLayout", "objectName": "mainRightView", "visible": True}
mainWindow_RighPanel = {"container": statusDesktop_mainWindow, "type": "ColumnLayout", "objectName": "mainRightView", "visible": True}
# Navigation Panel
mainWindow_StatusAppNavBar = {"container": statusDesktop_mainWindow, "type": "StatusAppNavBar", "unnamed": 1, "visible": True}
@ -68,3 +72,14 @@ ProfilePopup_SendContactRequestButton = {"container": statusDesktop_mainWindow_o
# Banners
mainWindow_secureYourSeedPhraseBanner_ModuleWarning = {"container": statusDesktop_mainWindow, "objectName": "secureYourSeedPhraseBanner", "type": "ModuleWarning", "visible": True}
# Context Menu
contextMenu_PopupItem = {"container": statusDesktop_mainWindow_overlay, "type": "PopupItem", "unnamed": 1, "visible": True}
contextMenuItem = {"container": statusDesktop_mainWindow_overlay, "type": "StatusBaseText", "unnamed": 1, "visible": True}
# Confirmation Popup
confirmButton = {"container": statusDesktop_mainWindow_overlay, "objectName": RegularExpression("confirm*"), "type": "StatusButton"}
# Emoji Popup
mainWallet_AddEditAccountPopup_AccountEmojiSearchBox = {"container": statusDesktop_mainWindow, "objectName": "StatusEmojiPopup_searchBox", "type": "TextEdit", "visible": True}
mainWallet_AddEditAccountPopup_AccountEmoji = {"container": statusDesktop_mainWindow, "type": "StatusEmoji", "visible": True}

View File

@ -60,4 +60,4 @@ onboarding_SeedPhrase_Input_TextField_20 = {"container": statusDesktop_mainWindo
onboarding_SeedPhrase_Input_TextField_21 = {"container": statusDesktop_mainWindow, "type": "TextEdit", "objectName": "statusSeedPhraseInputField21"}
onboarding_SeedPhrase_Input_TextField_22 = {"container": statusDesktop_mainWindow, "type": "TextEdit", "objectName": "statusSeedPhraseInputField22"}
onboarding_SeedPhrase_Input_TextField_23 = {"container": statusDesktop_mainWindow, "type": "TextEdit", "objectName": "statusSeedPhraseInputField23"}
onboarding_SeedPhrase_Input_TextField_24 = {"container": statusDesktop_mainWindow, "type": "TextEdit", "objectName": "statusSeedPhraseInputField24"}
onboarding_SeedPhrase_Input_TextField_24 = {"container": statusDesktop_mainWindow, "type": "TextEdit", "objectName": "statusSeedPhraseInputField24"}

View File

@ -1,3 +1,4 @@
from objectmaphelper import *
from scripts.global_names import *
from enum import Enum
@ -36,6 +37,7 @@ settingsContentBaseScrollView_Item = {"container": settingsContentBase_ScrollVie
mainWindow_LeftTabView = {"container": statusDesktop_mainWindow, "type": "LeftTabView", "unnamed": 1, "visible": True}
LeftTabView_ScrollView = {"container": mainWindow_LeftTabView, "type": "StatusScrollView", "unnamed": 1, "visible": True}
# ENS view;
settings_ENS_Start_Button = {"container": statusDesktop_mainWindow, "objectName": "ensStartButton", "type": "StatusButton"}
settings_ENS_Search_Input = {"container": statusDesktop_mainWindow, "objectName": "ensUsernameInput", "type": "StyledTextField"}
@ -86,7 +88,10 @@ linksView = {"container": statusDesktop_mainWindow, "id": "linksView", "type": "
edit_TextEdit = {"container": statusDesktop_mainWindow_overlay, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
# Wallet Settings:
settings_Wallet_MainView_GeneratedAccounts = {"container": statusDesktop_mainWindow, "objectName":'generatedAccounts', "type": 'ListView'}
mainWallet_Saved_Addreses_More_Edit = {"container": statusDesktop_mainWindow, "objectName": "editroot", "type": "StatusMenuItem"}
mainWallet_Saved_Addreses_More_Delete = {"container": statusDesktop_mainWindow, "objectName": "deleteSavedAddress", "type": "StatusMenuItem"}
mainWallet_Saved_Addreses_More_Confirm_Delete = {"container": statusDesktop_mainWindow, "objectName": "confirmDeleteSavedAddress", "type": "StatusButton"}
settings_Wallet_MainView_GeneratedAccounts = {"container": statusDesktop_mainWindow, "objectName": 'generatedAccounts', "type": 'ListView'}
settings_Wallet_AccountView_DeleteAccount = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "deleteAccountButton"}
settings_Wallet_AccountView_DeleteAccount_Confirm = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "confirmDeleteAccountButton"}
mainWindow_ScrollView_2 = {"container": statusDesktop_mainWindow, "occurrence": 2, "type": "StatusScrollView", "unnamed": 1, "visible": True}

View File

@ -1,27 +1,53 @@
from objectmaphelper import *
from scripts.global_names import *
from scripts.settings_names import *
# Main:
mainWindow_WalletLayout = {"container": statusDesktop_mainWindow, "type": "WalletLayout", "unnamed": 1, "visible": True}
mainWallet_LeftTab = {"container": statusDesktop_mainWindow, "objectName": "walletLeftTab", "type": "LeftTabView", "visible": True}
mainWallet_Saved_Addresses_Button = {"container": mainWindow_RighPanel, "objectName": "savedAddressesBtn", "type": "StatusButton"}
walletAccounts_StatusListView = {"container": statusDesktop_mainWindow, "objectName": "walletAccountsListView", "type": "StatusListView", "visible": True}
walletAccounts_WalletAccountItem_Placeholder = {"container": walletAccounts_StatusListView, "objectName": "walletAccount-%NAME%", "type": "StatusListItem", "visible": True}
walletAccount_StatusListItem = {"container": walletAccounts_StatusListView, "objectName": RegularExpression("walletAccount*"), "type": "StatusListItem", "visible": True}
# Context Menu
mainWallet_CopyAddress_MenuItem = {"container": contextMenu_PopupItem, "enabled": True, "objectName": RegularExpression("AccountMenu-CopyAddressAction*"), "type": "StatusMenuItem"}
mainWallet_EditAccount_MenuItem = {"container": contextMenu_PopupItem, "enabled": True, "objectName": RegularExpression("AccountMenu-EditAction*"), "type": "StatusMenuItem"}
mainWallet_DeleteAccount_MenuItem = {"container": contextMenu_PopupItem, "enabled": True, "objectName": RegularExpression("AccountMenu-DeleteAction*"), "type": "StatusMenuItem"}
mainWallet_AddNewAccount_MenuItem = {"container": contextMenu_PopupItem, "enabled": True, "objectName": RegularExpression("AccountMenu-AddNewAccountAction*"), "type": "StatusMenuItem"}
mainWallet_AddWatchOnlyAccount_MenuItem = {"container": contextMenu_PopupItem, "enabled": True, "objectName": RegularExpression("AccountMenu-AddWatchOnlyAccountAction*"), "type": "StatusMenuItem"}
# Saved Address View
mainWindow_SavedAddressesView = {"container": mainWindow_WalletLayout, "type": "SavedAddressesView", "unnamed": 1, "visible": True}
mainWallet_Saved_Addreses_Add_Buttton = {"container": mainWindow_SavedAddressesView, "objectName": "addNewAddressBtn", "type": "StatusButton"}
mainWallet_Saved_Addreses_List = {"container": mainWindow_SavedAddressesView, "objectName": "SavedAddressesView_savedAddresses", "type": "StatusListView"}
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": "", "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}
# Wallet Account Popup
mainWallet_AddEditAccountPopup_derivationPath = {"container": statusDesktop_mainWindow, "objectName": RegularExpression("AddAccountPopup-PreDefinedDerivationPath*"), "type": "StatusListItem", "visible": True}
addAccountPopup_GeneratedAddress = {"container": statusDesktop_mainWindow_overlay_popup2, "type": "Rectangle", "visible": True}
address_0x_StatusBaseText = {"container": statusDesktop_mainWindow_overlay_popup2, "text": RegularExpression("0x*"), "type": "StatusBaseText", "unnamed": 1, "visible": True}
addAccountPopup_GeneratedAddressesListPageIndicatior_StatusPageIndicator = {"container": statusDesktop_mainWindow_overlay_popup2, "objectName": "AddAccountPopup-GeneratedAddressesListPageIndicatior", "type": "StatusPageIndicator", "visible": True}
page_StatusBaseButton = {"checkable": False, "container": addAccountPopup_GeneratedAddressesListPageIndicatior_StatusPageIndicator, "objectName": RegularExpression("Page-*"), "type": "StatusBaseButton", "visible": True}
navBarListView_Wallet_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Wallet-navbar", "type": "StatusNavBarTabButton", "visible": True}
wallet_navbar_wallet_icon_StatusIcon = {"container": navBarListView_Wallet_navbar_StatusNavBarTabButton, "objectName": "wallet-icon", "type": "StatusIcon", "visible": True}
mainWallet_LeftTab = {"container": statusDesktop_mainWindow, "objectName": "walletLeftTab", "type": "LeftTabView", "visible": True}
mainWallet_Account_Name = {"container": statusDesktop_mainWindow, "objectName": "accountName", "type": "StatusBaseText", "visible": True}
mainWallet_Address_Panel = {"container": statusDesktop_mainWindow, "objectName": "addressPanel", "type": "StatusAddressPanel", "visible": True}
mainWallet_Add_Account_Button = {"container": statusDesktop_mainWindow, "objectName": "addAccountButton", "type": "StatusRoundButton", "visible": True}
signPhrase_Ok_Button = {"container": statusDesktop_mainWindow, "type": "StatusFlatButton", "objectName": "signPhraseModalOkButton", "visible": True}
mainWallet_Saved_Addresses_Button = {"container": statusDesktop_mainWindow, "objectName": "savedAddressesBtn", "type": "StatusButton"}
mainWallet_Network_Selector_Button = {"container": statusDesktop_mainWindow, "objectName": "networkSelectorButton", "type": "StatusListItem"}
mainWallet_Right_Side_Tab_Bar = {"container": statusDesktop_mainWindow, "objectName": "rightSideWalletTabBar", "type": "StatusTabBar"}
mainWallet_Ephemeral_Notification_List = {"container": statusDesktop_mainWindow, "objectName": "ephemeralNotificationList", "type": "StatusListView"}
mainWallet_RightClick_CopyAddress_MenuItem_Placeholder = {"container": statusDesktop_mainWindow, "enabled": True, "objectName": "AccountMenu-CopyAddressAction-%NAME%", "type": "StatusMenuItem"}
mainWallet_RightClick_EditAccount_MenuItem_Placeholder = {"container": statusDesktop_mainWindow, "enabled": True, "objectName": "AccountMenu-EditAction-%NAME%", "type": "StatusMenuItem"}
mainWallet_RightClick_DeleteAccount_MenuItem_Placeholder = {"container": statusDesktop_mainWindow, "enabled": True, "objectName": "AccountMenu-DeleteAction-%NAME%", "type": "StatusMenuItem"}
mainWallet_RightClick_AddNewAccount_MenuItem_Placeholder = {"container": statusDesktop_mainWindow, "enabled": True, "objectName": "AccountMenu-AddNewAccountAction-%NAME%", "type": "StatusMenuItem"}
mainWallet_RightClick_AddWatchOnlyAccount_MenuItem_Placeholder = {"container": statusDesktop_mainWindow, "enabled": True, "objectName": "AccountMenu-AddWatchOnlyAccountAction-%NAME%", "type": "StatusMenuItem"}
walletAccounts_StatusListView = {"container": statusDesktop_mainWindow, "objectName": "walletAccountsListView", "type": "StatusListView", "visible": True}
walletAccounts_WalletAccountItem_Placeholder = {"container": walletAccounts_StatusListView, "objectName": "walletAccount-%NAME%", "type": "StatusListItem", "visible": True}
# Assets view:
mainWallet_Assets_View_List = {"container": statusDesktop_mainWindow, "objectName": "assetViewStatusListView", "type": "StatusListView"}
@ -43,19 +69,24 @@ mainWallet_Send_Popup_Asset_List = {"container": statusDesktop_mainWindow, "obje
mainWallet_Send_Popup_GasPrice_Input = {"container": statusDesktop_mainWindow, "objectName": "gasPriceSelectorInput", "type": "StyledTextField"}
# 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, "id": "edit", "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}
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_AccountEmojiSearchBox = {"container": statusDesktop_mainWindow, "objectName": "StatusEmojiPopup_searchBox", "type": "TextEdit", "visible": True}
mainWallet_AddEditAccountPopup_AccountEmoji = {"container": statusDesktop_mainWindow, "objectName": "statusEmoji_%NAME%", "type": "StatusEmoji", "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, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
@ -89,7 +120,8 @@ mainWallet_AddEditAccountPopup_RevealSeedPhraseButton = {"container": mainWallet
mainWallet_AddEditAccountPopup_SeedPhraseWordAtIndex_Placeholder = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "SeedPhraseWordAtIndex-%WORD-INDEX%", "type": "StatusSeedPhraseInput", "visible": True}
mainWallet_AddEditAccountPopup_EnterSeedPhraseWordComponent = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-EnterSeedPhraseWord", "type": "StatusInput", "visible": True}
mainWallet_AddEditAccountPopup_EnterSeedPhraseWord = {"container": mainWallet_AddEditAccountPopup_EnterSeedPhraseWordComponent, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
confirmSeedPhrasePanel_StatusSeedPhraseInput = {"container": statusDesktop_mainWindow, "type": "StatusSeedPhraseInput", "visible": True}
mainWallet_AddEditAccountPopup_SPWord = {"container": mainWallet_AddEditAccountPopup_Content, "type": "TextEdit", "objectName": RegularExpression("statusSeedPhraseInputField*")}
mainWallet_AddEditAccountPopup_12WordsButton = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "12SeedButton", "type": "StatusSwitchTabButton"}
mainWallet_AddEditAccountPopup_18WordsButton = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "18SeedButton", "type": "StatusSwitchTabButton"}
mainWallet_AddEditAccountPopup_24WordsButton = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "24SeedButton", "type": "StatusSwitchTabButton"}
@ -126,13 +158,6 @@ mainWallet_Remove_Account_Popup_HavePenPaperCheckBox = {"checkable": True, "cont
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}
# saved address view
mainWallet_Saved_Addreses_Add_Buttton = {"container": statusDesktop_mainWindow, "objectName": "addNewAddressBtn", "type": "StatusButton"}
mainWallet_Saved_Addreses_List = {"container": statusDesktop_mainWindow, "objectName": "SavedAddressesView_savedAddresses", "type": "StatusListView"}
mainWallet_Saved_Addreses_More_Edit = {"container": statusDesktop_mainWindow, "objectName": "editroot", "type": "StatusMenuItem"}
mainWallet_Saved_Addreses_More_Delete = {"container": statusDesktop_mainWindow, "objectName": "deleteSavedAddress", "type": "StatusMenuItem"}
mainWallet_Saved_Addreses_More_Confirm_Delete = {"container": statusDesktop_mainWindow, "objectName": "confirmDeleteSavedAddress", "type": "StatusButton"}
# saved address add 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"}
@ -146,7 +171,8 @@ mainWallet_Collectibles_Repeater = {"container": statusDesktop_mainWindow, "obje
# Shared Popup
sharedPopup_Popup_Content = {"container": statusDesktop_mainWindow, "objectName": "KeycardSharedPopupContent", "type": "Item"}
sharedPopup_Password_Input = {"container": sharedPopup_Popup_Content, "objectName": "keycardPasswordInput", "type": "TextField"}
sharedPopup_Primary_Button = {"container": statusDesktop_mainWindow, "objectName": "PrimaryButton", "type": "StatusButton"}
sharedPopup_Primary_Button = {"container": statusDesktop_mainWindow, "objectName": "PrimaryButton", "type": "StatusButton", "visible": True, "enabled": True}
sharedPopup_Cancel_Button = {"container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "id": "cancelButton", "visible": True}
# Transactions view
mainWallet_Transactions_List = {"container": statusDesktop_mainWindow, "objectName": "walletAccountTransactionList", "type": "StatusListView"}

View File

@ -1,9 +1,7 @@
# encoding: UTF-8
from objectmaphelper import *
from scripts.login_names import *
from scripts.onboarding_names import *
from scripts.settings_names import *
from scripts.login_names import *
from wallet_names import *
from scripts.wallet_names import *

View File

@ -1,15 +1,16 @@
import walletInitSteps as wallet_init_steps
from common.Common import str_to_bool
from screens.StatusMainScreen import StatusMainScreen
from screens.StatusWalletScreen import StatusWalletScreen
from screens.StatusWalletScreen import MainWalletRightClickMenu
from screens.StatusWalletScreen import NOT_APPLICABLE, VALUE_YES
from screens.StatusWalletScreen import VALUE_YES
from screens.components.authenticate_popup import AuthenticatePopup
from scripts.decorators import verify_screenshot
from common.Common import str_to_bool
import walletInitSteps as wallet_init_steps
_statusMain = StatusMainScreen()
_walletScreen = StatusWalletScreen()
#########################
### PRECONDITIONS region:
#########################
@ -18,6 +19,7 @@ _walletScreen = StatusWalletScreen()
def step(context):
the_user_accepts_the_signing_phrase()
#########################
### ACTIONS region:
#########################
@ -30,98 +32,125 @@ def step(context):
def step(context):
_walletScreen.click_default_wallet_account()
@When("the user selects wallet account with \"|any|\"")
def step(context, name):
_walletScreen.left_panel.select_account(name)
@When("the user adds a watch only account \"|any|\" with \"|any|\" color \"|any|\" and emoji \"|any|\" via \"|any|\"")
@verify_screenshot
def step(context, address, name, color, emoji, via_right_click_menu):
if via_right_click_menu == VALUE_YES:
_walletScreen.click_option_from_left_part_right_click_menu(MainWalletRightClickMenu.ADD_WATCH_ONLY_ACCOUNT_ACTION_PLACEHOLDER.value)
account_popup = _walletScreen.left_panel.open_add_watch_anly_account_popup()
else:
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
_walletScreen.add_account_popup_set_watch_only_account_as_selected_origin(address)
_walletScreen.add_account_popup_do_primary_action()
account_popup = _walletScreen.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()
@When("the user adds a generated account with \"|any|\" color \"|any|\" and emoji \"|any|\" via \"|any|\" using password \"|any|\"")
@When("the user adds a generated account with \"|any|\" color \"|any|\" and emoji \"|any|\" via \"|any|\"")
@verify_screenshot
def step(context, name, color, emoji, via_right_click_menu, password):
def step(context, name, color, emoji, via_right_click_menu):
if via_right_click_menu == VALUE_YES:
_walletScreen.click_option_from_left_part_right_click_menu(MainWalletRightClickMenu.ADD_NEW_ACCOUNT_ACTION_PLACEHOLDER.value)
account_popup = _walletScreen.left_panel.open_add_new_account_popup()
else:
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
_walletScreen.add_account_popup_do_primary_action(password)
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup.set_name(name).set_emoji(emoji).set_color(color).save()
AuthenticatePopup().wait_until_appears().authenticate()
account_popup.wait_until_hidden()
@When("the user adds to \"|any|\" a custom generated account with \"|any|\" color \"|any|\" and emoji \"|any|\" using password \"|any|\" and setting custom path index \"|any|\" or selecting address with \"|any|\" using \"|any|\"")
@verify_screenshot
def step(context, keypair_name, name, color, emoji, password, index, order, is_ethereum_root):
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
if keypair_name != NOT_APPLICABLE:
_walletScreen.add_account_popup_change_origin_by_keypair_name(keypair_name)
_walletScreen.add_account_popup_open_edit_derivation_path_section(password)
_walletScreen.add_account_popup_change_derivation_path(index, order, is_ethereum_root)
_walletScreen.add_account_popup_do_primary_action()
@When("the user adds a private key account \"|any|\" with \"|any|\" color \"|any|\" and emoji \"|any|\" using password \"|any|\" making keypair with name \"|any|\"")
@When("the user adds a private key account \"|any|\" with \"|any|\" color \"|any|\" and emoji \"|any|\"")
@verify_screenshot
def step(context, private_key, name, color, emoji, password, keypair_name):
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
_walletScreen.add_account_popup_set_new_private_key_as_selected_origin(private_key, keypair_name)
_walletScreen.add_account_popup_do_primary_action(password)
def step(context, private_key, name, color, emoji):
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup.set_name(name).set_emoji(emoji).set_color(color).set_origin_private_key(private_key).save()
AuthenticatePopup().wait_until_appears().authenticate()
account_popup.wait_until_hidden()
@When("the user adds an imported seed phrase account \"|any|\" with \"|any|\" color \"|any|\" and emoji \"|any|\" using password \"|any|\" making keypair with name \"|any|\"")
@verify_screenshot
def step(context, seed_phrase, name, color, emoji, password, keypair_name):
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
_walletScreen.add_account_popup_set_new_seed_phrase_as_selected_origin(seed_phrase, keypair_name)
_walletScreen.add_account_popup_do_primary_action(password)
@When("the user adds a generated seed phrase account with \"|any|\" color \"|any|\" and emoji \"|any|\" using password \"|any|\" making keypair with name \"|any|\"")
@When("the user adds an imported seed phrase account \"|any|\" with \"|any|\" color \"|any|\" and emoji \"|any|\"")
@verify_screenshot
def step(context, name, color, emoji, password, keypair_name):
_walletScreen.open_add_account_popup()
_walletScreen.add_account_popup_change_account_name(name)
_walletScreen.add_account_popup_change_account_color(color)
_walletScreen.add_account_popup_change_account_emoji(emoji)
_walletScreen.add_account_popup_set_generated_seed_phrase_as_selected_origin(keypair_name)
_walletScreen.add_account_popup_do_primary_action(password)
def step(context, seed_phrase, name, color, emoji):
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup \
.set_name(name) \
.set_emoji(emoji) \
.set_color(color) \
.set_origin_seed_phrase(seed_phrase.split()) \
.save()
AuthenticatePopup().wait_until_appears().authenticate()
account_popup.wait_until_hidden()
@When("the user adds a custom generated account with \"|any|\" color \"|any|\" emoji \"|any|\" and derivation \"|any|\" \"|any|\"")
@verify_screenshot
def step(context, name, color, emoji, derivation_path, generated_address_index):
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup \
.set_name(name) \
.set_emoji(emoji) \
.set_color(color) \
.set_derivation_path(derivation_path, generated_address_index) \
.save()
@When("the user adds to \"|any|\" a custom generated account with \"|any|\" color \"|any|\" emoji \"|any|\" and derivation \"|any|\" \"|any|\"")
@verify_screenshot
def step(context, keypair_name, name, color, emoji, derivation_path, generated_address_index):
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup \
.set_name(name) \
.set_emoji(emoji) \
.set_color(color) \
.set_derivation_path(derivation_path, generated_address_index) \
.set_origin_keypair(keypair_name) \
.save()
@When(
"the user adds a generated seed phrase account with \"|any|\" color \"|any|\" emoji \"|any|\" and keypair \"|any|\"")
def step(context, name, color, emoji, keypair_name):
account_popup = _walletScreen.left_panel.open_add_account_popup()
account_popup \
.set_name(name) \
.set_emoji(emoji) \
.set_color(color) \
.set_origin_new_seed_phrase(keypair_name) \
.save()
AuthenticatePopup().wait_until_appears().authenticate()
account_popup.wait_until_hidden()
@When("the user adds new master key and go to use a Keycard")
def step(context):
_walletScreen.open_add_account_popup()
_walletScreen.left_panel.open_add_account_popup()
_walletScreen.add_account_popup_go_to_keycard_settings()
@When("the user edits an account with \"|any|\" to \"|any|\" with color \"|any|\" and emoji \"|any|\"")
def step(context, name, new_name, new_color, new_emoji):
_walletScreen.click_option_from_right_click_menu_of_account_with_name(MainWalletRightClickMenu.EDIT_ACCOUNT_ACTION_PLACEHOLDER.value, name)
_walletScreen.add_account_popup_change_account_name(new_name)
_walletScreen.add_account_popup_change_account_color(new_color)
_walletScreen.add_account_popup_change_account_emoji(new_emoji)
_walletScreen.add_account_popup_do_primary_action()
account_popup = _walletScreen.left_panel.open_edit_account_popup(name)
account_popup.set_name(new_name).set_emoji(new_emoji).set_color(new_color).save()
@When("the user removes an account with name \"|any|\" and path \"|any|\" using password \"|any|\" and test cancel \"|any|\"")
def step(context, name, path, password, test_cancel):
_walletScreen.click_option_from_right_click_menu_of_account_with_name(MainWalletRightClickMenu.DELETE_ACCOUNT_ACTION_PLACEHOLDER.value, name)
_walletScreen.remove_account_popup_verify_account_account_to_be_removed(name, path)
if test_cancel == VALUE_YES:
_walletScreen.remove_account_popup_do_cancel_action()
_walletScreen.click_option_from_right_click_menu_of_account_with_name(MainWalletRightClickMenu.DELETE_ACCOUNT_ACTION_PLACEHOLDER.value, name)
_walletScreen.remove_account_popup_verify_account_account_to_be_removed(name, path)
_walletScreen.remove_account_popup_do_remove_action(True if path != NOT_APPLICABLE else False, password)
@When("the user sends a transaction to himself from account \"|any|\" of \"|any|\" \"|any|\" on \"|any|\" with password \"|any|\"")
@When("the user removes account \"|any|\"")
def step(context, name):
_walletScreen.left_panel.delete_account(name).confirm()
@When("the user start removing account \"|any|\" and cancel it")
def step(context, name):
_walletScreen.left_panel.delete_account(name).cancel()
@When("the user removes account \"|any|\" with agreement")
def step(context, name):
_walletScreen.left_panel.delete_account(name).agree_and_confirm()
@When(
"the user sends a transaction to himself from account \"|any|\" of \"|any|\" \"|any|\" on \"|any|\" with password \"|any|\"")
def step(context, account_name, amount, token, chain_name, password):
_walletScreen.send_transaction(account_name, amount, token, chain_name, password)
@ -137,14 +166,17 @@ def step(context, name, ens_name):
def step(context, name, new_name):
_walletScreen.edit_saved_address(name, new_name)
@When("the user deletes the saved address with name \"|any|\"")
def step(context, name):
_walletScreen.delete_saved_address(name)
@When("the user toggles favourite for the saved address with name \"|any|\"")
def step(context, name):
_walletScreen.toggle_favourite_for_saved_address(name)
@When("the user toggles the network |any|")
def step(context, network_name):
_walletScreen.toggle_network(network_name)
@ -154,7 +186,7 @@ def step(context, network_name):
### VERIFICATIONS region:
#########################
@Then("the account is correctly displayed with \"|any|\" and \"|any|\" and emoji unicode \"|any|\"")
@Then("the account is correctly displayed with \"|any|\" and \"|any|\" and emoji unicode \"|any|\" in accounts list")
def step(context, name, color, emoji_unicode):
_walletScreen.verify_account_existence(name, color, emoji_unicode)
@ -166,6 +198,7 @@ def step(context):
def step(context, name):
_walletScreen.verify_account_doesnt_exist(name)
@Then("the user has a positive balance of \"|any|\"")
def step(context, symbol):
_walletScreen.verify_positive_balance(symbol)

View File

@ -12,17 +12,20 @@ import walletInitSteps as wallet_init_steps
_user = "tester123"
_password = "TesTEr16843/!@00"
@OnFeatureStart
def hook(context):
init_steps.context_init(context, testSettings)
init_steps.signs_up_process_steps(context, _user, _password)
wallet_init_steps.open_wallet()
@OnFeatureEnd
def hook(context):
currentApplicationContext().detach()
snooze(_app_closure_timeout)
@OnStepEnd
def hook(context):
context.userData["step_name"] = context._data["text"]

View File

@ -6,23 +6,28 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
sys.path.append(os.path.join(os.path.dirname(__file__), "../shared/steps/"))
import steps.commonInitSteps as init_steps
import walletInitSteps as wallet_init_steps
# Global properties for the specific feature
_user = "tester123"
_password = "TesTEr16843/!@00"
@OnFeatureStart
def hook(context):
init_steps.context_init(context, testSettings)
init_steps.signs_up_process_steps(context, _user, _password)
wallet_init_steps.open_wallet()
@OnFeatureEnd
def hook(context):
currentApplicationContext().detach()
snooze(_app_closure_timeout)
@OnStepEnd
def hook(context):
context.userData["step_name"] = context._data["text"]
@OnScenarioEnd
def hook(context):
[ctx.detach() for ctx in squish.applicationContextList()]

View File

@ -2,175 +2,150 @@ Feature: Status Desktop Wallet Section Wallet Account Management
As a user I want to add edit remove different types of wallet accounts
The feature start sequence is the following (setup on its own `bdd_hooks`):
Background:
Given A first time user lands on the status desktop and generates new key
Given the user signs up with username "tester123" and password "TesTEr16843/!@00"
And the user lands on the signed in app
And the user opens the wallet section
And the user accepts the signing phrase
** given A first time user lands on the status desktop and generates new key
** when user signs up with username "tester123" and password "TesTEr16843/!@00"
** and the user lands on the signed in app
** and the user opens the wallet section
** and the user accepts the signing phrase
@mayfail
Scenario Outline: The user edits default wallet account
When the user clicks on the default wallet account
Scenario Outline: The user edits default wallet account
When the user selects wallet account with "<name>"
And the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
Examples:
| name | new_name | new_color | new_emoji | new_emoji_unicode |
| Status account | My Primary Account | 7CDA00 | sunglasses | 1f60e |
| name | new_name | new_color | new_emoji | new_emoji_unicode |
| Status account | MyPrimaryAccount | 7CDA00 | sunglasses | 1f60e |
@mayfail
Scenario Outline: The user manages a watch only account
Scenario Outline: The user manages a watch only account
When the user adds a watch only account "<address>" with "<name>" color "#<color>" and emoji "<emoji>" via "<add_via_context_menu>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
When the user removes an account with name "<new_name>" and path "<path>" using password "<password>" and test cancel "yes"
Then the account with "<new_name>" is not displayed
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
When the user removes account "<new_name>"
Then the account with "<new_name>" is not displayed
Examples:
| address | name | color | emoji | emoji_unicode | add_via_context_menu | new_name | new_color | new_emoji | new_emoji_unicode |
| 0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A | AccWatch1 | 2946C4 | sunglasses | 1f60e | yes | AccWatch1edited | 7CDA00 | thumbsup | 1f44d |
| 0xea123F7beFF45E3C9fdF54B324c29DBdA14a639B | AccWatch2 | D37EF4 | sunglasses | 1f60e | no | AccWatch2edited | 26A69A | thumbsup | 1f44d |
Scenario Outline: The user cancel deliting watch only account
When the user adds a watch only account "<address>" with "<name>" color "#<color>" and emoji "<emoji>" via "<add_via_context_menu>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user start removing account "<name>" and cancel it
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
Examples:
| address | name | color | emoji | emoji_unicode |
| 0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A | AccWatch1 | 2946C4 | sunglasses | 1f60e |
Scenario Outline: The user manages a generated account
When the user adds a generated account with "<name>" color "#<color>" and emoji "<emoji>" via "<add_via_context_menu>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
When the user removes account "<new_name>" with agreement
Then the account with "<new_name>" is not displayed
Examples:
| password | address | path | name | color | emoji | emoji_unicode | add_via_context_menu | new_name | new_color | new_emoji | new_emoji_unicode |
| N/A | 0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A | N/A | AccWatch_1 | 2946C4 | sunglasses | 1f60e | yes | AccWatch_1_edited | 7CDA00 | thumbsup | 1f44d |
| N/A | 0xea123F7beFF45E3C9fdF54B324c29DBdA14a639B | N/A | AccWatch_2 | D37EF4 | sunglasses | 1f60e | no | AccWatch_2_edited | 26A69A | thumbsup | 1f44d |
| name | color | emoji | emoji_unicode | add_via_context_menu | new_name | new_color | new_emoji | new_emoji_unicode |
| GenAcc1 | 2946C4 | sunglasses | 1f60e | yes | GenAcc1edited | 7CDA00 | thumbsup | 1f44d |
| GenAcc2 | D37EF4 | sunglasses | 1f60e | no | GenAcc2edited | 26A69A | thumbsup | 1f44d |
##################################################################
# The following 2 scenarions have to be executed one after another,
# cause the second depends on the state made in the first one
#
# - Scenario Outline: The user manages a generated account
# - Scenario Outline: The user manages a custom generated account
##################################################################
@mayfail
Scenario Outline: The user manages a generated account
When the user adds a generated account with "<name>" color "#<color>" and emoji "<emoji>" via "<add_via_context_menu>" using password "<password>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
When the user removes an account with name "<new_name>" and path "<path>" using password "<password>" and test cancel "yes"
Then the account with "<new_name>" is not displayed
Scenario Outline: The user cancel deliting generated account
When the user adds a generated account with "<name>" color "#<color>" and emoji "<emoji>" via "<add_via_context_menu>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user start removing account "<name>" and cancel it
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
Examples:
| name | color | emoji | emoji_unicode | add_via_context_menu |
| GenAcc1 | 2946C4 | sunglasses | 1f60e | yes |
Scenario Outline: The user manages a custom generated account
When the user adds a custom generated account with "<name>" color "#<color>" emoji "<emoji>" and derivation "<path>" "<address_index>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user removes account "<name>" with agreement
Then the account with "<name>" is not displayed
Examples:
| password | path | name | color | emoji | emoji_unicode | add_via_context_menu | new_name | new_color | new_emoji | new_emoji_unicode |
| TesTEr16843/!@00 | m/44'/60'/0'/0/1 | GenAcc_1 | 2946C4 | sunglasses | 1f60e | yes | GenAcc_1_edited | 7CDA00 | thumbsup | 1f44d |
| TesTEr16843/!@00 | m/44'/60'/0'/0/2 | GenAcc_2 | D37EF4 | sunglasses | 1f60e | no | GenAcc_2_edited | 26A69A | thumbsup | 1f44d |
| address_index | path | name | color | emoji | emoji_unicode |
| 5 | Ethereum | CustomGenAcc1 | 7CDA00 | sunglasses | 1f60e |
| 10 | Ethereum Testnet (Ropsten) | CustomGenAcc2 | D37EF4 | sunglasses | 1f60e |
| 15 | Ethereum (Ledger) | CustomGenAcc3 | 26A69A | sunglasses | 1f60e |
| 20 | Ethereum (Ledger Live/KeepKey) | CustomGenAcc4 | D37EF4 | sunglasses | 1f60e |
| 95 | N/A | CustomGenAcc1 | 7CDA00 | sunglasses | 1f60e |
@mayfail
Scenario Outline: The user manages a custom generated account
When the user adds to "N/A" a custom generated account with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" and setting custom path index "<index>" or selecting address with "<order>" using "<is_ethereum_root>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user removes an account with name "<name>" and path "<path>" using password "<password>" and test cancel "no"
Then the account with "<name>" is not displayed
Scenario Outline: The user manages a private key imported account
When the user adds a private key account "<private_key>" with "<name>" color "#<color>" and emoji "<emoji>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
When the user removes account "<new_name>"
Then the account with "<new_name>" is not displayed
Examples:
| is_ethereum_root | index | order | password | path | name | color | emoji | emoji_unicode |
| yes | N/A | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/3 | CustomGenAcc_1 | 7CDA00 | sunglasses | 1f60e |
| yes | 10 | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/10 | CustomGenAcc_2 | D37EF4 | sunglasses | 1f60e |
| yes | N/A | 99 | TesTEr16843/!@00 | m/44'/60'/0'/0/99 | CustomGenAcc_3 | 26A69A | sunglasses | 1f60e |
| no | 10 | N/A | TesTEr16843/!@00 | m/44'/1'/0'/0/10 | CustomGenAcc_4 | D37EF4 | sunglasses | 1f60e |
| no | N/A | 99 | TesTEr16843/!@00 | m/44'/1'/0'/0/99 | CustomGenAcc_5 | 26A69A | sunglasses | 1f60e |
| private_key | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| 2daa36a3abe381a9c01610bf10fda272fbc1b8a22179a39f782c512346e3e470 | PrivKeyAcc1 | 2946C4 | sunglasses | 1f60e | PrivKeyAcc1edited | 7CDA00 | thumbsup | 1f44d |
##################################################################
@mayfail
Scenario Outline: The user manages a private key imported account
When the user adds a private key account "<private_key>" with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" making keypair with name "<keypair_name>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
Scenario Outline: The user manages a seed phrase imported account
When the user adds an imported seed phrase account "<seed_phrase>" with "<name>" color "#<color>" and emoji "<emoji>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
When the user removes an account with name "<new_name>" and path "<path>" using password "<password>" and test cancel "no"
Then the account with "<new_name>" is not displayed
Examples:
| password | keypair_name | private_key | path | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| TesTEr16843/!@00 | PrivateKeyKeypair | 2daa36a3abe381a9c01610bf10fda272fbc1b8a22179a39f782c512346e3e470 | N/A | PrivKeyAcc_1 | 2946C4 | sunglasses | 1f60e | PrivKeyAcc_1_edited | 7CDA00 | thumbsup | 1f44d |
@mayfail
Scenario Outline: The user manages a seed phrase imported account
When the user adds an imported seed phrase account "<seed_phrase>" with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" making keypair with name "<keypair_name>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
When the user removes an account with name "<new_name>" and path "<path>" using password "<password>" and test cancel "no"
Then the account with "<name>" is not displayed
Examples:
| password | keypair_name | path | seed_phrase | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| TesTEr16843/!@00 | SPKeyPair24 | m/44'/60'/0'/0/0 | elite dinosaur flavor canoe garbage palace antique dolphin virtual mixed sand impact solution inmate hair pipe affair cage vote estate gloom lamp robust like | SPAcc_24 | 2946C4 | sunglasses | 1f60e | SPAcc_24_edited | 7CDA00 | thumbsup | 1f44d |
| TesTEr16843/!@00 | SPKeyPair18 | m/44'/60'/0'/0/0 | kitten tiny cup admit cactus shrug shuffle accident century faith roof plastic beach police barely vacant sign blossom | SPAcc_18 | 2946C4 | sunglasses | 1f60e | SPAcc_18_edited | 7CDA00 | thumbsup | 1f44d |
| TesTEr16843/!@00 | SPKeyPair12 | m/44'/60'/0'/0/0 | pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial | SPAcc_12 | 2946C4 | sunglasses | 1f60e | SPAcc_12_edited | 7CDA00 | thumbsup | 1f44d |
##################################################################
# The following 2 scenarions have to be executed one after another,
# cause the second depends on the state made in the first one
#
# - Scenario Outline: The user adds an account from the imported seed phrase
# - Scenario Outline: The user manages an account created from the imported seed phrase
##################################################################
@mayfail
Scenario Outline: The user adds an account from the imported seed phrase
When the user adds an imported seed phrase account "<seed_phrase>" with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" making keypair with name "<keypair_name>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
Examples:
| password | keypair_name | path | seed_phrase | name | color | emoji | emoji_unicode |
| TesTEr16843/!@00 | SPKeyPair12 | m/44'/60'/0'/0/0 | pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial | SPAcc_12 | 2946C4 | sunglasses | 1f60e |
@mayfail
Scenario Outline: The user manages an account created from the imported seed phrase
When the user adds to "<keypair_name>" a custom generated account with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" and setting custom path index "<index>" or selecting address with "<order>" using "<is_ethereum_root>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user removes an account with name "<name>" and path "<path>" using password "<password>" and test cancel "no"
Then the account with "<name>" is not displayed
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
When the user removes account "<new_name>" with agreement
Then the account with "<name>" is not displayed
Examples:
| keypair_name | is_ethereum_root | index | order | password | path | name | color | emoji | emoji_unicode |
| SPKeyPair12 | yes | N/A | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/1 | CustomGenAcc_1 | 7CDA00 | sunglasses | 1f60e |
| SPKeyPair12 | yes | 10 | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/10 | CustomGenAcc_2 | D37EF4 | sunglasses | 1f60e |
| SPKeyPair12 | yes | N/A | 99 | TesTEr16843/!@00 | m/44'/60'/0'/0/99 | CustomGenAcc_3 | 26A69A | sunglasses | 1f60e |
| SPKeyPair12 | no | 10 | N/A | TesTEr16843/!@00 | m/44'/1'/0'/0/10 | CustomGenAcc_4 | D37EF4 | sunglasses | 1f60e |
| SPKeyPair12 | no | N/A | 99 | TesTEr16843/!@00 | m/44'/1'/0'/0/99 | CustomGenAcc_5 | 26A69A | sunglasses | 1f60e |
| seed_phrase | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| elite dinosaur flavor canoe garbage palace antique dolphin virtual mixed sand impact solution inmate hair pipe affair cage vote estate gloom lamp robust like | SPAcc24 | 2946C4 | sunglasses | 1f60e | SPAcc24edited | 7CDA00 | thumbsup | 1f44d |
| kitten tiny cup admit cactus shrug shuffle accident century faith roof plastic beach police barely vacant sign blossom | SPAcc18 | 2946C4 | sunglasses | 1f60e | SPAcc18edited | 7CDA00 | thumbsup | 1f44d |
| pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial | SPAcc12 | 2946C4 | sunglasses | 1f60e | SPAcc12edited | 7CDA00 | thumbsup | 1f44d |
##################################################################
##################################################################
# The following 2 scenarions have to be executed one after another,
# cause the second depends on the state made in the first one
#
# - Scenario Outline: The user adds and edits an account from the generated seed phrase
# - Scenario Outline: The user manages an account created from the generated seed phrase
##################################################################
@mayfail
Scenario Outline: The user adds and edits an account from the generated seed phrase
When the user adds a generated seed phrase account with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" making keypair with name "<keypair_name>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>"
Examples:
| password | keypair_name | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| TesTEr16843/!@00 | SPKeyPair | SPAcc | 2946C4 | sunglasses | 1f60e | SPAcc_edited | 7CDA00 | thumbsup | 1f44d |
@mayfail
Scenario Outline: The user manages an account created from the generated seed phrase
When the user adds to "<keypair_name>" a custom generated account with "<name>" color "#<color>" and emoji "<emoji>" using password "<password>" and setting custom path index "<index>" or selecting address with "<order>" using "<is_ethereum_root>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>"
When the user removes an account with name "<name>" and path "<path>" using password "<password>" and test cancel "no"
Then the account with "<name>" is not displayed
Scenario Outline: The user manages an account created from the imported seed phrase
When the user adds an imported seed phrase account "pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial" with "SPAcc12" color "#2946C4" and emoji "sunglasses"
And the user adds to "pcsomrselw" a custom generated account with "<name>" color "#<color>" emoji "<emoji>" and derivation "<path>" "<address_index>"
And the user removes account "<name>" with agreement
Then the account with "<name>" is not displayed
Examples:
| keypair_name | is_ethereum_root | index | order | password | path | name | color | emoji | emoji_unicode |
| SPKeyPair | yes | N/A | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/1 | CustomGenAcc_1 | 7CDA00 | sunglasses | 1f60e |
| SPKeyPair | yes | 10 | N/A | TesTEr16843/!@00 | m/44'/60'/0'/0/10 | CustomGenAcc_2 | D37EF4 | sunglasses | 1f60e |
| SPKeyPair | yes | N/A | 99 | TesTEr16843/!@00 | m/44'/60'/0'/0/99 | CustomGenAcc_3 | 26A69A | sunglasses | 1f60e |
| SPKeyPair | no | 10 | N/A | TesTEr16843/!@00 | m/44'/1'/0'/0/10 | CustomGenAcc_4 | D37EF4 | sunglasses | 1f60e |
| SPKeyPair | no | N/A | 99 | TesTEr16843/!@00 | m/44'/1'/0'/0/99 | CustomGenAcc_5 | 26A69A | sunglasses | 1f60e |
##################################################################
| address_index | path | name | color | emoji |
| 5 | Ethereum | CustomGenAcc1 | 7CDA00 | sunglasses |
| 10 | Ethereum Testnet (Ropsten) | CustomGenAcc2 | D37EF4 | sunglasses |
| 15 | Ethereum (Ledger) | CustomGenAcc3 | 26A69A | sunglasses |
| 20 | Ethereum (Ledger Live/KeepKey) | CustomGenAcc4 | D37EF4 | sunglasses |
| 95 | N/A | CustomGenAcc1 | 7CDA00 | sunglasses |
@mayfail
Scenario: The user adds an account and then decides to use a Keycard
When the user adds new master key and go to use a Keycard
Then settings keycard section is opened
Scenario Outline: The user adds and edits an account from the generated seed phrase
When the user adds a generated seed phrase account with "<name>" color "#<color>" emoji "<emoji>" and keypair "<keypair_name>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user edits an account with "<name>" to "<new_name>" with color "#<new_color>" and emoji "<new_emoji>"
Then the account is correctly displayed with "<new_name>" and "#<new_color>" and emoji unicode "<new_emoji_unicode>" in accounts list
Examples:
| keypair_name | name | color | emoji | emoji_unicode | new_name | new_color | new_emoji | new_emoji_unicode |
| SPKeyPair | SPAcc | 2946C4 | sunglasses | 1f60e | SPAcc_edited | 7CDA00 | thumbsup | 1f44d |
Scenario Outline: The user manages an account created from the generated seed phrase
When the user adds a generated seed phrase account with "SPKeyPair" color "#<color>" emoji "<emoji>" and keypair "<keypair_name>"
And the user adds to "<keypair_name>" a custom generated account with "<name>" color "#<color>" emoji "<emoji>" and derivation "<path>" "<address_index>"
Then the account is correctly displayed with "<name>" and "#<color>" and emoji unicode "<emoji_unicode>" in accounts list
When the user removes account "<name>" with agreement
Then the account with "<name>" is not displayed
Examples:
| address_index | path | name | color | emoji | emoji_unicode | keypair_name |
| 5 | Ethereum | CustomGenAcc1 | 7CDA00 | sunglasses | 1f60e | SPKeyPair |
| 10 | Ethereum Testnet (Ropsten) | CustomGenAcc2 | D37EF4 | sunglasses | 1f60e | SPKeyPair |
| 15 | Ethereum (Ledger) | CustomGenAcc3 | 26A69A | sunglasses | 1f60e | SPKeyPair |
| 20 | Ethereum (Ledger Live/KeepKey) | CustomGenAcc4 | D37EF4 | sunglasses | 1f60e | SPKeyPair |
| 95 | N/A | CustomGenAcc1 | 7CDA00 | sunglasses | 1f60e | SPKeyPair |
@mayfail
Scenario: The user adds an account and then decides to use a Keycard
When the user adds new master key and go to use a Keycard
Then settings keycard section is opened

View File

@ -1,7 +1,7 @@
source(findFile('scripts', 'python/bdd.py'))
setupHooks('bdd_hooks.py')
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
def main():
testSettings.throwOnFailure = True