basic e2e keycard

Signed-off-by: Churikova Tetiana <churikova.tm@gmail.com>
This commit is contained in:
Churikova Tetiana 2020-04-03 16:45:45 +02:00
parent efab1d30ed
commit 9b6e7cad6d
No known key found for this signature in database
GPG Key ID: 0D4EA7B33B47E6D8
8 changed files with 235 additions and 42 deletions

View File

@ -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}]]]]])))

View File

@ -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

View File

@ -1,4 +1,3 @@
import pytest
import random
from tests import marks, common_password, get_current_time, unique_password

View File

@ -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()

View File

@ -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):

View File

@ -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()

View File

@ -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):

View File

@ -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)