test: test_wallet_send_0_eth added

This commit is contained in:
Valentina Novgorodtceva 2023-12-05 20:23:02 +07:00 committed by Valentina1133
parent 2ad53d7599
commit fa48dad825
16 changed files with 244 additions and 18 deletions

View File

@ -2,4 +2,4 @@ import os
AUT_PORT = 61500 + int(os.getenv('BUILD_NUMBER', 0))
SERVER_PORT = 4322 + int(os.getenv('BUILD_NUMBER', 0))
CURSOR_ANIMATION = False
CURSOR_ANIMATION = True

View File

@ -17,6 +17,10 @@ user_account_one_changed_password = UserAccount('squisher', 'NewPassword@12345',
user_account_one_changed_name = UserAccount('NewUserName', '0000000000', [], '')
user_with_funds = UserAccount('User_with_funds', '0000000000', [
'vocal', 'fruit', 'ordinary', 'meadow', 'south', 'athlete', 'inherit', 'since', 'version', 'pitch', 'oppose', 'lonely'
], '0x26d6e10a6af4eb4d12ff4cf133a843eb4fa88d0b')
community_params = {
'name': 'Name',
'description': 'Description',

View File

@ -58,3 +58,7 @@ class WalletEditNetworkErrorMessages(Enum):
class WalletOrigin(Enum):
WATCHED_ADDRESS_ORIGIN = 'New watched address'
class WalletTransactions(Enum):
TRANSACTION_PENDING_TOAST_MESSAGE = 'Transaction pending'

View File

@ -1,8 +1,5 @@
import time
import squishtest # noqa
import configs
from . import server, context, objects_access, toplevel_window, aut, mouse
from .squish_api import *

View File

@ -1,6 +1,10 @@
import logging
import time
import object
import squish
import configs
LOG = logging.getLogger(__name__)
@ -10,3 +14,19 @@ def walk_children(parent, depth: int = 1000):
yield child
if depth:
yield from walk_children(child, depth - 1)
def wait_for_template(
real_name_template: dict, value: str, attr_name: str, timeout_sec: int = configs.timeouts.UI_LOAD_TIMEOUT_SEC):
started_at = time.monotonic()
while True:
for obj in squish.findAllObjects(real_name_template):
values = []
if hasattr(obj, attr_name):
current_value = str(getattr(obj, attr_name))
if current_value == value:
return obj
values.append(current_value)
if time.monotonic() - started_at > timeout_sec:
raise RuntimeError(f'Value not found in: {values}')
time.sleep(1)

View File

@ -0,0 +1,59 @@
import time
import allure
import configs
import constants
import driver
from driver.objects_access import wait_for_template
from gui.components.base_popup import BasePopup
from gui.components.community.authenticate_popup import AuthenticatePopup
from gui.elements.button import Button
from gui.elements.object import QObject
from gui.elements.text_edit import TextEdit
from gui.elements.text_label import TextLabel
class SendPopup(BasePopup):
def __init__(self):
super().__init__()
self._tab_item_template = QObject('tab_Status_template')
self._search_field = TextEdit('edit_TextEdit')
self._asset_list_item = QObject('o_TokenBalancePerChainDelegate_template')
self._amount_text_edit = TextEdit('amountInput_TextEdit')
self._paste_button = Button('paste_StatusButton')
self._ens_address_text_edit = TextEdit('ens_or_address_TextEdit')
self._my_accounts_tab = Button('accountSelectionTabBar_My_Accounts_StatusTabButton')
self._account_list_item = QObject('status_account_WalletAccountListItem_template')
self._arbitrum_network = QObject('arbitrum_StatusListItem')
self._mainnet_network = QObject('mainnet_StatusListItem')
self._fiat_fees_label = TextLabel('fiatFees_StatusBaseText')
self._send_button = Button('send_StatusFlatButton')
def _select_asset(self, asset: str):
item = wait_for_template(self._asset_list_item.real_name, asset, 'title')
driver.mouseClick(item)
def _open_tab(self, name: str):
assets_tab = wait_for_template(self._tab_item_template.real_name, name, 'text')
driver.mouseClick(assets_tab)
@allure.step('Send {2} {3} to {1}')
def send(self, address: str, amount: int, asset: str):
self._open_tab('Assets')
self._search_field.type_text(asset)
self._select_asset(asset)
self._amount_text_edit.text = str(amount)
self._ens_address_text_edit.type_text(address)
driver.waitFor(lambda: self._send_button.is_visible, timeout_msec=6000)
self._send_button.click()
def is_arbitrum_network_identified(self) -> bool:
return self._arbitrum_network.is_visible
def is_mainnet_network_identified(self) -> bool:
return self._mainnet_network.is_visible
def get_fiat_fees(self) -> str:
return self._fiat_fees_label.text

View File

@ -17,16 +17,17 @@ class TestnetModePopup(BasePopup):
self._close_cross_button.click()
self.wait_until_hidden()
@allure.step('Choose turn on option in the testnet modal')
def click_turn_on_testnet_mode_in_testnet_modal(self):
@allure.step('Confirm turning on in the testnet modal')
def turn_on_testnet_mode_in_testnet_modal(self):
self._turn_on_button.click()
self.wait_until_hidden()
@allure.step('Choose turn off option on the testnet modal')
@allure.step('Confirm turning off in the testnet modal')
def turn_off_testnet_mode_in_testnet_modal(self):
self._turn_off_button.click()
self.wait_until_hidden()
@allure.step('Cancel switching testnet mode in the testnet modal')
def click_cancel_button_in_testnet_modal(self):
self._cancel_button.click()
self.wait_until_hidden()

View File

@ -112,6 +112,20 @@ class QObject:
)
LOG.info('%s: clicked', self)
@allure.step('Native click {0}')
def native_click(
self,
x: typing.Union[int, driver.UiTypes.ScreenPoint] = None,
y: typing.Union[int, driver.UiTypes.ScreenPoint] = None,
button: driver.MouseButton = None
):
driver.nativeMouseClick(
x or self.bounds.x + self.width // 2,
y or self.bounds.y + self.height // 2,
button or driver.MouseButton.LeftButton
)
LOG.info(f'{self}: native clicked')
@allure.step('Hover {0}')
def hover(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC):
def _hover():

View File

@ -1,5 +1,6 @@
import logging
import os
import time
import typing
import allure
@ -12,6 +13,7 @@ from gui.components.community.invite_contacts import InviteContactsPopup
from gui.components.onboarding.before_started_popup import BeforeStartedPopUp
from gui.components.onboarding.beta_consent_popup import BetaConsentPopup
from gui.components.splash_screen import SplashScreen
from gui.components.toast_message import ToastMessage
from gui.components.user_canvas import UserCanvas
from gui.elements.button import Button
from gui.elements.object import QObject
@ -184,3 +186,13 @@ class MainWindow(Window):
create_community_form = communities_portal.open_create_community_popup()
app_screen = create_community_form.create(params)
return app_screen
@allure.step('Wait for notification and get text')
def wait_for_notification(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_SEC) -> str:
started_at = time.monotonic()
while True:
try:
return ToastMessage().get_toast_messages
except LookupError as err:
LOG.info(err)
assert time.monotonic() - started_at < timeout_msec, str(err)

View File

@ -207,6 +207,8 @@ addAccountPopup_GeneratedAddress = {"container": statusDesktop_mainWindow_overla
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}
mainWindow_DisabledTooltipButton = {"container": statusDesktop_mainWindow, "type": "DisabledTooltipButton", "icon": "send", "visible": True}
# Add/Edit account popup:
grid_Grid = {"container": statusDesktop_mainWindow_overlay, "id": "grid", "type": "Grid", "unnamed": 1, "visible": True}
@ -350,6 +352,23 @@ i_understand_the_key_pair_on_this_Keycard_will_be_deleted_StatusCheckBox = {"che
statusSmartIdenticonLetter_StatusLetterIdenticon = {"container": statusDesktop_mainWindow_overlay, "objectName": "statusSmartIdenticonLetter", "type": "StatusLetterIdenticon", "visible": True}
secondary_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "id": "secondaryButton", "type": "StatusButton", "unnamed": 1, "visible": True}
# Send Popup
o_StatusTabBar = {"container": statusDesktop_mainWindow_overlay, "type": "StatusTabBar", "unnamed": 1, "visible": True}
search_TextEdit = {"container": o_StatusTabBar, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
tab_Status_template = {"container": o_StatusTabBar, "type": "StatusBaseText", "unnamed": 1, "visible": True}
o_TokenBalancePerChainDelegate_template = {"container": statusDesktop_mainWindow_overlay, "type": "TokenBalancePerChainDelegate", "unnamed": 1, "visible": True}
amountInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "amountInput", "type": "TextEdit", "visible": True}
paste_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "type": "StatusButton", "unnamed": 1, "visible": True}
ens_or_address_TextEdit = {"container": statusDesktop_mainWindow_overlay, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
accountSelectionTabBar_StatusTabBar = {"container": statusDesktop_mainWindow_overlay, "id": "accountSelectionTabBar", "type": "StatusTabBar", "unnamed": 1, "visible": True}
accountSelectionTabBar_My_Accounts_StatusTabButton = {"checkable": True, "container": accountSelectionTabBar_StatusTabBar, "objectName": "myAccountsTab", "type": "StatusTabButton", "visible": True}
status_account_WalletAccountListItem_template = {"container": statusDesktop_mainWindow_overlay, "objectName": "Status account", "type": "WalletAccountListItem", "visible": True}
arbitrum_StatusListItem = {"container": statusDesktop_mainWindow_overlay, "objectName": "Arbitrum", "type": "StatusListItem", "visible": True}
mainnet_StatusListItem = {"container": statusDesktop_mainWindow_overlay, "objectName": "Mainnet", "type": "StatusListItem", "visible": True}
statusListItemSubTitle_StatusTextWithLoadingState = {"container": statusDesktop_mainWindow_overlay, "objectName": "statusListItemSubTitle", "type": "StatusTextWithLoadingState", "visible": True}
fiatFees_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "id": "fiatFees", "type": "StatusBaseText", "unnamed": 1, "visible": True}
send_StatusFlatButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "sendModalFooterSendButton", "type": "StatusFlatButton", "visible": True}
# Verify identity popup
profileSendContactRequestModal_sayWhoYouAreInput_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "ProfileSendContactRequestModal_sayWhoYouAreInput", "type": "TextEdit", "visible": True}
send_verification_request_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "ProfileSendContactRequestModal_sendContactRequestButton", "type": "StatusButton", "visible": True}

