diff --git a/test/appium/tests/critical/test_fallback.py b/test/appium/tests/critical/test_fallback.py index 6170026473..6f0990af60 100644 --- a/test/appium/tests/critical/test_fallback.py +++ b/test/appium/tests/critical/test_fallback.py @@ -9,6 +9,7 @@ from views.sign_in_view import SignInView @pytest.mark.xdist_group(name="new_six_2") @marks.nightly +@marks.secured class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase): def prepare_devices(self): @@ -159,6 +160,94 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase): self.errors.verify_no_errors() + @marks.testrail_id(741054) + def test_fallback_add_key_pair(self): + account_to_add = transaction_senders['ETH_1'] + self.home_1.navigate_back_to_home_view() + self.home_2.navigate_back_to_home_view() + wallet_1 = self.home_1.wallet_tab.click() + wallet_2 = self.home_2.wallet_tab.click() + regular_account_name = "New regular account" + key_pair_account_name = "Key pair account" + key_pair_name = "New key pair" + key_pair_account_address = '0x' + account_to_add['address'].lower() + + wallet_1.just_fyi("Device 1: add a new regular account") + regular_derivation_path = wallet_1.add_regular_account(account_name=regular_account_name) + regular_account_wallet_address = wallet_1.get_account_address().split(':')[-1] + account_element = wallet_1.get_account_element(account_name=regular_account_name) + wallet_1.close_account_button.click_until_presence_of_element(account_element) + + wallet_1.just_fyi("Device 1: add a new key pair account") + account_element.swipe_left_on_element() + key_pair_derivation_path = wallet_1.add_key_pair_account(account_name=key_pair_account_name, + passphrase=account_to_add['passphrase'], + key_pair_name=key_pair_name) + + self.home_2.just_fyi("Device 2: check imported accounts are shown before importing key pair") + self.home_2.profile_button.click() + self.profile_2.profile_wallet_button.click() + self.profile_2.key_pairs_and_accounts_button.click() + if not self.profile_2.get_missing_key_pair_by_name(key_pair_name=key_pair_name).is_element_displayed(): + self.errors.append("Key pair is not shown in profile as missing before importing") + if not self.profile_2.get_key_pair_account_by_name(account_name=regular_account_name).is_element_displayed(): + self.errors.append( + "Newly added regular account is not shown in profile as on device before importing key pair") + self.profile_2.options_button.click() + if not self.profile_2.import_by_entering_recovery_phrase_button.is_element_displayed(): + self.errors.append("Can not import key pair account from profile") + self.profile_2.click_system_back_button(times=4) + + wallet_2.just_fyi("Device 2: import key pair") + wallet_2.get_account_element(account_name=key_pair_account_name).click() + wallet_2.element_by_translation_id("import-key-pair").click() + self.sign_in_2.passphrase_edit_box.send_keys(account_to_add['passphrase']) + wallet_2.slide_and_confirm_with_password() + + self.home_2.just_fyi("Device 2: check imported accounts are shown in profile as added after importing key pair") + self.home_2.profile_button.click() + self.profile_2.profile_wallet_button.click() + self.profile_2.key_pairs_and_accounts_button.click() + if self.profile_2.get_key_pair_account_by_name(account_name=regular_account_name).is_element_displayed(): + address_text = self.profile_2.get_key_pair_account_by_name(account_name=regular_account_name).address.text + if address_text != '...'.join((regular_account_wallet_address[:5], regular_account_wallet_address[-3:])): + self.errors.append( + "Incorrect wallet address if shown for regular account after importing: " + address_text) + else: + self.errors.append("Newly added regular account is not shown in profile after importing key pair") + + if self.profile_2.get_key_pair_account_by_name(account_name=key_pair_account_name).is_element_displayed(): + address_text = self.profile_2.get_key_pair_account_by_name(account_name=key_pair_account_name).address.text + if address_text != '...'.join((key_pair_account_address[:5], key_pair_account_address[-3:])): + self.errors.append( + "Incorrect wallet address if shown for key pair account after importing: " + address_text) + else: + self.errors.append("Key pair account is not shown in profile as on device after importing key pair") + self.profile_2.click_system_back_button(times=3) + + wallet_2.just_fyi("Device 2: check wallet balance") + wallet_2.select_network(network_name='Arbitrum') + expected_balance = self.network_api.get_balance(key_pair_account_address) + shown_balance = wallet_2.get_asset(asset_name='Ether').get_amount() + if shown_balance != round(expected_balance, 5): + self.errors.append("Device 2: ETH balance %s doesn't match expected %s" % (shown_balance, expected_balance)) + + wallet_2.just_fyi("Device 2: check derivation paths of the regular and key pair accounts") + account_element = wallet_2.get_account_element(account_name=regular_account_name) + account_element.click() + wallet_2.about_tab.click() + der_path = wallet_2.account_about_derivation_path_text.text + if der_path != regular_derivation_path: + self.errors.append("Incorrect derivation path %s is shown for the regular account" % der_path) + wallet_2.close_account_button.click_until_presence_of_element(account_element) + account_element.swipe_left_on_element() + wallet_2.get_account_element(account_name=key_pair_account_name).click() + wallet_2.about_tab.click() + der_path = wallet_2.account_about_derivation_path_text.text + if der_path != key_pair_derivation_path: + self.errors.append("Incorrect derivation path %s is shown for the key pair account" % der_path) + self.errors.verify_no_errors() + @marks.testrail_id(740222) def test_fallback_validate_seed_phrase(self): self.sign_in_2.reopen_app(sign_in=False) diff --git a/test/appium/tests/critical/test_wallet.py b/test/appium/tests/critical/test_wallet.py index bcf5c5eddc..11a5e6944d 100644 --- a/test/appium/tests/critical/test_wallet.py +++ b/test/appium/tests/critical/test_wallet.py @@ -256,10 +256,7 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase): if self.wallet_view.account_name_text.text != new_account_name: pytest.fail("New account is not created") - self.wallet_view.account_emoji_button.click_until_presence_of_element(self.wallet_view.copy_address_button) - self.wallet_view.share_address_button.click() - new_wallet_address = self.wallet_view.sharing_text_native.text - self.wallet_view.click_system_back_button() + new_wallet_address = self.wallet_view.get_account_address() self.wallet_view.close_account_button.click_until_presence_of_element(self.home_view.show_qr_code_button) self.wallet_view.just_fyi("Checking that the new wallet is added to the Share QR Code menu") diff --git a/test/appium/views/profile_view.py b/test/appium/views/profile_view.py index 0c36c8c0c7..df06b3ef98 100644 --- a/test/appium/views/profile_view.py +++ b/test/appium/views/profile_view.py @@ -360,6 +360,10 @@ class ProfileView(BaseView): accessibility_id="icon, Legacy settings, label-component, icon") self.testnet_mode_toggle = Button(self.driver, accessibility_id="icon, Testnet mode, label-component") self.confirm_testnet_mode_change_button = Button(self.driver, accessibility_id="confirm-testnet-mode-change") + self.key_pairs_and_accounts_button = Button(self.driver, + accessibility_id="Key pairs and accounts, label-component, icon") + self.options_button = Button(self.driver, accessibility_id="options-button") + self.import_by_entering_recovery_phrase_button = Button(self.driver, accessibility_id="import-seed-phrase") def switch_network(self): self.driver.info("Toggling test mode") @@ -569,3 +573,16 @@ class ProfileView(BaseView): return Button(self.driver, xpath=self.locator + "//*[@content-desc='Unpair']") return PairedDeviceElement(self.driver, device_name) + + def get_key_pair_account_by_name(self, account_name: str): + class KeyPairAccountElement(BaseElement): + def __init__(self, driver, account_name): + locator = "//*[@content-desc='account-avatar']/following-sibling::*[@text='%s']" % account_name + super().__init__(driver, xpath=locator) + self.address = Text(driver, xpath=locator + "/following-sibling::android.widget.TextView") + + return KeyPairAccountElement(self.driver, account_name) + + def get_missing_key_pair_by_name(self, key_pair_name: str): + return BaseElement(self.driver, + xpath="//*[@content-desc='missing-keypair-item']//*[@text='%s']" % key_pair_name) diff --git a/test/appium/views/wallet_view.py b/test/appium/views/wallet_view.py index 317c1cdd8a..37e520eb7c 100644 --- a/test/appium/views/wallet_view.py +++ b/test/appium/views/wallet_view.py @@ -75,6 +75,8 @@ class WalletView(BaseView): self.account_has_activity_label = Text(self.driver, accessibility_id='account-has-activity') self.add_account_continue_button = Button(self.driver, accessibility_id='Continue') self.add_watched_address_button = Button(self.driver, accessibility_id='confirm-button-label') + self.add_account_derivation_path_text = Text( + self.driver, xpath="//*[contains(@content-desc,'icon, Derivation path')]/android.widget.TextView[2]") # Account view self.close_account_button = Button(self.driver, accessibility_id='top-bar') @@ -88,8 +90,11 @@ class WalletView(BaseView): self.share_address_button = Button(self.driver, accessibility_id='share-account') self.remove_account_button = Button(self.driver, accessibility_id='remove-account') self.derivation_path_note_checkbox = Button(self.driver, accessibility_id='checkbox-off') + self.account_about_derivation_path_text = Text( + self.driver, xpath="//*[@content-desc='derivation-path-icon']/following-sibling::*[2]") self.activity_tab = Button(self.driver, accessibility_id='activity-tab') + self.about_tab = Button(self.driver, accessibility_id='about') # Sending transaction self.address_text_input = EditBox(self.driver, accessibility_id='address-text-input') @@ -99,6 +104,15 @@ class WalletView(BaseView): self.confirm_button = Button(self.driver, accessibility_id='button-one') self.done_button = Button(self.driver, accessibility_id='done') + # Edit key pair + self.edit_key_pair_button = Button(self.driver, accessibility_id="Edit") + self.key_pairs_plus_button = Button(self.driver, accessibility_id="standard-title-action") + self.generate_new_keypair_button = Button(self.driver, accessibility_id="generate-new-keypair") + self.import_using_recovery_phrase_button = Button(self.driver, accessibility_id="import-using-phrase") + self.key_pair_continue_button = Button(self.driver, accessibility_id="Continue") + self.key_pair_name_input = EditBox( + self.driver, xpath="//*[@text='Key pair name']/..//following-sibling::*/*[@content-desc='input']") + def select_network(self, network_name: str): self.network_drop_down.click() Button(self.driver, accessibility_id="%s, label-component" % network_name.capitalize()).click() @@ -160,8 +174,10 @@ class WalletView(BaseView): def add_regular_account(self, account_name: str): self.add_account_button.click() self.create_account_button.click() + derivation_path = self.add_account_derivation_path_text.text SignInView(self.driver).profile_title_input.send_keys(account_name) self.slide_and_confirm_with_password() + return derivation_path.replace(' ', '') def add_watch_only_account(self, address: str, account_name: str): self.add_account_button.click() @@ -181,3 +197,33 @@ class WalletView(BaseView): def get_activity_element(self, index=1): return ActivityElement(self.driver, index=index) + + def add_key_pair_account(self, account_name, passphrase=None, key_pair_name=None): + self.add_account_button.click() + self.create_account_button.click() + signin_view = SignInView(self.driver) + signin_view.profile_title_input.send_keys(account_name) + self.edit_key_pair_button.click() + self.key_pairs_plus_button.click() + if passphrase: + self.import_using_recovery_phrase_button.click() + signin_view.passphrase_edit_box.send_keys(passphrase) + self.key_pair_continue_button.click() + self.key_pair_name_input.send_keys(key_pair_name) + self.key_pair_continue_button.click() + else: + self.generate_new_keypair_button.click() + for checkbox in self.checkbox_button.find_elements(): + checkbox.click() + self.element_by_translation_id("reveal-phrase").click() + # ToDo: can't be done in current small size emulators, add when moved to LambdaTest + self.slide_and_confirm_with_password() + derivation_path = self.add_account_derivation_path_text.text + return derivation_path.replace(' ', '') + + def get_account_address(self): + self.account_emoji_button.click_until_presence_of_element(self.copy_address_button) + self.share_address_button.click() + wallet_address = self.sharing_text_native.text + self.click_system_back_button() + return wallet_address