diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d3c6b44f81..fa97153a10 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,8 +28,8 @@ desktop/ @vkjr modules/react-native-desktop*/ @vkjr modules/react-native-desktop*/ @vkjr -/doc @oskarth @yenda @jeluard +/doc @oskarth @yenda @jeluard -/deployment @vkjr +/deployment @vkjr -/test/appium/ @antdanchenko @churik +/test/appium/ @churik diff --git a/src/status_im/ui/screens/wallet/recipient/views.cljs b/src/status_im/ui/screens/wallet/recipient/views.cljs index 927ac73783..b5a65a7187 100644 --- a/src/status_im/ui/screens/wallet/recipient/views.cljs +++ b/src/status_im/ui/screens/wallet/recipient/views.cljs @@ -227,15 +227,17 @@ :align-items :center :height 40 :margin-vertical 8} [quo/text (i18n/label :t/address-or-ens-name)]] [quo/text-input - {:multiline true - :default-value resolved-address - :height 70 - :editable false}]] + {:multiline true + :default-value resolved-address + :height 70 + :editable false + :accessibility-label :fav-address}]] [react/view {:height 16}] [quo/list-header (i18n/label :t/name-optional)] [react/view {:padding-horizontal 16} - [quo/text-input {:show-cancel false - :on-change-text #(reset! fav-name %)}]]] + [quo/text-input {:show-cancel false + :accessibility-label :fav-name + :on-change-text #(reset! fav-name %)}]]] [toolbar/toolbar {:show-border? true :center diff --git a/test/appium/support/api/network_api.py b/test/appium/support/api/network_api.py index 55c5ce385f..ba2881cc3e 100644 --- a/test/appium/support/api/network_api.py +++ b/test/appium/support/api/network_api.py @@ -32,13 +32,19 @@ class NetworkApi(object): return requests.request('GET', url=method, headers=self.headers).json()['result'] except TypeError as e: self.log("Check response from etherscan API. Returned values do not match expected. %s" % e) + except JSONDecodeError as e: + self.log(str(e)) + pass def get_token_transactions(self, address: str) -> List[dict]: method = self.network_url + 'module=account&action=tokentx&address=0x%s&sort=desc&apikey=%s' % (address, self.api_key) try: return requests.request('GET', url=method, headers=self.headers).json()['result'] except TypeError as e: - self.log("Check response from etherscan API. Returned values do not match expected. %s" % e) + self.log("Check response from etherscan API. Returned values do not match expected. %s" % str(e)) + except JSONDecodeError as e: + self.log(str(e)) + pass def is_transaction_successful(self, transaction_hash: str) -> int: method = self.network_url + 'module=transaction&action=getstatus&txhash=%s' % transaction_hash diff --git a/test/appium/tests/atomic/account_management/test_profile.py b/test/appium/tests/atomic/account_management/test_profile.py index bf31f71431..a1baa410f0 100644 --- a/test/appium/tests/atomic/account_management/test_profile.py +++ b/test/appium/tests/atomic/account_management/test_profile.py @@ -450,6 +450,7 @@ class TestProfileSingleDevice(SingleDeviceTestCase): @marks.critical @marks.testrail_id(5419) + @marks.flaky def test_logcat_backup_recovery_phrase(self): sign_in_view = SignInView(self.driver) sign_in_view.create_user() @@ -806,15 +807,16 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase): profile_1.mail_server_address_input.clear() profile_1.mail_server_address_input.set_value(mailserver_address) profile_1.save_button.click() - profile_1.mail_server_by_name(server_name).click() - profile_1.mail_server_connect_button.click() - profile_1.confirm_button.click() - if profile_1.element_by_text_part("Error connecting").is_element_displayed(40): - profile_1.retry_to_connect_to_mailserver() - profile_1.get_back_to_home_view() - profile_1.home_button.click() - # TODO: disabled due to 10065 + # profile_1.mail_server_by_name(server_name).click() + # profile_1.mail_server_connect_button.click() + # profile_1.confirm_button.click() + # if profile_1.element_by_text_part("Error connecting").is_element_displayed(40): + # profile_1.retry_to_connect_to_mailserver() + # profile_1.get_back_to_home_view() + # profile_1.home_button.click() + + # profile_1.just_fyi('start chat with user2 and check that all messages are delivered') # chat_1 = home_1.add_contact(public_key) # message = 'test message' diff --git a/test/appium/tests/atomic/chats/test_commands.py b/test/appium/tests/atomic/chats/test_commands.py index 454eff6940..77b95281dc 100644 --- a/test/appium/tests/atomic/chats/test_commands.py +++ b/test/appium/tests/atomic/chats/test_commands.py @@ -21,7 +21,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase): home_1, home_2 = device_1_sign_in.get_home_view(), device_2_sign_in.get_home_view() profile_2 = home_2.profile_button.click() device_2_username = profile_2.default_username_text.text - profile_2.switch_network('Mainnet with upstream RPC') + profile_2.switch_network() chat_2 = home_2.add_contact(sender['public_key']) chat_2.send_message("Hey there!") diff --git a/test/appium/tests/atomic/dapps_and_browsing/test_browsing.py b/test/appium/tests/atomic/dapps_and_browsing/test_browsing.py index e5b59c4359..adcc757d83 100644 --- a/test/appium/tests/atomic/dapps_and_browsing/test_browsing.py +++ b/test/appium/tests/atomic/dapps_and_browsing/test_browsing.py @@ -2,7 +2,6 @@ from tests import marks, connection_not_secure_text, connection_is_secure_text, from tests.base_test_case import SingleDeviceTestCase from views.sign_in_view import SignInView from views.dapps_view import DappsView -from time import sleep class TestBrowsing(SingleDeviceTestCase): @@ -73,15 +72,19 @@ class TestBrowsing(SingleDeviceTestCase): def test_open_blocked_site(self): home_view = SignInView(self.driver).create_user() daap_view = home_view.dapp_tab_button.click() - dapp_detail = daap_view.open_url('https://www.cryptokitties.domainname') - dapp_detail.find_text_part('This site is blocked') - if dapp_detail.browser_refresh_page_button.is_element_displayed(): - self.driver.fail("Refresh button is present in blocked site") - dapp_detail.go_back_button.click() - daap_view.element_by_text("Browser").click() - dapp_detail.continue_anyway_button.click() - if not dapp_detail.element_by_text("Unable to load page").is_element_displayed(): - self.driver.fail("Failed to open Dapp after 'Continue anyway' tapped") + for url in ('metamask.site', 'https://www.cryptokitties.domainname'): + dapp_detail = daap_view.open_url(url) + dapp_detail.find_text_part('This site is blocked') + if dapp_detail.browser_refresh_page_button.is_element_displayed(): + self.errors.append("Refresh button is present in blocked site") + dapp_detail.go_back_button.click() + daap_view.element_by_text("Browser").click() + dapp_detail.continue_anyway_button.click() + if dapp_detail.element_by_text('This site is blocked').is_element_displayed(): + self.errors.append("Failed to open Dapp after 'Continue anyway' tapped for %s" % url) + daap_view.cross_icon.click() + self.errors.verify_no_errors() + #TODO: waiting mode @marks.testrail_id(6300) diff --git a/test/appium/tests/atomic/transactions/test_wallet.py b/test/appium/tests/atomic/transactions/test_wallet.py index ec525a3acf..78362a2987 100644 --- a/test/appium/tests/atomic/transactions/test_wallet.py +++ b/test/appium/tests/atomic/transactions/test_wallet.py @@ -479,6 +479,90 @@ class TestTransactionWalletSingleDevice(SingleDeviceTestCase): self.errors.verify_no_errors() + @marks.testrail_id(6328) + @marks.medium + def test_send_transaction_set_recipient_options(self): + sender = wallet_users['D'] + sign_in_view = SignInView(self.driver) + sign_in_view.recover_access(sender['passphrase']) + home_view = sign_in_view.get_home_view() + nickname = 'my_some_nickname' + account_name = 'my_acc_name' + account_address = '0x8c2E3Cd844848E79cFd4671cE45C12F210b630d7' + recent_add_to_fav_name = 'my_Recent_STT' + recent_add_to_fav_address = '0xc039f82eceda458b63a0f327b7b0c20def5903d7' + basic_add_to_fav_name = 'my_basic_address' + + home_view.just_fyi('Add new account and new ENS contact for recipient') + chat = home_view.add_contact(ens_user_ropsten['ens']) + chat.chat_options.click() + chat.view_profile_button.click_until_presence_of_element(chat.remove_from_contacts) + chat.set_nickname(nickname) + wallet_view = home_view.wallet_button.click() + wallet_view.set_up_wallet() + wallet_view.add_account(account_name=account_name) + wallet_view.accounts_status_account.click() + send_transaction = wallet_view.send_transaction_button.click() + + send_transaction.just_fyi('Set one of my accounts') + send_transaction.chose_recipient_button.click() + send_transaction.element_by_text('My accounts').click() + send_transaction.element_by_text(account_name).click() + if send_transaction.enter_recipient_address_text.text != \ + send_transaction.get_formatted_recipient_address(account_address): + self.errors.append('Added account is not resolved as recipient') + + send_transaction.just_fyi('Set contact') + send_transaction.chose_recipient_button.click() + send_transaction.element_by_text('Contacts').click() + send_transaction.element_by_text(nickname).scroll_and_click() + send_transaction.recipient_done.click() + if send_transaction.enter_recipient_address_text.text != \ + send_transaction.get_formatted_recipient_address(ens_user_ropsten['address']): + self.errors.append('ENS from contact is not resolved as recipient') + + send_transaction.just_fyi('Set contract address from recent and check smart contract error') + send_transaction.chose_recipient_button.click() + send_transaction.element_by_text('Recent').click() + send_transaction.element_by_text('↑ 0 ETHro').click() + if not send_transaction.element_by_text_part('is a smart contract').is_element_displayed(): + self.driver.fail('No warning is shown at attempt to set as recipient smart contract') + send_transaction.ok_button.click() + send_transaction.element_by_text('↑ 2 STT').scroll_and_click() + send_transaction.add_to_favorites(recent_add_to_fav_name) + + send_transaction.just_fyi('Scan code, add it to favorites and recheck that it is preserved') + send_transaction.scan_qr_code_button.click() + send_transaction.allow_button.click(1) + wallet_view.enter_qr_edit_box.set_value(basic_user['address']) + wallet_view.ok_button.click() + send_transaction.add_to_favorites(basic_add_to_fav_name) + send_transaction.element_by_text('Favourites').scroll_and_click() + for name in (recent_add_to_fav_name, basic_add_to_fav_name): + if not send_transaction.element_by_text(name).is_element_displayed(): + self.errors.append('%s was not added to Favourites' % name) + send_transaction.element_by_text(recent_add_to_fav_name).click() + if str(send_transaction.enter_recipient_address_text.text).lower() != \ + send_transaction.get_formatted_recipient_address(recent_add_to_fav_address): + self.errors.append('Recent address that was added to favourites was not resolved correctly') + + send_transaction.just_fyi('Check search and set address from search') + send_transaction.chose_recipient_button.click() + send_transaction.search_by_keyword(ens_user_ropsten['ens'][:2]) + if not send_transaction.element_by_text('@' + ens_user_ropsten['ens']).is_element_displayed(): + self.errors.append('ENS address from contacts is not shown in search') + send_transaction.cancel_button.click() + send_transaction.search_by_keyword('my') + for name in (nickname, account_name, recent_add_to_fav_name, basic_add_to_fav_name): + if not send_transaction.element_by_text(name).is_element_displayed(): + self.errors.append('%s is not shown in search when searching by namepart' % name) + send_transaction.element_by_text(basic_add_to_fav_name).click() + if send_transaction.enter_recipient_address_text.text!= send_transaction.get_formatted_recipient_address('0x' + basic_user['address']): + self.errors.append('QR scanned address that was added to favourites was not resolved correctly') + + self.errors.verify_no_errors() + + @marks.testrail_id(5437) @marks.medium def test_validation_amount_errors(self): diff --git a/test/appium/tests/users.py b/test/appium/tests/users.py index fc547f10d6..e8589a811f 100644 --- a/test/appium/tests/users.py +++ b/test/appium/tests/users.py @@ -18,6 +18,7 @@ ens_user['address'] = '0x1eE3058Bd300246B4B20E687Efc9Eba81FF7814b' ens_user_ropsten = dict() ens_user_ropsten['ens'] = 'nastya' ens_user_ropsten['username'] = 'Thoughtful Stupendous Graywolf' +ens_user_ropsten['address'] = '0x58d8c3D70ce4FA4b9fb10a665C8712238746F2ff' dummy_user = dict() dummy_user['username'] = "Vain Wordy Hagfish" diff --git a/test/appium/views/base_element.py b/test/appium/views/base_element.py index 66fb10e817..a17f933a9e 100644 --- a/test/appium/views/base_element.py +++ b/test/appium/views/base_element.py @@ -125,6 +125,10 @@ class BaseElement(object): raise NoSuchElementException( "Device %s: '%s' is not found on the screen" % (self.driver.number, self.name)) from None + def scroll_and_click(self): + self.scroll_to_element() + self.click() + def is_element_present(self, sec=5): try: self.driver.info('Wait for %s' % self.name) diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index 20edda35b0..773060049c 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -652,6 +652,8 @@ class BaseView(object): def close_share_popup(self): TouchAction(self.driver).tap(None, 255, 104, 1).perform() + time.sleep(3) + def get_public_key_and_username(self, return_username=False): profile_view = self.profile_button.click() diff --git a/test/appium/views/send_transaction_view.py b/test/appium/views/send_transaction_view.py index d51ee01dfc..5163454c71 100644 --- a/test/appium/views/send_transaction_view.py +++ b/test/appium/views/send_transaction_view.py @@ -196,19 +196,39 @@ class ValidationErrorOnSendTransaction(BaseButton): super(ValidationErrorOnSendTransaction, self).__init__(driver) self.locator = self.Locator.xpath_selector("//*[@text='%s']/../*[@content-desc='icon']" % field) + class ValidationIconOnSendTransaction(BaseButton): def __init__(self, driver): super(ValidationIconOnSendTransaction, self).__init__(driver) self.locator = self.Locator.xpath_selector('//*[@content-desc="custom-gas-fee"]/../android.view.ViewGroup//*[@content-desc="icon"]') - class ShareButton(BaseButton): - def __init__(self, driver): super(ShareButton, self).__init__(driver) self.locator = self.Locator.accessibility_id('share-address-button') +class RecipientAddToFavoritesButton(BaseButton): + def __init__(self, driver): + super(RecipientAddToFavoritesButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id('participant-add-to-favs') + +class RecipientDoneButton(BaseButton): + def __init__(self, driver): + super(RecipientDoneButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id('participant-done') + + +class NewFavoriteNameInput(BaseEditBox): + def __init__(self, driver): + super(NewFavoriteNameInput, self).__init__(driver) + self.locator = self.Locator.accessibility_id('fav-name') + + +class NewFavoriteAddFavorite(BaseButton): + def __init__(self, driver): + super(NewFavoriteAddFavorite, self).__init__(driver) + self.locator = self.Locator.accessibility_id('add-fav') class OnboardingMessage(BaseElement): def __init__(self, driver): @@ -335,6 +355,12 @@ class SendTransactionView(BaseView): self.select_button = SelectButton(self.driver) self.request_transaction_button = RequestTransactionButtonBottomSheet(self.driver) + # Elements on set recipient screen + self.recipient_add_to_favorites = RecipientAddToFavoritesButton(self.driver) + self.recipient_done = RecipientDoneButton(self.driver) + self.new_favorite_name_input = NewFavoriteNameInput(self.driver) + self.new_favorite_add_favorite = NewFavoriteAddFavorite(self.driver) + def complete_onboarding(self): if self.onboarding_message.is_element_displayed(): from views.wallet_view import WalletView @@ -395,3 +421,8 @@ class SendTransactionView(BaseView): data['gas_price'] = self.gas_price_input.text self.cancel_button.click() return data + + def add_to_favorites(self, name): + self.recipient_add_to_favorites.click() + self.new_favorite_name_input.set_value(name) + self.new_favorite_add_favorite.click() \ No newline at end of file