From 162f13c6ea33517107a8932d029f50e9c3665031 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 21 Nov 2023 13:51:59 +0100 Subject: [PATCH] tests: use read_layout everywhere --- tests/click_tests/common.py | 29 ++-- tests/click_tests/recovery.py | 46 +++-- tests/click_tests/reset.py | 44 ++--- tests/click_tests/test_autolock.py | 72 ++++---- tests/click_tests/test_lock.py | 15 +- tests/click_tests/test_passphrase_tr.py | 2 +- tests/click_tests/test_passphrase_tt.py | 14 +- tests/click_tests/test_pin.py | 38 ++-- tests/click_tests/test_tutorial.py | 24 +-- tests/common.py | 14 +- tests/conftest.py | 2 + tests/device_tests/cardano/test_sign_tx.py | 2 +- tests/device_tests/test_busy_state.py | 18 +- tests/device_tests/test_sdcard.py | 2 +- .../test_session_id_and_passphrase.py | 8 +- tests/input_flows.py | 163 +++++++++--------- tests/input_flows_helpers.py | 120 ++++++------- .../test_shamir_persistence.py | 22 +-- 18 files changed, 315 insertions(+), 320 deletions(-) diff --git a/tests/click_tests/common.py b/tests/click_tests/common.py index e6753a669f..16bad617c5 100644 --- a/tests/click_tests/common.py +++ b/tests/click_tests/common.py @@ -42,25 +42,23 @@ def get_char_category(char: str) -> PassphraseCategory: return PassphraseCategory.SPECIAL -def go_next(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: +def go_next(debug: "DebugLink") -> "LayoutContent": if debug.model == "T": - return debug.click(buttons.OK, wait=wait) # type: ignore + return debug.click(buttons.OK) elif debug.model == "Safe 3": - return debug.press_right(wait=wait) # type: ignore + return debug.press_right() else: raise RuntimeError("Unknown model") -def go_back( - debug: "DebugLink", wait: bool = False, r_middle: bool = False -) -> "LayoutContent" | None: +def go_back(debug: "DebugLink", r_middle: bool = False) -> "LayoutContent": if debug.model == "T": - return debug.click(buttons.CANCEL, wait=wait) # type: ignore + return debug.click(buttons.CANCEL) elif debug.model == "Safe 3": if r_middle: - return debug.press_middle(wait=wait) # type: ignore + return debug.press_middle() else: - return debug.press_left(wait=wait) # type: ignore + return debug.press_left() else: raise RuntimeError("Unknown model") @@ -101,10 +99,7 @@ def navigate_to_action_and_press( ) # Press or hold - if hold_ms: - debug.press_middle_htc(1000) - else: - debug.press_middle(wait=True) + debug.press_middle(hold_ms=hold_ms) def _get_action_index(wanted_action: str, all_actions: list[str]) -> int: @@ -136,14 +131,14 @@ def _move_one_closer( if not is_carousel: # Simply move according to the index in a closed list if index_diff > 0: - return debug.press_right(wait=True) + return debug.press_right() else: - return debug.press_left(wait=True) + return debug.press_left() else: # Carousel can move in a circle - over the edges # Always move the shortest way action_half = len(all_actions) // 2 if index_diff > action_half or -action_half < index_diff < 0: - return debug.press_left(wait=True) + return debug.press_left() else: - return debug.press_right(wait=True) + return debug.press_right() diff --git a/tests/click_tests/recovery.py b/tests/click_tests/recovery.py index 306cc75390..ab0edaeb0b 100644 --- a/tests/click_tests/recovery.py +++ b/tests/click_tests/recovery.py @@ -15,7 +15,7 @@ def enter_word( for coords in buttons.type_word(typed_word, is_slip39=is_slip39): debug.click(coords) - return debug.click(buttons.CONFIRM_WORD, wait=True) + return debug.click(buttons.CONFIRM_WORD) elif debug.model == "Safe 3": letter_index = 0 layout = debug.read_layout() @@ -24,36 +24,32 @@ def enter_word( while layout.find_values_by_key("letter_choices"): letter = word[letter_index] while not layout.get_middle_choice() == letter: - layout = debug.press_right(wait=True) + layout = debug.press_right() - layout = debug.press_middle(wait=True) + layout = debug.press_middle() letter_index += 1 # Word choices while not layout.get_middle_choice() == word: - layout = debug.press_right(wait=True) + layout = debug.press_right() - return debug.press_middle(wait=True) + return debug.press_middle() else: raise ValueError("Unknown model") def confirm_recovery(debug: "DebugLink") -> None: - layout = debug.wait_layout() + layout = debug.read_layout() if debug.model == "T": assert layout.title().startswith(("RECOVER WALLET", "BACKUP CHECK")) - debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) elif debug.model == "Safe 3": assert layout.title() == "RECOVER WALLET" - debug.press_right(wait=True) + debug.press_right() debug.press_right() -def select_number_of_words( - debug: "DebugLink", num_of_words: int = 20, wait: bool = True -) -> None: - if wait: - debug.wait_layout() +def select_number_of_words(debug: "DebugLink", num_of_words: int = 20) -> None: if debug.model == "T": assert "number of words" in debug.read_layout().text_content() assert debug.read_layout().title() in ( @@ -68,10 +64,10 @@ def select_number_of_words( num_of_words ) # raises if num of words is invalid coords = buttons.grid34(index % 3, index // 3) - layout = debug.click(coords, wait=True) + layout = debug.click(coords) elif debug.model == "Safe 3": assert "number of words" in debug.read_layout().text_content() - layout = debug.press_right(wait=True) + layout = debug.press_right() assert layout.title() == "NUMBER OF WORDS" @@ -79,8 +75,8 @@ def select_number_of_words( word_options = (12, 18, 20, 24, 33) index = word_options.index(num_of_words) for _ in range(index): - debug.press_right(wait=True) - layout = debug.press_middle(wait=True) + debug.press_right() + layout = debug.press_middle() else: raise ValueError("Unknown model") @@ -94,7 +90,7 @@ def enter_share( debug: "DebugLink", share: str, is_first: bool = True ) -> "LayoutContent": if debug.model == "T": - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert layout.main_component() == "MnemonicKeyboard" for word in share.split(" "): @@ -102,12 +98,12 @@ def enter_share( return layout elif debug.model == "Safe 3": - assert "RECOVER WALLET" in debug.wait_layout().title() - layout = debug.press_right(wait=True) + assert "RECOVER WALLET" in debug.read_layout().title() + layout = debug.press_right() if is_first: # Word entering info debug.press_right() - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "MnemonicKeyboard" in layout.all_components() for word in share.split(" "): @@ -132,14 +128,14 @@ def enter_shares(debug: "DebugLink", shares: list[str]) -> None: def enter_seed(debug: "DebugLink", seed_words: list[str]) -> None: assert "Enter" in debug.read_layout().text_content() if debug.model == "T": - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert layout.main_component() == "MnemonicKeyboard" elif debug.model == "Safe 3": - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "RECOVER WALLET" in layout.title() debug.press_right() - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "MnemonicKeyboard" in layout.all_components() for word in seed_words: @@ -149,6 +145,6 @@ def enter_seed(debug: "DebugLink", seed_words: list[str]) -> None: def finalize(debug: "DebugLink") -> None: - layout = go_next(debug, wait=True) + layout = go_next(debug) assert layout is not None assert layout.main_component() == "Homescreen" diff --git a/tests/click_tests/reset.py b/tests/click_tests/reset.py index 5824cc1533..e220264247 100644 --- a/tests/click_tests/reset.py +++ b/tests/click_tests/reset.py @@ -11,13 +11,13 @@ if TYPE_CHECKING: def confirm_new_wallet(debug: "DebugLink") -> None: - layout = debug.wait_layout() + layout = debug.read_layout() assert layout.title().startswith("CREATE WALLET") if debug.model == "T": - debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) elif debug.model == "Safe 3": - debug.press_right(wait=True) - debug.press_right(wait=True) + debug.press_right() + debug.press_right() def confirm_read(debug: "DebugLink", title: str, middle_r: bool = False) -> None: @@ -42,14 +42,14 @@ def confirm_read(debug: "DebugLink", title: str, middle_r: bool = False) -> None assert title.upper() in layout.title() if debug.model == "T": - debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) elif debug.model == "Safe 3": if layout.page_count() > 1: - debug.press_right(wait=True) + debug.press_right() if middle_r: - debug.press_middle(wait=True) + debug.press_middle() else: - debug.press_right(wait=True) + debug.press_right() def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> None: @@ -57,20 +57,20 @@ def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> Non assert "NumberInputDialog" in debug.read_layout().all_components() for _ in range(diff): debug.click(button) - debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) elif debug.model == "Safe 3": layout = debug.read_layout() if layout.title() in ("NUMBER OF SHARES", "THRESHOLD"): # Special info screens - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "NumberInput" in layout.all_components() if button == buttons.RESET_MINUS: for _ in range(diff): - debug.press_left(wait=True) + debug.press_left() else: for _ in range(diff): - debug.press_right(wait=True) - debug.press_middle(wait=True) + debug.press_right() + debug.press_middle() def read_words( @@ -95,12 +95,12 @@ def read_words( assert layout.title() == "STANDARD BACKUP" assert "Write down" in layout.text_content() - layout = debug.press_right(wait=True) + layout = debug.press_right() # Swiping through all the pages and loading the words for _ in range(layout.page_count() - 1): words.extend(layout.seed_words()) - layout = debug.swipe_up(wait=True) + layout = debug.swipe_up() assert layout is not None if debug.model == "T": words.extend(layout.seed_words()) @@ -108,9 +108,9 @@ def read_words( # There is hold-to-confirm button if do_htc: if debug.model == "T": - debug.click_hold(buttons.OK, hold_ms=1500) + debug.click(buttons.OK, hold_ms=1500) elif debug.model == "Safe 3": - debug.press_right_htc(1200) + debug.press_right(hold_ms=1200) else: # It would take a very long time to test 16-of-16 with doing 1500 ms HTC after # each word set @@ -120,7 +120,7 @@ def read_words( def confirm_words(debug: "DebugLink", words: list[str]) -> None: - layout = debug.wait_layout() + layout = debug.read_layout() if debug.model == "T": assert "Select word" in layout.text_content() for _ in range(3): @@ -133,10 +133,10 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None: ] wanted_word = words[word_pos - 1].lower() button_pos = btn_texts.index(wanted_word) - layout = debug.click(buttons.RESET_WORD_CHECK[button_pos], wait=True) + layout = debug.click(buttons.RESET_WORD_CHECK[button_pos]) elif debug.model == "Safe 3": assert "Select the correct word" in layout.text_content() - layout = debug.press_right(wait=True) + layout = debug.press_right() for _ in range(3): # "SELECT 2ND WORD" # ^ @@ -144,9 +144,9 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None: wanted_word = words[word_pos - 1].lower() while not layout.get_middle_choice() == wanted_word: - layout = debug.press_right(wait=True) + layout = debug.press_right() - layout = debug.press_middle(wait=True) + layout = debug.press_middle() def validate_mnemonics(mnemonics: list[str], expected_ems: bytes) -> None: diff --git a/tests/click_tests/test_autolock.py b/tests/click_tests/test_autolock.py index b15503a224..cac9c55809 100644 --- a/tests/click_tests/test_autolock.py +++ b/tests/click_tests/test_autolock.py @@ -59,15 +59,15 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int) device_handler.run(device.apply_settings, auto_lock_delay_ms=delay_ms) # type: ignore - assert "PinKeyboard" in debug.wait_layout().all_components() + assert "PinKeyboard" in debug.read_layout().all_components() debug.input("1234") assert ( f"Auto-lock your Trezor after {delay_ms // 1000} seconds" - in debug.wait_layout().text_content() + in debug.read_layout().text_content() ) - layout = go_next(debug, wait=True) + layout = go_next(debug) assert layout.main_component() == "Homescreen" assert device_handler.result() == "Settings applied" @@ -97,16 +97,16 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"): assert ( "1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1" - in debug.wait_layout().text_content().replace(" ", "") + in debug.read_layout().text_content().replace(" ", "") ) if debug.model == "T": - debug.click(buttons.OK, wait=True) - layout = debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) + layout = debug.click(buttons.OK) assert "Total amount: 0.0039 BTC" in layout.text_content() elif debug.model == "Safe 3": - debug.press_right(wait=True) - layout = debug.press_right(wait=True) + debug.press_right() + layout = debug.press_right() assert "Total amount: 0.0039 BTC" in layout.text_content() # wait for autolock to kick in @@ -142,16 +142,16 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa assert ( "1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1" - in debug.wait_layout().text_content().replace(" ", "") + in debug.read_layout().text_content().replace(" ", "") ) if debug.model == "T": - debug.click(buttons.OK, wait=True) - layout = debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) + layout = debug.click(buttons.OK) assert "Total amount: 0.0039 BTC" in layout.text_content() elif debug.model == "Safe 3": - debug.press_right(wait=True) - layout = debug.press_right(wait=True) + debug.press_right() + layout = debug.press_right() assert "Total amount: 0.0039 BTC" in layout.text_content() def sleepy_filter(msg: MessageType) -> MessageType: @@ -163,9 +163,9 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa device_handler.client.set_filter(messages.TxAck, sleepy_filter) # confirm transaction if debug.model == "T": - debug.click(buttons.OK) + debug.click(buttons.OK, wait=False) elif debug.model == "Safe 3": - debug.press_middle() + debug.press_middle(wait=False) signatures, tx = device_handler.result() assert len(signatures) == 1 @@ -182,7 +182,7 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler") # get address device_handler.run(common.get_test_address) # type: ignore - assert "PassphraseKeyboard" in debug.wait_layout().all_components() + assert "PassphraseKeyboard" in debug.read_layout().all_components() if debug.model == "Safe 3": # Going into the selected character category @@ -203,9 +203,9 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler") # Send the passphrase to the client (TT has it clicked already, TR needs to input it) if debug.model == "T": - debug.click(buttons.OK, wait=True) + debug.click(buttons.OK) elif debug.model == "Safe 3": - debug.input("j" * 8, wait=True) + debug.input("j" * 8) # address corresponding to "jjjjjjjj" passphrase assert device_handler.result() == "mnF4yRWJXmzRB6EuBzuVigqeqTqirQupxJ" @@ -219,7 +219,7 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler # get address device_handler.run(common.get_test_address) # type: ignore - assert "PassphraseKeyboard" in debug.wait_layout().all_components() + assert "PassphraseKeyboard" in debug.read_layout().all_components() if debug.model == "Safe 3": # Going into the selected character category @@ -236,17 +236,17 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler # wait for autolock to kick in time.sleep(10.1) - assert debug.wait_layout().main_component() == "Lockscreen" + assert debug.read_layout().main_component() == "Lockscreen" with pytest.raises(exceptions.Cancelled): device_handler.result() def unlock_dry_run(debug: "DebugLink") -> "LayoutContent": - assert "Check your backup?" in debug.wait_layout().text_content() - layout = go_next(debug, wait=True) + assert "Check your backup?" in debug.read_layout().text_content() + layout = go_next(debug) assert "PinKeyboard" in layout.all_components() - layout = debug.input(PIN4, wait=True) + layout = debug.input(PIN4) assert layout is not None return layout @@ -262,20 +262,20 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle assert "number of words" in layout.text_content() if debug.model == "Safe 3": - debug.press_right(wait=True) + debug.press_right() # wait for autolock to trigger time.sleep(10.1) - assert debug.wait_layout().main_component() == "Lockscreen" + assert debug.read_layout().main_component() == "Lockscreen" with pytest.raises(exceptions.Cancelled): device_handler.result() # unlock # lockscreen triggered automatically - debug.wait_layout(wait_for_external_change=True) - layout = go_next(debug, wait=True) + # debug.wait_layout() + layout = go_next(debug) assert "PinKeyboard" in layout.all_components() - layout = debug.input(PIN4, wait=True) + layout = debug.input(PIN4) assert layout is not None # we are back at homescreen @@ -295,15 +295,15 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"): recovery.select_number_of_words(debug, 20) if debug.model == "T": - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert layout.main_component() == "MnemonicKeyboard" elif debug.model == "Safe 3": - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "MnemonicKeyboard" in layout.all_components() # make sure keyboard locks time.sleep(10.1) - assert debug.wait_layout().main_component() == "Lockscreen" + assert debug.read_layout().main_component() == "Lockscreen" with pytest.raises(exceptions.Cancelled): device_handler.result() @@ -321,25 +321,25 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"): recovery.select_number_of_words(debug, 20) if debug.model == "T": - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert layout.main_component() == "MnemonicKeyboard" # type the word OCEAN slowly for coords in buttons.type_word("ocea", is_slip39=True): time.sleep(9) debug.click(coords) - layout = debug.click(buttons.CONFIRM_WORD, wait=True) + layout = debug.click(buttons.CONFIRM_WORD) # should not have locked, even though we took 9 seconds to type each letter assert layout.main_component() == "MnemonicKeyboard" elif debug.model == "Safe 3": - layout = debug.press_right(wait=True) + layout = debug.press_right() assert "MnemonicKeyboard" in layout.all_components() # pressing middle button three times for _ in range(3): time.sleep(9) debug.press_middle() - layout = debug.wait_layout() + layout = debug.read_layout() # should not have locked, even though we took 9 seconds to type each letter assert "MnemonicKeyboard" in layout.all_components() @@ -367,7 +367,7 @@ def test_autolock_does_not_interrupt_preauthorized( coin_name="Testnet", script_type=messages.InputScriptType.SPENDTAPROOT, ) - debug.press_yes(wait=True) + debug.press_yes() device_handler.result() inputs = [ diff --git a/tests/click_tests/test_lock.py b/tests/click_tests/test_lock.py index 1996310212..db2a2b9081 100644 --- a/tests/click_tests/test_lock.py +++ b/tests/click_tests/test_lock.py @@ -37,17 +37,17 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): def hold(duration: int, wait: bool = True) -> None: if debug.model == "Safe 3": - debug.press_right_htc(hold_ms=duration) + debug.press_right(hold_ms=duration) else: - debug.input(x=13, y=37, hold_ms=duration, wait=wait) + debug.click((13, 37), hold_ms=duration, wait=wait) assert device_handler.features().unlocked is False # unlock with message device_handler.run(common.get_test_address) - assert "PinKeyboard" in debug.wait_layout().all_components() - debug.input("1234", wait=True) + assert "PinKeyboard" in debug.read_layout().all_components() + debug.input("1234") assert device_handler.result() assert device_handler.features().unlocked is True @@ -65,12 +65,11 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): # unlock by touching if debug.model == "Safe 3": # Doing a short HTC to simulate a click - debug.press_right_htc(hold_ms=100) - layout = debug.wait_layout() + layout = debug.press_right(hold_ms=100) else: - layout = debug.click(buttons.INFO, wait=True) + layout = debug.click(buttons.INFO) assert "PinKeyboard" in layout.all_components() - debug.input("1234", wait=True) + debug.input("1234") assert device_handler.features().unlocked is True diff --git a/tests/click_tests/test_passphrase_tr.py b/tests/click_tests/test_passphrase_tr.py index 508211c26c..2509567e18 100644 --- a/tests/click_tests/test_passphrase_tr.py +++ b/tests/click_tests/test_passphrase_tr.py @@ -88,7 +88,7 @@ def prepare_passphrase_dialogue( ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() device_handler.run(get_test_address) # type: ignore - layout = debug.wait_layout() + layout = debug.read_layout() assert "PassphraseKeyboard" in layout.all_components() assert layout.passphrase() == "" assert _current_category(debug) == PassphraseCategory.MENU diff --git a/tests/click_tests/test_passphrase_tt.py b/tests/click_tests/test_passphrase_tt.py index 8ec3c1cee6..cc85581053 100644 --- a/tests/click_tests/test_passphrase_tt.py +++ b/tests/click_tests/test_passphrase_tt.py @@ -70,7 +70,7 @@ def prepare_passphrase_dialogue( ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() device_handler.run(get_test_address) # type: ignore - assert debug.wait_layout().main_component() == "PassphraseKeyboard" + assert debug.read_layout().main_component() == "PassphraseKeyboard" # Resetting the category as it could have been changed by previous tests global TT_CATEGORY @@ -96,10 +96,10 @@ def go_to_category(debug: "DebugLink", category: PassphraseCategory) -> None: target_index = TT_CATEGORIES.index(category) if target_index > current_index: for _ in range(target_index - current_index): - debug.swipe_left(wait=True) + debug.swipe_left() else: for _ in range(current_index - target_index): - debug.swipe_right(wait=True) + debug.swipe_right() TT_CATEGORY = category # type: ignore # Category changed, reset coordinates TT_COORDS_PREV = (0, 0) # type: ignore @@ -125,7 +125,7 @@ def press_char(debug: "DebugLink", char: str) -> None: time.sleep(1.1) TT_COORDS_PREV = coords # type: ignore for _ in range(amount): - debug.click(coords, wait=True) + debug.click(coords) def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> None: @@ -142,13 +142,13 @@ def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> def enter_passphrase(debug: "DebugLink") -> None: """Enter a passphrase""" coords = buttons.pin_passphrase_grid(11) - debug.click(coords, wait=True) + debug.click(coords) def delete_char(debug: "DebugLink") -> None: """Deletes the last char""" coords = buttons.pin_passphrase_grid(9) - debug.click(coords, wait=True) + debug.click(coords) VECTORS = ( # passphrase, address @@ -185,7 +185,6 @@ def test_passphrase_delete(device_handler: "BackgroundDeviceHandler"): for _ in range(4): delete_char(debug) - debug.wait_layout() input_passphrase(debug, CommonPass.SHORT[8 - 4 :]) enter_passphrase(debug) @@ -215,7 +214,6 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler PassphraseCategory.SPECIAL, ): go_to_category(debug, category) - debug.wait_layout() enter_passphrase(debug) coords = buttons.pin_passphrase_grid(11) diff --git a/tests/click_tests/test_pin.py b/tests/click_tests/test_pin.py index 50e4e5921e..870f1b7233 100644 --- a/tests/click_tests/test_pin.py +++ b/tests/click_tests/test_pin.py @@ -84,37 +84,35 @@ def prepare( elif situation == Situation.PIN_SETUP: # Set new PIN device_handler.run(device.change_pin) # type: ignore - assert "Turn on" in debug.wait_layout().text_content() + assert "Turn on" in debug.read_layout().text_content() if debug.model == "T": go_next(debug) elif debug.model == "Safe 3": - go_next(debug, wait=True) - go_next(debug, wait=True) - go_next(debug, wait=True) - go_next(debug, wait=True) + go_next(debug) + go_next(debug) + go_next(debug) + go_next(debug) elif situation == Situation.PIN_CHANGE: # Change PIN device_handler.run(device.change_pin) # type: ignore _input_see_confirm(debug, old_pin) assert "Change PIN" in debug.read_layout().text_content() - go_next(debug, wait=True) + go_next(debug) _input_see_confirm(debug, old_pin) elif situation == Situation.WIPE_CODE_SETUP: # Set wipe code device_handler.run(device.change_wipe_code) # type: ignore if old_pin: _input_see_confirm(debug, old_pin) - assert "Turn on" in debug.wait_layout().text_content() - go_next(debug, wait=True) + assert "Turn on" in debug.read_layout().text_content() + go_next(debug) if debug.model == "Safe 3": - go_next(debug, wait=True) - go_next(debug, wait=True) - go_next(debug, wait=True) + go_next(debug) + go_next(debug) + go_next(debug) if old_pin: - debug.wait_layout() _input_see_confirm(debug, old_pin) - debug.wait_layout() _assert_pin_entry(debug) yield debug go_next(debug) @@ -135,7 +133,7 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None: for digit in pin: digit_index = digits_order.index(digit) coords = buttons.pin_passphrase_index(digit_index) - debug.click(coords, wait=True) + debug.click(coords) elif debug.model == "Safe 3": for digit in pin: navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS) @@ -148,7 +146,7 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None: def _see_pin(debug: "DebugLink") -> None: """Navigate to "SHOW" and press it""" if debug.model == "T": - debug.click(buttons.TOP_ROW, wait=True) + debug.click(buttons.TOP_ROW) elif debug.model == "Safe 3": navigate_to_action_and_press(debug, "SHOW", TR_PIN_ACTIONS) @@ -160,7 +158,7 @@ def _delete_pin(debug: "DebugLink", digits_to_delete: int, check: bool = True) - for _ in range(digits_to_delete): if debug.model == "T": - debug.click(buttons.pin_passphrase_grid(9), wait=True) + debug.click(buttons.pin_passphrase_grid(9)) elif debug.model == "Safe 3": navigate_to_action_and_press(debug, "DELETE", TR_PIN_ACTIONS) @@ -172,7 +170,7 @@ def _delete_pin(debug: "DebugLink", digits_to_delete: int, check: bool = True) - def _delete_all(debug: "DebugLink", check: bool = True) -> None: """Navigate to "DELETE" and hold it until all digits are deleted""" if debug.model == "T": - debug.click_hold(buttons.pin_passphrase_grid(9), hold_ms=1500) + debug.click(buttons.pin_passphrase_grid(9), hold_ms=1500) elif debug.model == "Safe 3": navigate_to_action_and_press(debug, "DELETE", TR_PIN_ACTIONS, hold_ms=1000) @@ -191,7 +189,7 @@ def _cancel_pin(debug: "DebugLink") -> None: def _confirm_pin(debug: "DebugLink") -> None: """Navigate to "ENTER" and press it""" if debug.model == "T": - debug.click(buttons.pin_passphrase_grid(11), wait=True) + debug.click(buttons.pin_passphrase_grid(11)) elif debug.model == "Safe 3": navigate_to_action_and_press(debug, "ENTER", TR_PIN_ACTIONS) @@ -207,7 +205,7 @@ def _enter_two_times(debug: "DebugLink", pin1: str, pin2: str) -> None: if debug.model == "Safe 3": # Please re-enter - go_next(debug, wait=True) + go_next(debug) _input_see_confirm(debug, pin2) @@ -331,7 +329,7 @@ def test_wipe_code_same_as_pin(device_handler: "BackgroundDeviceHandler"): with prepare(device_handler, Situation.WIPE_CODE_SETUP, old_pin="1") as debug: _input_see_confirm(debug, "1") # Try again - go_next(debug, wait=True) + go_next(debug) _enter_two_times(debug, "2", "2") diff --git a/tests/click_tests/test_tutorial.py b/tests/click_tests/test_tutorial.py index 0cb70387ba..2020fd5510 100644 --- a/tests/click_tests/test_tutorial.py +++ b/tests/click_tests/test_tutorial.py @@ -49,12 +49,12 @@ def prepare_tutorial_and_cancel_after_it( def go_through_tutorial(debug: "DebugLink") -> None: - debug.press_right(wait=True) - debug.press_right(wait=True) - debug.press_right_htc(hold_ms=1000) - debug.press_right(wait=True) - debug.press_right(wait=True) - layout = debug.press_middle(wait=True) + debug.press_right() + debug.press_right() + debug.press_right(hold_ms=1000) + debug.press_right() + debug.press_right() + layout = debug.press_middle() assert layout.title() == "TUTORIAL COMPLETE" @@ -65,15 +65,15 @@ def test_tutorial_finish(device_handler: "BackgroundDeviceHandler"): go_through_tutorial(debug) # FINISH - debug.press_right(wait=True) + debug.press_right() @pytest.mark.setup_client(uninitialized=True) def test_tutorial_skip(device_handler: "BackgroundDeviceHandler"): with prepare_tutorial_and_cancel_after_it(device_handler, cancelled=True) as debug: # SKIP - debug.press_left(wait=True) - debug.press_right(wait=True) + debug.press_left() + debug.press_right() @pytest.mark.setup_client(uninitialized=True) @@ -83,8 +83,8 @@ def test_tutorial_again_and_skip(device_handler: "BackgroundDeviceHandler"): go_through_tutorial(debug) # AGAIN - debug.press_left(wait=True) + debug.press_left() # SKIP - debug.press_left(wait=True) - debug.press_right(wait=True) + debug.press_left() + debug.press_right() diff --git a/tests/common.py b/tests/common.py index d6f601935c..cb12936d28 100644 --- a/tests/common.py +++ b/tests/common.py @@ -188,10 +188,8 @@ def read_and_confirm_mnemonic_tt( br = yield assert br.pages is not None - debug.wait_layout() - for i in range(br.pages): - words = debug.wait_layout().seed_words() + words = debug.read_layout().seed_words() mnemonic.extend(words) # Not swiping on the last page if i < br.pages - 1: @@ -201,7 +199,9 @@ def read_and_confirm_mnemonic_tt( # check share for _ in range(3): - word_pos = int(debug.wait_layout().text_content().split()[2]) + text_content = debug.read_layout().text_content() + assert text_content.startswith("Select word ") + word_pos = int(text_content.split()[2]) index = word_pos - 1 if choose_wrong: debug.input(mnemonic[(index + 1) % len(mnemonic)]) @@ -221,7 +221,7 @@ def read_and_confirm_mnemonic_tr( br = yield assert br.pages is not None for _ in range(br.pages - 1): - layout = debug.wait_layout() + layout = debug.read_layout() words = layout.seed_words() mnemonic.extend(words) debug.press_right() @@ -232,7 +232,7 @@ def read_and_confirm_mnemonic_tr( # check share for _ in range(3): - word_pos_match = re.search(r"\d+", debug.wait_layout().title()) + word_pos_match = re.search(r"\d+", debug.read_layout().title()) assert word_pos_match is not None word_pos = int(word_pos_match.group(0)) index = word_pos - 1 @@ -248,8 +248,8 @@ def read_and_confirm_mnemonic_tr( def click_info_button_tt(debug: "DebugLink"): """Click Shamir backup info button and return back.""" debug.press_info() - yield # Info screen with text debug.press_yes() + yield def check_pin_backoff_time(attempts: int, start: float) -> None: diff --git a/tests/conftest.py b/tests/conftest.py index 432cd22fe1..3899c271aa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -46,6 +46,8 @@ HERE = Path(__file__).resolve().parent # So that we see details of failed asserts from this module pytest.register_assert_rewrite("tests.common") +pytest.register_assert_rewrite("tests.input_flows") +pytest.register_assert_rewrite("tests.input_flows_helpers") def _emulator_wrapper_main_args() -> list[str]: diff --git a/tests/device_tests/cardano/test_sign_tx.py b/tests/device_tests/cardano/test_sign_tx.py index 2b79e5d23f..9f374c85e5 100644 --- a/tests/device_tests/cardano/test_sign_tx.py +++ b/tests/device_tests/cardano/test_sign_tx.py @@ -31,7 +31,7 @@ pytestmark = [ def show_details_input_flow(client: Client): yield - client.debug.wait_layout() + client.debug.read_layout() # Clicking for model T, pressing right for model R if client.features.model == "T": SHOW_ALL_BUTTON_POSITION = (143, 167) diff --git a/tests/device_tests/test_busy_state.py b/tests/device_tests/test_busy_state.py index c81ac98436..932b12349b 100644 --- a/tests/device_tests/test_busy_state.py +++ b/tests/device_tests/test_busy_state.py @@ -63,17 +63,23 @@ def test_busy_state(client: Client): @pytest.mark.flaky(max_runs=5) def test_busy_expiry(client: Client): + WAIT_TIME_MS = 1500 + TOLERANCE = 1000 + _assert_busy(client, False) + # Start a timer + start = time.monotonic() # Show the busy dialog. - device.set_busy(client, expiry_ms=1500) + device.set_busy(client, expiry_ms=WAIT_TIME_MS) _assert_busy(client, True) - # Hasn't expired yet. - time.sleep(0.1) - _assert_busy(client, True) + # Wait until the layout changes + client.debug.wait_layout() + end = time.monotonic() - # Wait for it to expire. Add some tolerance to account for CI/hardware slowness. - time.sleep(4.0) + # Check that the busy dialog was shown for at least WAIT_TIME_MS. + duration = (end - start) * 1000 + assert WAIT_TIME_MS <= duration <= WAIT_TIME_MS + TOLERANCE # Check that the device is no longer busy. # Also needs to come back to Homescreen (for UI tests). diff --git a/tests/device_tests/test_sdcard.py b/tests/device_tests/test_sdcard.py index 983d1d914e..71faa69965 100644 --- a/tests/device_tests/test_sdcard.py +++ b/tests/device_tests/test_sdcard.py @@ -49,7 +49,7 @@ def test_sd_no_format(client: Client): @pytest.mark.sd_card @pytest.mark.setup_client(pin="1234") def test_sd_protect_unlock(client: Client): - layout = client.debug.wait_layout + layout = client.debug.read_layout def input_flow_enable_sd_protect(): yield # Enter PIN to unlock device diff --git a/tests/device_tests/test_session_id_and_passphrase.py b/tests/device_tests/test_session_id_and_passphrase.py index 2bb9677e5d..cafd1871c0 100644 --- a/tests/device_tests/test_session_id_and_passphrase.py +++ b/tests/device_tests/test_session_id_and_passphrase.py @@ -395,7 +395,7 @@ def test_hide_passphrase_from_host(client: Client): def input_flow(): yield - layout = client.debug.wait_layout() + layout = client.debug.read_layout() if client.debug.model == "T": assert ( "Passphrase provided by host will be used but will not be displayed due to the device settings." @@ -403,7 +403,7 @@ def test_hide_passphrase_from_host(client: Client): ) client.debug.press_yes() elif client.debug.model == "Safe 3": - layout = client.debug.wait_layout() + layout = client.debug.read_layout() assert "will not be displayed" in layout.text_content() client.debug.press_right() client.debug.press_right() @@ -433,12 +433,12 @@ def test_hide_passphrase_from_host(client: Client): def input_flow(): yield - layout = client.debug.wait_layout() + layout = client.debug.read_layout() assert "Next screen will show the passphrase" in layout.text_content() client.debug.press_yes() yield - layout = client.debug.wait_layout() + layout = client.debug.read_layout() assert "confirm passphrase" in layout.title().lower() assert passphrase in layout.text_content() diff --git a/tests/input_flows.py b/tests/input_flows.py index c416e460fa..359196df6d 100644 --- a/tests/input_flows.py +++ b/tests/input_flows.py @@ -75,16 +75,16 @@ class InputFlowBase: raise NotImplementedError def text_content(self) -> str: - return self.debug.wait_layout().text_content() + return self.debug.read_layout().text_content() def main_component(self) -> str: - return self.debug.wait_layout().main_component() + return self.debug.read_layout().main_component() def all_components(self) -> list[str]: - return self.debug.wait_layout().all_components() + return self.debug.read_layout().all_components() def title(self) -> str: - return self.debug.wait_layout().title() + return self.debug.read_layout().title() class InputFlowSetupDevicePINWIpeCode(InputFlowBase): @@ -215,13 +215,13 @@ class InputFlowSignMessagePagination(InputFlowBase): layouts: list[LayoutContent] = [] br = yield # confirm address - self.debug.wait_layout() + self.debug.read_layout() self.debug.press_yes() br = yield assert br.pages is not None for i in range(br.pages): - layout = self.debug.wait_layout() + layout = self.debug.read_layout() layouts.append(layout) if i < br.pages - 1: @@ -261,9 +261,9 @@ class InputFlowSignMessageInfo(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield # show address/message info - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.press_no(wait=True) + self.debug.click(buttons.CORNER_BUTTON) + self.debug.click(buttons.CORNER_BUTTON) + self.debug.press_no() self.debug.synchronize_at("mismatch") # address mismatch? self.debug.press_no() @@ -272,8 +272,8 @@ class InputFlowSignMessageInfo(InputFlowBase): yield self.debug.press_no() yield - self.debug.press_no(wait=True) - self.debug.press_yes(wait=True) + self.debug.press_no() + self.debug.press_yes() class InputFlowShowAddressQRCode(InputFlowBase): @@ -282,16 +282,16 @@ class InputFlowShowAddressQRCode(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield - self.debug.click(buttons.CORNER_BUTTON, wait=True) + self.debug.click(buttons.CORNER_BUTTON) # synchronize; TODO get rid of this once we have single-global-layout self.debug.synchronize_at("SimplePage") - self.debug.swipe_left(wait=True) - self.debug.swipe_right(wait=True) - self.debug.swipe_left(wait=True) - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.press_no(wait=True) - self.debug.press_no(wait=True) + self.debug.swipe_left() + self.debug.swipe_right() + self.debug.swipe_left() + self.debug.click(buttons.CORNER_BUTTON) + self.debug.press_no() + self.debug.press_no() self.debug.press_yes() def input_flow_tr(self) -> BRGeneratorType: @@ -322,13 +322,13 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield - self.debug.click(buttons.CORNER_BUTTON, wait=True) + self.debug.click(buttons.CORNER_BUTTON) # synchronize; TODO get rid of this once we have single-global-layout self.debug.synchronize_at("SimplePage") - self.debug.swipe_left(wait=True) - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.press_no(wait=True) + self.debug.swipe_left() + self.debug.click(buttons.CORNER_BUTTON) + self.debug.press_no() self.debug.press_yes() def input_flow_tr(self) -> BRGeneratorType: @@ -357,14 +357,14 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): self.debug.press_yes() yield # show address - layout = self.debug.wait_layout() + layout = self.debug.read_layout() assert "RECEIVE ADDRESS\n(MULTISIG)" == layout.title() assert layout.text_content().replace(" ", "") == self.address self.debug.click(buttons.CORNER_BUTTON) assert "Qr" in self.all_components() - layout = self.debug.swipe_left(wait=True) + layout = self.debug.swipe_left() # address details assert "Multisig 2 of 3" in layout.screen_content() assert "Derivation path:" in layout.screen_content() @@ -374,16 +374,16 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): expected_title = f"MULTISIG XPUB #{xpub_num + 1}\n" + ( "(YOURS)" if self.index == xpub_num else "(COSIGNER)" ) - layout = self.debug.swipe_left(wait=True) + layout = self.debug.swipe_left() assert expected_title == layout.title() content = layout.text_content().replace(" ", "") assert self.xpubs[xpub_num] in content - self.debug.click(buttons.CORNER_BUTTON, wait=True) + self.debug.click(buttons.CORNER_BUTTON) # show address - self.debug.press_no(wait=True) + self.debug.press_no() # address mismatch - self.debug.press_no(wait=True) + self.debug.press_no() # show address self.debug.press_yes() @@ -392,14 +392,14 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): self.debug.press_middle() yield # show address - layout = self.debug.wait_layout() + layout = self.debug.read_layout() assert "RECEIVE ADDRESS (MULTISIG)" in layout.title() assert layout.text_content().replace(" ", "") == self.address self.debug.press_right() assert "Qr" in self.all_components() - layout = self.debug.press_right(wait=True) + layout = self.debug.press_right() # address details # TODO: locate it more precisely assert "Multisig 2 of 3" in layout.json_str @@ -409,14 +409,14 @@ class InputFlowShowMultisigXPUBs(InputFlowBase): expected_title = f"MULTISIG XPUB #{xpub_num + 1} " + ( "(YOURS)" if self.index == xpub_num else "(COSIGNER)" ) - layout = self.debug.press_right(wait=True) + layout = self.debug.press_right() assert expected_title in layout.title() xpub_part_1 = layout.text_content().replace(" ", "") # Press "SHOW MORE" - layout = self.debug.press_middle(wait=True) + layout = self.debug.press_middle() xpub_part_2 = layout.text_content().replace(" ", "") # Go back - self.debug.press_left(wait=True) + self.debug.press_left() assert self.xpubs[xpub_num] == xpub_part_1 + xpub_part_2 for _ in range(5): @@ -442,23 +442,23 @@ class InputFlowShowXpubQRCode(InputFlowBase): self.debug.press_yes() br = yield - layout = self.debug.wait_layout() + layout = self.debug.read_layout() if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath: self.debug.press_yes() br = yield - self.debug.click(buttons.CORNER_BUTTON, wait=True) + self.debug.click(buttons.CORNER_BUTTON) # synchronize; TODO get rid of this once we have single-global-layout self.debug.synchronize_at("SimplePage") - self.debug.swipe_left(wait=True) - self.debug.swipe_right(wait=True) - self.debug.swipe_left(wait=True) - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.press_no(wait=True) - self.debug.press_no(wait=True) + self.debug.swipe_left() + self.debug.swipe_right() + self.debug.swipe_left() + self.debug.click(buttons.CORNER_BUTTON) + self.debug.press_no() + self.debug.press_no() for _ in range(br.pages - 1): - self.debug.swipe_up(wait=True) + self.debug.swipe_up() self.debug.press_yes() def input_flow_tr(self) -> BRGeneratorType: @@ -469,18 +469,18 @@ class InputFlowShowXpubQRCode(InputFlowBase): self.debug.press_right() br = yield - layout = self.debug.wait_layout() + layout = self.debug.read_layout() if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath: self.debug.press_yes() br = yield # Go into details - self.debug.press_right(wait=True) + self.debug.press_right() # Go through details and back - self.debug.press_right(wait=True) - self.debug.press_right(wait=True) - self.debug.press_left(wait=True) - self.debug.press_left(wait=True) + self.debug.press_right() + self.debug.press_right() + self.debug.press_left() + self.debug.press_left() assert br.pages is not None for _ in range(br.pages - 1): self.debug.press_right() @@ -495,21 +495,21 @@ class InputFlowPaymentRequestDetails(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield # request to see details - self.debug.wait_layout() + self.debug.read_layout() self.debug.press_info() yield # confirm first output assert self.outputs[0].address[:16] in self.text_content() # type: ignore self.debug.press_yes() yield # confirm first output - self.debug.wait_layout() + self.debug.read_layout() self.debug.press_yes() yield # confirm second output assert self.outputs[1].address[:16] in self.text_content() # type: ignore self.debug.press_yes() yield # confirm second output - self.debug.wait_layout() + self.debug.read_layout() self.debug.press_yes() yield # confirm transaction @@ -543,20 +543,20 @@ class InputFlowSignTxHighFee(InputFlowBase): def sign_tx_go_to_info(client: Client) -> Generator[None, None, str]: yield # confirm output - client.debug.wait_layout() + client.debug.read_layout() client.debug.press_yes() yield # confirm output - client.debug.wait_layout() + client.debug.read_layout() client.debug.press_yes() yield # confirm transaction - client.debug.wait_layout() + client.debug.read_layout() client.debug.press_info() - layout = client.debug.wait_layout() + layout = client.debug.read_layout() content = layout.text_content().lower() - client.debug.click(buttons.CORNER_BUTTON, wait=True) + client.debug.click(buttons.CORNER_BUTTON) return content @@ -565,24 +565,24 @@ def sign_tx_go_to_info_tr( client: Client, ) -> Generator[None, None, str]: yield # confirm address - client.debug.wait_layout() + client.debug.read_layout() client.debug.press_yes() # CONTINUE yield # confirm amount - client.debug.wait_layout() + client.debug.read_layout() client.debug.press_yes() # CONFIRM screen_texts: list[str] = [] yield # confirm total - layout = client.debug.wait_layout() + layout = client.debug.read_layout() if "multiple accounts" in layout.text_content().lower(): client.debug.press_middle() yield - layout = client.debug.press_right(wait=True) + layout = client.debug.press_right() screen_texts.append(layout.text_content()) - layout = client.debug.press_right(wait=True) + layout = client.debug.press_right() screen_texts.append(layout.text_content()) client.debug.press_left() @@ -660,15 +660,16 @@ class InputFlowSignTxInformationReplacement(InputFlowBase): yield # confirm address self.debug.press_yes() # go back to address + yield self.debug.press_no() # confirm address self.debug.press_yes() - yield # confirm amount + # confirm amount self.debug.press_yes() yield # transaction summary, press info - self.debug.click(buttons.CORNER_BUTTON, wait=True) - self.debug.click(buttons.CORNER_BUTTON, wait=True) + self.debug.click(buttons.CORNER_BUTTON) + self.debug.click(buttons.CORNER_BUTTON) self.debug.press_yes() def input_flow_tr(self) -> BRGeneratorType: @@ -691,10 +692,10 @@ def lock_time_input_flow_tt( double_confirm: bool = False, ) -> BRGeneratorType: yield # confirm output - debug.wait_layout() + debug.read_layout() debug.press_yes() yield # confirm output - debug.wait_layout() + debug.read_layout() debug.press_yes() yield # confirm locktime @@ -712,10 +713,10 @@ def lock_time_input_flow_tr( debug: DebugLink, layout_assert_func: Callable[[DebugLink], None] ) -> BRGeneratorType: yield # confirm address - debug.wait_layout() + debug.read_layout() debug.press_yes() yield # confirm amount - debug.wait_layout() + debug.read_layout() debug.press_yes() yield # confirm locktime @@ -732,7 +733,7 @@ class InputFlowLockTimeBlockHeight(InputFlowBase): self.block_height = block_height def assert_func(self, debug: DebugLink) -> None: - layout_text = debug.wait_layout().text_content() + layout_text = debug.read_layout().text_content() assert "blockheight" in layout_text assert self.block_height in layout_text @@ -751,7 +752,7 @@ class InputFlowLockTimeDatetime(InputFlowBase): self.lock_time_str = lock_time_str def assert_func(self, debug: DebugLink): - layout_text = debug.wait_layout().text_content() + layout_text = debug.read_layout().text_content() assert "Locktime" in layout_text assert self.lock_time_str in layout_text @@ -782,7 +783,7 @@ class InputFlowEIP712ShowMore(InputFlowBase): self.debug.press_yes() yield # confirm domain - self.debug.wait_layout() + self.debug.read_layout() self._confirm_show_more() # confirm domain properties @@ -791,11 +792,11 @@ class InputFlowEIP712ShowMore(InputFlowBase): self.debug.press_yes() yield # confirm message - self.debug.wait_layout() + self.debug.read_layout() self._confirm_show_more() yield # confirm message.from - self.debug.wait_layout() + self.debug.read_layout() self._confirm_show_more() # confirm message.from properties @@ -804,7 +805,7 @@ class InputFlowEIP712ShowMore(InputFlowBase): self.debug.press_yes() yield # confirm message.to - self.debug.wait_layout() + self.debug.read_layout() self._confirm_show_more() # confirm message.to properties @@ -1023,15 +1024,15 @@ class InputFlowSlip39BasicBackup(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield # 1. Checklist self.debug.press_yes() + yield # 2. Number of shares (5) if self.click_info: yield from click_info_button_tt(self.debug) - yield # 2. Number of shares (5) self.debug.press_yes() yield # 3. Checklist self.debug.press_yes() + yield # 4. Threshold (3) if self.click_info: yield from click_info_button_tt(self.debug) - yield # 4. Threshold (3) self.debug.press_yes() yield # 5. Checklist self.debug.press_yes() @@ -1151,26 +1152,26 @@ class InputFlowSlip39AdvancedBackup(InputFlowBase): def input_flow_tt(self) -> BRGeneratorType: yield # 1. Checklist self.debug.press_yes() + yield # 2. Set and confirm group count if self.click_info: yield from click_info_button_tt(self.debug) - yield # 2. Set and confirm group count self.debug.press_yes() yield # 3. Checklist self.debug.press_yes() + yield # 4. Set and confirm group threshold if self.click_info: yield from click_info_button_tt(self.debug) - yield # 4. Set and confirm group threshold self.debug.press_yes() yield # 5. Checklist self.debug.press_yes() for _ in range(5): # for each of 5 groups - if self.click_info: - yield from click_info_button_tt(self.debug) yield # Set & Confirm number of shares - self.debug.press_yes() if self.click_info: yield from click_info_button_tt(self.debug) + self.debug.press_yes() yield # Set & confirm share threshold value + if self.click_info: + yield from click_info_button_tt(self.debug) self.debug.press_yes() yield # Confirm show seeds self.debug.press_yes() diff --git a/tests/input_flows_helpers.py b/tests/input_flows_helpers.py index 64aefaa739..8fa25e3861 100644 --- a/tests/input_flows_helpers.py +++ b/tests/input_flows_helpers.py @@ -15,14 +15,14 @@ class PinFlow: self, pin: str, second_different_pin: str | None = None ) -> BRGeneratorType: yield # Enter PIN - assert "PinKeyboard" in self.debug.wait_layout().all_components() + assert "PinKeyboard" in self.debug.read_layout().all_components() self.debug.input(pin) if self.debug.model == "Safe 3": yield # Reenter PIN - assert "re-enter PIN" in self.debug.wait_layout().text_content() + assert "re-enter PIN" in self.debug.read_layout().text_content() self.debug.press_yes() yield # Enter PIN again - assert "PinKeyboard" in self.debug.wait_layout().all_components() + assert "PinKeyboard" in self.debug.read_layout().all_components() if second_different_pin is not None: self.debug.input(second_different_pin) else: @@ -36,7 +36,7 @@ class BackupFlow: def confirm_new_wallet(self) -> BRGeneratorType: yield - assert "By continuing you agree" in self.debug.wait_layout().text_content() + assert "By continuing you agree" in self.debug.read_layout().text_content() if self.debug.model == "Safe 3": self.debug.press_right() self.debug.press_yes() @@ -49,14 +49,14 @@ class RecoveryFlow: def confirm_recovery(self) -> BRGeneratorType: yield - assert "By continuing you agree" in self.debug.wait_layout().text_content() + assert "By continuing you agree" in self.debug.read_layout().text_content() if self.debug.model == "Safe 3": self.debug.press_right() self.debug.press_yes() def confirm_dry_run(self) -> BRGeneratorType: yield - assert "Check your backup" in self.debug.wait_layout().text_content() + assert "Check your backup" in self.debug.read_layout().text_content() self.debug.press_yes() def setup_slip39_recovery(self, num_words: int) -> BRGeneratorType: @@ -73,43 +73,43 @@ class RecoveryFlow: def tr_recovery_homescreen(self) -> BRGeneratorType: yield - assert "number of words" in self.debug.wait_layout().text_content() + assert "number of words" in self.debug.read_layout().text_content() self.debug.press_yes() def enter_your_backup(self) -> BRGeneratorType: yield - assert "Enter your backup" in self.debug.wait_layout().text_content() + assert "Enter your backup" in self.debug.read_layout().text_content() if ( self.debug.model == "Safe 3" - and "BACKUP CHECK" not in self.debug.wait_layout().title() + and "BACKUP CHECK" not in self.debug.read_layout().title() ): # Normal recovery has extra info (not dry run) - self.debug.press_right(wait=True) - self.debug.press_right(wait=True) + self.debug.press_right() + self.debug.press_right() self.debug.press_yes() def enter_any_share(self) -> BRGeneratorType: yield - assert "Enter any share" in self.debug.wait_layout().text_content() + assert "Enter any share" in self.debug.read_layout().text_content() if ( self.debug.model == "Safe 3" - and "BACKUP CHECK" not in self.debug.wait_layout().title() + and "BACKUP CHECK" not in self.debug.read_layout().title() ): # Normal recovery has extra info (not dry run) - self.debug.press_right(wait=True) - self.debug.press_right(wait=True) + self.debug.press_right() + self.debug.press_right() self.debug.press_yes() def abort_recovery(self, confirm: bool) -> BRGeneratorType: yield if self.debug.model == "Safe 3": - assert "number of words" in self.debug.wait_layout().text_content() + assert "number of words" in self.debug.read_layout().text_content() else: - assert "Enter any share" in self.debug.wait_layout().text_content() + assert "Enter any share" in self.debug.read_layout().text_content() self.debug.press_no() yield - assert "cancel the recovery" in self.debug.wait_layout().text_content() + assert "cancel the recovery" in self.debug.read_layout().text_content() if self.debug.model == "Safe 3": self.debug.press_right() if confirm: @@ -121,33 +121,33 @@ class RecoveryFlow: br = yield assert br.code == B.MnemonicWordCount if self.debug.model == "Safe 3": - assert "NUMBER OF WORDS" in self.debug.wait_layout().title() + assert "NUMBER OF WORDS" in self.debug.read_layout().title() else: - assert "number of words" in self.debug.wait_layout().text_content() + assert "number of words" in self.debug.read_layout().text_content() self.debug.input(str(num_words)) def warning_invalid_recovery_seed(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "Invalid recovery seed" in self.debug.wait_layout().text_content() + assert "Invalid recovery seed" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_invalid_recovery_share(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "Invalid recovery share" in self.debug.wait_layout().text_content() + assert "Invalid recovery share" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_group_threshold_reached(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "Group threshold reached" in self.debug.wait_layout().text_content() + assert "Group threshold reached" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_share_already_entered(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "Share already entered" in self.debug.wait_layout().text_content() + assert "Share already entered" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_share_from_another_shamir(self) -> BRGeneratorType: @@ -155,46 +155,46 @@ class RecoveryFlow: assert br.code == B.Warning assert ( "You have entered a share from another Shamir Backup" - in self.debug.wait_layout().text_content() + in self.debug.read_layout().text_content() ) self.debug.press_yes() def success_share_group_entered(self) -> BRGeneratorType: yield - assert "You have entered" in self.debug.wait_layout().text_content() - assert "Group" in self.debug.wait_layout().text_content() + assert "You have entered" in self.debug.read_layout().text_content() + assert "Group" in self.debug.read_layout().text_content() self.debug.press_yes() def success_wallet_recovered(self) -> BRGeneratorType: br = yield assert br.code == B.Success assert ( - "Wallet recovered successfully" in self.debug.wait_layout().text_content() + "Wallet recovered successfully" in self.debug.read_layout().text_content() ) self.debug.press_yes() def success_bip39_dry_run_valid(self) -> BRGeneratorType: br = yield assert br.code == B.Success - assert "recovery seed is valid" in self.debug.wait_layout().text_content() + assert "recovery seed is valid" in self.debug.read_layout().text_content() self.debug.press_yes() def success_slip39_dryrun_valid(self) -> BRGeneratorType: br = yield assert br.code == B.Success - assert "recovery shares are valid" in self.debug.wait_layout().text_content() + assert "recovery shares are valid" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_slip39_dryrun_mismatch(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "do not match" in self.debug.wait_layout().text_content() + assert "do not match" in self.debug.read_layout().text_content() self.debug.press_yes() def warning_bip39_dryrun_mismatch(self) -> BRGeneratorType: br = yield assert br.code == B.Warning - assert "does not match" in self.debug.wait_layout().text_content() + assert "does not match" in self.debug.read_layout().text_content() self.debug.press_yes() def success_more_shares_needed( @@ -202,23 +202,23 @@ class RecoveryFlow: ) -> BRGeneratorType: yield assert ( - "1 more share needed" in self.debug.wait_layout().text_content().lower() - or "more shares needed" in self.debug.wait_layout().text_content().lower() + "1 more share needed" in self.debug.read_layout().text_content().lower() + or "more shares needed" in self.debug.read_layout().text_content().lower() ) if count_needed is not None: - assert str(count_needed) in self.debug.wait_layout().text_content() + assert str(count_needed) in self.debug.read_layout().text_content() self.debug.press_yes() def input_mnemonic(self, mnemonic: list[str]) -> BRGeneratorType: br = yield assert br.code == B.MnemonicInput - assert "MnemonicKeyboard" in self.debug.wait_layout().all_components() + assert "MnemonicKeyboard" in self.debug.read_layout().all_components() for index, word in enumerate(mnemonic): if self.debug.model == "Safe 3": - assert f"WORD {index + 1}" in self.debug.wait_layout().title() + assert f"WORD {index + 1}" in self.debug.read_layout().title() else: assert ( - f"Type word {index + 1}" in self.debug.wait_layout().text_content() + f"Type word {index + 1}" in self.debug.read_layout().text_content() ) self.debug.input(word) @@ -243,8 +243,8 @@ class RecoveryFlow: self, ) -> BRGeneratorType: # Moving through the INFO button - self.debug.press_info() yield + self.debug.press_info() self.debug.swipe_up() self.debug.press_yes() @@ -258,8 +258,8 @@ class EthereumFlow: def confirm_data(self, info: bool = False, cancel: bool = False) -> BRGeneratorType: yield - assert self.debug.wait_layout().title() == "CONFIRM DATA" - assert "Size:" in self.debug.wait_layout().text_content() + assert self.debug.read_layout().title() == "CONFIRM DATA" + assert "Size:" in self.debug.read_layout().text_content() if info: self.debug.press_info() elif cancel: @@ -269,22 +269,22 @@ class EthereumFlow: def paginate_data(self) -> BRGeneratorType: br = yield - assert self.debug.wait_layout().title() == "CONFIRM DATA" + assert self.debug.read_layout().title() == "CONFIRM DATA" assert br.pages is not None for i in range(br.pages): - self.debug.wait_layout() + self.debug.read_layout() if i < br.pages - 1: self.debug.swipe_up() self.debug.press_yes() def paginate_data_go_back(self) -> BRGeneratorType: br = yield - assert self.debug.wait_layout().title() == "CONFIRM DATA" + assert self.debug.read_layout().title() == "CONFIRM DATA" assert br.pages is not None assert br.pages > 2 if self.debug.model == "T": - self.debug.swipe_up(wait=True) - self.debug.swipe_up(wait=True) + self.debug.swipe_up() + self.debug.swipe_up() self.debug.click(self.GO_BACK) else: self.debug.press_right() @@ -295,7 +295,7 @@ class EthereumFlow: def confirm_tx(self, cancel: bool = False, info: bool = False) -> BRGeneratorType: yield - assert self.debug.wait_layout().title() == "RECIPIENT" + assert self.debug.read_layout().title() == "RECIPIENT" if self.debug.model == "T": if cancel: @@ -303,25 +303,25 @@ class EthereumFlow: else: self.debug.press_yes() yield - assert self.debug.wait_layout().title() == "SUMMARY" - assert "Maximum fee:" in self.debug.wait_layout().text_content() + assert self.debug.read_layout().title() == "SUMMARY" + assert "Maximum fee:" in self.debug.read_layout().text_content() if info: - self.debug.press_info(wait=True) - assert "Gas limit:" in self.debug.wait_layout().text_content() - assert "Gas price:" in self.debug.wait_layout().text_content() - self.debug.press_no(wait=True) + self.debug.press_info() + assert "Gas limit:" in self.debug.read_layout().text_content() + assert "Gas price:" in self.debug.read_layout().text_content() + self.debug.press_no() self.debug.press_yes() else: if cancel: self.debug.press_left() else: self.debug.press_right() - assert "Maximum fee:" in self.debug.wait_layout().text_content() + assert "Maximum fee:" in self.debug.read_layout().text_content() if info: - self.debug.press_right(wait=True) - assert "Gas limit:" in self.debug.wait_layout().text_content() - self.debug.press_right(wait=True) - assert "Gas price:" in self.debug.wait_layout().text_content() - self.debug.press_left(wait=True) - self.debug.press_left(wait=True) + self.debug.press_right() + assert "Gas limit:" in self.debug.read_layout().text_content() + self.debug.press_right() + assert "Gas price:" in self.debug.read_layout().text_content() + self.debug.press_left() + self.debug.press_left() self.debug.press_middle() diff --git a/tests/persistence_tests/test_shamir_persistence.py b/tests/persistence_tests/test_shamir_persistence.py index fb3cc5881d..360d782802 100644 --- a/tests/persistence_tests/test_shamir_persistence.py +++ b/tests/persistence_tests/test_shamir_persistence.py @@ -42,9 +42,9 @@ def test_abort(core_emulator: Emulator): device_handler.run(device.recover, pin_protection=False) - assert debug.wait_layout().title() == "RECOVER WALLET" + assert debug.read_layout().title() == "RECOVER WALLET" - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert "number of words" in layout.text_content() debug = _restart(device_handler, core_emulator) @@ -55,14 +55,14 @@ def test_abort(core_emulator: Emulator): # no waiting for layout because layout doesn't change assert "number of words" in debug.read_layout().text_content() # clicking at 24 in word choice (the same coords as CANCEL) - layout = debug.click(buttons.CANCEL, wait=True) + layout = debug.click(buttons.CANCEL) # Cancelling the backup assert "Enter your backup" in debug.read_layout().text_content() - layout = debug.click(buttons.CANCEL, wait=True) + layout = debug.click(buttons.CANCEL) assert layout.title() in ("ABORT RECOVERY", "CANCEL RECOVERY") - layout = debug.click(buttons.OK, wait=True) + layout = debug.click(buttons.OK) assert layout.main_component() == "Homescreen" features = device_handler.features() @@ -89,7 +89,7 @@ def test_recovery_single_reset(core_emulator: Emulator): assert features.recovery_mode is True # we need to enter the number of words again, that's a feature - recovery.select_number_of_words(debug, wait=False) + recovery.select_number_of_words(debug) recovery.enter_shares(debug, MNEMONIC_SLIP39_BASIC_20_3of6) recovery.finalize(debug) @@ -126,7 +126,7 @@ def test_recovery_on_old_wallet(core_emulator: Emulator): assert features.recovery_mode is True # enter number of words - recovery.select_number_of_words(debug, wait=False) + recovery.select_number_of_words(debug) first_share = MNEMONIC_SLIP39_BASIC_20_3of6[0] words = first_share.split(" ") @@ -134,11 +134,11 @@ def test_recovery_on_old_wallet(core_emulator: Emulator): # start entering first share assert "Enter any share" in debug.read_layout().text_content() debug.press_yes() - assert debug.wait_layout().main_component() == "MnemonicKeyboard" + assert debug.read_layout().main_component() == "MnemonicKeyboard" # enter first word debug.input(words[0]) - layout = debug.wait_layout() + layout = debug.read_layout() # while keyboard is open, hit the device with Initialize/GetFeatures device_handler.client.init_device() @@ -148,7 +148,7 @@ def test_recovery_on_old_wallet(core_emulator: Emulator): for word in words[1:]: assert layout.main_component() == "MnemonicKeyboard" debug.input(word) - layout = debug.wait_layout() + layout = debug.read_layout() # check that we entered the first share successfully assert "1 of 3 shares entered" in layout.text_content() @@ -202,7 +202,7 @@ def test_recovery_multiple_resets(core_emulator: Emulator): assert features.recovery_mode is True # enter the number of words again, that's a feature! - recovery.select_number_of_words(debug, wait=False) + recovery.select_number_of_words(debug) # enter shares and restart after each one enter_shares_with_restarts(debug)