test: test_setup_keycard_with_existing_account added (#282)

This commit is contained in:
Valentina1133 2023-11-10 12:34:49 +01:00 committed by GitHub
parent 026d0ebb06
commit 7358849af2
11 changed files with 245 additions and 34 deletions

View File

@ -51,5 +51,5 @@ boundaries = {
class ColorCodes(Enum):
GREEN = '#4ebc60'
BLUE = '#4360df'
BLUE = '#2a4af5'

View File

@ -5,16 +5,23 @@ class Keycard(Enum):
KEYCARD_PIN = '000000'
KEYCARD_NAME = 'Test Keycard'
ACCOUNT_NAME = 'Test Account'
KEYCARD_POPUP_HEADER = 'Create a new Keycard account with a new seed phrase'
KEYCARD_POPUP_HEADER_IMPORT = 'Import or restore a Keycard via a seed phrase'
KEYCARD_POPUP_HEADER_CREATE_SEED = 'Create a new Keycard account with a new seed phrase'
KEYCARD_POPUP_HEADER_IMPORT_SEED = 'Import or restore a Keycard via a seed phrase'
KEYCARD_POPUP_HEADER_SET_UP_EXISTING = 'Set up a new Keycard with an existing account'
KEYCARD_INSTRUCTIONS_PLUG_IN = 'Plug in Keycard reader...'
KEYCARD_INSTRUCTIONS_INSERT_KEYCARD = 'Insert Keycard...'
KEYCARD_RECOGNIZED = 'Keycard recognized'
KEYCARD_CHOOSE_PIN = 'Choose a Keycard PIN'
KEYCARD_NOTE = 'It is very important that you do not lose this PIN'
KEYCARD_PIN_NOTE = 'It is very important that you do not lose this PIN'
KEYCARD_REPEAT_PIN = 'Repeat Keycard PIN'
KEYCARD_PIN_SET = 'Keycard PIN set'
KEYCARD_NAME_IT = 'Name this Keycard'
KEYCARD_NAME_KEYCARD = 'Name this Keycard'
KEYCARD_NAME_ACCOUNTS = 'Name accounts'
KEYCARD_NEW_ACCOUNT_CREATED = 'New account successfully created'
KEYCARD_READY = 'Keycard is ready to use!'
KEYCARD_SELECT_KEYPAIR = 'Select a key pair'
KEYCARD_SELECT_WHICH_PAIR = 'Select which key pair youd like to move to this Keycard'
KEYCARD_KEYPAIR_INFO = 'Moving this key pair will require you to use your Keycard to login'
KEYCARD_MIGRATING = 'Migrating key pair to Keycard'
KEYCARD_KEYPAIR_MIGRATED = 'Keypair successfully migrated'
KEYCARD_COMPLETE_MIGRATION = 'To complete migration close Status and log in with your new Keycard'

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@ import typing
import allure
import configs
import driver
from gui.components.base_popup import BasePopup
from gui.elements.button import Button
@ -32,6 +33,8 @@ class KeycardPopup(BasePopup):
self._field_object = QObject('edit_TextEdit')
self._keypair_item = QObject('o_KeyPairItem')
self._keypair_tag = QObject('o_StatusListItemTag')
self._selection_box = QObject('radioButton_StatusRadioButton')
self._keycard_init = QObject('o_KeycardInit')
@property
@allure.step('Get keycard image')
@ -65,19 +68,44 @@ class KeycardPopup(BasePopup):
return phrases
@property
@allure.step('Get keycard name in preview')
def keycard_preview_name(self) -> str:
@allure.step('Get keycard name in keypair')
def keypair_name(self) -> str:
return self._keypair_item.object.title
@property
@allure.step('Get account name in preview')
def account_preview_name(self) -> str:
@allure.step('Get info title in keypair')
def keypair_info_title(self) -> str:
return self._keypair_item.object.beneathTagsTitle
@property
@allure.step('Get account name in keypair')
def keypair_account_name(self) -> str:
return self._keypair_tag.object.title
@property
@allure.step('Get color in preview')
def preview_color(self) -> str:
return str(self._keypair_item.object.beneathTagsIconColor.name)
@allure.step('Get account color in keypair')
def keypair_account_color(self) -> str:
return str(self._keypair_tag.object.bgColor.name)
@property
@allure.step('Get keycard init state')
def keycard_init_state(self) -> str:
return self._keycard_init.object.state
@property
@allure.step('Get selection box "checked" state')
def is_keypair_selection_box_checked(self) -> bool:
return self._selection_box.object.checked
@property
@allure.step('Get next button "enabled" state')
def is_next_button_enabled(self) -> bool:
return driver.waitForObjectExists(self._next_button.real_name, configs.timeouts.UI_LOAD_TIMEOUT_MSEC).enabled
@allure.step('Click selection box on profile keypair')
def click_selection_box_on_keypair(self):
self._selection_box.click()
return self
@allure.step('Set pin')
def input_pin(self, pin):
@ -118,24 +146,42 @@ class KeycardPopup(BasePopup):
@allure.step('Name keycard')
def name_keycard(self, name: str):
driver.type(self.get_text_fields[0], name)
return self
@allure.step('Name account')
def name_account(self, name: str):
driver.type(self.get_text_fields[0], name)
return self
@allure.step('Create keycard account with seed phrase')
def create_keycard_account_with_seed_phrase(self, keycard_name: str, account_name: str):
self.reveal_seed_phrase_and_confirm_words()
self.name_keycard_and_account(keycard_name, account_name)
@allure.step('Reveal seed phrase and confirm words')
def reveal_seed_phrase_and_confirm_words(self):
time.sleep(1)
self.click_next().reveal_seed_phrase()
seed_phrases = self.get_seed_phrases
self.click_next()
self.confirm_first_word(seed_phrases).confirm_second_word(seed_phrases).confirm_third_word(seed_phrases)
self.click_next().name_keycard(keycard_name)
self.click_next().name_account(account_name)
self.click_next()
@allure.step('Name keycard and account')
def name_keycard_and_account(self, keycard_name, account_name):
self.name_keycard(keycard_name).click_next()
self.name_account(account_name).click_next()
@allure.step('Import keycard via seed phrase')
def import_keycard_via_seed_phrase(self, seed_phrase_words: list, pin: str, keycard_name: str, account_name: str):
self.input_seed_phrase(seed_phrase_words)
self.name_keycard_and_account(keycard_name, account_name)
self.input_pin(pin)
self.input_pin(pin)
self.click_next()
def input_seed_phrase(self, seed_phrase_words: list):
self.click_next()
if len(seed_phrase_words) == 12:
self._seed_phrase_12_words_button.click()
elif len(seed_phrase_words) == 18:
@ -148,8 +194,3 @@ class KeycardPopup(BasePopup):
self._seed_phrase_word_text_edit.real_name['objectName'] = f'statusSeedPhraseInputField{count}'
self._seed_phrase_word_text_edit.text = word
self.click_next()
self.input_pin(pin)
self.input_pin(pin)
self.click_next().name_keycard(keycard_name)
self.click_next().name_account(account_name)
self.click_next()

View File

@ -1,9 +1,12 @@
import time
import typing
import allure
import driver
from gui.elements.button import Button
from gui.elements.object import QObject
from gui.elements.scroll import Scroll
from gui.elements.window import Window
@ -16,12 +19,20 @@ class MockedKeycardController(Window):
self._insert_keycard_1_button = Button('insert_Keycard_1_StatusButton')
self._insert_keycard_2_button = Button('insert_Keycard_2_StatusButton')
self._remove_keycard_button = Button('remove_Keycard_StatusButton')
self._reader_unplugged_button = Button('set_initial_reader_state_StatusButton')
self._empty_keycard_button = Button('set_initial_keycard_state_StatusButton')
self._reader_state_button = Button('set_initial_reader_state_StatusButton')
self._keycard_state_button = Button('set_initial_keycard_state_StatusButton')
self._register_keycard_button = Button('register_Keycard_StatusButton')
self._reader_unplugged_item = QObject('reader_Unplugged_StatusMenuItem')
self._keycard_not_inserted_item = QObject('keycard_Not_Inserted_StatusMenuItem')
self._keycard_inserted_item = QObject('keycard_Inserted_StatusMenuItem')
self._custom_keycard_item = QObject('custom_Keycard_StatusMenuItem')
self._field_object = QObject('keycard_edit_TextEdit')
self._scroll = Scroll('keycardFlickable')
@property
@allure.step('Get text fields')
def get_text_fields(self) -> typing.List[str]:
return driver.findAllObjects(self._field_object.real_name)
@allure.step('Click Plug in reader')
def plugin_reader(self):
@ -33,6 +44,8 @@ class MockedKeycardController(Window):
@allure.step('Click Register keycard')
def register_keycard(self):
time.sleep(1)
if not self._register_keycard_button.is_visible:
self._scroll.vertical_down_to(self._register_keycard_button)
self._register_keycard_button.click()
time.sleep(1)
return self
@ -42,3 +55,19 @@ class MockedKeycardController(Window):
self._insert_keycard_1_button.click()
time.sleep(1)
return self
@allure.step('Choose custom keycard from initial keycard state dropdown')
def choose_custom_keycard(self):
if not self._keycard_state_button.is_visible:
self._scroll.vertical_scroll_to(self._keycard_state_button)
self._keycard_state_button.click()
self._custom_keycard_item.click()
time.sleep(1)
return self
@allure.step('Input custom keycard details to custom text field')
def input_custom_keycard_details(self, details: str, index: int):
fields = self.get_text_fields
self._scroll.vertical_scroll_to(QObject(name='', real_name=driver.objectMap.realName(fields[index])))
driver.type(fields[index], details)
time.sleep(1)

View File

@ -191,8 +191,7 @@ delete_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow
# Authenticate Popup
keycardSharedPopupContent_KeycardPopupContent = {"container": statusDesktop_mainWindow_overlay, "objectName": "KeycardSharedPopupContent", "type": "KeycardPopupContent", "visible": True}
password_PlaceholderText = {"container": statusDesktop_mainWindow_overlay, "type": "PlaceholderText", "unnamed": 1, "visible": True}
authenticate_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "PrimaryButton", "type": "StatusButton", "visible": True}
authenticate_StatusButton = {"container": statusDesktop_mainWindow_overlay, "objectName": "PrimaryButton", "text": "Authenticate", "type": "StatusButton", "visible": True}
# Shared Popup
sharedPopup_Popup_Content = {"container": statusDesktop_mainWindow, "objectName": "KeycardSharedPopupContent", "type": "Item"}
@ -335,6 +334,7 @@ word1_StatusInput = {"container": statusDesktop_mainWindow_overlay, "id": "word1
word2_StatusInput = {"container": statusDesktop_mainWindow_overlay, "id": "word2", "type": "StatusInput", "unnamed": 1, "visible": True}
o_KeyPairItem = {"container": statusDesktop_mainWindow_overlay, "type": "KeyPairItem", "unnamed": 1, "visible": True}
o_StatusListItemTag = {"container": statusDesktop_mainWindow_overlay, "type": "StatusListItemTag", "unnamed": 1, "visible": True}
radioButton_StatusRadioButton = {"checkable": True, "container": statusDesktop_mainWindow_overlay, "id": "radioButton", "type": "StatusRadioButton", "unnamed": 1, "visible": True}
statusSeedPhraseInputField_TextEdit = {"container": statusDesktop_mainWindow_overlay, "objectName": "statusSeedPhraseInputField", "type": "TextEdit", "visible": True}
switchTabBar_StatusSwitchTabBar = {"container": statusDesktop_mainWindow_overlay, "id": "switchTabBar", "type": "StatusSwitchTabBar", "unnamed": 1, "visible": True}
switchTabBar_12_words_StatusSwitchTabButton = {"checkable": True, "container": switchTabBar_StatusSwitchTabBar, "objectName": "12SeedButton", "text": "12 words", "type": "StatusSwitchTabButton", "visible": True}

View File

@ -18,8 +18,11 @@ max_PIN_Retries_Reached_StatusMenuItem = {"checkable": False, "container": mocke
max_PUK_Retries_Reached_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "maxPUKRetriesReachedAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
keycard_With_Mnemonic_Only_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "keycardWithMnemonicOnlyAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
keycard_With_Mnemonic_Metadata_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "keycardWithMnemonicAndMedatadaAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
custom_Keycard_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "customKeycardAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
custom_Keycard_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "customKeycardAction", "type": "StatusMenuItem", "visible": True}
reader_Unplugged_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "readerStateReaderUnpluggedAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
keycard_Not_Inserted_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "readerStateKeycardNotInsertedAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
keycard_Inserted_StatusMenuItem = {"checkable": False, "container": mocked_Keycard_Lib_Controller_Overlay, "enabled": True, "objectName": "readerStateKeycardInsertedAction", "type": "StatusMenuItem", "unnamed": 1, "visible": True}
keycard_edit_TextEdit = {"container": keycardSettingsTab, "id": "edit", "type": "TextEdit", "unnamed": 1, "visible": True}
keycardFlickable = {"container": keycardSettingsTab, "type": "Flickable", "unnamed": 1, "visible": True}

View File

@ -34,6 +34,11 @@ class KeycardSettingsView(QObject):
self._import_restore_via_seed_phrase_button.click()
return KeycardPopup().wait_until_appears()
@allure.step('Choose setup keycard with an existing account')
def click_setup_keycard_with_existing_account(self):
self._setup_keycard_with_existing_account_button.click()
return KeycardPopup().wait_until_appears()
@allure.step('Check that all keycard options displayed')
def all_keycard_options_available(self):
assert self._setup_keycard_with_existing_account_button.is_visible, f'Setup keycard with existing account not visible'

View File

@ -21,9 +21,9 @@ def test_create_keycard_account_with_new_seed_phrase(main_screen: MainWindow, op
keycard_settings = main_screen.left_panel.open_settings().left_panel.open_keycard_settings()
keycard_popup = keycard_settings.click_create_new_account_with_new_seed_phrase()
with (step('Verify displayed keycard popup instructions are correct')):
with step('Verify displayed keycard popup instructions are correct'):
with step('Verify header is correct'):
assert keycard_popup.keycard_header == Keycard.KEYCARD_POPUP_HEADER.value, "The header is incorrect"
assert keycard_popup.keycard_header == Keycard.KEYCARD_POPUP_HEADER_CREATE_SEED.value, "The header is incorrect"
with step('Verify instructions are correct'):
assert Keycard.KEYCARD_INSTRUCTIONS_PLUG_IN.value in keycard_popup.keycard_instructions, \
"There is no correct keycard instruction"
@ -52,7 +52,7 @@ def test_create_keycard_account_with_new_seed_phrase(main_screen: MainWindow, op
with step('Verify that asked to choose PIN'):
assert driver.waitFor(lambda: Keycard.KEYCARD_CHOOSE_PIN.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
assert Keycard.KEYCARD_NOTE.value in keycard_popup.keycard_instructions
assert Keycard.KEYCARD_PIN_NOTE.value in keycard_popup.keycard_instructions
with step('Insert PIN and repeat PIN and verify keycard popup instructions are correct'):
pin = Keycard.KEYCARD_PIN.value
@ -72,8 +72,8 @@ def test_create_keycard_account_with_new_seed_phrase(main_screen: MainWindow, op
assert driver.waitFor(lambda: Keycard.KEYCARD_NEW_ACCOUNT_CREATED.value in keycard_popup.keycard_instructions), \
"There is no correct keycard instruction"
assert keycard_popup.keycard_preview_name == keycard_name, "Keycard name in preview is incorrect"
assert keycard_popup.account_preview_name == account_name, "Account name in preview is incorrect"
assert keycard_popup.preview_color == ColorCodes.BLUE.value, "Color in preview is incorrect"
assert keycard_popup.keypair_name == keycard_name, "Keycard name in preview is incorrect"
assert keycard_popup.keypair_account_name == account_name, "Account name in preview is incorrect"
assert keycard_popup.keypair_account_color == ColorCodes.BLUE.value, "Color in preview is incorrect"
keycard_popup.click_next()

View File

@ -25,7 +25,7 @@ def test_import_restore_keycard_via_seed_phrase(main_screen: MainWindow, user_ac
with (step('Verify displayed keycard popup instructions are correct')):
with step('Verify header is correct'):
assert keycard_popup.keycard_header == Keycard.KEYCARD_POPUP_HEADER_IMPORT.value, "The header is incorrect"
assert keycard_popup.keycard_header == Keycard.KEYCARD_POPUP_HEADER_IMPORT_SEED.value, "The header is incorrect"
with step('Verify instructions are correct'):
assert Keycard.KEYCARD_INSTRUCTIONS_PLUG_IN.value in keycard_popup.keycard_instructions, \
"There is no correct keycard instruction"
@ -62,8 +62,8 @@ def test_import_restore_keycard_via_seed_phrase(main_screen: MainWindow, user_ac
assert driver.waitFor(lambda: Keycard.KEYCARD_READY.value in keycard_popup.keycard_instructions), \
"There is no correct keycard instruction"
assert keycard_popup.keycard_preview_name == keycard_name, "Keycard name in preview is incorrect"
assert keycard_popup.account_preview_name == account_name, "Account name in preview is incorrect"
assert keycard_popup.preview_color == ColorCodes.BLUE.value, "Color in preview is incorrect"
assert keycard_popup.keypair_name == keycard_name, "Keycard name in preview is incorrect"
assert keycard_popup.keypair_account_name == account_name, "Account name in preview is incorrect"
assert keycard_popup.keypair_account_color == ColorCodes.BLUE.value, "Color in preview is incorrect"
keycard_popup.click_next()

View File

@ -0,0 +1,125 @@
from pathlib import Path
import allure
import pytest
from allure import step
import configs
import constants
import driver
from constants import ColorCodes, aut_options
from constants.keycard import Keycard
from gui.components.community.authenticate_popup import AuthenticatePopup
from gui.main_window import MainWindow
from gui.mocked_keycard_controller import MockedKeycardController
@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703623',
'Setup a keycard with an existing account')
@pytest.mark.case(703623)
@pytest.mark.parametrize('user_account', [constants.user.user_account_one])
@pytest.mark.parametrize('account_name', [pytest.param('Status account')])
@pytest.mark.parametrize('options', [aut_options.MOCK_KEYCARD])
@pytest.mark.skip(reason="https://github.com/status-im/desktop-qa-automation/issues/274")
def test_setup_keycard_with_existing_account(main_screen: MainWindow, user_account, account_name, options):
main_screen.prepare()
with step('Choose option Setup keycard with existing account in settings'):
keycard_settings = main_screen.left_panel.open_settings().left_panel.open_keycard_settings()
keycard_popup = keycard_settings.click_setup_keycard_with_existing_account()
with step('Verify displayed keycard popup instructions are correct'):
with step('Verify header is correct'):
assert keycard_popup.keycard_header == Keycard.KEYCARD_POPUP_HEADER_SET_UP_EXISTING.value, "The header is incorrect"
with step('Verify instructions are correct'):
assert Keycard.KEYCARD_SELECT_KEYPAIR.value in keycard_popup.keycard_instructions, \
"There is no correct keycard instruction"
assert Keycard.KEYCARD_SELECT_WHICH_PAIR.value in keycard_popup.keycard_instructions, \
"There is no correct keycard instruction"
with step(
'Verify that profile keypair include correct keycard and account name, account color and info title are correct'):
assert keycard_popup.keypair_name == user_account.name, "Keycard name in keypair is incorrect"
assert keycard_popup.keypair_account_name == account_name, "Account name in keypair is incorrect"
assert keycard_popup.keypair_account_color == ColorCodes.BLUE.value, "Account color in keypair is incorrect"
assert keycard_popup.keypair_info_title == Keycard.KEYCARD_KEYPAIR_INFO.value, "Info in keypair is incorrect"
with step('Verify selection box is present and not checked by default'):
assert not keycard_popup.is_keypair_selection_box_checked
with step('Click selection box on keypair and click continue'):
keycard_popup.click_selection_box_on_keypair().click_next()
with step(
'Verify that profile keypair include correct keycard and account name, account color and info title are correct'):
assert keycard_popup.keypair_name == user_account.name, "Keycard name in keypair is incorrect"
assert keycard_popup.keypair_account_name == account_name, "Account name in keypair is incorrect"
assert keycard_popup.keypair_account_color == ColorCodes.BLUE.value, "Account color in keypair is incorrect"
assert keycard_popup.keypair_info_title == Keycard.KEYCARD_KEYPAIR_INFO.value, "Info in keypair is incorrect"
with step('Verify displayed keycard popup instructions are correct'):
assert Keycard.KEYCARD_INSTRUCTIONS_PLUG_IN.value in keycard_popup.keycard_instructions, \
"There is no correct keycard instruction"
with step('Verify input seed phrase button is disabled'):
assert not keycard_popup.is_next_button_enabled
with step('Plug in reader'):
main_screen.hide()
keycard_controller = MockedKeycardController().wait_until_appears()
keycard_controller.plugin_reader()
main_screen.show()
with step('Verify displayed keycard popup instructions are correct'):
assert driver.waitFor(
lambda: Keycard.KEYCARD_INSTRUCTIONS_INSERT_KEYCARD.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
with step('Register and insert custom emtpy keycard with custom details'):
main_screen.hide()
first_details = '{}'
second_details_path = configs.testpath.TEST_FILES / 'Keycard1_details.txt'
second_details = Path(second_details_path).read_text()
keycard_controller.choose_custom_keycard()
keycard_controller.input_custom_keycard_details(first_details, 0)
keycard_controller.input_custom_keycard_details(second_details, 1)
keycard_controller.register_keycard()
keycard_controller.insert_keycard_1()
main_screen.show()
with step('Verify displayed keycard popup instructions are correct'):
with step('Verify keycard is recognized'):
assert driver.waitFor(lambda: Keycard.KEYCARD_RECOGNIZED.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
with step('Verify that asked to choose PIN'):
assert driver.waitFor(lambda: Keycard.KEYCARD_CHOOSE_PIN.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
assert Keycard.KEYCARD_PIN_NOTE.value in keycard_popup.keycard_instructions
with step('Insert PIN and repeat PIN and verify keycard popup instructions are correct'):
pin = Keycard.KEYCARD_PIN.value
keycard_popup.input_pin(pin)
assert driver.waitFor(lambda: Keycard.KEYCARD_REPEAT_PIN.value in keycard_popup.keycard_instructions), \
"There is no correct keycard instruction"
keycard_popup.input_pin(pin)
assert driver.waitFor(lambda: Keycard.KEYCARD_PIN_SET.value in keycard_popup.keycard_instructions), \
"There is no correct keycard instruction"
with step('Create keycard account using new seed phrase'):
keycard_popup.reveal_seed_phrase_and_confirm_words()
authenticate_popup = AuthenticatePopup().wait_until_appears()
authenticate_popup.authenticate(user_account.password)
with step('Verify displayed keycard popup instructions are correct'):
assert driver.waitFor(
lambda: Keycard.KEYCARD_MIGRATING.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
with step('Click on done and verify instructions are correct'):
assert driver.waitFor(
lambda: Keycard.KEYCARD_KEYPAIR_MIGRATED.value in keycard_popup.keycard_instructions,
configs.timeouts.APP_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
assert driver.waitFor(
lambda: Keycard.KEYCARD_COMPLETE_MIGRATION.value in keycard_popup.keycard_instructions,
configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"
keycard_popup.click_next()