371 lines
18 KiB
Python
371 lines
18 KiB
Python
from ast import Tuple
|
|
from enum import Enum
|
|
import time
|
|
import os
|
|
import sys
|
|
from common.SeedUtils import *
|
|
from .StatusMainScreen import StatusMainScreen
|
|
from .StatusMainScreen import authenticatePopupEnterPassword
|
|
from drivers.SquishDriver import type_text as type_text
|
|
|
|
class Tokens(Enum):
|
|
ETH: str = "ETH"
|
|
|
|
class SigningPhrasePopUp(Enum):
|
|
OK_GOT_IT_BUTTON: str = "signPhrase_Ok_Button"
|
|
|
|
class MainWalletScreen(Enum):
|
|
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"
|
|
FIRST_ACCOUNT_ITEM: str = "firstWalletAccount_Item"
|
|
EPHEMERAL_NOTIFICATION_LIST: str = "mainWallet_Ephemeral_Notification_List"
|
|
TOTAL_CURRENCY_BALANCE: str = "mainWallet_totalCurrencyBalance"
|
|
|
|
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"
|
|
HEADER_ACCOUNTS_LIST: str = "mainWallet_Send_Popup_Header_Accounts"
|
|
AMOUNT_INPUT: str = "mainWallet_Send_Popup_Amount_Input"
|
|
MY_ACCOUNTS_TAB: str = "mainWallet_Send_Popup_My_Accounts_Tab"
|
|
MY_ACCOUNTS_LIST: str = "mainWallet_Send_Popup_My_Accounts_List"
|
|
NETWORKS_LIST: str = "mainWallet_Send_Popup_Networks_List"
|
|
SEND_BUTTON: str = "mainWallet_Send_Popup_Send_Button"
|
|
ASSET_SELECTOR: str = "mainWallet_Send_Popup_Asset_Selector"
|
|
ASSET_LIST: str = "mainWallet_Send_Popup_Asset_List"
|
|
HIGH_GAS_BUTTON: str = "mainWallet_Send_Popup_GasSelector_HighGas_Button"
|
|
|
|
class AddAccountPopup(Enum):
|
|
SCROLL_BAR: str = "mainWallet_Add_Account_Popup_Main"
|
|
PASSWORD_INPUT: str = "mainWallet_Add_Account_Popup_Password"
|
|
ACCOUNT_NAME_INPUT: str = "mainWallet_Add_Account_Popup_Account_Name"
|
|
ADVANCE_SECTION: str = "mainWallet_Add_Account_Popup_Advanced"
|
|
TYPE_SELECTOR: str = "mainWallet_Add_Account_Popup_Type_Selector"
|
|
TYPE_WATCH_ONLY: str = "mainWallet_Add_Account_Popup_Type_Watch_Only"
|
|
TYPE_SEED_PHRASE: str = "mainWallet_Add_Account_Popup_Type_Seed_Phrase"
|
|
TYPE_PRIVATE_KEY: str = "mainWallet_Add_Account_Popup_Type_Private_Key"
|
|
ADDRESS_INPUT: str = "mainWallet_Add_Account_Popup_Watch_Only_Address"
|
|
ADDRESS_INPUT_PLACEHOLDER: str = "mainWallet_Add_Account_Popup_Watch_Only_Address_Placeholder"
|
|
PRIVATE_KEY_INPUT: str = "mainWallet_Add_Account_Popup_Private_Key"
|
|
ADD_ACCOUNT_BUTTON: str = "mainWallet_Add_Account_Popup_Footer_Add_Account"
|
|
SEED_PHRASE_INPUT_TEMPLATE: str = "mainWindow_Add_Account_Popup_Seed_Phrase_"
|
|
SEED_PHRASE_INPUT_LAST: str = "mainWindow_Add_Account_Popup_Seed_Phrase_12"
|
|
FULLY_CUSTOM_PATH_CHECKBOX: str = "mainWallet_Add_Account_Popup_Advanced_Accept_Responsibility_Checkbox"
|
|
ADD_ACCOUNT_POPUP_ROOT: str = "mainWallet_Add_Account_Popup_Root"
|
|
|
|
class CollectiblesView(Enum):
|
|
COLLECTIONS_REPEATER: str = "mainWallet_Collections_Repeater"
|
|
COLLECTIBLES_REPEATER: str = "mainWallet_Collectibles_Repeater"
|
|
|
|
class WalletTabBar(Enum):
|
|
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"
|
|
|
|
class StatusWalletScreen:
|
|
|
|
#####################################
|
|
### Screen actions region:
|
|
#####################################
|
|
|
|
def accept_signing_phrase(self):
|
|
click_obj_by_name(SigningPhrasePopUp.OK_GOT_IT_BUTTON.value)
|
|
|
|
def add_watch_only_account(self, account_name: str, address: str, password: str):
|
|
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
type_text(AddAccountPopup.ACCOUNT_NAME_INPUT.value, account_name)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADVANCE_SECTION.value, 2000)
|
|
|
|
# Found that all the involved controls are switching availability states very quickly based on the model data
|
|
# which makes it almost impossible to do a reliable check for different states, hence the retry for 10 seconds
|
|
# workaround.
|
|
# TODO remove workaround to retry after add account modal refactoring
|
|
max_expected_step_duration_ms = 10000
|
|
def scroll_and_type_fn():
|
|
try:
|
|
click_obj_by_name(AddAccountPopup.TYPE_SELECTOR.value)
|
|
click_obj_by_name(AddAccountPopup.TYPE_WATCH_ONLY.value)
|
|
|
|
scroll_item_until_item_is_visible(AddAccountPopup.SCROLL_BAR.value, AddAccountPopup.ADDRESS_INPUT_PLACEHOLDER.value, 2000)
|
|
wait_for_object_and_type(AddAccountPopup.ADDRESS_INPUT_PLACEHOLDER.value, address)
|
|
except Exception as e:
|
|
log(f"Expected fail, ignore it for {max_expected_step_duration_ms/1000} seconds; exception {str(e)}")
|
|
|
|
do_until_validation_with_timeout(
|
|
scroll_and_type_fn,
|
|
lambda: is_loaded_visible_and_enabled(AddAccountPopup.ADDRESS_INPUT.value, 500)[0],
|
|
timeout_ms=max_expected_step_duration_ms,
|
|
message="Fill watch only account address")
|
|
|
|
click_obj_by_name(AddAccountPopup.ADD_ACCOUNT_BUTTON.value, 2000)
|
|
|
|
def import_private_key(self, account_name: str, password: str, private_key: str):
|
|
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
type_text(AddAccountPopup.ACCOUNT_NAME_INPUT.value, account_name)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADVANCE_SECTION.value)
|
|
click_obj_by_name(AddAccountPopup.TYPE_SELECTOR.value)
|
|
click_obj_by_name(AddAccountPopup.TYPE_PRIVATE_KEY.value)
|
|
|
|
scroll_item_until_item_is_visible(AddAccountPopup.SCROLL_BAR.value, AddAccountPopup.PRIVATE_KEY_INPUT.value)
|
|
type_text(AddAccountPopup.PRIVATE_KEY_INPUT.value, private_key)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
authenticatePopupEnterPassword(password)
|
|
|
|
def import_seed_phrase(self, account_name: str, password: str, mnemonic: str):
|
|
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
type_text(AddAccountPopup.ACCOUNT_NAME_INPUT.value, account_name)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADVANCE_SECTION.value)
|
|
click_obj_by_name(AddAccountPopup.TYPE_SELECTOR.value)
|
|
click_obj_by_name(AddAccountPopup.TYPE_SEED_PHRASE.value)
|
|
|
|
is_loaded_visible_and_enabled(AddAccountPopup.SCROLL_BAR.value, 1000)
|
|
scroll_item_until_item_is_visible(AddAccountPopup.SCROLL_BAR.value, AddAccountPopup.SEED_PHRASE_INPUT_LAST.value)
|
|
|
|
words = mnemonic.split()
|
|
input_seed_phrase(AddAccountPopup.SEED_PHRASE_INPUT_TEMPLATE.value, words)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
authenticatePopupEnterPassword(password)
|
|
|
|
def generate_new_account(self, account_name: str, password: str):
|
|
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
type_text(AddAccountPopup.ACCOUNT_NAME_INPUT.value, account_name)
|
|
|
|
click_obj_by_name(AddAccountPopup.ADD_ACCOUNT_BUTTON.value)
|
|
|
|
authenticatePopupEnterPassword(password)
|
|
|
|
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)
|
|
|
|
click_obj_by_name(MainWalletScreen.SEND_BUTTON_FOOTER.value)
|
|
|
|
self._click_repeater(SendPopup.HEADER_ACCOUNTS_LIST.value, account_name)
|
|
is_loaded_visible_and_enabled(SendPopup.AMOUNT_INPUT.value, 1000)
|
|
type_text(SendPopup.AMOUNT_INPUT.value, amount)
|
|
|
|
click_obj_by_name(SendPopup.ASSET_SELECTOR.value)
|
|
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):
|
|
click_obj(asset_list.itemAtIndex(index))
|
|
break
|
|
|
|
click_obj_by_name(SendPopup.MY_ACCOUNTS_TAB.value)
|
|
|
|
accounts = get_obj(SendPopup.MY_ACCOUNTS_LIST.value)
|
|
for index in range(accounts.count):
|
|
if(accounts.itemAtIndex(index).objectName == account_name):
|
|
print("WE FOUND THE ACCOUNT")
|
|
click_obj(accounts.itemAtIndex(index))
|
|
break
|
|
|
|
scroll_obj_by_name(SendPopup.SCROLL_BAR.value)
|
|
|
|
click_obj_by_name(SendPopup.SEND_BUTTON.value)
|
|
|
|
authenticatePopupEnterPassword(password)
|
|
|
|
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):
|
|
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)
|
|
|
|
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)
|
|
type_text(AddSavedAddressPopup.NAME_INPUT.value, new_name)
|
|
click_obj_by_name(AddSavedAddressPopup.ADD_BUTTON.value)
|
|
|
|
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)
|
|
|
|
def toggle_favourite_for_saved_address(self, name: str):
|
|
# Find the saved address and click favourite to toggle
|
|
item = self._get_saved_address_delegate_item(name)
|
|
favouriteButton = item.statusListItemIcon
|
|
is_object_loaded_visible_and_enabled(favouriteButton)
|
|
click_obj(favouriteButton)
|
|
|
|
def check_favourite_status_for_saved_address(self, name: str, favourite: bool):
|
|
# Find the saved address
|
|
item = self._get_saved_address_delegate_item(name)
|
|
favouriteButton = item.statusListItemIcon
|
|
wait_for_prop_value(favouriteButton, "asset.name", ("star-icon" if favourite else "favourite"))
|
|
|
|
def toggle_network(self, network_name: str):
|
|
is_loaded_visible_and_enabled(MainWalletScreen.NETWORK_SELECTOR_BUTTON.value, 2000)
|
|
click_obj_by_name(MainWalletScreen.NETWORK_SELECTOR_BUTTON.value)
|
|
|
|
is_loaded_visible_and_enabled(NetworkSelectorPopup.LAYER_1_REPEATER.value, 2000)
|
|
list = wait_and_get_obj(NetworkSelectorPopup.LAYER_1_REPEATER.value)
|
|
for index in range(list.count):
|
|
item = list.itemAt(index)
|
|
if item.objectName == network_name:
|
|
click_obj(item)
|
|
click_obj_by_name(MainWalletScreen.ACCOUNT_NAME.value)
|
|
return
|
|
|
|
assert False, "network name not found"
|
|
|
|
def click_first_account(self):
|
|
click_obj_by_name(MainWalletScreen.FIRST_ACCOUNT_ITEM.value)
|
|
|
|
|
|
#####################################
|
|
### Verifications region:
|
|
#####################################
|
|
|
|
def verify_account_name_is_present(self, account_name: str):
|
|
# Wait 2 second for UI text to update
|
|
test.verify(wait_for_text_matching(MainWalletScreen.ACCOUNT_NAME.value, account_name, 2000), "Account name was updated and matches expected")
|
|
|
|
def verify_account_balance_is_positive(self, list, symbol: str) -> Tuple(bool, ):
|
|
if list is None:
|
|
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_TokenListItem_" + symbol and tokenListItem.item.balance != "0":
|
|
return (True, tokenListItem)
|
|
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)
|
|
|
|
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"')
|
|
|
|
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')
|
|
|
|
def verify_transaction(self):
|
|
pass
|
|
# TODO: figure out why it doesn t work in CI
|
|
# ephemeral_notification_list = get_obj(MainWalletScreen.EPHEMERAL_NOTIFICATION_LIST.value)
|
|
# print(ephemeral_notification_list.itemAtIndex(0).objectName)
|
|
# verify(str(ephemeral_notification_list.itemAtIndex(0).primaryText ) == "Transaction pending...", "Tx was not sent!")
|
|
|
|
def verify_collectibles_exist(self, account_name: str):
|
|
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):
|
|
collectionsRepeater.itemAt(0).expanded = True
|
|
collectiblesRepeater = get_obj(CollectiblesView.COLLECTIBLES_REPEATER.value)
|
|
verify(collectiblesRepeater.count > 0, "Collectibles not retrieved for the account")
|
|
|
|
def verify_transactions_exist(self):
|
|
tabbar = get_obj(MainWalletScreen.RIGHT_SIDE_TABBAR.value)
|
|
click_obj(tabbar.itemAt(WalletTabBar.ACTIVITY_TAB.value))
|
|
|
|
transaction_list_view = get_obj(TransactionsView.TRANSACTIONS_LISTVIEW.value)
|
|
|
|
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)
|
|
transaction_detail_header = get_obj(TransactionsView.TRANSACTIONS_DETAIL_VIEW_HEADER.value)
|
|
|
|
click_obj(transaction_item)
|
|
|
|
verify_equal(transaction_item.item.cryptoValue, transaction_detail_header.cryptoValue)
|
|
verify_equal(transaction_item.item.transferStatus, transaction_detail_header.transferStatus)
|
|
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)
|
|
|