Test/97 wallet generated custom private key account (#12080)

* test(Wallet) Edit the default wallet account and Manage a watch-only account cases automated

* test(Wallet) Manage generated and custom generated account

* test(Wallet) Manage private key imported account
This commit is contained in:
Valentina1133 2023-09-07 11:13:38 +07:00 committed by GitHub
parent 8ddf480479
commit f11b2b1e86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 296 additions and 12 deletions

View File

@ -0,0 +1,9 @@
from enum import Enum
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

@ -0,0 +1,25 @@
import allure
from gui.elements.qt.button import Button
from gui.elements.qt.text_edit import TextEdit
from gui.elements.qt.object import QObject
class AuthenticatePopup(QObject):
def __init__(self):
super(AuthenticatePopup, self).__init__('contextMenu_PopupItem')
self._password_text_edit = TextEdit('sharedPopup_Password_Input')
self._primary_button = Button('sharedPopup_Primary_Button')
@allure.step('Authenticate action with password')
def authenticate(self, password: str, attempt: int = 2):
self._password_text_edit.text = password
self._primary_button.click()
try:
self._primary_button.wait_until_hidden()
except AssertionError as err:
if attempt:
self.authenticate(password, attempt - 1)
else:
raise err

View File

@ -22,4 +22,4 @@ class EmojiPopup(BasePopup):
self._search_text_edit.text = name
self._emoji_item.real_name['objectName'] = 'statusEmoji_' + name
self._emoji_item.click()
self._search_text_edit.wait_until_hidden()
self._search_text_edit.wait_until_hidden()

View File

@ -22,4 +22,9 @@ class RemoveWalletAccountPopup(BasePopup):
@allure.step('Confirm removing account')
def confirm(self):
self._confirm_button.click()
self._confirm_button.wait_until_hidden()
self._confirm_button.wait_until_hidden()
@allure.step('Agree and confirm removing account')
def agree_and_confirm(self):
self._have_pen_paper_checkbox.wait_until_appears().set(True)
self.confirm()

View File

@ -1,6 +1,9 @@
import allure
import configs
import constants.wallet
import driver
from gui.components.authenticate_popup import AuthenticatePopup
from gui.components.base_popup import BasePopup
from gui.components.emoji_popup import EmojiPopup
from gui.elements.qt.button import Button
@ -9,6 +12,7 @@ from gui.elements.qt.text_edit import TextEdit
from gui.elements.qt.scroll import Scroll
from gui.elements.qt.object import QObject
GENERATED_PAGES_LIMIT = 20
class AccountPopup(BasePopup):
def __init__(self):
@ -66,7 +70,88 @@ class AccountPopup(BasePopup):
self._address_text_edit.text = value
return self
@allure.step('Set private key for account')
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
@allure.step('Set derivation path for account')
def set_derivation_path(self, value: str, index: int, password: str):
self._edit_derivation_path_button.hover().click()
AuthenticatePopup().wait_until_appears().authenticate(password)
if value in [_.value for _ in constants.wallet.DerivationPath]:
self._derivation_path_combobox_button.click()
self._derivation_path_list_item.real_name['title'] = value
self._derivation_path_list_item.click()
del self._derivation_path_list_item.real_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
@allure.step('Save added account')
def save(self):
self._add_account_button.wait_until_appears().click()
return self
return self
class AddNewAccountPopup(BasePopup):
def __init__(self):
super(AddNewAccountPopup, self).__init__()
self._import_private_key_button = Button('mainWallet_AddEditAccountPopup_MasterKey_ImportPrivateKeyOption')
self._private_key_text_edit = TextEdit('mainWallet_AddEditAccountPopup_PrivateKey')
self._private_key_name_text_edit = TextEdit('mainWallet_AddEditAccountPopup_PrivateKeyName')
self._continue_button = Button('mainWallet_AddEditAccountPopup_PrimaryButton')
@allure.step('Import private key')
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]
class GeneratedAddressesList(QObject):
def __init__(self):
super(GeneratedAddressesList, self).__init__('statusDesktop_mainWindow_overlay_popup2')
self._address_list_item = QObject('addAccountPopup_GeneratedAddress')
self._paginator_page = QObject('page_StatusBaseButton')
@property
@allure.step('Load generated addresses list')
def is_paginator_load(self) -> bool:
try:
return str(driver.findAllObjects(self._paginator_page.real_name)[0].text) == '1'
except IndexError:
return False
@allure.step('Wait until appears {0}')
def wait_until_appears(self, timeout_msec: int = configs.timeouts.UI_LOAD_TIMEOUT_MSEC):
if 'text' in self._paginator_page.real_name:
del self._paginator_page.real_name['text']
assert driver.waitFor(lambda: self.is_paginator_load, timeout_msec), 'Generated address list not load'
return self
@allure.step('Select address in list')
def select(self, index: int):
self._address_list_item.real_name['objectName'] = f'AddAccountPopup-GeneratedAddress-{index}'
selected_page_number = 1
while selected_page_number != GENERATED_PAGES_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.real_name['text'] = selected_page_number
self._paginator_page.click()