View File

@ -23,3 +23,4 @@ savedAddressView_Delegate_menuButton = {"container": mainWindow_SavedAddressesVi
# 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}
mainWindow_Send_Button = {"container": mainWindow_StatusWindow, "type": "DisabledTooltipButton", "icon": "send", "visible": True}

View File

@ -41,22 +41,22 @@ class LeftPanel(QObject):
return CommunitiesSettingsView()
@allure.step('Open wallet settings')
def open_wallet_settings(self):
def open_wallet_settings(self) -> WalletSettingsView:
self._open_settings('4-AppMenuItem')
return WalletSettingsView().wait_until_appears()
@allure.step('Open profile settings')
def open_profile_settings(self):
def open_profile_settings(self) -> ProfileSettingsView:
self._open_settings('0-MainMenuItem')
return ProfileSettingsView()
@allure.step('Choose back up seed phrase in settings')
def open_back_up_seed_phrase(self):
def open_back_up_seed_phrase(self) -> BackUpYourSeedPhrasePopUp:
self._open_settings('17-MainMenuItem')
return BackUpYourSeedPhrasePopUp()
@allure.step('Open syncing settings')
def open_syncing_settings(self, attempts: int = 2):
def open_syncing_settings(self, attempts: int = 2) -> SyncingSettingsView:
self._open_settings('8-MainMenuItem')
try:
return SyncingSettingsView().wait_until_appears()
@ -72,7 +72,7 @@ class LeftPanel(QObject):
return SignOutPopup()
@allure.step('Open keycard settings')
def open_keycard_settings(self):
def open_keycard_settings(self) -> KeycardSettingsView:
self._open_settings('13-MainMenuItem')
return KeycardSettingsView()

View File

@ -41,7 +41,7 @@ class WalletSettingsView(QObject):
return AccountPopup().wait_until_appears()
@allure.step('Open networks in wallet settings')
def open_networks(self, attempts: int = 2):
def open_networks(self, attempts: int = 2) -> 'NetworkWalletSettings':
self._wallet_network_button.click()
try:
return NetworkWalletSettings().wait_until_appears()
@ -159,6 +159,10 @@ class AccountDetailsView(WalletSettingsView):
def is_account_storage_visible(self):
return self._wallet_account_stored.is_visible
@allure.step('Click back button')
def click_back_button(self):
self._back_button.click()
class NetworkWalletSettings(WalletSettingsView):
@ -210,12 +214,12 @@ class NetworkWalletSettings(WalletSettingsView):
return items_amount
@allure.step('Switch testnet mode toggle')
def switch_testnet_mode_toggle(self):
def switch_testnet_mode_toggle(self) -> TestnetModePopup:
self._testnet_mode_toggle.click()
return TestnetModePopup().wait_until_appears()
@allure.step('Get testnet mode toggle status')
def is_testnet_mode_toggle_checked(self):
def is_testnet_mode_toggle_checked(self) -> bool:
return self._testnet_mode_toggle.is_checked

View File

@ -11,6 +11,7 @@ from gui.components.context_menu import ContextMenu
from gui.components.wallet.add_saved_address_popup import AddressPopup, EditSavedAddressPopup
from gui.components.wallet.confirmation_popup import ConfirmationPopup
from gui.components.wallet.remove_wallet_account_popup import RemoveWalletAccountPopup
from gui.components.wallet.send_popup import SendPopup
from gui.components.wallet.wallet_account_popups import AccountPopup
from gui.elements.button import Button
from gui.elements.object import QObject
@ -22,7 +23,7 @@ class WalletScreen(QObject):
def __init__(self):
super().__init__('mainWindow_WalletLayout')
self.left_panel = LeftPanel()
self.left_panel: LeftPanel = LeftPanel()
class LeftPanel(QObject):
@ -35,6 +36,10 @@ class LeftPanel(QObject):
self._all_accounts_button = Button('mainWallet_All_Accounts_Button')
self._all_accounts_balance = TextLabel('mainWallet_All_Accounts_Balance')
@allure.step('Get total balance visibility state')
def is_total_balance_visible(self) -> bool:
return self._all_accounts_balance.is_visible
@property
@allure.step('Get all accounts from list')
def accounts(self) -> typing.List[constants.user.account_list_item]:
@ -179,6 +184,7 @@ class WalletAccountView(QObject):
super(WalletAccountView, self).__init__('mainWindow_StatusSectionLayout_ContentItem')
self._account_name_text_label = TextLabel('mainWallet_Account_Name')
self._addresses_panel = QObject('mainWallet_Address_Panel')
self._send_button = Button('mainWindow_Send_Button')
@property
@allure.step('Get name of account')
@ -194,3 +200,8 @@ class WalletAccountView(QObject):
def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC):
self._account_name_text_label.wait_until_appears(timeout_msec)
return self
@allure.step('Open send popup')
def open_send_popup(self) -> SendPopup:
self._send_button.click()
return SendPopup().wait_until_appears()

