diff --git a/core/src/apps/debug/__init__.py b/core/src/apps/debug/__init__.py index c082d6887..7dd837859 100644 --- a/core/src/apps/debug/__init__.py +++ b/core/src/apps/debug/__init__.py @@ -11,7 +11,7 @@ if __debug__: from trezor import log, loop, utils, wire from trezor.ui import display - from trezor.enums import MessageType, DebugPhysicalButton + from trezor.enums import MessageType from trezor.messages import ( DebugLinkLayout, Success, @@ -33,20 +33,16 @@ if __debug__: DebugLinkWatchLayout, ) - reset_current_words = loop.chan() reset_word_index = loop.chan() - confirm_chan = loop.chan() swipe_chan = loop.chan() - input_chan = loop.chan() - model_r_btn_chan = loop.chan() - confirm_signal = confirm_chan.take + result_chan = loop.chan() + button_chan = loop.chan() + click_chan = loop.chan() swipe_signal = swipe_chan.take - input_signal = input_chan.take - model_r_btn_signal = model_r_btn_chan.take - - synthetic_event = loop.chan() - synthetic_event_signal = synthetic_event.take + result_signal = result_chan.take + button_signal = button_chan.take + click_signal = click_chan.take debuglink_decision_chan = loop.chan() @@ -74,21 +70,18 @@ if __debug__: event_id: int | None, msg: DebugLinkDecision ) -> None: from trezor.enums import DebugButton - from trezor.ui import Result if msg.button is not None: if msg.button == DebugButton.NO: - await confirm_chan.put(Result(trezorui2.CANCELLED)) + await result_chan.put((event_id, trezorui2.CANCELLED)) elif msg.button == DebugButton.YES: - await confirm_chan.put(Result(trezorui2.CONFIRMED)) + await result_chan.put((event_id, trezorui2.CONFIRMED)) elif msg.button == DebugButton.INFO: - await confirm_chan.put(Result(trezorui2.INFO)) - if msg.physical_button is not None: - await model_r_btn_chan.put(msg.physical_button) + await result_chan.put((event_id, trezorui2.INFO)) + if msg.input is not None: + await result_chan.put((event_id, msg.input)) if msg.swipe is not None: await swipe_chan.put((event_id, msg.swipe)) - if msg.input is not None: - await input_chan.put(Result(msg.input)) async def debuglink_decision_dispatcher() -> None: while True: @@ -105,12 +98,12 @@ if __debug__: while True: event_id, content = await layout_change_chan.take() - if event_id is None or awaited_event_id is None: + if awaited_event_id is None or event_id is None: # Not waiting for anything or event does not have ID break elif event_id == awaited_event_id: # We found what we were waiting for - storage.awaited_event = None + debug_events.awaited_event = None break elif event_id > awaited_event_id: # Sanity check @@ -136,21 +129,6 @@ if __debug__: await DEBUG_CONTEXT.write(DebugLinkState(layout_lines=content)) storage.layout_watcher = LAYOUT_WATCHER_NONE - async def touch_hold( - event_id: int | None, x: int, y: int, duration_ms: int - ) -> None: - from trezor import io - - await loop.sleep(duration_ms) - event = (event_id, io.TOUCH_END) - synthetic_event.publish((event, x, y)) - - async def button_hold(btn: int, duration_ms: int) -> None: - from trezor import io - - await loop.sleep(duration_ms) - synthetic_event.publish((io.BUTTON, (io.BUTTON_RELEASED, btn))) - async def dispatch_DebugLinkWatchLayout( ctx: wire.Context, msg: DebugLinkWatchLayout ) -> Success: @@ -161,7 +139,10 @@ if __debug__: # analyze the resulted layout. # Resetting the debug events makes sure that the previous # events/layouts are not mixed with the new ones. - storage.reset_debug_events() + # TODO: create a special flag for resetting this (DebugLinkWatchLayout.reset_debug_events) + # OR a custom message - DebugLinkResetDebugEvents + if not msg.watch: + storage.reset_debug_events() layout_change_chan.putters.clear() if msg.watch: @@ -173,7 +154,7 @@ if __debug__: async def dispatch_DebugLinkDecision( ctx: wire.Context, msg: DebugLinkDecision ) -> None: - from trezor import io, workflow + from trezor import workflow workflow.idle_timer.touch() @@ -183,42 +164,21 @@ if __debug__: x = msg.x # local_cache_attribute y = msg.y # local_cache_attribute - event_id = debug_events.last_event + 1 + # Incrementing the counter for last events so we know what to await debug_events.last_event += 1 # TT click on specific coordinates, with possible hold if x is not None and y is not None and utils.MODEL in ("T",): - # Getting IDs and incrementing the counter for next events - # Sending two events - click down and click up - first_evt_id = event_id - second_evt_id = debug_events.last_event + 1 - debug_events.last_event += 1 - - evt_down = (first_evt_id, io.TOUCH_START), x, y - evt_up = (second_evt_id, io.TOUCH_END), x, y - synthetic_event.publish(evt_down) - if msg.hold_ms is not None: - loop.schedule(touch_hold(second_evt_id, x, y, msg.hold_ms)) - else: - synthetic_event.publish(evt_up) - # TR hold of a specific button - elif ( - msg.physical_button is not None - and msg.hold_ms is not None - and utils.MODEL in ("R",) - ): - if msg.physical_button == DebugPhysicalButton.LEFT_BTN: - btn = io.BUTTON_LEFT - elif msg.physical_button == DebugPhysicalButton.RIGHT_BTN: - btn = io.BUTTON_RIGHT - else: - raise wire.ProcessError("Unknown physical button") - synthetic_event.publish((io.BUTTON, (io.BUTTON_PRESSED, btn))) - loop.schedule(button_hold(btn, msg.hold_ms)) + click_chan.publish((debug_events.last_event, x, y, msg.hold_ms)) + # TR press specific button + elif msg.physical_button is not None and utils.MODEL in ("R",): + button_chan.publish( + (debug_events.last_event, msg.physical_button, msg.hold_ms) + ) # Something more general else: # Will get picked up by _dispatch_debuglink_decision eventually - debuglink_decision_chan.publish((event_id, msg)) + debuglink_decision_chan.publish((debug_events.last_event, msg)) if msg.wait: # We wait for all the previously sent events @@ -251,8 +211,6 @@ if __debug__: if msg.wait_word_pos: m.reset_word_pos = await reset_word_index.take() - if msg.wait_word_list: - m.reset_word = " ".join(await reset_current_words.take()) return m async def dispatch_DebugLinkRecordScreen( diff --git a/core/src/trezor/ui/layouts/tr/__init__.py b/core/src/trezor/ui/layouts/tr/__init__.py index 5ec3e6a20..6d9c9e440 100644 --- a/core/src/trezor/ui/layouts/tr/__init__.py +++ b/core/src/trezor/ui/layouts/tr/__init__.py @@ -57,71 +57,95 @@ class RustLayout(ui.Layout): from trezor.enums import DebugPhysicalButton def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: - from apps.debug import confirm_signal, input_signal - return ( self.handle_input_and_rendering(), self.handle_timers(), - self.handle_swipe(), - self.handle_button_click(), - confirm_signal(), - input_signal(), + self.handle_swipe_signal(), + self.handle_button_signal(), + self.handle_result_signal(), ) + async def handle_result_signal(self) -> None: + """Enables sending arbitrary input - ui.Result. + + Waits for `result_signal` and carries it out. + """ + from apps.debug import result_signal + from storage import debug as debug_storage + + while True: + event_id, result = await result_signal() + # Layout change will be notified in _first_paint of the next layout + debug_storage.new_layout_event_id = event_id + raise ui.Result(result) + def read_content(self) -> list[str]: """Gets the visible content of the screen.""" - self._place_layout() + self._place_layout() # TODO: is this necessary? raw = self._read_content_raw() return " ".join(raw).split("\n") - def _press_left(self) -> Any: + async def _press_left(self, hold_ms: int | None) -> Any: """Triggers left button press.""" self.layout.button_event(io.BUTTON_PRESSED, io.BUTTON_LEFT) self._paint() + if hold_ms is not None: + await loop.sleep(hold_ms) return self.layout.button_event(io.BUTTON_RELEASED, io.BUTTON_LEFT) - def _press_right(self) -> Any: + async def _press_right(self, hold_ms: int | None) -> Any: """Triggers right button press.""" self.layout.button_event(io.BUTTON_PRESSED, io.BUTTON_RIGHT) self._paint() + if hold_ms is not None: + await loop.sleep(hold_ms) return self.layout.button_event(io.BUTTON_RELEASED, io.BUTTON_RIGHT) - def _press_middle(self) -> Any: + async def _press_middle(self, hold_ms: int | None) -> Any: """Triggers middle button press.""" self.layout.button_event(io.BUTTON_PRESSED, io.BUTTON_LEFT) self._paint() self.layout.button_event(io.BUTTON_PRESSED, io.BUTTON_RIGHT) self._paint() + if hold_ms is not None: + await loop.sleep(hold_ms) self.layout.button_event(io.BUTTON_RELEASED, io.BUTTON_LEFT) self._paint() return self.layout.button_event(io.BUTTON_RELEASED, io.BUTTON_RIGHT) - def _press_button(self, btn_to_press: DebugPhysicalButton) -> Any: + async def _press_button( + self, + event_id: int | None, + btn_to_press: DebugPhysicalButton, + hold_ms: int | None, + ) -> Any: from trezor.enums import DebugPhysicalButton from trezor import workflow from apps.debug import notify_layout_change + from storage import debug as debug_storage if btn_to_press == DebugPhysicalButton.LEFT_BTN: - msg = self._press_left() + msg = await self._press_left(hold_ms) elif btn_to_press == DebugPhysicalButton.MIDDLE_BTN: - msg = self._press_middle() + msg = await self._press_middle(hold_ms) elif btn_to_press == DebugPhysicalButton.RIGHT_BTN: - msg = self._press_right() + msg = await self._press_right(hold_ms) else: raise Exception(f"Unknown button: {btn_to_press}") - self.layout.paint() if msg is not None: + # Layout change will be notified in _first_paint of the next layout + debug_storage.new_layout_event_id = event_id raise ui.Result(msg) # So that these presses will keep trezor awake # (it will not be locked after auto_lock_delay_ms) workflow.idle_timer.touch() - ui.refresh() # so that a screenshot is taken - notify_layout_change(self) + self._paint() + notify_layout_change(self, event_id) - def _swipe(self, direction: int) -> None: + async def _swipe(self, event_id: int | None, direction: int) -> None: """Triggers swipe in the given direction. Only `UP` and `DOWN` directions are supported. @@ -135,9 +159,9 @@ class RustLayout(ui.Layout): else: raise Exception(f"Unsupported direction: {direction}") - self._press_button(btn_to_press) + await self._press_button(event_id, btn_to_press, None) - async def handle_swipe(self) -> None: + async def handle_swipe_signal(self) -> None: """Enables pagination through the current page/flow page. Waits for `swipe_signal` and carries it out. @@ -145,19 +169,19 @@ class RustLayout(ui.Layout): from apps.debug import swipe_signal while True: - direction = await swipe_signal() - self._swipe(direction) + event_id, direction = await swipe_signal() + await self._swipe(event_id, direction) - async def handle_button_click(self) -> None: + async def handle_button_signal(self) -> None: """Enables clicking arbitrary of the three buttons. - Waits for `model_r_btn_signal` and carries it out. + Waits for `button_signal` and carries it out. """ - from apps.debug import model_r_btn_signal + from apps.debug import button_signal while True: - btn = await model_r_btn_signal() - self._press_button(btn) + event_id, btn, hold_ms = await button_signal() + await self._press_button(event_id, btn, hold_ms) else: @@ -172,12 +196,21 @@ class RustLayout(ui.Layout): if __debug__ and self.should_notify_layout_change: from apps.debug import notify_layout_change + from storage import debug as debug_storage # notify about change and do not notify again until next await. # (handle_rendering might be called multiple times in a single await, # because of the endless loop in __iter__) self.should_notify_layout_change = False - notify_layout_change(self) + + # Possibly there is an event ID that caused the layout change, + # so notifying with this ID. + event_id = None + if debug_storage.new_layout_event_id is not None: + event_id = debug_storage.new_layout_event_id + debug_storage.new_layout_event_id = None + + notify_layout_change(self, event_id) # Turn the brightness on again. ui.backlight_fade(self.BACKLIGHT_LEVEL) diff --git a/core/src/trezor/ui/layouts/tr/homescreen.py b/core/src/trezor/ui/layouts/tr/homescreen.py index 8da0cc921..b8455ae24 100644 --- a/core/src/trezor/ui/layouts/tr/homescreen.py +++ b/core/src/trezor/ui/layouts/tr/homescreen.py @@ -31,7 +31,11 @@ class HomescreenBase(RustLayout): # In __debug__ mode, ignore {confirm,swipe,input}_signal. def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: - return self.handle_timers(), self.handle_input_and_rendering() + return ( + self.handle_timers(), + self.handle_input_and_rendering(), + self.handle_button_signal(), # so we can receive debug events + ) class Homescreen(HomescreenBase): diff --git a/core/src/trezor/ui/layouts/tt_v2/__init__.py b/core/src/trezor/ui/layouts/tt_v2/__init__.py index f2f6d7f35..efe4849cc 100644 --- a/core/src/trezor/ui/layouts/tt_v2/__init__.py +++ b/core/src/trezor/ui/layouts/tt_v2/__init__.py @@ -56,16 +56,27 @@ class RustLayout(ui.Layout): if __debug__: def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: - from apps.debug import confirm_signal, input_signal - return ( self.handle_timers(), self.handle_input_and_rendering(), self.handle_swipe(), - confirm_signal(), - input_signal(), + self.handle_click_signal(), + self.handle_result_signal(), ) + async def handle_result_signal(self) -> None: + """Enables sending arbitrary input - ui.Result. + + Waits for `result_signal` and carries it out. + """ + from apps.debug import result_signal + from storage import debug as debug_storage + + while True: + event_id, result = await result_signal() + debug_storage.new_layout_event_id = event_id + raise ui.Result(result) + def read_content(self) -> list[str]: result: list[str] = [] @@ -103,6 +114,45 @@ class RustLayout(ui.Layout): notify_layout_change(self, event_id) + async def _click( + self, + event_id: int | None, + x: int, + y: int, + hold_ms: int | None, + ) -> Any: + from trezor import workflow + from apps.debug import notify_layout_change + from storage import debug as debug_storage + + self.layout.touch_event(io.TOUCH_START, x, y) + self._paint() + if hold_ms is not None: + await loop.sleep(hold_ms) + msg = self.layout.touch_event(io.TOUCH_END, x, y) + + if msg is not None: + debug_storage.new_layout_event_id = event_id + raise ui.Result(msg) + + # So that these presses will keep trezor awake + # (it will not be locked after auto_lock_delay_ms) + workflow.idle_timer.touch() + + self._paint() + notify_layout_change(self, event_id) + + async def handle_click_signal(self) -> None: + """Enables clicking somewhere on the screen. + + Waits for `click_signal` and carries it out. + """ + from apps.debug import click_signal + + while True: + event_id, x, y, hold_ms = await click_signal() + await self._click(event_id, x, y, hold_ms) + else: def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: @@ -138,35 +188,16 @@ class RustLayout(ui.Layout): def handle_input_and_rendering(self) -> loop.Task: # type: ignore [awaitable-is-generator] from trezor import workflow - if __debug__: - from apps.debug import notify_layout_change, synthetic_event_signal - from storage import debug as debug_storage - touch = loop.wait(io.TOUCH) self._first_paint() while True: # Using `yield` instead of `await` to avoid allocations. - event_id: int | None = None - if __debug__: - # When using `yield` here, it misses some events - event, x, y = await loop.race(touch, synthetic_event_signal()) - if isinstance(event, tuple): - event_id, event = event - else: - event, x, y = yield touch + event, x, y = yield touch workflow.idle_timer.touch() msg = None if event in (io.TOUCH_START, io.TOUCH_MOVE, io.TOUCH_END): msg = self.layout.touch_event(event, x, y) - if __debug__: - if msg is not None: - # Going to new layout - notify about change there (in first paint) - debug_storage.new_layout_event_id = event_id - else: - # Layout change happens in this layout - notify_layout_change(self, event_id) - if msg is not None: raise ui.Result(msg) self._paint() diff --git a/core/src/trezor/ui/layouts/tt_v2/fido.py b/core/src/trezor/ui/layouts/tt_v2/fido.py index 142a7a089..778b73bc6 100644 --- a/core/src/trezor/ui/layouts/tt_v2/fido.py +++ b/core/src/trezor/ui/layouts/tt_v2/fido.py @@ -26,15 +26,11 @@ if __debug__: ) async def handle_debug_confirm(self) -> None: - from apps.debug import confirm_signal - - try: - await confirm_signal() - except Result as r: - if r.value is not trezorui2.CONFIRMED: - raise - else: - return + from apps.debug import result_signal + + _event_id, result = await result_signal() + if result is not trezorui2.CONFIRMED: + raise Result(result) for event, x, y in ( (io.TOUCH_START, 220, 220), diff --git a/core/src/trezor/ui/layouts/tt_v2/homescreen.py b/core/src/trezor/ui/layouts/tt_v2/homescreen.py index 16478303b..f991738aa 100644 --- a/core/src/trezor/ui/layouts/tt_v2/homescreen.py +++ b/core/src/trezor/ui/layouts/tt_v2/homescreen.py @@ -31,7 +31,11 @@ class HomescreenBase(RustLayout): # In __debug__ mode, ignore {confirm,swipe,input}_signal. def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: - return self.handle_timers(), self.handle_input_and_rendering() + return ( + self.handle_timers(), + self.handle_input_and_rendering(), + self.handle_click_signal(), # so we can receive debug events + ) class Homescreen(HomescreenBase): diff --git a/python/src/trezorlib/debuglink.py b/python/src/trezorlib/debuglink.py index a5bb57bf1..d3d2bbedc 100644 --- a/python/src/trezorlib/debuglink.py +++ b/python/src/trezorlib/debuglink.py @@ -668,16 +668,13 @@ class DebugLink: ) def press_right_htc( - self, hold_ms: int, extra_ms: int = 200 + self, hold_ms: int, extra_ms: int = 200, wait: bool = True ) -> Optional[LayoutContent]: - hold_ms = hold_ms + extra_ms # safety margin - result = self.input( + return self.input( physical_button=messages.DebugPhysicalButton.RIGHT_BTN, - hold_ms=hold_ms, + hold_ms=hold_ms + extra_ms, # safety margin + wait=wait, ) - # sleeping little longer for UI to update - time.sleep(hold_ms / 1000 + 0.1) - return result def stop(self) -> None: self._call(messages.DebugLinkStop(), nowait=True) diff --git a/tests/click_tests/common.py b/tests/click_tests/common.py index b4a45f664..c616cbcb0 100644 --- a/tests/click_tests/common.py +++ b/tests/click_tests/common.py @@ -47,6 +47,8 @@ def go_next(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: return debug.click(buttons.OK, wait=wait) # type: ignore elif debug.model == "R": return debug.press_right(wait=wait) # type: ignore + else: + raise ValueError(f"Unknown model {debug.model}") def go_back(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: @@ -54,6 +56,8 @@ def go_back(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: return debug.click(buttons.CANCEL, wait=wait) # type: ignore elif debug.model == "R": return debug.press_left(wait=wait) # type: ignore + else: + raise ValueError(f"Unknown model {debug.model}") def navigate_to_action_and_press( diff --git a/tests/click_tests/reset.py b/tests/click_tests/reset.py index 795c14412..6c888a20b 100644 --- a/tests/click_tests/reset.py +++ b/tests/click_tests/reset.py @@ -112,13 +112,15 @@ def read_words( words.extend(layout.seed_words()) # There is hold-to-confirm button - if debug.model == "T": + if do_htc: + if debug.model == "T": + debug.click(buttons.OK, hold_ms=1500, wait=True) + elif debug.model == "R": + debug.press_right_htc(1000) + else: # It would take a very long time to test 16-of-16 with doing 1500 ms HTC after # each word set - if do_htc: - debug.click(buttons.OK, hold_ms=1500, wait=True) - else: - debug.press_yes() + debug.press_yes() return words diff --git a/tests/click_tests/test_autolock.py b/tests/click_tests/test_autolock.py index c23afb3e5..e88e67202 100644 --- a/tests/click_tests/test_autolock.py +++ b/tests/click_tests/test_autolock.py @@ -73,11 +73,10 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int) ) if debug.model == "T": - debug.click(buttons.OK) + layout = debug.click(buttons.OK, wait=True) elif debug.model == "R": - debug.press_right() + layout = debug.press_right(wait=True) - layout = debug.wait_layout() assert "Homescreen" in layout.str_content assert device_handler.result() == "Settings applied" @@ -301,12 +300,12 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle if debug.model == "T": # Need to click two times to get the correct layout # because of the lockscreen - layout = debug.click(buttons.OK, wait=True) + debug.click(buttons.OK, wait=True) layout = debug.click(buttons.OK, wait=True) assert "PinKeyboard" in layout.str_content elif debug.model == "R": - # Doing a short HTC to simulate a real click - debug.press_right_htc(hold_ms=100) + # Again needs two waits to get the correct layout + debug.press_right(wait=True) layout = debug.wait_layout() assert "PinEntry" in layout.str_content layout = debug.input(PIN4, wait=True) diff --git a/tests/click_tests/test_lock.py b/tests/click_tests/test_lock.py index 4d1e74f7b..011c7698c 100644 --- a/tests/click_tests/test_lock.py +++ b/tests/click_tests/test_lock.py @@ -14,7 +14,6 @@ # You should have received a copy of the License along with this library. # If not, see . -import time from typing import TYPE_CHECKING import pytest @@ -37,10 +36,9 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): def hold(duration: int, wait: bool = True) -> None: if debug.model == "R": - debug.press_right_htc(hold_ms=duration) + debug.press_right_htc(hold_ms=duration, wait=wait) else: debug.input(x=13, y=37, hold_ms=duration, wait=wait) - time.sleep(duration / 1000 + 0.5) assert device_handler.features().unlocked is False diff --git a/tests/click_tests/test_reset_slip39_advanced.py b/tests/click_tests/test_reset_slip39_advanced.py index f9a3286e2..8b1d4a4a5 100644 --- a/tests/click_tests/test_reset_slip39_advanced.py +++ b/tests/click_tests/test_reset_slip39_advanced.py @@ -119,7 +119,9 @@ def _slip39_advanced_reset( for _ in range(group_count): for _ in range(share_count): # read words - words = reset.read_words(debug, messages.BackupType.Slip39_Advanced, do_htc=False) + words = reset.read_words( + debug, messages.BackupType.Slip39_Advanced, do_htc=False + ) # confirm words reset.confirm_words(debug, words) diff --git a/tests/click_tests/test_tutorial.py b/tests/click_tests/test_tutorial.py index 9e936f4ee..8273dc0ca 100644 --- a/tests/click_tests/test_tutorial.py +++ b/tests/click_tests/test_tutorial.py @@ -36,6 +36,7 @@ def prepare_tutorial_and_cancel_after_it( ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() device_handler.run(device.show_device_tutorial) + debug.wait_layout() yield debug @@ -45,7 +46,7 @@ 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_htc(hold_ms=1000, wait=True) debug.press_right(wait=True) debug.press_right(wait=True) layout = debug.press_middle(wait=True) diff --git a/tests/conftest.py b/tests/conftest.py index 7250664d3..447eed9d0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -200,6 +200,9 @@ def client( request.session.shouldstop = "Failed to communicate with Trezor" pytest.fail("Failed to communicate with Trezor") + # Resetting all the debug events with this + _raw_client.debug.watch_layout(False) + if test_ui: # we need to reseed before the wipe _raw_client.debug.reseed(0) diff --git a/tests/input_flows.py b/tests/input_flows.py index 06abb7d23..7f1b7f361 100644 --- a/tests/input_flows.py +++ b/tests/input_flows.py @@ -1176,7 +1176,6 @@ class InputFlowBip39RecoveryDryRun(InputFlowBase): assert "WORD" in self.layout().title() self.debug.input(word) - self.debug.wait_layout() self.debug.press_right() yield self.debug.press_yes() diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index e6461beb7..e7606d663 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -697,45 +697,45 @@ }, "TR": { "click_tests": { -"TR_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "a4479d59a39611bf43210095f53a278f0dac5be3dad86ed476ecd3430741d583", -"TR_test_autolock.py::test_autolock_does_not_interrupt_signing": "7e0a7fccbae1cf66671ca728e791e9757a363c6ae8960c2346d8c6aca666c4b2", -"TR_test_autolock.py::test_autolock_interrupts_passphrase": "0faa1c1a538d3b2c58bbe2b22b979125c51ba7473deec4078b8a152562c8a977", -"TR_test_autolock.py::test_autolock_interrupts_signing": "c95681f193c90df6aa57b37bea0049a4173dc657158c60ed22a733121ba8b859", -"TR_test_autolock.py::test_autolock_passphrase_keyboard": "0c91241f889fb6b0950420d878a8b2f85a67795235c7dc1973fb44c221c9318a", -"TR_test_autolock.py::test_dryrun_enter_word_slowly": "4cd93dd877ba173376b6e9f36bda3805c89ccdd86b5aa08fcee856008678a2d4", -"TR_test_autolock.py::test_dryrun_locks_at_number_of_words": "254f203f761d297bd996aaa92303578a05ed4dca5a450f91c6cbe61d78123952", -"TR_test_autolock.py::test_dryrun_locks_at_word_entry": "f822aa0cbbc05b31bdc4db4d3183eae4b822e8bf3184f3d97c38ed98705edada", +"TR_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "af6935488ae01501e9e83ed6c729879f13fd3d84915488db98d9b2ad79b1b9ff", +"TR_test_autolock.py::test_autolock_does_not_interrupt_signing": "61e5cb6eaf2fc1d794991f0689d61e8ddd2e36e950a5d92de2600703d8270b58", +"TR_test_autolock.py::test_autolock_interrupts_passphrase": "04d35a1d4878daa58c91bda51b28e135fe1a2864f3b7eb2cc199b5800345e396", +"TR_test_autolock.py::test_autolock_interrupts_signing": "188aefa3cb768e2ef94590aacd8cc6a961175004b3919547dab1fb67cdd09901", +"TR_test_autolock.py::test_autolock_passphrase_keyboard": "77c0efface8caaedad05ea8c5900d29a7002c6c6f57ba5b0e0be1524f540ab08", +"TR_test_autolock.py::test_dryrun_enter_word_slowly": "b4a5526e9d761a69b27875d6cb03001912b910ecd148cb8b776a4d5b092c12d2", +"TR_test_autolock.py::test_dryrun_locks_at_number_of_words": "990d72f473d8efd2f299e74af78692c7aef3c60c44638cd689dffa9ce589b5b3", +"TR_test_autolock.py::test_dryrun_locks_at_word_entry": "328b70515909b5afbc919592358dd7ee5421cc8e504d4b0ea79f42934e9c5559", "TR_test_lock.py::test_hold_to_lock": "7038f39afc7aa10640d91ada92656389b4989d885d49a43356976ac142b6aa9a", -"TR_test_passphrase_tr.py::test_cancel": "32e55986b0bcda321feb908e771909da59c28871d755fdbf9960744403e21c0b", -"TR_test_passphrase_tr.py::test_passphrase_delete": "183f40a7b2c40f1303ad4d6d08312ec04f38fd2a81ba3de6b55d671593d6fef5", -"TR_test_passphrase_tr.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZW-381132c0": "ae08209522ff09ea34c9ec91ef8b38168fa0df8381baaeb05046952233392f22", -"TR_test_passphrase_tr.py::test_passphrase_input[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-166c898a": "8c65664112a3486d40305d0006357041c77aed9c042f27461c2320987c768860", -"TR_test_passphrase_tr.py::test_passphrase_input[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-334262e9": "582d0fdf15f4a1f021e45153451d273728090a805e6433547471ceb977b4e84e", -"TR_test_passphrase_tr.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "51f75222d1668738b32bbbd1f0b99ff6a7ee4c494aa4e3fc551600cdfcea1a27", -"TR_test_passphrase_tr.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "e757dd50a11d98ab4cef52059c2e6e6ca50d35b94112b2e2284936d1ed9aa828", -"TR_test_passphrase_tr.py::test_passphrase_input_over_50_chars": "ae55ccc679bbab7efe3ae546c683b91de1032c2eefe1845b4e6543f7725ec5d3", -"TR_test_passphrase_tr.py::test_passphrase_loop_all_characters": "b5cb25d78372c9ad55e78472369f401bce96c9e637a2e14dc23c41d3e9ed2bac", -"TR_test_pin.py::test_pin_change": "6c5cfbcd4631f21eb781556528b8ef704a257f2e77a46b0538bfd99cfcbc73e6", -"TR_test_pin.py::test_pin_incorrect": "2c6e81bc3331525af99841c5dd79e738ed2a35439592f2a9e1a16591496db7ba", -"TR_test_pin.py::test_pin_long": "ba2b5442d3c4b12c3a63f785920576f67ed86f95ae3967a960c7626d6e2e9b15", -"TR_test_pin.py::test_pin_long_delete": "840fd586b2eca792f7ac5b3ae472371d4d0db3184e9a6303871620dff745eff5", -"TR_test_pin.py::test_pin_longer_than_max": "3c13175230f7ed3d12e26e0bbca0377a5ed090e5ef8f31215132c385f4fd78e2", -"TR_test_pin.py::test_pin_same_as_wipe_code": "7a8d370d21ecc71058ee15b6d1c69d0ef8540c30185b408b7584eb784917cbcc", -"TR_test_pin.py::test_pin_setup": "e5ac93f7e14b493c7dae04f69f671f7c8159208df4b82efe94c51b81ca3696ea", -"TR_test_pin.py::test_pin_setup_mismatch": "f9a37629e03350250aadeeb5a1d41628cbda60a54b863bfcf71204c7e28a5a2e", -"TR_test_pin.py::test_pin_short": "ea33035f923447bc3afdc6d3ca5b4d5e5696ac4102c7d896192857f3a823ae1a", -"TR_test_pin.py::test_wipe_code_same_as_pin": "d2883c4ebb7b8c09593e4a1ad962132fb261abdefb7abe157a9c2cb1c875b43e", -"TR_test_pin.py::test_wipe_code_setup": "03db18acb089e0c7438c9b9e79e17bf8aa3a9dd8467f91279d9323783e1f10e9", -"TR_test_recovery.py::test_recovery_bip39": "48fe32b05771080a4dfaacddeb63b322c7269115f0cdbcf3ab3610fa2f64580e", -"TR_test_recovery.py::test_recovery_slip39_basic": "244c609f395a4e88789f857cb51f5577b145c912f357717d667bca62e20d6bad", -"TR_test_reset_bip39.py::test_reset_bip39": "27181b86545df487343375d05806c191062809ae29aa5298d191f76a5a2fb48c", -"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced_16of16groups_16of16shares": "b6d32e0206f793e0b4fd91dde49f5831f83502f655b20912e9d3c7e1fad18275", -"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced_2of2groups_2of2shares": "9cfeeda665bbee154f18bb774ff28f87bb0577e46dc38ae23d8a9b4b9a5e6255", -"TR_test_reset_slip39_basic.py::test_reset_slip39_basic_16of16": "3283e383f930c31ace9ac837f1cf05f7d67c34c29e0cc9a275f2dba7840f6cdc", -"TR_test_reset_slip39_basic.py::test_reset_slip39_basic_1of1": "7ecd7789a0dcb8e5dd07213040f89bf89e5942894dccd6d1544968b6a92017dc", -"TR_test_tutorial.py::test_tutorial_again_and_skip": "756ec36eeccadc8040677f654a9188c6d5b7bbdc784b9d08d662508b61a013ac", -"TR_test_tutorial.py::test_tutorial_finish": "136588edb98e21272c68661c467e1c41bacc0a9b475d15f59bfcf22f6a3b9d08", -"TR_test_tutorial.py::test_tutorial_skip": "2d461f1cc9848d51435d5ccaf89a60db870e3f0a353212e99a8b098c90dabac0" +"TR_test_passphrase_tr.py::test_cancel": "5e79367294b6ae6445289906428097af26e4a2d1797df7095cfcf1c7d658046d", +"TR_test_passphrase_tr.py::test_passphrase_delete": "789a89c318b8d6ebf561d0730081946182d464658294ffb6784bcf78724fb3d6", +"TR_test_passphrase_tr.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZW-381132c0": "7caeb5e0ab810b72a88abd492cdb90c7a3ba4c783652e766f561c77b7bf5ec21", +"TR_test_passphrase_tr.py::test_passphrase_input[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-166c898a": "6349515fe41dfd99362c239e1e6171bccb86651483d89f5d6c86cba531017ea7", +"TR_test_passphrase_tr.py::test_passphrase_input[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-334262e9": "5adba8f36d96a98248221d44d8a8b899ddada3d8107d33595108778d17f96e7c", +"TR_test_passphrase_tr.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "5dc1c896ce689911f2d44a9c3d65655e2ab55cbc68c143bb181b5b5ba2e76cfc", +"TR_test_passphrase_tr.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "c92e48e2dee2c2cbaead6077d6e5dacaf300f224709a87224f1881dfc2657905", +"TR_test_passphrase_tr.py::test_passphrase_input_over_50_chars": "10e52c457d523afd387104609d9a35cbf40df5d3bb7cbd0c9d7236a60e4e1fc6", +"TR_test_passphrase_tr.py::test_passphrase_loop_all_characters": "4a7e3b18e6214a4c6962145fd3f97e0cb0c2547d838d56805d1c20d91f2e26e3", +"TR_test_pin.py::test_pin_change": "bac906a59d56900f90a125843360ba2e1984d37721955769ffd952b4996bf993", +"TR_test_pin.py::test_pin_incorrect": "ebb48ada5b0430ca562462ddc3c855cdbf133efabaa5e6318f058f2c2f914f23", +"TR_test_pin.py::test_pin_long": "5ea37cdbe11f6773ea1aafb7fa81b16fda31ac810af0e5dad7dc35b12c1e5645", +"TR_test_pin.py::test_pin_long_delete": "d329ebad67773c012fc7ef7ff18b1e720e6b31b0b3afc91cd7501adcfc05f178", +"TR_test_pin.py::test_pin_longer_than_max": "b93d02197bad78b4cdf4fe2766604607834ffc3f6d1981aecfc67d896117bd72", +"TR_test_pin.py::test_pin_same_as_wipe_code": "801f58ca38219ce38f6804697baef94f0de1258d9fcb4f51ebc3d7498467bd2f", +"TR_test_pin.py::test_pin_setup": "2d4389f9a63a57e6022928a5ed93b40c71ceb0a64f0d963198d0b0287dbed0c8", +"TR_test_pin.py::test_pin_setup_mismatch": "b03768bf0b9f6675539646865296dd195be4d09c9b3d114aabbb111a641d931d", +"TR_test_pin.py::test_pin_short": "1ed7da1bc77ae245e0d4c33791dd826505bb98ce556e10faefdc1dc76b077360", +"TR_test_pin.py::test_wipe_code_same_as_pin": "e9e7e049fa5b2c05b9cbd83f201a522420b05c0e2219286f9b3426e404efe09e", +"TR_test_pin.py::test_wipe_code_setup": "a8993cdb355fe713933356341cc363d0703261e209aced6c80b591e5ed5f5d2c", +"TR_test_recovery.py::test_recovery_bip39": "7d3ea332623b84b309fc8749dc21ed49f09c3114753834fc08f9dcdf6d0c0ecf", +"TR_test_recovery.py::test_recovery_slip39_basic": "3f4effc83ae39f45fe683272a72e37399353fc4139fa807f9273572593d89b3b", +"TR_test_reset_bip39.py::test_reset_bip39": "196400e33cfe2ec0f0c1dad4f37e58c60866f4e8f6506866fdede28dd0b29c90", +"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced_16of16groups_16of16shares": "9d17020acf413873fb338697e074c9bf03dcf97d60dbc30169c3fcc21ae93c9e", +"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced_2of2groups_2of2shares": "7153250d3d9539eaee44f3bf60aa675f890cdbd230420e2a05126d77e783d184", +"TR_test_reset_slip39_basic.py::test_reset_slip39_basic_16of16": "4a4f1a507a28d1b66e36154db7d56628034e9061a140e766175dbf7dbd11029e", +"TR_test_reset_slip39_basic.py::test_reset_slip39_basic_1of1": "8242865f813cf1a3a816661e6d94614b6d1e69c59eb6b5c17c16925e69002992", +"TR_test_tutorial.py::test_tutorial_again_and_skip": "db80b891aaf5266e98962527993e4e335399d7356746fe63ca0879451462c091", +"TR_test_tutorial.py::test_tutorial_finish": "6820baed02fc5967c8b4b1634be24de934db92c26cd13b391d2732a9526d7635", +"TR_test_tutorial.py::test_tutorial_skip": "6beeace983acf29f6f77cd69e911c86592c9a45eb8a318d09c729a1a71ed97cb" }, "device_tests": { "TR_binance-test_get_address.py::test_binance_get_address[m-44h-714h-0h-0-0-bnb1hgm0p7khfk85zpz-68e2cb5a": "d1d72604826a36dc2ead1b56f770868207c9929533236609ccefa8a8fdadd60a", @@ -1659,9 +1659,9 @@ "TR_reset_recovery-test_recovery_bip39_dryrun.py::test_bad_parameters[passphrase_protection-True]": "e9533f210cda5d7b96fbd84c17ae12cf83218b2b68e2185f49e7033a69d6792d", "TR_reset_recovery-test_recovery_bip39_dryrun.py::test_bad_parameters[pin_protection-True]": "e9533f210cda5d7b96fbd84c17ae12cf83218b2b68e2185f49e7033a69d6792d", "TR_reset_recovery-test_recovery_bip39_dryrun.py::test_bad_parameters[u2f_counter-1]": "e9533f210cda5d7b96fbd84c17ae12cf83218b2b68e2185f49e7033a69d6792d", -"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_dry_run": "8648f3559d1810c07937a285d750fe17996d673a9ad3a3163506b90585bc2818", -"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_invalid_seed_core": "43241e8c57808a7243ca948a8afa4b2d9a9d2a1a9dafea272ed7cb404d888d2f", -"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_seed_mismatch": "aa431ba0e34a17dda6b4133ad5289e484a41cc18efdbd26cc2ffc680493beb48", +"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_dry_run": "8ace2543ac2c5190e5c4c03410606c4708f6ab84c15460217bef4940e19ed7dc", +"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_invalid_seed_core": "360d49527425f0b286691db83b913a2b8e945415a3ac0257f5db2daec094d714", +"TR_reset_recovery-test_recovery_bip39_dryrun.py::test_seed_mismatch": "10736aecc57f44effad5e6ca7ecfaa4999418c4810184ff14b844210b6b51744", "TR_reset_recovery-test_recovery_bip39_dryrun.py::test_uninitialized": "c86cb7f895fb74064cb765c269611d667f76e745a09ad56aaae2ba05b9683909", "TR_reset_recovery-test_recovery_bip39_t2.py::test_already_initialized": "e9533f210cda5d7b96fbd84c17ae12cf83218b2b68e2185f49e7033a69d6792d", "TR_reset_recovery-test_recovery_bip39_t2.py::test_tt_nopin_nopassphrase": "28c8478ae971b4c7c8c84b7504f4c768662463b733f7f30dc3760f345c892007", @@ -1886,47 +1886,47 @@ }, "TT": { "click_tests": { -"TT_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "03e156da82e7acd3509f831d1fc2e635fcebc673f3c14d61d141273e608fc7a4", -"TT_test_autolock.py::test_autolock_does_not_interrupt_signing": "6711f75420f88f7500a6adfa8d9d25007871f698e08f048a80450085d9452133", -"TT_test_autolock.py::test_autolock_interrupts_passphrase": "d1f797544d62708739c340dd4aa4ee28cfc65e9b643f595a55706de5917ee82f", -"TT_test_autolock.py::test_autolock_interrupts_signing": "ae4d3cc00fd5482b4499eff1c73aec75f4153e34950db910d4f787cc5f9b4208", -"TT_test_autolock.py::test_autolock_passphrase_keyboard": "d1be209e13144850fc8b2cca8fded027cd53d2a9990af3c5be1db489995dc821", -"TT_test_autolock.py::test_dryrun_enter_word_slowly": "d3f2dc99db5a3fea22c075a74f15e8cf6a1ca655be29042eb845f033851edf78", -"TT_test_autolock.py::test_dryrun_locks_at_number_of_words": "b9a320b598b73d52a4d9e117e3c7c962ccaccb8a386f52a836add95be0f897b6", -"TT_test_autolock.py::test_dryrun_locks_at_word_entry": "092e18ed76d31d6b608a6a4b8ca2d742d070903c2c0090ef3760d2b9ae70f238", -"TT_test_lock.py::test_hold_to_lock": "73bfeda4595c74c9c08b552651920beb903b59bb6f1b08fcb29399f92a6a6ade", -"TT_test_passphrase_tt.py::test_passphrase_click_same_button_many_times": "1e8778a6aece69bdaa3fc5678e74bd282f7633f95c4f34e288472086950233c7", -"TT_test_passphrase_tt.py::test_passphrase_delete": "14d66f44f33520849c082f1f26a1559cbc57959e782dd2357e6e5759f0030957", -"TT_test_passphrase_tt.py::test_passphrase_delete_all": "684b4ce76c5fb620a2409c81e4c760620858564515cddf0ba380a5fc4525eca1", -"TT_test_passphrase_tt.py::test_passphrase_dollar_sign_deletion": "9805f7a79fda34020e5f0ea4ab8f30f1e841d696702e7f1dd88241b8f2819345", -"TT_test_passphrase_tt.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZW-78765865": "6ad969956a956d309f69e3711510f72c0ef5e0e3d96033df505bcf049cdc0657", -"TT_test_passphrase_tt.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "d165ad086b7f8abe0d4e678e578703c2c930601f4a845896613ef596a1ed51eb", -"TT_test_passphrase_tt.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "759fb6628f9fb532e1dcfd764be5689ea57ababc4b58bf8aca5ea4e6eab7a8fe", -"TT_test_passphrase_tt.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadada-1cc97541": "dcd3bc20a4caa908625b39f4cc3a7d33e47f35ce6531a52fc31bd90e0b12a67d", -"TT_test_passphrase_tt.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadada-ca475dad": "1da0831b4ee13b7bc3df0de07a539822103437adb6e7f159aabf1519cb9c2019", -"TT_test_passphrase_tt.py::test_passphrase_input_over_50_chars": "dcd3bc20a4caa908625b39f4cc3a7d33e47f35ce6531a52fc31bd90e0b12a67d", -"TT_test_passphrase_tt.py::test_passphrase_long_spaces_deletion": "82a90342be1b83f51219d9faec25c7dbf83733a99a6a535791015d30d40485bf", -"TT_test_passphrase_tt.py::test_passphrase_loop_all_characters": "d29136fd1fcb4bd5575b9225e30b455e7a0798bb0887dcdf17a689dfe485fdb3", -"TT_test_passphrase_tt.py::test_passphrase_prompt_disappears": "4b16a81abd2c3eef2263e97952c535b40b1b64e4b175285a73135b0c675a4d9e", -"TT_test_pin.py::test_pin_cancel": "8f40ce02fb129962837393ffcd6ad19e07a3e81870b4e50205f2b64f9c8b1cf1", -"TT_test_pin.py::test_pin_change": "0f6951c2354ae02b5fa1df0ae030093d259bea4e1e962100da1900259cc8e830", -"TT_test_pin.py::test_pin_incorrect": "8daa7625b896f4faa3c9dd4f8a254af1cc6b66fc71edd2a0d968db1ee424f5d9", -"TT_test_pin.py::test_pin_long": "34692638906727bd3ebf89468aa8d4658866f1aac7775e8cae28bb337d588b3d", -"TT_test_pin.py::test_pin_long_delete": "eea0b6485700cce2bc6c13e6d1971e4add11355aa155edf2fcb9bb699dfb0654", -"TT_test_pin.py::test_pin_longer_than_max": "6a7e55fd6d3ff117ee5deb40f1c07cf8d3248931a29e4de6498d813744af2981", -"TT_test_pin.py::test_pin_same_as_wipe_code": "f09497fa686f884706818c0c850db9c351b5cd30ebc60f9aab11c62b75714ebe", -"TT_test_pin.py::test_pin_setup": "470ba3c1e991f14b99ef0256774dcb25ec8efa2e24951f923e9439e1f5d9e71d", -"TT_test_pin.py::test_pin_setup_mismatch": "bc3d883b79a2edef4cc38f0284afe8afcb5f7cc49d601a371a131859bfb628cb", -"TT_test_pin.py::test_pin_short": "b5377990e4a1f324133601e3ca4726cde7af50b3e2c3f53738022ed9108a6a79", -"TT_test_pin.py::test_wipe_code_same_as_pin": "91e501a4bd812ddaf9d39bfb86ab37fa18c75f33ec903d26ccbb30e5e3148f49", -"TT_test_pin.py::test_wipe_code_setup": "7132ac8f27171c3c916047e0f93bfcf1703eafec3bdc5dc02c8e1184351f5bd2", -"TT_test_recovery.py::test_recovery_bip39": "614e9204c01c379b4b88ba618addd50f22cf9f75492f2363cdca14acee1c883f", -"TT_test_recovery.py::test_recovery_slip39_basic": "73e2c4e4c4cb75206a5b739e4196035a4a3eef83a434a880ac27a8c7b5a3a0e2", -"TT_test_reset_bip39.py::test_reset_bip39": "01547ca97308b6b3b54fab9c8f18d4d43a8ca0637a95f4de6e0690808342fe4c", -"TT_test_reset_slip39_advanced.py::test_reset_slip39_advanced_16of16groups_16of16shares": "4ddcb8eeb9062e739926998abb0bbed918b63cf1065c61199194f99034d54968", -"TT_test_reset_slip39_advanced.py::test_reset_slip39_advanced_2of2groups_2of2shares": "37f5730dc1da45ef31792733a9272626ab070c8245d95b062df8695a6a9cf6c7", -"TT_test_reset_slip39_basic.py::test_reset_slip39_basic_16of16": "1a1d30da89b002e082c03fca80c99d515fee1ff144ec01a24f8bcfd4cf831ec3", -"TT_test_reset_slip39_basic.py::test_reset_slip39_basic_1of1": "ffc727ca4ec65738618ed20fcf0bd91c6d693d22575ab9a56c8c1bab1c66b3ec" +"TT_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "e04f6bd04b26e4c1b669943701eb6f81ead01aff04008c30f75c4872dd711bc0", +"TT_test_autolock.py::test_autolock_does_not_interrupt_signing": "ad03151b8418ecf7277a78a35938c9ea169c99f8a0c5ab4a8ae54377ad97ca70", +"TT_test_autolock.py::test_autolock_interrupts_passphrase": "9c7844133c0ce5c841f5546a15361b1d021f754c45deb92abba649910f858067", +"TT_test_autolock.py::test_autolock_interrupts_signing": "ad03151b8418ecf7277a78a35938c9ea169c99f8a0c5ab4a8ae54377ad97ca70", +"TT_test_autolock.py::test_autolock_passphrase_keyboard": "9c7844133c0ce5c841f5546a15361b1d021f754c45deb92abba649910f858067", +"TT_test_autolock.py::test_dryrun_enter_word_slowly": "74ad36b3c4f6c2b1589d2cb3c7059790718218a70e85cded713899942bd07933", +"TT_test_autolock.py::test_dryrun_locks_at_number_of_words": "74ad36b3c4f6c2b1589d2cb3c7059790718218a70e85cded713899942bd07933", +"TT_test_autolock.py::test_dryrun_locks_at_word_entry": "74ad36b3c4f6c2b1589d2cb3c7059790718218a70e85cded713899942bd07933", +"TT_test_lock.py::test_hold_to_lock": "929ad4987e920f4cf6a0bf9689c31dee0509109c3c32835cdc22bd97841fdbe1", +"TT_test_passphrase_tt.py::test_passphrase_click_same_button_many_times": "67e72c423dc025569b51c8870c1308abcf090cb87c8e98631ea54f4dbc406f6f", +"TT_test_passphrase_tt.py::test_passphrase_delete": "b92f9ec5db4a4c67599ff2b899ce2394dac4a095da30aa8bad7c2c15a0a014f9", +"TT_test_passphrase_tt.py::test_passphrase_delete_all": "2fde55a5bbc98ebf732c70557a2b3d79af9116f413c62a32d6c4e0281b0a4d44", +"TT_test_passphrase_tt.py::test_passphrase_dollar_sign_deletion": "c6b96c572d841d4fe845c2e5dd5902d298678a0c4b8da588678cec35245681ac", +"TT_test_passphrase_tt.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZW-78765865": "03d200ce4735c3d7bba2549fef0a5b24a0c5b4a35c05a6aaaebf5121a8ac9cb5", +"TT_test_passphrase_tt.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "7aac85ab8a1f2fbabd72a5133d030aab38b140ea7e58025b285ade367bb3d9b5", +"TT_test_passphrase_tt.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "5751b5c27df31536887a3dd19f2684b3e4d6b230fba7949320c4e46eb0691e3a", +"TT_test_passphrase_tt.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadada-1cc97541": "79005c64239d61e7fb692f709b5fee55371636340c8a123ce97040e23d607875", +"TT_test_passphrase_tt.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadada-ca475dad": "c2b2081575601168db7dea4eaf0ec93f3b0bf73088eeafe98fd05ec3f02de00e", +"TT_test_passphrase_tt.py::test_passphrase_input_over_50_chars": "79005c64239d61e7fb692f709b5fee55371636340c8a123ce97040e23d607875", +"TT_test_passphrase_tt.py::test_passphrase_long_spaces_deletion": "a2c0a9ea72534e69351581ef76a3c980ca95ccedf63b0e0e6a6d89a5a00b6df2", +"TT_test_passphrase_tt.py::test_passphrase_loop_all_characters": "c166a018c27a2d1037dfe309485f981c02eaf72b03f33e90eb24439ba310ff0a", +"TT_test_passphrase_tt.py::test_passphrase_prompt_disappears": "df5d06a0e97d1ece6374f7e2fd423cf50953f377fbf4c2751f7e7b5e2706d1b1", +"TT_test_pin.py::test_pin_cancel": "896edbb1b6fc3b35db5f066004660403c9aa4228e1d313a373e225e6cdfa0433", +"TT_test_pin.py::test_pin_change": "e3c858f93ba6fde78b42ffda52de687e40f82db68468dfcfe19a417f1ebba2d9", +"TT_test_pin.py::test_pin_incorrect": "1c146baaa485871f80d0a1a2a01cf05401b252679a5f6ab7c72a651ef3810d58", +"TT_test_pin.py::test_pin_long": "c6da95e5e60f26feff227a1b3ce5d9b11cabaa44e613abffde3bb91b4ddcfac0", +"TT_test_pin.py::test_pin_long_delete": "fa7c90ec909a47c3d2fec91d185c0bab288b91803719094f8a3bac88095aedd0", +"TT_test_pin.py::test_pin_longer_than_max": "a7b78e1514f564a3f38b005f099324773c2c57f2c6dfc5afc4afb82dda09f6cc", +"TT_test_pin.py::test_pin_same_as_wipe_code": "ce5542e0126035b0a11c2c306fb4bb7d2c6b9ed3f0544986dd8a74e9f82eb698", +"TT_test_pin.py::test_pin_setup": "2ff5a373d2772ccf4e55c05d07d06b9edfa303f465968be90022c77e81022a2d", +"TT_test_pin.py::test_pin_setup_mismatch": "d9f6d7d66e92c9000bd0e5db533e4e94e9a59788b278952f793eaea5d579f2da", +"TT_test_pin.py::test_pin_short": "ba6538602cf63d2776e17f6d9b9a3fd7cb5fdf5b6a6bbd1debe21a12af597896", +"TT_test_pin.py::test_wipe_code_same_as_pin": "507126101e78e316d030a21f6dfc36f76a88be0cca0251442ae78b96b93e766a", +"TT_test_pin.py::test_wipe_code_setup": "d3b9ba77ff4110d5ff191188a577203d956d4ac07c178316cb053b432116e777", +"TT_test_recovery.py::test_recovery_bip39": "a5ef33d7408e4a78ab3070dd56ceb4316d5505903f2c4f4a2a6935f26ac8e9f9", +"TT_test_recovery.py::test_recovery_slip39_basic": "2c983e0c87f50ac850b68872aeedd65d05966c2497ac65134c2a45851ff62dcd", +"TT_test_reset_bip39.py::test_reset_bip39": "0f4b7588543acd9dfae3a366d872ba55bb3783302f08cc72f10e41510495a484", +"TT_test_reset_slip39_advanced.py::test_reset_slip39_advanced_16of16groups_16of16shares": "e90a492431f6e481eb44661382ab08eb594e2a5319e73055e26a7cfc04df4dba", +"TT_test_reset_slip39_advanced.py::test_reset_slip39_advanced_2of2groups_2of2shares": "9a499f4dea0fcfb98e1cc33130f7b5093d0f70c474f38331aedaf37e665b1385", +"TT_test_reset_slip39_basic.py::test_reset_slip39_basic_16of16": "ee4fd329bd3b518e5e0551a52f1505d3aa60b42474166eb06972789105191fbb", +"TT_test_reset_slip39_basic.py::test_reset_slip39_basic_1of1": "a41a660e0cf3b964c1a8c83e96acbb3a0eecaf9bce69f9c4ac267585bc3b4b12" }, "device_tests": { "TT_binance-test_get_address.py::test_binance_get_address[m-44h-714h-0h-0-0-bnb1hgm0p7khfk85zpz-68e2cb5a": "483ff25f0ff24de80631dfb202ac681c38dfbf44c5905505281c2d0719a94fc6",