View File

@ -116,6 +116,8 @@ class QObject(BaseObject):
return False
assert driver.waitFor(lambda: _hover(), timeout_msec)
return self
@allure.step('Open context menu')
def open_context_menu(

View File

@ -22,3 +22,12 @@ class Scroll(QObject):
raise LookupError(f'Object not found: {element}')
if hasattr(element.object, 'y'):
driver.flick(self.object, 0, int(element.object.y))
@allure.step('Scroll down to object')
def vertical_down_to(self, element: QObject, timeout_sec: int = 5):
started_at = time.monotonic()
step = 100
while not element.is_visible:
driver.flick(self.object, 0, step)
if time.monotonic() - started_at > timeout_sec:
raise LookupError(f'Object not found: {element}')

View File

@ -2,6 +2,7 @@ from objectmaphelper import *
from .main_names import statusDesktop_mainWindow
from .main_names import statusDesktop_mainWindow_overlay
from .main_names import statusDesktop_mainWindow_overlay_popup2
# Scroll
o_Flickable = {"container": statusDesktop_mainWindow_overlay, "type": "Flickable", "unnamed": 1, "visible": True}
@ -154,9 +155,18 @@ mainWallet_AddEditAccountPopup_AccountEmoji = {"container": statusDesktop_mainWi
o_StatusDialogBackground = {"container": statusDesktop_mainWindow_overlay, "type": "StatusDialogBackground", "unnamed": 1, "visible": True}
delete_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "deleteChatConfirmationDialogDeleteButton", "type": "StatusButton", "visible": True}
# 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", "visible": True, "enabled": True}
# Wallet Account Popup
mainWallet_AddEditAccountPopup_derivationPath = {"container": statusDesktop_mainWindow, "objectName": RegularExpression("AddAccountPopup-PreDefinedDerivationPath*"), "type": "StatusListItem", "visible": True}
mainWallet_Address_Panel = {"container": statusDesktop_mainWindow, "objectName": "addressPanel", "type": "StatusAddressPanel", "visible": True}
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}
# Add/Edit account popup:
grid_Grid = {"container": statusDesktop_mainWindow_overlay, "id": "grid", "type": "Grid", "unnamed": 1, "visible": True}
@ -184,4 +194,8 @@ mainWallet_AddEditAccountPopup_DerivationPathInputComponent = {"container": stat
mainWallet_AddEditAccountPopup_DerivationPathInput = {"container": mainWallet_AddEditAccountPopup_DerivationPathInputComponent, "type": "TextEdit", "unnamed": 1, "visible": True}
mainWallet_AddEditAccountPopup_PreDefinedDerivationPathsButton = {"container": mainWallet_AddEditAccountPopup_DerivationPathInputComponent, "objectName": "chevron-down-icon", "type": "StatusIcon", "visible": True}
mainWallet_AddEditAccountPopup_GeneratedAddressComponent = {"container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-GeneratedAddress", "type": "StatusListItem", "visible": True}
mainWallet_AddEditAccountPopup_NonEthDerivationPathCheckBox = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-ConfirmAddingNonEthDerivationPath", "type": "StatusCheckBox", "visible": True}
mainWallet_AddEditAccountPopup_NonEthDerivationPathCheckBox = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "AddAccountPopup-ConfirmAddingNonEthDerivationPath", "type": "StatusCheckBox", "visible": True}
mainWallet_AddEditAccountPopup_MasterKey_ImportPrivateKeyOption = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-ImportPrivateKey", "type": "StatusListItem", "visible": True}
mainWallet_AddEditAccountPopup_PrivateKey = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-PrivateKeyInput", "type": "StatusPasswordInput", "visible": True}
mainWallet_AddEditAccountPopup_PrivateKeyNameComponent = {"container": mainWallet_AddEditAccountPopup_Content, "objectName": "AddAccountPopup-PrivateKeyName", "type": "StatusInput", "visible": True}
mainWallet_AddEditAccountPopup_PrivateKeyName = {"container": mainWallet_AddEditAccountPopup_PrivateKeyNameComponent, "type": "TextEdit", "unnamed": 1, "visible": True}

