diff --git a/python/src/trezorlib/debuglink.py b/python/src/trezorlib/debuglink.py index 943cabbcb..ca98bcf3c 100644 --- a/python/src/trezorlib/debuglink.py +++ b/python/src/trezorlib/debuglink.py @@ -17,6 +17,7 @@ import logging import re import textwrap +import time from copy import deepcopy from datetime import datetime from enum import IntEnum @@ -252,6 +253,16 @@ class DebugLink: raise TrezorFailure(obj) return LayoutContent(obj.layout_lines) + def synchronize_at(self, layout_text: str, timeout: float = 5) -> LayoutContent: + now = time.monotonic() + while True: + layout = self.read_layout() + if layout_text in layout.text: + return layout + if time.monotonic() - now > timeout: + raise RuntimeError("Timeout waiting for layout") + time.sleep(0.1) + def watch_layout(self, watch: bool) -> None: """Enable or disable watching layouts. If disabled, wait_layout will not work. @@ -372,11 +383,27 @@ class DebugLink: def swipe_down(self, wait: bool = False) -> None: self.input(swipe=messages.DebugSwipeDirection.DOWN, wait=wait) - def swipe_right(self, wait: bool = False) -> None: - self.input(swipe=messages.DebugSwipeDirection.RIGHT, wait=wait) + @overload + def swipe_right(self) -> None: + ... + + @overload + def swipe_right(self, wait: Literal[True]) -> LayoutContent: + ... + + def swipe_right(self, wait: bool = False) -> Union[LayoutContent, None]: + return self.input(swipe=messages.DebugSwipeDirection.RIGHT, wait=wait) + + @overload + def swipe_left(self) -> None: + ... + + @overload + def swipe_left(self, wait: Literal[True]) -> LayoutContent: + ... - def swipe_left(self, wait: bool = False) -> None: - self.input(swipe=messages.DebugSwipeDirection.LEFT, wait=wait) + def swipe_left(self, wait: bool = False) -> Union[LayoutContent, None]: + return self.input(swipe=messages.DebugSwipeDirection.LEFT, wait=wait) def stop(self) -> None: self._call(messages.DebugLinkStop(), nowait=True) diff --git a/tests/device_tests/bitcoin/test_getaddress_show.py b/tests/device_tests/bitcoin/test_getaddress_show.py index 750d4cbd1..c63b880be 100644 --- a/tests/device_tests/bitcoin/test_getaddress_show.py +++ b/tests/device_tests/bitcoin/test_getaddress_show.py @@ -80,6 +80,9 @@ def test_show_tt( yield client.debug.click(CORNER_BUTTON) yield + # synchronize; TODO get rid of this once we have single-global-layout + client.debug.synchronize_at("HorizontalPage") + client.debug.swipe_left(wait=True) client.debug.swipe_right(wait=True) client.debug.swipe_left(wait=True) @@ -114,6 +117,9 @@ def test_show_cancel( yield client.debug.click(CORNER_BUTTON) yield + # synchronize; TODO get rid of this once we have single-global-layout + client.debug.synchronize_at("HorizontalPage") + client.debug.swipe_left(wait=True) client.debug.click(CORNER_BUTTON) yield @@ -242,8 +248,6 @@ VECTORS_MULTISIG = ( # script_type, bip48_type, address, xpubs, ignore_xpub_mag ) -# NOTE: contains wait_layout race that manifests on hw sometimes -@pytest.mark.flaky(max_runs=5) @pytest.mark.skip_t1 @pytest.mark.multisig @pytest.mark.parametrize( @@ -276,7 +280,7 @@ def test_show_multisig_xpubs( def input_flow(): yield # show address - layout = client.debug.wait_layout() # TODO: do not need to *wait* now? + layout = client.debug.wait_layout() assert layout.get_title() == "RECEIVE ADDRESS (MULTISIG)" assert layout.get_content().replace(" ", "") == address @@ -284,9 +288,8 @@ def test_show_multisig_xpubs( yield # show QR code assert "Qr" in client.debug.wait_layout().text - client.debug.swipe_left() + layout = client.debug.swipe_left(wait=True) # address details - layout = client.debug.wait_layout() assert "Multisig 2 of 3" in layout.text # Three xpub pages with the same testing logic @@ -295,8 +298,7 @@ def test_show_multisig_xpubs( "(YOURS)" if i == xpub_num else "(COSIGNER)" ) - client.debug.swipe_left() - layout = client.debug.wait_layout() + layout = client.debug.swipe_left(wait=True) assert layout.get_title() == expected_title content = layout.get_content().replace(" ", "") assert xpubs[xpub_num] in content @@ -310,8 +312,9 @@ def test_show_multisig_xpubs( client.debug.press_yes() with client: - client.watch_layout() client.set_input_flow(input_flow) + client.debug.synchronize_at("Homescreen") + client.watch_layout() btc.get_address( client, "Bitcoin",