diff --git a/src/status_im/ui/screens/keycard/onboarding/views.cljs b/src/status_im/ui/screens/keycard/onboarding/views.cljs index 6152d2da2c..df46d7ab1b 100644 --- a/src/status_im/ui/screens/keycard/onboarding/views.cljs +++ b/src/status_im/ui/screens/keycard/onboarding/views.cljs @@ -96,7 +96,8 @@ :width 133 :height 44 :border-radius 10} - [react/text {:style {:color colors/blue}} + [react/text {:style {:color colors/blue} + :accessibility-label :begin-set-up} (i18n/label :t/begin-set-up)]]]]]])) (defview puk-code [] @@ -110,7 +111,8 @@ {:handler #(re-frame/dispatch [::hardwallet.onboarding/cancel-pressed]) :style {:padding-left 21}} (i18n/label :t/cancel)] - [react/text {:style {:color colors/gray}} + [react/text {:style {:color colors/gray} + :accessibility-label :cancel-keycard-setup} (i18n/label :t/step-i-of-n {:step "2" :number steps})]] [react/scroll-view {:content-container-style {:flex-grow 1 @@ -145,10 +147,11 @@ (i18n/label :t/puk-code)]] [react/view {:justify-content :flex-start :flex 1} - [react/text {:style {:typography :header - :font-family "monospace" - :text-align :center - :color colors/blue}} + [react/text {:style {:typography :header + :font-family "monospace" + :text-align :center + :color colors/blue} + :accessibility-label :puk-code} puk-code]]]] [react/view {:margin-top 16} [react/text {:style {:color colors/gray}} @@ -172,10 +175,11 @@ (i18n/label :t/pair-code)]] [react/view {:justify-content :flex-start :flex 1} - [react/text {:style {:typography :header - :text-align :center - :font-family "monospace" - :color colors/blue}} + [react/text {:style {:typography :header + :text-align :center + :font-family "monospace" + :color colors/blue} + :accessibility-label :pair-code} (:password secrets)]]]] [react/view {:margin-top 16} [react/text {:style {:color colors/gray}} @@ -293,7 +297,7 @@ :margin-left 12} [react/text {:style {:color colors/gray}} (str (inc i) ". ")] - [react/text + [react/text {:accessibility-label (str "word" i)} word]])])] [react/view {:margin-top 24} [react/text {:style {:text-align :center}} @@ -320,6 +324,7 @@ {:transparent? true} [toolbar/nav-text {:handler #(re-frame/dispatch [::hardwallet.onboarding/cancel-pressed]) + :accessibility-label :cancel-keycard-setup :style {:padding-left 21}} (i18n/label :t/cancel)] [react/text {:style {:color colors/gray}} @@ -336,23 +341,26 @@ (i18n/label :t/keycard-recovery-phrase-confirm-header)]] [react/view {:margin-top 16 :align-items :center} - [react/text {:style {:typography :header - :color colors/gray - :text-align :center}} + [react/text {:style {:typography :header + :color colors/gray + :text-align :center} + :accessibility-label :word-number} + (i18n/label :t/word-n {:number (inc idx)})]]] [react/view [text-input/text-input-with-label - {:on-change-text #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed %]) - :auto-focus true - :on-submit-editing #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted]) - :placeholder nil - :auto-correct false - :keyboard-type "visible-password" - :container {:background-color colors/white} - :style {:background-color colors/white - :text-align :center - :height 52 - :typography :header}}] + {:on-change-text #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed %]) + :auto-focus true + :on-submit-editing #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted]) + :placeholder nil + :auto-correct false + :keyboard-type "visible-password" + :accessibility-label :enter-word + :container {:background-color colors/white} + :style {:background-color colors/white + :text-align :center + :height 52 + :typography :header}}] [react/view {:margin-top 5 :width 250} [tooltip/tooltip error]]] @@ -368,7 +376,8 @@ :label (i18n/label :t/back)}]] [react/view {:margin-right 20} [components.common/bottom-button - {:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed]) - :label (i18n/label :t/next) - :disabled? (empty? input-word) - :forward? true}]]]]]))) + {:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed]) + :label (i18n/label :t/next) + :accessibility-label :next + :disabled? (empty? input-word) + :forward? true}]]]]]))) diff --git a/src/status_im/ui/screens/wallet/accounts/views.cljs b/src/status_im/ui/screens/wallet/accounts/views.cljs index 511eafca05..69f9d2d9c2 100644 --- a/src/status_im/ui/screens/wallet/accounts/views.cljs +++ b/src/status_im/ui/screens/wallet/accounts/views.cljs @@ -31,7 +31,8 @@ [react/view {:style {:flex-direction :row}} (if prices-loading? [react/small-loading-indicator :colors/white-persist] - [react/text {:style {:color colors/white-persist :font-weight "500"}} portfolio-value]) + [react/text {:style {:color colors/white-persist :font-weight "500"} + :accessibility-label "account-total-value"} portfolio-value]) [react/text {:style {:color colors/white-transparent-persist :font-weight "500"}} (str " " (:code currency))]] [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover diff --git a/test/appium/tests/atomic/account_management/test_create_account.py b/test/appium/tests/atomic/account_management/test_create_account.py index 887f19aa09..c7a5f5a185 100644 --- a/test/appium/tests/atomic/account_management/test_create_account.py +++ b/test/appium/tests/atomic/account_management/test_create_account.py @@ -1,4 +1,3 @@ -import pytest import random from tests import marks, common_password, get_current_time, unique_password diff --git a/test/appium/tests/atomic/account_management/test_keycard.py b/test/appium/tests/atomic/account_management/test_keycard.py new file mode 100644 index 0000000000..4d0699cf4b --- /dev/null +++ b/test/appium/tests/atomic/account_management/test_keycard.py @@ -0,0 +1,42 @@ +from tests import marks +from tests.base_test_case import SingleDeviceTestCase +from views.sign_in_view import SignInView + + +@marks.all +@marks.account +class TestCreateAccount(SingleDeviceTestCase): + + @marks.testrail_id(5689) + @marks.critical + def test_add_new_keycard_account(self): + sign_in = SignInView(self.driver) + sign_in.create_user(keycard=True) + + sign_in.just_fyi('Check that after creating keycard account balance is 0, not ...') + wallet_view = sign_in.wallet_button.click() + wallet_view.set_up_wallet() + if wallet_view.status_account_total_usd_value.text != '0': + self.errors.append("Account USD value is not 0, it is %s" % wallet_view.status_account_total_usd_value.text) + public_key = sign_in.get_public_key() + profile = sign_in.get_profile_view() + default_username = profile.default_username_text.text + profile.logout() + + sign_in.just_fyi('Check that can login with keycard account') + sign_in.multi_account_on_login_button.wait_for_visibility_of_element(5) + sign_in.multi_account_on_login_button.click() + from views.keycard_view import KeycardView + keycard_view = KeycardView(self.driver) + # TODO: disabled due to 10272 + # for text in (public_key[-5:],default_username): + if not keycard_view.element_by_text_part(default_username).is_element_displayed(): + self.errors.append("%s is not found on keycard login screen!" % default_username) + keycard_view.enter_default_pin() + keycard_view.connect_card_button.click() + # TODO: disabled as login is not made in e2e builds + # if not sign_in.home_button.is_element_displayed(): + # self.driver.fail('Keycard user is not logged in') + + self.errors.verify_no_errors() + diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index 61f6e7d673..f97bfb0895 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -243,7 +243,7 @@ class DiscardButton(BaseButton): class ConfirmButton(BaseButton): def __init__(self, driver): super(ConfirmButton, self).__init__(driver) - self.locator = self.Locator.xpath_selector("//*[@text='CONFIRM']") + self.locator = self.Locator.xpath_selector("//*[@text='CONFIRM' or @text='Confirm']") class ProgressBar(BaseElement): diff --git a/test/appium/views/keycard_view.py b/test/appium/views/keycard_view.py new file mode 100644 index 0000000000..9a1722322e --- /dev/null +++ b/test/appium/views/keycard_view.py @@ -0,0 +1,100 @@ +from views.base_element import BaseButton, BaseText, BaseElement, BaseEditBox +from views.base_view import BaseView + + +class BeginSetupButton(BaseButton): + def __init__(self, driver): + super(BeginSetupButton, self).__init__(driver) + self.locator = self.Locator.text_selector("Begin setup") + + +class OnePinKeyboardButton(BaseButton): + def __init__(self, driver): + super(OnePinKeyboardButton, self).__init__(driver) + self.locator = self.Locator.text_selector("1") + + +class TwoPinKeyboardButton(BaseButton): + def __init__(self, driver): + super(TwoPinKeyboardButton, self).__init__(driver) + self.locator = self.Locator.text_selector("2") + +class ConnectCardButton(BaseButton): + def __init__(self, driver): + super(ConnectCardButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id("connect-card") + + +class DisconnectCardButton(BaseButton): + def __init__(self, driver): + super(DisconnectCardButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id("disconnect-card") + + +class ResetCardButton(BaseButton): + def __init__(self, driver): + super(ResetCardButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id("keycard-reset-state") + + +class RecoveryWordText(BaseText): + def __init__(self, driver, word_id): + super(RecoveryWordText, self).__init__(driver) + self.word_id = word_id + self.locator = self.Locator.accessibility_id("word%s" % word_id) + +class WordNumberText(BaseText): + def __init__(self, driver): + super(WordNumberText, self).__init__(driver) + self.locator = self.Locator.accessibility_id("word-number") + +class ConfirmSeedPhraseInput(BaseEditBox): + def __init__(self, driver): + super(ConfirmSeedPhraseInput, self).__init__(driver) + self.locator = self.Locator.accessibility_id("enter-word") + + +class KeycardView(BaseView): + def __init__(self, driver): + super(KeycardView, self).__init__(driver) + self.begin_setup_button = BeginSetupButton(self.driver) + self.connect_card_button = ConnectCardButton(self.driver) + self.disconnect_card_button = DisconnectCardButton(self.driver) + self.reset_card_state_button = ResetCardButton(self.driver) + + #keyboard + self.one_button = OnePinKeyboardButton(self.driver) + self.two_button = TwoPinKeyboardButton(self.driver) + + #backup seed phrase + self.confirm_seed_phrase_edit_box = ConfirmSeedPhraseInput(self.driver) + + def enter_default_pin(self): + for _ in range(3): + self.one_button.click() + self.two_button.click() + + def get_recovery_word(self, word_id): + word_element = RecoveryWordText(self.driver, word_id) + return word_element.text + + def get_required_word_number(self): + description = WordNumberText(self.driver) + full_text = description.text + if ("11" in full_text) or ("12" in full_text): + word_number = full_text[-2:] + else: + word_number = full_text[-1] + return word_number + + def backup_seed_phrase(self): + recovery_phrase = dict() + for i in range(0,12): + word = self.get_recovery_word(i) + recovery_phrase[str(i+1)] = word + self.confirm_button.click() + self.yes_button.click() + for _ in range(2): + number = self.get_required_word_number() + self.confirm_seed_phrase_edit_box.set_value(recovery_phrase[number]) + self.next_button.click() diff --git a/test/appium/views/sign_in_view.py b/test/appium/views/sign_in_view.py index 251640929e..fd14c50a79 100644 --- a/test/appium/views/sign_in_view.py +++ b/test/appium/views/sign_in_view.py @@ -5,7 +5,6 @@ from tests import common_password from views.base_element import BaseButton, BaseEditBox, BaseText from views.base_view import BaseView - class MultiAccountButton(BaseButton): class Username(BaseText): def __init__(self, driver, locator_value): @@ -78,6 +77,21 @@ class RecoverAccessButton(BaseButton): from views.recover_access_view import RecoverAccessView return RecoverAccessView(self.driver) +class KeycardKeyStorageButton(BaseButton): + + def __init__(self, driver): + super(KeycardKeyStorageButton, self).__init__(driver) + self.locator = self.Locator.accessibility_id("select-storage-:advanced") + + def navigate(self): + from views.keycard_view import KeycardView + return KeycardView(self.driver) + + def click(self): + self.scroll_to_element().click() + return self.navigate() + + class CreateMultiaccountButton(BaseButton): def __init__(self, driver): @@ -200,16 +214,30 @@ class SignInView(BaseView): self.multi_account_on_login_button = MultiAccountOnLoginButton(self.driver) self.privacy_policy_link = PrivacyPolicyLink(self.driver) self.lets_go_button = LetsGoButton(self.driver) + self.keycard_storage_button = KeycardKeyStorageButton(self.driver) - def create_user(self, password=common_password): + def create_user(self, password=common_password, keycard=False): self.get_started_button.click() self.generate_key_button.click() self.next_button.click() - self.next_button.click() - self.create_password_input.set_value(password) - self.next_button.click() - self.confirm_your_password_input.set_value(password) - self.next_button.click() + if keycard: + keycard_flow = self.keycard_storage_button.click() + self.next_button.click() + keycard_flow.begin_setup_button.click() + keycard_flow.connect_card_button.click() + keycard_flow.enter_default_pin() + keycard_flow.enter_default_pin() + self.next_button.scroll_to_element() + self.next_button.wait_for_visibility_of_element(20) + self.next_button.click() + self.yes_button.click() + keycard_flow.backup_seed_phrase() + else: + self.next_button.click() + self.create_password_input.set_value(password) + self.next_button.click() + self.confirm_your_password_input.set_value(password) + self.next_button.click() self.lets_go_button.wait_for_visibility_of_element(30) self.lets_go_button.click_until_absense_of_element(self.lets_go_button) self.profile_button.wait_for_visibility_of_element(30) @@ -231,11 +259,17 @@ class SignInView(BaseView): self.profile_button.wait_for_visibility_of_element(30) return self.get_home_view() - def sign_in(self, password=common_password): + def sign_in(self, password=common_password, keycard=False): self.multi_account_on_login_button.wait_for_visibility_of_element(5) self.multi_account_on_login_button.click() - self.password_input.set_value(password) - self.sign_in_button.click() + if keycard: + from views.keycard_view import KeycardView + keycard_view = KeycardView(self.driver) + keycard_view.enter_default_pin() + keycard_view.connect_card_button.click() + else: + self.password_input.set_value(password) + self.sign_in_button.click() return self.get_home_view() def get_account_by_position(self, position: int): diff --git a/test/appium/views/wallet_view.py b/test/appium/views/wallet_view.py index 7c5383f6f8..ad26183754 100644 --- a/test/appium/views/wallet_view.py +++ b/test/appium/views/wallet_view.py @@ -224,6 +224,12 @@ class AccountElementButton(BaseButton): amount_text.locator = amount_text.Locator.xpath_selector(self.locator.value + "//*[@text=' USD']") return amount_text.is_element_image_equals_template(expected_color_image_name) +class StatusAccountTotalValueText(BaseText): + def __init__(self, driver): + super(StatusAccountTotalValueText, self).__init__(driver) + self.locator = self.Locator.accessibility_id('account-total-value') + + class SendTransactionButton(BaseButton): @@ -382,6 +388,7 @@ class WalletView(BaseView): self.add_custom_token_button = AddCustomTokenButton(self.driver) # elements for multiaccount + self.multiaccount_more_options = MultiaccountMoreOptions(self.driver) self.accounts_status_account = AccountElementButton(self.driver, account_name="Status account") self.collectibles_button = CollectiblesButton(self.driver) @@ -401,6 +408,7 @@ class WalletView(BaseView): self.account_name_input = AccountNameInput(self.driver) self.account_color_button = AccountColorButton(self.driver) self.add_account_generate_account_button = AddAccountGenerateAnAccountButton(self.driver) + self.status_account_total_usd_value = StatusAccountTotalValueText(self.driver) # individual account settings self.account_settings_button = AccountSettingsButton(self.driver)