View File

@ -1,5 +1,6 @@
statusDesktop_mainWindow = {"name": "mainWindow", "type": "StatusWindow", "visible": True}
statusDesktop_mainWindow_overlay = {"container": statusDesktop_mainWindow, "type": "Overlay", "unnamed": 1, "visible": True}
statusDesktop_mainWindow_overlay_popup2 = {"container": statusDesktop_mainWindow_overlay, "occurrence": 2, "type": "PopupItem", "unnamed": 1, "visible": True}
scrollView_StatusScrollView = {"container": statusDesktop_mainWindow_overlay, "id": "scrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True}
splashScreen = {"container": statusDesktop_mainWindow, "objectName": "splashScreen", "type": "DidYouKnowSplashScreen"}

View File

@ -7,6 +7,7 @@ from allure import step
import configs.timeouts
import constants
import driver
from gui.components.authenticate_popup import AuthenticatePopup
from gui.components.signing_phrase_popup import SigningPhrasePopup
from gui.main_window import MainWindow
@ -52,7 +53,8 @@ def test_manage_saved_address(main_screen: MainWindow, name: str, address: str,
@pytest.mark.parametrize('name, new_name, new_color, new_emoji, new_emoji_unicode', [
pytest.param('Status account', 'MyPrimaryAccount', '#216266', 'sunglasses', '1f60e')
])
def test_edit_default_wallet_account(main_screen: MainWindow, name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str):
def test_edit_default_wallet_account(main_screen: MainWindow, name: str, new_name: str, new_color: str, new_emoji: str,
new_emoji_unicode: str):
with step('Select wallet account'):
wallet = main_screen.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
@ -73,12 +75,13 @@ def test_edit_default_wallet_account(main_screen: MainWindow, name: str, new_nam
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703026', 'Manage a watch-only account')
@pytest.mark.case(703026)
@pytest.mark.parametrize('address, name, color, emoji, emoji_unicode, new_name, '
'new_color, new_emoji, new_emoji_unicode', [
pytest.param('0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A', 'AccWatch1', '#2a4af5', 'sunglasses', '1f60e',
'AccWatch1edited', '#216266', 'thumbsup', '1f44d')
])
def test_manage_watch_only_account(main_screen: MainWindow, address: str, color: str, emoji:str, emoji_unicode: str, name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str):
@pytest.mark.parametrize('address, name, color, emoji, emoji_unicode, new_name, new_color,'
'new_emoji, new_emoji_unicode', [
pytest.param('0xea123F7beFF45E3C9fdF54B324c29DBdA14a639A', 'AccWatch1', '#2a4af5',
'sunglasses', '1f60e', 'AccWatch1edited', '#216266', 'thumbsup', '1f44d')
])
def test_manage_watch_only_account(main_screen: MainWindow, address: str, color: str, emoji: str, emoji_unicode: str,
name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str):
with step('Create watch-only wallet account'):
wallet = main_screen.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
@ -116,4 +119,135 @@ def test_manage_watch_only_account(main_screen: MainWindow, address: str, color:
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703033', 'Manage a generated account')
@pytest.mark.case(703033)
@pytest.mark.parametrize('user_account', [constants.user.user_account_default])
@pytest.mark.parametrize('name, color, emoji, emoji_unicode, '
'new_name, new_color, new_emoji, new_emoji_unicode', [
pytest.param('GenAcc1', '#2a4af5', 'sunglasses', '1f60e',
'GenAcc1edited', '#216266', 'thumbsup', '1f44d')
])
def test_manage_generated_account(main_screen: MainWindow, user_account,
color: str, emoji: str, emoji_unicode: str,
name: str, new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str):
with step('Create generated wallet account'):
wallet = main_screen.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
account_popup = wallet.left_panel.open_add_account_popup()
account_popup.set_name(name).set_emoji(emoji).set_color(color).save()
AuthenticatePopup().wait_until_appears().authenticate(user_account.password)
account_popup.wait_until_hidden()
with step('Verify that the account is correctly displayed in accounts list'):
expected_account = constants.user.account_list_item(name, color.lower(), emoji_unicode)
started_at = time.monotonic()
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
with step('Edit wallet account'):
account_popup = wallet.left_panel.open_edit_account_popup(name)
account_popup.set_name(new_name).set_emoji(new_emoji).set_color(new_color).save()
with step('Verify that the account is correctly displayed in accounts list'):
expected_account = constants.user.account_list_item(new_name, new_color.lower(), new_emoji_unicode)
started_at = time.monotonic()
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
with step('Delete wallet account with agreement'):
wallet.left_panel.delete_account(new_name).agree_and_confirm()
with step('Verify that the account is not displayed in accounts list'):
assert driver.waitFor(lambda: new_name not in [account.name for account in wallet.left_panel.accounts], 10000), \
f'Account with {new_name} is still displayed even it should not be'
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703028', 'Manage a custom generated account')
@pytest.mark.case(703028)
@pytest.mark.parametrize('user_account', [constants.user.user_account_default])
@pytest.mark.parametrize('derivation_path, generated_address_index, name, color, emoji, emoji_unicode', [
pytest.param('Ethereum', '5', 'Ethereum', '#216266', 'sunglasses', '1f60e'),
pytest.param('Ethereum Testnet (Ropsten)', '10', 'Ethereum Testnet ', '#7140fd', 'sunglasses', '1f60e'),
pytest.param('Ethereum (Ledger)', '15', 'Ethereum Ledger', '#2a799b', 'sunglasses', '1f60e'),
pytest.param('Ethereum (Ledger Live/KeepKey)', '20', 'Ethereum Ledger Live', '#7140fd', 'sunglasses', '1f60e'),
pytest.param('N/A', '95', 'Custom path', '#216266', 'sunglasses', '1f60e')
])
def test_manage_custom_generated_account(main_screen: MainWindow, user_account,
derivation_path: str, generated_address_index: int,
name: str, color: str, emoji: str, emoji_unicode: str):
with step('Create generated wallet account'):
wallet = main_screen.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
account_popup = wallet.left_panel.open_add_account_popup()
account_popup.set_name(name).set_emoji(emoji).set_color(color).set_derivation_path(derivation_path, generated_address_index, user_account.password).save()
with step('Verify that the account is correctly displayed in accounts list'):
expected_account = constants.user.account_list_item(name, color.lower(), emoji_unicode)
started_at = time.monotonic()
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
with step('Delete wallet account with agreement'):
wallet.left_panel.delete_account(name).agree_and_confirm()
with step('Verify that the account is not displayed in accounts list'):
assert driver.waitFor(lambda: name not in [account.name for account in wallet.left_panel.accounts], 10000), \
f'Account with {name} is still displayed even it should not be'
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703029', 'Manage a private key imported account')
@pytest.mark.case(703029)
@pytest.mark.parametrize('user_account', [constants.user.user_account_default])
@pytest.mark.parametrize('name, color, emoji, emoji_unicode, '
'new_name, new_color, new_emoji, new_emoji_unicode, private_key', [
pytest.param('PrivKeyAcc1', '#2a4af5', 'sunglasses', '1f60e',
'PrivKeyAcc1edited', '#216266', 'thumbsup', '1f44d',
'2daa36a3abe381a9c01610bf10fda272fbc1b8a22179a39f782c512346e3e470')
])
def test_private_key_imported_account(main_screen: MainWindow, user_account,
name: str, color: str, emoji: str, emoji_unicode: str,
new_name: str, new_color: str, new_emoji: str, new_emoji_unicode: str,
private_key: str):
with step('Create generated wallet account'):
wallet = main_screen.left_panel.open_wallet()
SigningPhrasePopup().wait_until_appears().confirm_phrase()
account_popup = wallet.left_panel.open_add_account_popup()
account_popup.set_name(name).set_emoji(emoji).set_color(color).set_origin_private_key(private_key).save()
AuthenticatePopup().wait_until_appears().authenticate(user_account.password)
account_popup.wait_until_hidden()
with step('Verify that the account is correctly displayed in accounts list'):
expected_account = constants.user.account_list_item(name, color.lower(), emoji_unicode)
started_at = time.monotonic()
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
with step('Edit wallet account'):
account_popup = wallet.left_panel.open_edit_account_popup(name)
account_popup.set_name(new_name).set_emoji(new_emoji).set_color(new_color).save()
with step('Verify that the account is correctly displayed in accounts list'):
expected_account = constants.user.account_list_item(new_name, new_color.lower(), new_emoji_unicode)
started_at = time.monotonic()
while expected_account not in wallet.left_panel.accounts:
time.sleep(1)
if time.monotonic() - started_at > 15:
raise LookupError(f'Account {expected_account} not found in {wallet.left_panel.accounts}')
with step('Delete wallet account with agreement'):
wallet.left_panel.delete_account(new_name).confirm()
with step('Verify that the account is not displayed in accounts list'):
assert driver.waitFor(lambda: new_name not in [account.name for account in wallet.left_panel.accounts], 10000), \
f'Account with {new_name} is still displayed even it should not be'