diff --git a/constants/images_paths.py b/constants/images_paths.py index d5db236..47f62f3 100644 --- a/constants/images_paths.py +++ b/constants/images_paths.py @@ -9,3 +9,4 @@ KEYCARD_INSERTED_IMAGE_PATH = '/imports/assets/png/keycard/card-inserted.png' CHOOSE_KEYCARD_PIN_IMAGE_PATH = '/imports/assets/png/keycard/enter-pin-0.png' KEYCARD_SUCCESS_IMAGE_PATH = '/imports/assets/png/keycard/strong_success/img-20.png' KEYCARD_RECOGNIZED_IMAGE_PATH = '/imports/assets/png/keycard/success/img-13.png' +KEYCARD_ERROR_IMAGE_PATH = '/imports/assets/png/keycard/plain-error.png' diff --git a/constants/keycard.py b/constants/keycard.py index 0017bca..d28e375 100644 --- a/constants/keycard.py +++ b/constants/keycard.py @@ -3,6 +3,7 @@ from enum import Enum class Keycard(Enum): KEYCARD_PIN = '111111' + KEYCARD_INCORRECT_PIN = '222222' KEYCARD_NAME = 'Test Keycard' ACCOUNT_NAME = 'Test Account' KEYCARD_POPUP_HEADER_CREATE_SEED = 'Create a new Keycard account with a new seed phrase' @@ -13,6 +14,7 @@ class Keycard(Enum): KEYCARD_RECOGNIZED = 'Keycard recognized' KEYCARD_CHOOSE_PIN = 'Choose a Keycard PIN' KEYCARD_ENTER_PIN = "Enter this Keycard’s PIN" + KEYCARD_ENTER_PIN_2 = "Enter Keycard 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' @@ -34,3 +36,10 @@ class Keycard(Enum): KEYCARD_LOCKED = 'Keycard locked' KEYCARD_LOCKED_NOTE = 'You will need to unlock it before proceeding' KEYCARD_ACCOUNTS = 'Accounts on this Keycard' + KEYCARD_FACTORY_RESET_TITLE = 'A factory reset will delete the key on this Keycard.\nAre you sure you want to do this?' + KEYCARD_FACTORY_RESET_SUCCESSFUL = 'Keycard successfully factory reset' + KEYCARD_YOU_CAN_USE_AS_EMPTY = 'You can now use this Keycard as if it\nwas a brand new empty Keycard' + KEYCARD_INCORRECT_PIN_MESSAGE = 'PIN incorrect' + KEYCARD_2_ATTEMPTS_REMAINING = '2 attempts remaining' + KEYCARD_1_ATTEMPT_REMAINING = '1 attempt remaining' + KEYCARD_LOCKED_INCORRECT_PIN = 'Pin entered incorrectly too many times' diff --git a/gui/components/settings/keycard_popup.py b/gui/components/settings/keycard_popup.py index 5a16699..dcbe960 100644 --- a/gui/components/settings/keycard_popup.py +++ b/gui/components/settings/keycard_popup.py @@ -7,6 +7,7 @@ import configs import driver from gui.components.base_popup import BasePopup from gui.elements.button import Button +from gui.elements.check_box import CheckBox from gui.elements.object import QObject from gui.elements.text_edit import TextEdit from gui.elements.text_label import TextLabel @@ -37,6 +38,8 @@ class KeycardPopup(BasePopup): self._selection_box = QObject('radioButton_StatusRadioButton') self._keycard_init = QObject('o_KeycardInit') self._cancel_button = Button('cancel_StatusButton') + self._understand_keypair_deleted_checkbox = CheckBox( + 'i_understand_the_key_pair_on_this_Keycard_will_be_deleted_StatusCheckBox') @property @allure.step('Get keycard image source path') @@ -205,3 +208,7 @@ class KeycardPopup(BasePopup): @allure.step('Click cancel button') def cancel(self): self._cancel_button.click() + + @allure.step('Confirm that understand that keypair will be deleted in checkbox') + def confirm_keypair_will_be_deleted(self, value: bool): + self._understand_keypair_deleted_checkbox.set(value) diff --git a/gui/objects_map/component_names.py b/gui/objects_map/component_names.py index 4e2c13d..7787c6b 100644 --- a/gui/objects_map/component_names.py +++ b/gui/objects_map/component_names.py @@ -343,3 +343,4 @@ switchTabBar_StatusSwitchTabBar = {"container": statusDesktop_mainWindow_overlay switchTabBar_12_words_StatusSwitchTabButton = {"checkable": True, "container": switchTabBar_StatusSwitchTabBar, "objectName": "12SeedButton", "text": "12 words", "type": "StatusSwitchTabButton", "visible": True} switchTabBar_18_words_StatusSwitchTabButton = {"checkable": True, "container": switchTabBar_StatusSwitchTabBar, "objectName": "18SeedButton", "text": "18 words", "type": "StatusSwitchTabButton", "visible": True} switchTabBar_24_words_StatusSwitchTabButton = {"checkable": True, "container": switchTabBar_StatusSwitchTabBar, "objectName": "24SeedButton", "text": "24 words", "type": "StatusSwitchTabButton", "visible": True} +i_understand_the_key_pair_on_this_Keycard_will_be_deleted_StatusCheckBox = {"checkable": True, "container": statusDesktop_mainWindow_overlay, "id": "confirmation", "type": "StatusCheckBox", "visible": True} diff --git a/gui/screens/settings_keycard.py b/gui/screens/settings_keycard.py index 02b4115..dd61ee5 100644 --- a/gui/screens/settings_keycard.py +++ b/gui/screens/settings_keycard.py @@ -44,6 +44,11 @@ class KeycardSettingsView(QObject): self._check_whats_on_keycard_button.click() return KeycardPopup().wait_until_appears() + @allure.step('Choose factory reset a keycard') + def click_factory_reset_keycard(self): + self._factory_reset_keycard_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' diff --git a/tests/settings/settings_keycard/test_factory_reset_keycard.py b/tests/settings/settings_keycard/test_factory_reset_keycard.py new file mode 100644 index 0000000..76a4b4d --- /dev/null +++ b/tests/settings/settings_keycard/test_factory_reset_keycard.py @@ -0,0 +1,158 @@ +import allure +import pytest +from allure_commons._allure import step + +import configs +import constants +import driver +from constants import aut_options +from constants.images_paths import KEYCARD_ERROR_IMAGE_PATH +from constants.keycard import Keycard +from gui.main_window import MainWindow +from gui.mocked_keycard_controller import MockedKeycardController + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/703628', 'Factory reset a Keycard') +@pytest.mark.case(703628) +@pytest.mark.parametrize('user_account', [constants.user.user_account_one]) +@pytest.mark.parametrize('options', [aut_options.MOCK_KEYCARD]) +@pytest.mark.skip(reason="https://github.com/status-im/desktop-qa-automation/issues/274") +def test_factory_reset_keycard(main_screen: MainWindow, user_account, options): + main_screen.prepare() + + with step('Open keycard settings'): + keycard_settings = main_screen.left_panel.open_settings().left_panel.open_keycard_settings() + + with step('Choose option Factory reset a keycard'): + keycard_popup = keycard_settings.click_factory_reset_keycard() + + with step('Insert keycard with accounts on it'): + main_screen.hide() + keycard_controller = MockedKeycardController().wait_until_appears() + keycard_controller.plugin_reader() + keycard_controller.choose_mnemonic_metadata_keycard() + keycard_controller.register_keycard() + keycard_controller.insert_keycard_1() + main_screen.show() + + with step('Enter PIN and verify keycard popup instructions are correct'): + assert driver.waitFor(lambda: Keycard.KEYCARD_ENTER_PIN.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + pin = Keycard.KEYCARD_PIN.value + keycard_name = 'Card-1 Name' + keycard_popup.input_pin(pin) + assert driver.waitFor(lambda: Keycard.KEYCARD_PIN_VERIFIED.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + + with step('Close keycard popup'): + keycard_popup.click_next() + + with step('Verify that preview shows correct keycard and instructions are correct'): + assert driver.waitFor(lambda: Keycard.KEYCARD_ACCOUNTS.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + + assert keycard_popup.keypair_on_keycard_name == keycard_name, "Keycard name in preview is incorrect" + keycard_popup.click_next() + + with step('Verify keycard factory reset title'): + assert driver.waitFor(lambda: Keycard.KEYCARD_FACTORY_RESET_TITLE.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), f"There is no correct keycard instruction {keycard_popup.keycard_instructions}" + + with step('Confirm that keypair will be deleted in checkbox'): + keycard_popup.confirm_keypair_will_be_deleted(True) + keycard_popup.click_next() + + with step('Verify keycard factory successful'): + assert driver.waitFor( + lambda: Keycard.KEYCARD_FACTORY_RESET_SUCCESSFUL.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + assert driver.waitFor( + lambda: Keycard.KEYCARD_YOU_CAN_USE_AS_EMPTY.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + + +@allure.testcase('https://ethstatus.testrail.net/index.php?/cases/view/704606', 'Factory reset a Keycard: incorrect PIN') +@pytest.mark.case(704606) +@pytest.mark.parametrize('user_account', [constants.user.user_account_one]) +@pytest.mark.parametrize('options', [aut_options.MOCK_KEYCARD]) +@pytest.mark.skip(reason="https://github.com/status-im/desktop-qa-automation/issues/274") +def test_factory_reset_keycard_incorrect_pin(main_screen: MainWindow, user_account, options): + main_screen.prepare() + + with step('Open keycard settings'): + keycard_settings = main_screen.left_panel.open_settings().left_panel.open_keycard_settings() + + with step('Choose option Factory reset a keycard'): + keycard_popup = keycard_settings.click_factory_reset_keycard() + + with step('Insert keycard with accounts on it'): + main_screen.hide() + keycard_controller = MockedKeycardController().wait_until_appears() + keycard_controller.plugin_reader() + keycard_controller.choose_mnemonic_metadata_keycard() + keycard_controller.register_keycard() + keycard_controller.insert_keycard_1() + main_screen.show() + + with step('Enter incorrect PIN and verify keycard popup instructions are correct'): + assert driver.waitFor(lambda: Keycard.KEYCARD_ENTER_PIN.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + incorrect_pin = Keycard.KEYCARD_INCORRECT_PIN.value + keycard_popup.input_pin(incorrect_pin) + + assert driver.waitFor( + lambda: Keycard.KEYCARD_INCORRECT_PIN_MESSAGE.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + assert driver.waitFor( + lambda: Keycard.KEYCARD_2_ATTEMPTS_REMAINING.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + assert KEYCARD_ERROR_IMAGE_PATH == keycard_popup.keycard_image_source_path + + with step('Enter incorrect PIN again and verify keycard popup instructions are correct'): + assert driver.waitFor(lambda: Keycard.KEYCARD_ENTER_PIN_2.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + incorrect_pin = Keycard.KEYCARD_INCORRECT_PIN.value + keycard_popup.input_pin(incorrect_pin) + + assert driver.waitFor( + lambda: Keycard.KEYCARD_INCORRECT_PIN_MESSAGE.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + assert driver.waitFor( + lambda: Keycard.KEYCARD_1_ATTEMPT_REMAINING.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + assert KEYCARD_ERROR_IMAGE_PATH == keycard_popup.keycard_image_source_path + + with step('Enter incorrect PIN again and verify keycard popup instructions are correct'): + assert driver.waitFor(lambda: Keycard.KEYCARD_ENTER_PIN_2.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + incorrect_pin = Keycard.KEYCARD_INCORRECT_PIN.value + keycard_popup.input_pin(incorrect_pin) + + assert driver.waitFor( + lambda: Keycard.KEYCARD_LOCKED.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + assert driver.waitFor( + lambda: Keycard.KEYCARD_LOCKED_INCORRECT_PIN.value in keycard_popup.keycard_instructions), \ + "There is no correct keycard instruction" + + with step('Close keycard popup'): + keycard_popup.cancel() + + with step('Choose option Factory reset a keycard'): + keycard_popup = keycard_settings.click_factory_reset_keycard() + + with step('Verify keycard factory reset title'): + assert driver.waitFor(lambda: Keycard.KEYCARD_FACTORY_RESET_TITLE.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), f"There is no correct keycard instruction {keycard_popup.keycard_instructions}" + + with step('Confirm that keypair will be deleted in checkbox'): + keycard_popup.confirm_keypair_will_be_deleted(True) + keycard_popup.click_next() + + with step('Verify keycard factory successful'): + assert driver.waitFor( + lambda: Keycard.KEYCARD_FACTORY_RESET_SUCCESSFUL.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction" + assert driver.waitFor( + lambda: Keycard.KEYCARD_YOU_CAN_USE_AS_EMPTY.value in keycard_popup.keycard_instructions, + configs.timeouts.UI_LOAD_TIMEOUT_MSEC), "There is no correct keycard instruction"