View File

@ -26,7 +26,7 @@ def test_switch_testnet_mode(main_screen: MainWindow):
assert not networks.is_testnet_mode_toggle_checked(), f"Testnet toggle is on when it should not"
with step('Turn on Testnet mode'):
networks.switch_testnet_mode_toggle().click_turn_on_testnet_mode_in_testnet_modal()
networks.switch_testnet_mode_toggle().turn_on_testnet_mode_in_testnet_modal()
with step('Verify that Testnet mode turned on'):
assert len(ToastMessage().get_toast_messages) == 1, \
@ -101,7 +101,7 @@ def test_switch_testnet_off_by_toggle_and_cancel_in_confirmation(main_screen: Ma
testnet_modal = networks.switch_testnet_mode_toggle()
with step('Confirm enabling testnet mode in testnet modal'):
testnet_modal.click_turn_on_testnet_mode_in_testnet_modal()
testnet_modal.turn_on_testnet_mode_in_testnet_modal()
with step('Verify testnet mode is enabled'):
assert len(ToastMessage().get_toast_messages) == 1, \

View File

@ -0,0 +1,80 @@
import allure
import pytest
from allure_commons._allure import step
import configs
import constants
import driver
from constants.wallet import WalletTransactions
from gui.components.onboarding.before_started_popup import BeforeStartedPopUp
from gui.components.onboarding.beta_consent_popup import BetaConsentPopup
from gui.components.signing_phrase_popup import SigningPhrasePopup
from gui.components.splash_screen import SplashScreen
from gui.components.wallet.authenticate_popup import AuthenticatePopup
from gui.screens.onboarding import KeysView, AllowNotificationsView, WelcomeToStatusView, BiometricsView
@pytest.fixture
def keys_screen(main_window) -> KeysView:
with step('Open Generate new keys view'):
if configs.system.IS_MAC:
AllowNotificationsView().wait_until_appears().allow()
BeforeStartedPopUp().get_started()
wellcome_screen = WelcomeToStatusView().wait_until_appears()
return wellcome_screen.get_keys()
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/704527',
'Send: can send 0 ETH to address pasted into receiver field with Simple flow')
@pytest.mark.case(704527)
@pytest.mark.parametrize('user_account', [constants.user.user_with_funds])
@pytest.mark.parametrize('receiver_account_address, amount, asset', [
pytest.param(constants.user.user_account_one.status_address, 0, 'Ether')
])
def test_wallet_send_0_eth(keys_screen, main_window, user_account, receiver_account_address, amount, asset):
with step('Open import seed phrase view and enter seed phrase'):
input_view = keys_screen.open_import_seed_phrase_view().open_seed_phrase_input_view()
input_view.input_seed_phrase(user_account.seed_phrase, True)
profile_view = input_view.import_seed_phrase()
profile_view.set_display_name(user_account.name)
with step('Finalize onboarding and open main screen'):
details_view = profile_view.next()
create_password_view = details_view.next()
confirm_password_view = create_password_view.create_password(user_account.password)
confirm_password_view.confirm_password(user_account.password)
if configs.system.IS_MAC:
BiometricsView().wait_until_appears().prefer_password()
SplashScreen().wait_until_appears().wait_until_hidden()
if not configs.system.TEST_MODE:
BetaConsentPopup().confirm()
with step('Verify that restored account reveals correct status wallet address'):
wallet_settings = main_window.left_panel.open_settings().left_panel.open_wallet_settings()
status_acc_view = wallet_settings.open_status_account_in_settings()
address = status_acc_view.get_account_address_value()
assert address == user_account.status_address, \
f"Recovered account should have address {user_account.status_address}, but has {address}"
status_acc_view.click_back_button()
with step('Set testnet mode'):
wallet_settings.open_networks().switch_testnet_mode_toggle().turn_on_testnet_mode_in_testnet_modal()
with step('Open send popup'):
wallet = main_window.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
assert driver.waitFor(lambda: wallet.left_panel.is_total_balance_visible, configs.timeouts.UI_LOAD_TIMEOUT_SEC)
f"Total balance is not visible"
wallet_account = wallet.left_panel.select_account('Status account')
send_popup = wallet_account.open_send_popup()
with step('Enter asset, amount and address and click send and verify Mainnet network is shown'):
send_popup.send(receiver_account_address, amount, asset)
assert driver.waitFor(lambda: send_popup.is_mainnet_network_identified, configs.timeouts.UI_LOAD_TIMEOUT_SEC)
with step('Enter password in authenticate popup'):
AuthenticatePopup().wait_until_appears().authenticate(user_account.password)
with step('Verify toast message with Transaction pending appears'):
assert WalletTransactions.TRANSACTION_PENDING_TOAST_MESSAGE.value in ' '.join(
main_window.wait_for_notification())