diff --git a/tests/click_tests/test_autolock.py b/tests/click_tests/test_autolock.py index 9de92b57ac..152021a57c 100644 --- a/tests/click_tests/test_autolock.py +++ b/tests/click_tests/test_autolock.py @@ -21,9 +21,12 @@ from typing import TYPE_CHECKING, Tuple import pytest from trezorlib import btc, device, exceptions, messages +from trezorlib.client import PASSPHRASE_ON_DEVICE from trezorlib.debuglink import DebugLink, LayoutType +from trezorlib.debuglink import SessionDebugWrapper as Session from trezorlib.protobuf import MessageType from trezorlib.tools import parse_path +from trezorlib.transport.session import SessionV1, derive_seed from .. import common from .. import translations as TR @@ -66,8 +69,8 @@ def _center_button(debug: DebugLink) -> Tuple[int, int]: def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int): debug = device_handler.debuglink() - - device_handler.run(device.apply_settings, auto_lock_delay_ms=delay_ms) # type: ignore + device_handler.client.get_seedless_session().lock() + device_handler.run_with_session(device.apply_settings, auto_lock_delay_ms=delay_ms) # type: ignore assert "PinKeyboard" in debug.read_layout().all_components() @@ -106,7 +109,7 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"): script_type=messages.OutputScriptType.PAYTOADDRESS, ) - device_handler.run(btc.sign_tx, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET) # type: ignore + device_handler.run_with_session(btc.sign_tx, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET) # type: ignore assert ( "1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1" @@ -144,6 +147,10 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() + + # Prepare session to use later + session = device_handler.client.get_session() + # try to sign a transaction inp1 = messages.TxInputType( address_n=parse_path("86h/0h/0h/0/0"), @@ -159,8 +166,8 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa script_type=messages.OutputScriptType.PAYTOADDRESS, ) - device_handler.run( - btc.sign_tx, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET + device_handler.run_with_provided_session( + session, btc.sign_tx, "Bitcoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET ) assert ( @@ -190,14 +197,14 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa def sleepy_filter(msg: MessageType) -> MessageType: time.sleep(10.1) - device_handler.client.set_filter(messages.TxAck, None) + session.set_filter(messages.TxAck, None) return msg - with device_handler.client: - device_handler.client.set_filter(messages.TxAck, sleepy_filter) + with session, device_handler.client: + session.set_filter(messages.TxAck, sleepy_filter) # confirm transaction if debug.layout_type is LayoutType.Bolt: - debug.click(debug.screen_buttons.ok()) + debug.click(debug.screen_buttons.ok(), hold_ms=1000) elif debug.layout_type is LayoutType.Delizia: debug.click(debug.screen_buttons.tap_to_confirm()) elif debug.layout_type is LayoutType.Caesar: @@ -206,7 +213,6 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa signatures, tx = device_handler.result() assert len(signatures) == 1 assert tx - assert device_handler.features().unlocked is False @@ -215,9 +221,10 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler") set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() - # get address - device_handler.run(common.get_test_address) # type: ignore + session = Session(SessionV1.new(device_handler.client)) + # session = device_handler.client.get_session(passphrase=PASSPHRASE_ON_DEVICE) + device_handler.run_with_provided_session(session, derive_seed, passphrase=PASSPHRASE_ON_DEVICE) # type: ignore assert "PassphraseKeyboard" in debug.read_layout().all_components() if debug.layout_type is LayoutType.Caesar: @@ -243,7 +250,10 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler") elif debug.layout_type is LayoutType.Caesar: debug.input("j" * 8) - # address corresponding to "jjjjjjjj" passphrase + device_handler.result() + + # get address corresponding to "jjjjjjjj" passphrase + device_handler.run_with_provided_session(session, common.get_test_address) assert device_handler.result() == "mnF4yRWJXmzRB6EuBzuVigqeqTqirQupxJ" @@ -252,9 +262,11 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() - # get address - device_handler.run(common.get_test_address) # type: ignore - + # get address (derive_seed) + session = Session(SessionV1.new(client=device_handler.client)) + device_handler.run_with_provided_session( + session, derive_seed, passphrase=PASSPHRASE_ON_DEVICE + ) # type: ignore assert "PassphraseKeyboard" in debug.read_layout().all_components() if debug.layout_type is LayoutType.Caesar: @@ -293,7 +305,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() - device_handler.run(device.recover, type=messages.RecoveryType.DryRun) + device_handler.run_with_session(device.recover, type=messages.RecoveryType.DryRun) layout = unlock_dry_run(debug) assert TR.recovery__num_of_words in debug.read_layout().text_content() @@ -326,7 +338,7 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"): set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() - device_handler.run(device.recover, type=messages.RecoveryType.DryRun) + device_handler.run_with_session(device.recover, type=messages.RecoveryType.DryRun) unlock_dry_run(debug) @@ -353,7 +365,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"): set_autolock_delay(device_handler, 10_000) debug = device_handler.debuglink() - device_handler.run(device.recover, type=messages.RecoveryType.DryRun) + device_handler.run_with_session(device.recover, type=messages.RecoveryType.DryRun) unlock_dry_run(debug) @@ -418,7 +430,11 @@ def test_autolock_does_not_interrupt_preauthorized( debug = device_handler.debuglink() - device_handler.run( + # Prepare session to use later + session = device_handler.client.get_session() + + device_handler.run_with_provided_session( + session, btc.authorize_coinjoin, coordinator="www.example.com", max_rounds=2, @@ -532,14 +548,15 @@ def test_autolock_does_not_interrupt_preauthorized( def sleepy_filter(msg: MessageType) -> MessageType: time.sleep(10.1) - device_handler.client.set_filter(messages.SignTx, None) + session.set_filter(messages.SignTx, None) return msg - with device_handler.client: + with session: # Start DoPreauthorized flow when device is unlocked. Wait 10s before # delivering SignTx, by that time autolock timer should have fired. - device_handler.client.set_filter(messages.SignTx, sleepy_filter) - device_handler.run( + session.set_filter(messages.SignTx, sleepy_filter) + device_handler.run_with_provided_session( + session, btc.sign_tx, "Testnet", inputs, diff --git a/tests/click_tests/test_backup_slip39_custom.py b/tests/click_tests/test_backup_slip39_custom.py index c98752d2c0..98dff0cc8a 100644 --- a/tests/click_tests/test_backup_slip39_custom.py +++ b/tests/click_tests/test_backup_slip39_custom.py @@ -52,7 +52,9 @@ def test_backup_slip39_custom( assert features.initialized is False - device_handler.run( + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.setup, strength=128, backup_type=messages.BackupType.Slip39_Basic, @@ -71,7 +73,7 @@ def test_backup_slip39_custom( # retrieve the result to check that it's not a TrezorFailure exception device_handler.result() - device_handler.run( + device_handler.run_with_session( device.backup, group_threshold=group_threshold, groups=[(share_threshold, share_count)], diff --git a/tests/click_tests/test_lock.py b/tests/click_tests/test_lock.py index f8ddacec23..f3e48cd72a 100644 --- a/tests/click_tests/test_lock.py +++ b/tests/click_tests/test_lock.py @@ -19,7 +19,7 @@ from typing import TYPE_CHECKING import pytest -from trezorlib import models +from trezorlib import messages, models from trezorlib.debuglink import LayoutType from .. import common @@ -34,6 +34,9 @@ PIN4 = "1234" @pytest.mark.setup_client(pin=PIN4) def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() + session = device_handler.client.get_seedless_session() + session.call(messages.LockDevice()) + session.refresh_features() short_duration = { models.T1B1: 500, @@ -59,22 +62,25 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): assert device_handler.features().unlocked is False # unlock with message - device_handler.run(common.get_test_address) + device_handler.run_with_session(common.get_test_address) assert "PinKeyboard" in debug.read_layout().all_components() - debug.input("1234") + debug.input(PIN4) assert device_handler.result() + session.refresh_features() assert device_handler.features().unlocked is True # short touch hold(short_duration) time.sleep(0.5) # so that the homescreen appears again (hacky) + session.refresh_features() assert device_handler.features().unlocked is True # lock hold(lock_duration) + session.refresh_features() assert device_handler.features().unlocked is False # unlock by touching @@ -86,8 +92,10 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"): assert "PinKeyboard" in layout.all_components() debug.input("1234") + session.refresh_features() assert device_handler.features().unlocked is True # lock hold(lock_duration) + session.refresh_features() assert device_handler.features().unlocked is False diff --git a/tests/click_tests/test_passphrase_bolt_delizia.py b/tests/click_tests/test_passphrase_bolt_delizia.py index f97cf12f1e..f6fe7cd598 100644 --- a/tests/click_tests/test_passphrase_bolt_delizia.py +++ b/tests/click_tests/test_passphrase_bolt_delizia.py @@ -20,9 +20,12 @@ from typing import TYPE_CHECKING, Generator, Optional import pytest +from trezorlib import messages from trezorlib.debuglink import LayoutType +from trezorlib.debuglink import SessionDebugWrapper as Session +from trezorlib.transport.session import SessionV1 -from ..common import get_test_address +from ..common import TEST_ADDRESS_N from .common import CommonPass, PassphraseCategory, get_char_category if TYPE_CHECKING: @@ -68,12 +71,27 @@ assert len(DA_51) == 51 assert DA_51_ADDRESS == DA_50_ADDRESS +def _get_test_address(session: Session) -> None: + resp = session.call_raw( + messages.GetAddress(address_n=TEST_ADDRESS_N, coin_name="Testnet") + ) + if isinstance(resp, messages.ButtonRequest): + resp = session._callback_button(resp) + if isinstance(resp, messages.PassphraseRequest): + resp = session.call_raw(messages.PassphraseAck(on_device=True)) + if isinstance(resp, messages.ButtonRequest): + resp = session._callback_button(resp) + assert isinstance(resp, messages.Address) + return resp.address + + @contextmanager def prepare_passphrase_dialogue( device_handler: "BackgroundDeviceHandler", address: Optional[str] = None ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() - device_handler.run(get_test_address) # type: ignore + session = SessionV1.new(device_handler.client) + device_handler.run_with_provided_session(session, _get_test_address) # type: ignore assert debug.read_layout().main_component() == "PassphraseKeyboard" # Resetting the category as it could have been changed by previous tests diff --git a/tests/click_tests/test_passphrase_caesar.py b/tests/click_tests/test_passphrase_caesar.py index 57685451ba..ce5f11914f 100644 --- a/tests/click_tests/test_passphrase_caesar.py +++ b/tests/click_tests/test_passphrase_caesar.py @@ -19,9 +19,11 @@ from typing import TYPE_CHECKING, Generator, Optional import pytest -from trezorlib import exceptions +from trezorlib import exceptions, messages +from trezorlib.debuglink import SessionDebugWrapper as Session +from trezorlib.transport.session import SessionV1 -from ..common import get_test_address +from ..common import TEST_ADDRESS_N from .common import ( CommonPass, PassphraseCategory, @@ -77,6 +79,7 @@ SPECIAL_ACTIONS = [ ] # fmt: on + CATEGORY_ACTIONS = { PassphraseCategory.MENU: MENU_ACTIONS, PassphraseCategory.DIGITS: DIGITS_ACTIONS, @@ -86,12 +89,29 @@ CATEGORY_ACTIONS = { } +def _get_test_address(session: Session) -> None: + resp = session.call_raw( + messages.GetAddress(address_n=TEST_ADDRESS_N, coin_name="Testnet") + ) + if isinstance(resp, messages.ButtonRequest): + resp = session._callback_button(resp) + if isinstance(resp, messages.PassphraseRequest): + resp = session.call_raw(messages.PassphraseAck(on_device=True)) + if isinstance(resp, messages.ButtonRequest): + resp = session._callback_button(resp) + if isinstance(resp, messages.Address): + return resp.address + else: + raise exceptions.Cancelled + + @contextmanager def prepare_passphrase_dialogue( device_handler: "BackgroundDeviceHandler", address: Optional[str] = None ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() - device_handler.run(get_test_address) # type: ignore + session = SessionV1.new(device_handler.client) + device_handler.run_with_provided_session(session, _get_test_address) # type: ignore layout = debug.read_layout() assert "PassphraseKeyboard" in layout.all_components() assert layout.passphrase() == "" diff --git a/tests/click_tests/test_pin.py b/tests/click_tests/test_pin.py index b46cb32350..4f5a5fb1dd 100644 --- a/tests/click_tests/test_pin.py +++ b/tests/click_tests/test_pin.py @@ -90,17 +90,19 @@ def prepare( tap = False + device_handler.client.get_seedless_session().lock() + # Setup according to the wanted situation if situation == Situation.PIN_INPUT: # Any action triggering the PIN dialogue - device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore + device_handler.run_with_session(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore tap = True if situation == Situation.PIN_INPUT_CANCEL: # Any action triggering the PIN dialogue - device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore + device_handler.run_with_session(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore elif situation == Situation.PIN_SETUP: # Set new PIN - device_handler.run(device.change_pin) # type: ignore + device_handler.run_with_session(device.change_pin) # type: ignore assert ( TR.pin__turn_on in debug.read_layout().text_content() or TR.pin__info in debug.read_layout().text_content() @@ -114,14 +116,14 @@ def prepare( go_next(debug) elif situation == Situation.PIN_CHANGE: # Change PIN - device_handler.run(device.change_pin) # type: ignore + device_handler.run_with_session(device.change_pin) # type: ignore _input_see_confirm(debug, old_pin) assert TR.pin__change in debug.read_layout().text_content() 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 + device_handler.run_with_session(device.change_wipe_code) # type: ignore if old_pin: _input_see_confirm(debug, old_pin) assert TR.wipe_code__turn_on in debug.read_layout().text_content() diff --git a/tests/click_tests/test_recovery.py b/tests/click_tests/test_recovery.py index ade8526e6d..deb2c851e8 100644 --- a/tests/click_tests/test_recovery.py +++ b/tests/click_tests/test_recovery.py @@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Generator import pytest from trezorlib import device, exceptions, messages +from trezorlib.transport.session import SessionV1 from ..common import MNEMONIC12, MNEMONIC_SLIP39_BASIC_20_3of6 from . import recovery @@ -40,7 +41,10 @@ def prepare_recovery_and_evaluate( features = device_handler.features() debug = device_handler.debuglink() assert features.initialized is False - device_handler.run(device.recover, pin_protection=False) # type: ignore + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.recover, pin_protection=False + ) # type: ignore yield debug @@ -58,7 +62,10 @@ def prepare_recovery_and_evaluate_cancel( features = device_handler.features() debug = device_handler.debuglink() assert features.initialized is False - device_handler.run(device.recover, pin_protection=False) # type: ignore + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.recover, pin_protection=False + ) # type: ignore yield debug @@ -113,7 +120,10 @@ def test_recovery_cancel_issue4613(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() # initiate and confirm the recovery - device_handler.run(device.recover, type=messages.RecoveryType.DryRun) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.recover, type=messages.RecoveryType.DryRun + ) recovery.confirm_recovery(debug, title="recovery__title_dry_run") # select number of words recovery.select_number_of_words(debug, num_of_words=12) @@ -129,7 +139,9 @@ def test_recovery_cancel_issue4613(device_handler: "BackgroundDeviceHandler"): # Ping the Trezor with an Initialize message (listed in DO_NOT_RESTART) try: - features = device_handler.client.call(messages.Initialize()) + session = SessionV1(device_handler.client, id=b"") + session.client._last_active_session = session + features = session.call(messages.Initialize()) except exceptions.Cancelled: # due to a related problem, the first call in this situation will return # a Cancelled failure. This test does not care, we just retry. diff --git a/tests/click_tests/test_repeated_backup.py b/tests/click_tests/test_repeated_backup.py index 3e0ca6946c..7ff1973e3a 100644 --- a/tests/click_tests/test_repeated_backup.py +++ b/tests/click_tests/test_repeated_backup.py @@ -40,7 +40,9 @@ def test_repeated_backup( assert features.initialized is False - device_handler.run( + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.setup, strength=128, backup_type=messages.BackupType.Slip39_Basic, @@ -93,7 +95,7 @@ def test_repeated_backup( assert features.recovery_status == messages.RecoveryStatus.Nothing # run recovery to unlock backup - device_handler.run( + device_handler.run_with_session( device.recover, type=messages.RecoveryType.UnlockRepeatedBackup, ) @@ -160,7 +162,7 @@ def test_repeated_backup( assert features.recovery_status == messages.RecoveryStatus.Nothing # try to unlock backup again... - device_handler.run( + device_handler.run_with_session( device.recover, type=messages.RecoveryType.UnlockRepeatedBackup, ) diff --git a/tests/click_tests/test_reset_bip39.py b/tests/click_tests/test_reset_bip39.py index d405f51441..98e4b4b050 100644 --- a/tests/click_tests/test_reset_bip39.py +++ b/tests/click_tests/test_reset_bip39.py @@ -38,8 +38,9 @@ def test_reset_bip39(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() assert features.initialized is False - - device_handler.run( + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.setup, strength=128, backup_type=messages.BackupType.Bip39, diff --git a/tests/click_tests/test_reset_slip39_advanced.py b/tests/click_tests/test_reset_slip39_advanced.py index 42798661ed..5c16a0532e 100644 --- a/tests/click_tests/test_reset_slip39_advanced.py +++ b/tests/click_tests/test_reset_slip39_advanced.py @@ -50,7 +50,9 @@ def test_reset_slip39_advanced( assert features.initialized is False - device_handler.run( + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.setup, backup_type=messages.BackupType.Slip39_Advanced, pin_protection=False, diff --git a/tests/click_tests/test_reset_slip39_basic.py b/tests/click_tests/test_reset_slip39_basic.py index 4ddfdd7e12..a690e51505 100644 --- a/tests/click_tests/test_reset_slip39_basic.py +++ b/tests/click_tests/test_reset_slip39_basic.py @@ -46,7 +46,9 @@ def test_reset_slip39_basic( assert features.initialized is False - device_handler.run( + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session( + session, device.setup, strength=128, backup_type=messages.BackupType.Slip39_Basic, diff --git a/tests/click_tests/test_tutorial_caesar.py b/tests/click_tests/test_tutorial_caesar.py index 2394b0a102..aa03518a55 100644 --- a/tests/click_tests/test_tutorial_caesar.py +++ b/tests/click_tests/test_tutorial_caesar.py @@ -39,7 +39,8 @@ def prepare_tutorial_and_cancel_after_it( device_handler: "BackgroundDeviceHandler", cancelled: bool = False ) -> Generator["DebugLink", None, None]: debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) yield debug diff --git a/tests/click_tests/test_tutorial_delizia.py b/tests/click_tests/test_tutorial_delizia.py index 0f7912fc76..dfe04d4ccf 100644 --- a/tests/click_tests/test_tutorial_delizia.py +++ b/tests/click_tests/test_tutorial_delizia.py @@ -35,7 +35,8 @@ pytestmark = [ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) assert debug.read_layout().title() == TR.tutorial__welcome_safe5 debug.click(debug.screen_buttons.tap_to_confirm()) @@ -55,7 +56,8 @@ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"): def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) assert debug.read_layout().title() == TR.tutorial__welcome_safe5 debug.click(debug.screen_buttons.tap_to_confirm()) @@ -81,7 +83,8 @@ def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"): def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) assert debug.read_layout().title() == TR.tutorial__welcome_safe5 debug.click(debug.screen_buttons.tap_to_confirm()) @@ -104,7 +107,8 @@ def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"): def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) assert debug.read_layout().title() == TR.tutorial__welcome_safe5 debug.click(debug.screen_buttons.tap_to_confirm()) @@ -134,7 +138,8 @@ def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"): def test_tutorial_menu_funfact(device_handler: "BackgroundDeviceHandler"): debug = device_handler.debuglink() - device_handler.run(device.show_device_tutorial) + session = device_handler.client.get_seedless_session() + device_handler.run_with_provided_session(session, device.show_device_tutorial) assert debug.read_layout().title() == TR.tutorial__welcome_safe5 debug.click(debug.screen_buttons.tap_to_confirm())