From adc9b523bee55b2cd74e5ca61896ecc91be5d103 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 21 Nov 2023 16:55:46 +0100 Subject: [PATCH] tests: fix small irregularities --- .../src/trezor/ui/layouts/mercury/__init__.py | 3 +- core/src/trezor/ui/layouts/tr/__init__.py | 4 +- core/src/trezor/ui/layouts/tt/__init__.py | 3 +- core/src/trezor/ui/layouts/tt/recovery.py | 2 +- tests/click_tests/common.py | 12 +- tests/click_tests/reset.py | 9 +- .../click_tests/test_backup_slip39_custom.py | 15 ++- tests/click_tests/test_lock.py | 3 +- tests/click_tests/test_repeated_backup.py | 25 +--- tests/click_tests/test_reset_bip39.py | 12 +- .../click_tests/test_reset_slip39_advanced.py | 20 +++ tests/click_tests/test_reset_slip39_basic.py | 20 +++ tests/common.py | 10 +- .../test_recovery_slip39_advanced.py | 1 + .../test_msg_change_wipe_code_t2.py | 2 +- tests/device_tests/test_msg_changepin_t2.py | 2 +- tests/input_flows.py | 123 +++++++++--------- tests/input_flows_helpers.py | 58 +++++---- tests/persistence_tests/test_wipe_code.py | 6 +- 19 files changed, 186 insertions(+), 144 deletions(-) diff --git a/core/src/trezor/ui/layouts/mercury/__init__.py b/core/src/trezor/ui/layouts/mercury/__init__.py index a740cd4c8..0605ccb0a 100644 --- a/core/src/trezor/ui/layouts/mercury/__init__.py +++ b/core/src/trezor/ui/layouts/mercury/__init__.py @@ -1151,6 +1151,7 @@ async def confirm_reenter_pin(is_wipe_code: bool = False) -> None: def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[ui.UiResult]: title = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch description = TR.wipe_code__enter_new if is_wipe_code else TR.pin__reenter_new + br_name = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch" return interact( error_popup( @@ -1158,7 +1159,7 @@ def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[ui.UiResult]: description, button=TR.buttons__try_again, ), - "pin_mismatch", + br_name, BR_CODE_OTHER, ) diff --git a/core/src/trezor/ui/layouts/tr/__init__.py b/core/src/trezor/ui/layouts/tr/__init__.py index 047a1587e..c55726fa3 100644 --- a/core/src/trezor/ui/layouts/tr/__init__.py +++ b/core/src/trezor/ui/layouts/tr/__init__.py @@ -1263,9 +1263,9 @@ def _confirm_multiple_pages_texts( def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[None]: description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch - br_code = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch" + br_name = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch" layout = show_warning( - br_code, + br_name, description, TR.pin__please_check_again, TR.buttons__check_again, diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index 9db8af480..9202c4348 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -1213,6 +1213,7 @@ async def confirm_reenter_pin(is_wipe_code: bool = False) -> None: def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[None]: title = TR.wipe_code__wipe_code_mismatch if is_wipe_code else TR.pin__pin_mismatch + br_name = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch" description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch return interact( error_popup( @@ -1220,7 +1221,7 @@ def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[None]: description, button=TR.buttons__try_again, ), - "pin_mismatch", + br_name, BR_CODE_OTHER, raise_on_cancel=None, ) diff --git a/core/src/trezor/ui/layouts/tt/recovery.py b/core/src/trezor/ui/layouts/tt/recovery.py index ca7e163ba..b751039df 100644 --- a/core/src/trezor/ui/layouts/tt/recovery.py +++ b/core/src/trezor/ui/layouts/tt/recovery.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: async def request_word_count(recovery_type: RecoveryType) -> int: count = await interact( trezorui2.select_word_count(recovery_type=recovery_type), - "word_count", + "recovery_word_count", ButtonRequestType.MnemonicWordCount, ) return int(count) diff --git a/tests/click_tests/common.py b/tests/click_tests/common.py index ee48fa1d0..cd1c1edf6 100644 --- a/tests/click_tests/common.py +++ b/tests/click_tests/common.py @@ -47,9 +47,9 @@ def get_char_category(char: str) -> PassphraseCategory: def go_next(debug: "DebugLink") -> LayoutContent: if debug.layout_type is LayoutType.TT: - return debug.click(buttons.OK) # type: ignore + return debug.click(buttons.OK) elif debug.layout_type is LayoutType.TR: - return debug.press_right() # type: ignore + return debug.press_right() elif debug.layout_type is LayoutType.Mercury: return debug.swipe_up() else: @@ -58,18 +58,18 @@ def go_next(debug: "DebugLink") -> LayoutContent: def tap_to_confirm(debug: "DebugLink") -> LayoutContent: if debug.layout_type is LayoutType.TT: - return debug.read_layout() # type: ignore + return debug.read_layout() elif debug.layout_type is LayoutType.TR: - return debug.read_layout() # type: ignore + return debug.read_layout() elif debug.layout_type is LayoutType.Mercury: - return debug.click(buttons.TAP_TO_CONFIRM, ) + return debug.click(buttons.TAP_TO_CONFIRM) else: raise RuntimeError("Unknown model") def go_back(debug: "DebugLink", r_middle: bool = False) -> LayoutContent: if debug.layout_type in (LayoutType.TT, LayoutType.Mercury): - return debug.click(buttons.CANCEL) # type: ignore + return debug.click(buttons.CANCEL) elif debug.layout_type is LayoutType.TR: if r_middle: return debug.press_middle() diff --git a/tests/click_tests/reset.py b/tests/click_tests/reset.py index 4bbc91fcb..b5c601ba3 100644 --- a/tests/click_tests/reset.py +++ b/tests/click_tests/reset.py @@ -19,10 +19,15 @@ def confirm_new_wallet(debug: "DebugLink") -> None: elif debug.layout_type is LayoutType.Mercury: debug.swipe_up() debug.click(buttons.TAP_TO_CONFIRM) - debug.swipe_up() # Wallet created elif debug.layout_type is LayoutType.TR: debug.press_right() debug.press_right() + TR.assert_in_multiple( + debug.read_layout().text_content(), + ["backup__new_wallet_successfully_created", "backup__new_wallet_created"], + ) + if debug.layout_type is LayoutType.Mercury: + debug.swipe_up() def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None: @@ -109,7 +114,7 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]: if debug.layout_type is LayoutType.TT: debug.click(buttons.OK, hold_ms=1500) elif debug.layout_type is LayoutType.Mercury: - debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1500) + debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1500) elif debug.layout_type is LayoutType.TR: debug.press_right(hold_ms=1200) else: diff --git a/tests/click_tests/test_backup_slip39_custom.py b/tests/click_tests/test_backup_slip39_custom.py index 2a99f9744..654d9db2f 100644 --- a/tests/click_tests/test_backup_slip39_custom.py +++ b/tests/click_tests/test_backup_slip39_custom.py @@ -22,6 +22,7 @@ from trezorlib import device, messages from trezorlib.debuglink import LayoutType from ..common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy +from .. import translations as TR from . import reset if TYPE_CHECKING: @@ -73,15 +74,17 @@ def test_backup_slip39_custom( groups=[(share_threshold, share_count)], ) - # confirm backup warning - reset.confirm_read(debug, middle_r=True) + # confirm backup configuration if share_count > 1: - # confirm shamir warning - reset.confirm_read(debug, middle_r=True) + TR.assert_template(debug.read_layout().text_content(), "reset__create_x_of_y_multi_share_backup_template") else: - # confirm backup intro - reset.confirm_read(debug, middle_r=True) + TR.assert_template(debug.read_layout().text_content(), "backup__info_single_share_backup") + reset.confirm_read(debug) + + # confirm backup intro + TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy") + reset.confirm_read(debug, middle_r=True) all_words: list[str] = [] for _ in range(share_count): diff --git a/tests/click_tests/test_lock.py b/tests/click_tests/test_lock.py index 4088ae858..4b719885e 100644 --- a/tests/click_tests/test_lock.py +++ b/tests/click_tests/test_lock.py @@ -79,8 +79,7 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): # unlock by touching if debug.layout_type is LayoutType.TR: - # Doing a short HTC to simulate a click - layout = debug.press_right(hold_ms=100) + layout = debug.press_right() else: layout = debug.click(buttons.INFO) assert "PinKeyboard" in layout.all_components() diff --git a/tests/click_tests/test_repeated_backup.py b/tests/click_tests/test_repeated_backup.py index b8d1cbb02..d61d97962 100644 --- a/tests/click_tests/test_repeated_backup.py +++ b/tests/click_tests/test_repeated_backup.py @@ -51,10 +51,8 @@ def test_repeated_backup( # confirm new wallet reset.confirm_new_wallet(debug) - # confirm back up reset.confirm_read(debug) - # confirm backup intro reset.confirm_read(debug) @@ -65,34 +63,24 @@ def test_repeated_backup( # confirm checklist reset.confirm_read(debug) - # shares=1 reset.set_selection(debug, buttons.reset_minus(model_name), 5 - 1) - # confirm checklist reset.confirm_read(debug) - # threshold=1 reset.set_selection(debug, buttons.reset_plus(model_name), 0) - # confirm checklist reset.confirm_read(debug) - # confirm backup warning reset.confirm_read(debug, middle_r=True) - # read words initial_backup_1_of_1 = reset.read_words(debug) - # confirm words reset.confirm_words(debug, initial_backup_1_of_1) - # confirm share checked reset.confirm_read(debug) - # confirm backup done reset.confirm_read(debug) - # Your backup is done go_next(debug) @@ -112,7 +100,6 @@ def test_repeated_backup( ) recovery.confirm_recovery(debug, "recovery__title_unlock_repeated_backup") - recovery.select_number_of_words(debug, num_of_words=20, unlock_repeated_backup=True) recovery.enter_seed( debug, @@ -123,8 +110,6 @@ def test_repeated_backup( ) # backup is enabled - go_next(debug) - assert device_handler.result().message == "Backup unlocked" # we are now in recovery mode @@ -136,29 +121,21 @@ def test_repeated_backup( assert features.recovery_status == messages.RecoveryStatus.Backup # at this point, the backup is unlocked... + go_next(debug) # ... so let's try to do a 2-of-3 backup - - debug.read_layout() - # confirm backup intro reset.confirm_read(debug) - # confirm checklist reset.confirm_read(debug) - # shares=3 reset.set_selection(debug, buttons.reset_minus(model_name), 5 - 3) - # confirm checklist reset.confirm_read(debug) - # threshold=2 reset.set_selection(debug, buttons.reset_minus(model_name), 1) - # confirm checklist reset.confirm_read(debug) - # confirm backup warning reset.confirm_read(debug, middle_r=True) diff --git a/tests/click_tests/test_reset_bip39.py b/tests/click_tests/test_reset_bip39.py index 9af853f84..81af5d49b 100644 --- a/tests/click_tests/test_reset_bip39.py +++ b/tests/click_tests/test_reset_bip39.py @@ -21,6 +21,7 @@ import pytest from trezorlib import device, messages from ..common import WITH_MOCK_URANDOM +from .. import translations as TR from . import reset from .common import go_next @@ -50,12 +51,21 @@ def test_reset_bip39(device_handler: "BackgroundDeviceHandler"): reset.confirm_new_wallet(debug) # confirm back up + TR.assert_in_multiple( + debug.read_layout().text_content(), + ["backup__it_should_be_backed_up", "backup__it_should_be_backed_up_now"], + ) reset.confirm_read(debug) # confirm backup intro - reset.confirm_read(debug, middle_r=True) + # parametrized string + TR.assert_template( + debug.read_layout().text_content(), "backup__info_single_share_backup" + ) + reset.confirm_read(debug) # confirm backup warning + TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy") reset.confirm_read(debug, middle_r=True) # read words diff --git a/tests/click_tests/test_reset_slip39_advanced.py b/tests/click_tests/test_reset_slip39_advanced.py index 0d8a2d95b..4634843f1 100644 --- a/tests/click_tests/test_reset_slip39_advanced.py +++ b/tests/click_tests/test_reset_slip39_advanced.py @@ -21,6 +21,7 @@ import pytest from trezorlib import device, messages from .. import buttons +from .. import translations as TR from ..common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy from . import reset @@ -62,12 +63,20 @@ def test_reset_slip39_advanced( reset.confirm_new_wallet(debug) # confirm back up + TR.assert_in_multiple( + debug.read_layout().text_content(), + ["backup__it_should_be_backed_up", "backup__it_should_be_backed_up_now"], + ) reset.confirm_read(debug) # confirm backup intro + TR.assert_in(debug.read_layout().text_content(), "backup__info_multi_share_backup") reset.confirm_read(debug) # confirm checklist + TR.assert_in( + debug.read_layout().text_content(), "reset__slip39_checklist_num_groups" + ) reset.confirm_read(debug) # set num of groups - default is 5 @@ -79,6 +88,9 @@ def test_reset_slip39_advanced( reset.set_selection(debug, buttons.reset_plus(model_name), group_count - 5) # confirm checklist + TR.assert_in( + debug.read_layout().text_content(), "reset__slip39_checklist_set_threshold" + ) reset.confirm_read(debug) # set group threshold @@ -91,6 +103,13 @@ def test_reset_slip39_advanced( raise RuntimeError("not a supported combination") # confirm checklist + TR.assert_in_multiple( + debug.read_layout().text_content(), + [ + "reset__slip39_checklist_set_sizes", + "reset__slip39_checklist_set_sizes_longer", + ], + ) reset.confirm_read(debug) # set share num and threshold for groups @@ -111,6 +130,7 @@ def test_reset_slip39_advanced( raise RuntimeError("not a supported combination") # confirm backup warning + TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy") reset.confirm_read(debug, middle_r=True) all_words: list[str] = [] diff --git a/tests/click_tests/test_reset_slip39_basic.py b/tests/click_tests/test_reset_slip39_basic.py index b34827e86..a10106c3b 100644 --- a/tests/click_tests/test_reset_slip39_basic.py +++ b/tests/click_tests/test_reset_slip39_basic.py @@ -21,6 +21,7 @@ import pytest from trezorlib import device, messages from .. import buttons +from .. import translations as TR from ..common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy from . import reset @@ -59,12 +60,20 @@ def test_reset_slip39_basic( reset.confirm_new_wallet(debug) # confirm back up + TR.assert_in_multiple( + debug.read_layout().text_content(), + ["backup__it_should_be_backed_up", "backup__it_should_be_backed_up_now"], + ) reset.confirm_read(debug) # confirm backup intro + TR.assert_in(debug.read_layout().text_content(), "backup__info_multi_share_backup") reset.confirm_read(debug) # confirm checklist + TR.assert_in( + debug.read_layout().text_content(), "reset__slip39_checklist_num_shares" + ) reset.confirm_read(debug) # set num of shares - default is 5 @@ -76,6 +85,9 @@ def test_reset_slip39_basic( reset.set_selection(debug, buttons.reset_plus(model_name), num_of_shares - 5) # confirm checklist + TR.assert_in( + debug.read_layout().text_content(), "reset__slip39_checklist_set_threshold" + ) reset.confirm_read(debug) # set threshold @@ -88,9 +100,17 @@ def test_reset_slip39_basic( raise RuntimeError("not a supported combination") # confirm checklist + TR.assert_in_multiple( + debug.read_layout().text_content(), + [ + "reset__slip39_checklist_write_down", + "reset__slip39_checklist_write_down_recovery", + ], + ) reset.confirm_read(debug) # confirm backup warning + TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy") reset.confirm_read(debug, middle_r=True) all_words: list[str] = [] diff --git a/tests/common.py b/tests/common.py index 964bd3f0c..b2a20bb39 100644 --- a/tests/common.py +++ b/tests/common.py @@ -20,7 +20,7 @@ import json import re import time from pathlib import Path -from typing import TYPE_CHECKING, Generator, Optional +from typing import TYPE_CHECKING, Any, Generator, Optional from unittest import mock import pytest @@ -315,17 +315,17 @@ def check_share( return True -def click_info_button_tt(debug: "DebugLink"): +def click_info_button_tt(debug: "DebugLink") -> Generator[Any, Any, ButtonRequest]: """Click Shamir backup info button and return back.""" debug.press_info() debug.press_yes() - yield + return (yield) def click_info_button_mercury(debug: "DebugLink"): """Click Shamir backup info button and return back.""" - debug.click(buttons.CORNER_BUTTON) - debug.synchronize_at("VerticalMenu") + layout = debug.click(buttons.CORNER_BUTTON) + assert "VerticalMenu" in layout.all_components() debug.click(buttons.VERTICAL_MENU[0]) debug.click(buttons.CORNER_BUTTON) debug.click(buttons.CORNER_BUTTON) diff --git a/tests/device_tests/reset_recovery/test_recovery_slip39_advanced.py b/tests/device_tests/reset_recovery/test_recovery_slip39_advanced.py index c49d8dc01..fa1811173 100644 --- a/tests/device_tests/reset_recovery/test_recovery_slip39_advanced.py +++ b/tests/device_tests/reset_recovery/test_recovery_slip39_advanced.py @@ -75,6 +75,7 @@ def test_secret(client: Client, shares: list[str], secret: str): @pytest.mark.parametrize("shares, secret", VECTORS) @pytest.mark.setup_client(uninitialized=True) +@pytest.mark.models(skip="safe3", reason="safe3 does not have info button") def test_secret_click_info_button(client: Client, shares: list[str], secret: str): _test_secret(client, shares, secret, click_info=True) diff --git a/tests/device_tests/test_msg_change_wipe_code_t2.py b/tests/device_tests/test_msg_change_wipe_code_t2.py index e25374050..27ca3922b 100644 --- a/tests/device_tests/test_msg_change_wipe_code_t2.py +++ b/tests/device_tests/test_msg_change_wipe_code_t2.py @@ -110,7 +110,7 @@ def test_set_remove_wipe_code(client: Client): def test_set_wipe_code_mismatch(client: Client): with client, pytest.raises(TrezorFailure): - IF = InputFlowNewCodeMismatch(client, WIPE_CODE4, WIPE_CODE6) + IF = InputFlowNewCodeMismatch(client, WIPE_CODE4, WIPE_CODE6, what="wipe_code") client.set_input_flow(IF.get()) device.change_wipe_code(client) diff --git a/tests/device_tests/test_msg_changepin_t2.py b/tests/device_tests/test_msg_changepin_t2.py index 599f502ab..023a5821f 100644 --- a/tests/device_tests/test_msg_changepin_t2.py +++ b/tests/device_tests/test_msg_changepin_t2.py @@ -133,7 +133,7 @@ def test_set_failed(client: Client): _check_no_pin(client) with client, pytest.raises(TrezorFailure): - IF = InputFlowNewCodeMismatch(client, PIN4, PIN60) + IF = InputFlowNewCodeMismatch(client, PIN4, PIN60, what="pin") client.set_input_flow(IF.get()) device.change_pin(client) diff --git a/tests/input_flows.py b/tests/input_flows.py index 1d690bb1b..1166a096a 100644 --- a/tests/input_flows.py +++ b/tests/input_flows.py @@ -115,13 +115,15 @@ class InputFlowNewCodeMismatch(InputFlowBase): client: Client, first_code: str, second_code: str, + what: str, ): super().__init__(client) self.first_code = first_code self.second_code = second_code + self.what = what def input_flow_common(self) -> BRGeneratorType: - yield # do you want to set/change the pin/wipe code? + assert (yield).name == f"set_{self.what}" self.debug.press_yes() if self.client.layout_type is LayoutType.TR: @@ -129,19 +131,21 @@ class InputFlowNewCodeMismatch(InputFlowBase): self.debug.press_yes() def input_two_different_pins() -> BRGeneratorType: - yield from self.PIN.setup_new_pin(self.first_code, self.second_code) + yield from self.PIN.setup_new_pin( + self.first_code, self.second_code, what=self.what + ) yield from input_two_different_pins() - yield # PIN mismatch + assert (yield).name == f"{self.what}_mismatch" # PIN mismatch self.debug.press_yes() # try again yield from input_two_different_pins() - yield # PIN mismatch + assert (yield).name == f"{self.what}_mismatch" # PIN mismatch self.debug.press_yes() # try again - yield # PIN entry again + assert (yield).name == "pin_device" # PIN entry again self.debug.press_no() # cancel @@ -463,7 +467,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): # Three xpub pages with the same testing logic for xpub_num in range(3): expected_title = f"MULTISIG XPUB #{xpub_num + 1}\n" + ( - "(YOURS)" if self.index == xpub_num else "(COSIGNER)" + "(Yours)" if self.index == xpub_num else "(Cosigner)" ) layout = self.debug.swipe_left() assert expected_title == layout.title() @@ -499,7 +503,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): # Three xpub pages with the same testing logic for xpub_num in range(3): expected_title = f"MULTISIG XPUB #{xpub_num + 1} " + ( - "(YOURS)" if self.index == xpub_num else "(COSIGNER)" + "(Yours)" if self.index == xpub_num else "(Cosigner)" ) layout = self.debug.press_right() assert expected_title in layout.title() @@ -979,32 +983,17 @@ class InputFlowSignTxInformationReplacement(InputFlowBase): yield # confirm txid self.debug.press_right() self.debug.press_right() - yield # confirm address + yield # modify amount - address + self.debug.press_right() + self.debug.press_right() + yield # modify amount - amount + self.debug.press_right() + yield # modify fee self.debug.press_right() self.debug.press_right() self.debug.press_right() - yield # confirm amount - self.debug.press_right() - self.debug.press_right() - self.debug.press_right() - yield - def input_flow_t3t1(self) -> BRGeneratorType: - yield # confirm txid - self.debug.press_yes() - yield # confirm address - self.debug.press_yes() - # go back to address - self.debug.press_no() - # confirm address - self.debug.press_yes() - yield # confirm amount - self.debug.press_yes() - - yield # transaction summary, press info - self.debug.click(buttons.CORNER_BUTTON) - self.debug.click(buttons.CORNER_BUTTON) - self.debug.press_yes() + input_flow_t3t1 = input_flow_tt def lock_time_input_flow_tt( @@ -1436,23 +1425,29 @@ class InputFlowSlip39BasicBackup(InputFlowBase): self.repeated = repeated def input_flow_tt(self) -> BRGeneratorType: - yield # 1. Checklist + if self.repeated: + assert (yield).name == "confirm_repeated_backup" + self.debug.press_yes() + + assert (yield).name == "backup_intro" self.debug.press_yes() - yield # 2. Number of shares (5) + assert (yield).name == "slip39_checklist" + self.debug.press_yes() + assert (yield).name == "slip39_shares" if self.click_info: - yield from click_info_button_tt(self.debug) - yield # 3. Number of shares (5) + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_shares" self.debug.press_yes() - yield # 4. Checklist + assert (yield).name == "slip39_checklist" self.debug.press_yes() - yield # 4. Threshold (3) + assert (yield).name == "slip39_threshold" if self.click_info: - yield from click_info_button_tt(self.debug) - yield # 5. Threshold (3) + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_threshold" self.debug.press_yes() - yield # 6. Checklist + assert (yield).name == "slip39_checklist" self.debug.press_yes() - yield # 7. Confirm show seeds + assert (yield).name == "backup_warning" self.debug.press_yes() # Mnemonic phrases @@ -1497,26 +1492,26 @@ class InputFlowSlip39BasicBackup(InputFlowBase): def input_flow_t3t1(self) -> BRGeneratorType: if self.repeated: # intro confirmation screen - yield + assert (yield).name == "confirm_repeated_backup" self.debug.press_yes() - yield # 1. Backup intro - self.debug.read_layout() + assert (yield).name == "backup_intro" self.debug.swipe_up() - yield # 2. Checklist - self.debug.read_layout() + assert (yield).name == "slip39_checklist" self.debug.swipe_up() + assert (yield).name == "slip39_shares" if self.click_info: click_info_button_mercury(self.debug) self.debug.swipe_up() - yield # 4. Checklist + assert (yield).name == "slip39_checklist" self.debug.swipe_up() + assert (yield).name == "slip39_threshold" if self.click_info: click_info_button_mercury(self.debug) self.debug.swipe_up() - yield # 6. Checklist + assert (yield).name == "slip39_checklist" self.debug.swipe_up() - yield # 7. Confirm show seeds + assert (yield).name == "backup_warning" self.debug.swipe_up() # Mnemonic phrases @@ -1702,34 +1697,36 @@ class InputFlowSlip39AdvancedBackup(InputFlowBase): self.click_info = click_info def input_flow_tt(self) -> BRGeneratorType: - yield # 1. Backup intro + assert (yield).name == "backup_intro" self.debug.press_yes() - yield # 2. Checklist + assert (yield).name == "slip39_checklist" self.debug.press_yes() - yield # 2. Set and confirm group count + assert (yield).name == "slip39_groups" if self.click_info: - yield from click_info_button_tt(self.debug) - yield # 3. Set and confirm group count + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_groups" self.debug.press_yes() - yield # 4. Checklist + assert (yield).name == "slip39_checklist" self.debug.press_yes() - yield # 4. Set and confirm group threshold + assert (yield).name == "slip39_group_threshold" if self.click_info: - yield from click_info_button_tt(self.debug) - yield # 5. Set and confirm group threshold + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_group_threshold" self.debug.press_yes() - yield # 6. Checklist + assert (yield).name == "slip39_checklist" self.debug.press_yes() for _ in range(5): # for each of 5 groups - yield # Set & Confirm number of shares + assert (yield).name == "slip39_shares" if self.click_info: - yield from click_info_button_tt(self.debug) + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_shares" self.debug.press_yes() - yield # Set & confirm share threshold value + assert (yield).name == "slip39_threshold" if self.click_info: - yield from click_info_button_tt(self.debug) + br = yield from click_info_button_tt(self.debug) + assert br.name == "slip39_threshold" self.debug.press_yes() - yield # Confirm show seeds + assert (yield).name == "backup_warning" self.debug.press_yes() # Mnemonic phrases - show & confirm shares for all groups @@ -2077,7 +2074,7 @@ class InputFlowSlip39BasicRecoveryDryRun(InputFlowBase): yield from self.REC.input_all_slip39_shares(self.shares) if self.mismatch: yield from self.REC.warning_slip39_dryrun_mismatch() - else: + elif not self.unlock_repeated_backup: yield from self.REC.success_slip39_dryrun_valid() diff --git a/tests/input_flows_helpers.py b/tests/input_flows_helpers.py index 92a3dc252..58b04e349 100644 --- a/tests/input_flows_helpers.py +++ b/tests/input_flows_helpers.py @@ -1,3 +1,5 @@ +import typing as t + from trezorlib import messages from trezorlib.debuglink import LayoutType from trezorlib.debuglink import TrezorClientDebugLink as Client @@ -16,18 +18,21 @@ class PinFlow: self.debug = self.client.debug def setup_new_pin( - self, pin: str, second_different_pin: str | None = None + self, + pin: str, + second_different_pin: str | None = None, + what: str = "pin", ) -> BRGeneratorType: - yield # Enter PIN + assert (yield).name == "pin_device" # Enter PIN assert "PinKeyboard" in self.debug.read_layout().all_components() self.debug.input(pin) if self.client.layout_type is LayoutType.TR: - yield # Reenter PIN + assert (yield).name == f"reenter_{what}" # Reenter PIN TR.assert_in( - self.debug.read_layout().text_content(), "pin__reenter_to_confirm" + self.debug.read_layout().text_content(), f"{what}__reenter_to_confirm" ) self.debug.press_yes() - yield # Enter PIN again + assert (yield).name == "pin_device" # Enter PIN again assert "PinKeyboard" in self.debug.read_layout().all_components() if second_different_pin is not None: self.debug.input(second_different_pin) @@ -58,14 +63,14 @@ class RecoveryFlow: return layout.title() + " " + layout.text_content() def confirm_recovery(self) -> BRGeneratorType: - yield + assert (yield).name == "recover_device" TR.assert_in(self._text_content(), "reset__by_continuing") if self.client.layout_type is LayoutType.TR: self.debug.press_right() self.debug.press_yes() def confirm_dry_run(self) -> BRGeneratorType: - yield + assert (yield).name == "confirm_seedcheck" TR.assert_in(self._text_content(), "recovery__check_dry_run") self.debug.press_yes() @@ -93,7 +98,7 @@ class RecoveryFlow: self.debug.press_yes() def enter_your_backup(self) -> BRGeneratorType: - yield + assert (yield).name == "recovery" if self.debug.layout_type is LayoutType.Mercury: TR.assert_in(self._text_content(), "recovery__enter_each_word") else: @@ -109,7 +114,7 @@ class RecoveryFlow: self.debug.press_yes() def enter_any_share(self) -> BRGeneratorType: - yield + assert (yield).name == "recovery" TR.assert_in_multiple( self._text_content(), ["recovery__enter_any_share", "recovery__enter_each_word"], @@ -172,9 +177,9 @@ class RecoveryFlow: self.debug.click(buttons.CORNER_BUTTON) self.debug.synchronize_at("VerticalMenu") self.debug.click(buttons.VERTICAL_MENU[0]) - self.debug.swipe_up() assert (yield).name == "abort_recovery" - self.debug.synchronize_at("PromptScreen") + layout = self.debug.swipe_up() + TR.assert_equals(layout.title(), "recovery__title_cancel_recovery") self.debug.click(buttons.TAP_TO_CONFIRM) else: TR.assert_template( @@ -188,6 +193,7 @@ class RecoveryFlow: def input_number_of_words(self, num_words: int) -> BRGeneratorType: br = yield assert br.code == B.MnemonicWordCount + assert br.name == "recovery_word_count" if self.client.layout_type is LayoutType.TR: TR.assert_in(self.debug.read_layout().title(), "word_count__title") else: @@ -227,7 +233,7 @@ class RecoveryFlow: self.debug.press_yes() def success_share_group_entered(self) -> BRGeneratorType: - yield + assert (yield).name == "share_success" TR.assert_in(self._text_content(), "recovery__you_have_entered") self.debug.press_yes() @@ -274,17 +280,20 @@ class RecoveryFlow: self.debug.press_yes() def success_more_shares_needed( - self, count_needed: int | None = None + self, count_needed: int | None = None, click_ok: bool = True ) -> BRGeneratorType: br = yield + assert br.name == "recovery" text = get_text_possible_pagination(self.debug, br) if count_needed is not None: assert str(count_needed) in text - self.debug.press_yes() + if click_ok: + self.debug.press_yes() def input_mnemonic(self, mnemonic: list[str]) -> BRGeneratorType: br = yield assert br.code == B.MnemonicInput + assert br.name == "mnemonic" assert "MnemonicKeyboard" in self.debug.read_layout().all_components() for _, word in enumerate(mnemonic): self.debug.input(word) @@ -302,27 +311,26 @@ class RecoveryFlow: if index < len(shares) - 1: if has_groups: yield from self.success_share_group_entered() + + yield from self.success_more_shares_needed(click_ok=not click_info) if click_info: if self.client.layout_type is LayoutType.TT: yield from self.tt_click_info() elif self.client.layout_type is LayoutType.Mercury: yield from self.mercury_click_info() - yield from self.success_more_shares_needed() + else: + raise ValueError("Unknown model!") + yield from self.success_more_shares_needed() - def tt_click_info( - self, - ) -> BRGeneratorType: - # Moving through the INFO button - yield + def tt_click_info(self) -> t.Generator[t.Any, t.Any, None]: self.debug.press_info() - self.debug.swipe_up() + br = yield + assert br.name == "show_shares" + for _ in range(br.pages): + self.debug.swipe_up() self.debug.press_yes() def mercury_click_info(self) -> BRGeneratorType: - # Starting on the homepage, handle the repeated button request - br = yield - assert br.name == "recovery" - assert br.code == B.RecoveryHomepage # Moving through the menu into the show_shares screen self.debug.click(buttons.CORNER_BUTTON) self.debug.synchronize_at("VerticalMenu") diff --git a/tests/persistence_tests/test_wipe_code.py b/tests/persistence_tests/test_wipe_code.py index 9ea382272..46dd5a183 100644 --- a/tests/persistence_tests/test_wipe_code.py +++ b/tests/persistence_tests/test_wipe_code.py @@ -1,5 +1,6 @@ from trezorlib import debuglink, device, messages from trezorlib.debuglink import TrezorClientDebugLink as Client +from trezorlib.debuglink import message_filters from ..common import MNEMONIC12 from ..emulators import Emulator, EmulatorWrapper @@ -48,9 +49,8 @@ def test_wipe_code_activate_core(core_emulator: Emulator): ret = core_emulator.client.call_raw(messages.ButtonAck()) # Enter the wipe code instead of the current PIN - assert ret == messages.ButtonRequest( - code=messages.ButtonRequestType.PinEntry, name="pin_device" - ) + expected = message_filters.ButtonRequest(code=messages.ButtonRequestType.PinEntry) + assert expected.match(ret) core_emulator.client._raw_write(messages.ButtonAck()) core_emulator.client.debug.input(WIPE_CODE)