1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-19 12:58:13 +00:00

refactor(tests): introduce a better model selection mechanism

This commit is contained in:
matejcik 2024-09-02 13:01:16 +02:00 committed by matejcik
parent 6506b02e2e
commit b3bd85b1fb
110 changed files with 590 additions and 578 deletions

View File

@ -308,7 +308,7 @@ VECTORS = ( # name, amount, show_display
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("name, amount, show_display", VECTORS)
def test_hello_world(
client: Client, name: str, amount: Optional[int], show_display: bool
@ -325,7 +325,7 @@ def test_hello_world(
Unlike in unit tests, [pytest](https://docs.pytest.org) is used as the test framework, which is more suitable for bigger and more complex test suites.
As the functionality is developed only for `TT`, to not break the `CI`, we want to skip this test's execution for model `T1`, by adding `@pytest.mark.skip_t1b1` decorator.
As the functionality is developed only for `core`, we want to limit the test via `@pytest.mark.models("core")`, otherwise the CI would run it (and fail) for Trezor One too.
We are also using the `@pytest.mark.parametrize` decorator, which is an efficient way of testing multiple inputs into the same test case.

View File

@ -105,12 +105,28 @@ the following marker:
This marker must be registered in `REGISTERED_MARKERS` file in `tests` folder.
Tests can be run only for specific models - it is done by disallowing the tests for the other models.
`@pytest.mark.skip_t1b1`
`@pytest.mark.skip_t2t1`
`@pytest.mark.skip_t2b1`
`@pytest.mark.skip_t3t1`
are valid markers to skip current test for Model 1, Model T, Safe 3, and T3T1 respectively.
Tests can be run only for specific models. The marker `@pytest.mark.models()` can be
used to narrow the selection:
* `@pytest.mark.models("t3b1", "t2t1)` - only for Safe 3 rev2 and Trezor T
* `@pytest.mark.models("core")` - only for trezor-core models (skip Trezor One)
* `@pytest.mark.models(skip="t3t1")` - for all models except Safe 5
* `@pytest.mark.models("core", skip="t3t1")` - for all trezor-core models except Safe 5
Arguments can be a list of internal model names, or one of the following shortcuts:
* `core` - all trezor-core models
* `legacy` - just Trezor One
* `safe` - Trezor Safe family
* `safe3` - Trezor Safe 3 (covers T2B1 and T2T1)
* `mercury` - covers the `mercury` layout (currently T3T1 only)
You can specify a list as positional arguments, and exclude from it via `skip` keyword argument.
You can provide a list of strings, a list of `TrezorModel` instances, or a
comma-separated string of model names or shortcuts.
You can specify a skip reason as `reason="TODO implement for Mercury too"`.
[pytest-random-order]: https://pypi.org/project/pytest-random-order/

View File

@ -3,7 +3,7 @@ from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
from trezorlib import models
from trezorlib.debuglink import LayoutType
from .. import buttons
from .. import translations as TR
@ -45,23 +45,23 @@ def get_char_category(char: str) -> PassphraseCategory:
return PassphraseCategory.SPECIAL
def go_next(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None:
if debug.model in (models.T2T1,):
def go_next(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
if debug.layout_type is LayoutType.TT:
return debug.click(buttons.OK, wait=wait) # type: ignore
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
return debug.press_right(wait=wait) # type: ignore
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
return debug.swipe_up(wait=wait)
else:
raise RuntimeError("Unknown model")
def tap_to_confirm(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None:
if debug.model in (models.T2T1,):
def tap_to_confirm(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
if debug.layout_type is LayoutType.TT:
return debug.read_layout() # type: ignore
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
return debug.read_layout() # type: ignore
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
return debug.click(buttons.TAP_TO_CONFIRM, wait=wait)
else:
raise RuntimeError("Unknown model")
@ -69,10 +69,10 @@ def tap_to_confirm(debug: "DebugLink", wait: bool = False) -> "LayoutContent" |
def go_back(
debug: "DebugLink", wait: bool = False, r_middle: bool = False
) -> "LayoutContent" | None:
if debug.model in (models.T2T1, models.T3T1):
) -> LayoutContent | None:
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
return debug.click(buttons.CANCEL, wait=wait) # type: ignore
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
if r_middle:
return debug.press_middle(wait=wait) # type: ignore
@ -124,12 +124,12 @@ def navigate_to_action_and_press(
debug.press_middle(wait=True)
def unlock_gesture(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None:
if debug.model in (models.T2T1,):
def unlock_gesture(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
if debug.layout_type is LayoutType.TT:
return debug.click(buttons.OK, wait=wait) # type: ignore
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
return debug.press_right(wait=wait) # type: ignore
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
return debug.click(buttons.TAP_TO_CONFIRM, wait=wait) # type: ignore
else:
raise RuntimeError("Unknown model")

View File

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING
from trezorlib import models
from trezorlib.debuglink import LayoutType
from .. import buttons
from .. import translations as TR
@ -18,15 +18,15 @@ DELETE_BTN_TEXTS = get_possible_btn_texts("inputs__delete") + get_possible_btn_t
def enter_word(
debug: "DebugLink", word: str, is_slip39: bool = False
) -> "LayoutContent":
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
typed_word = word[:4]
for coords in buttons.type_word(typed_word, is_slip39=is_slip39):
debug.click(coords)
if debug.model is models.T3T1 and not is_slip39 and len(word) > 4:
if debug.layout_type is LayoutType.Mercury and not is_slip39 and len(word) > 4:
# T3T1 (mercury) BIP39 keyboard allows to "confirm" only if the word is fully written, you need to click the word to auto-complete
debug.click(buttons.CONFIRM_WORD, wait=True)
return debug.click(buttons.CONFIRM_WORD, wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
letter_index = 0
layout = debug.read_layout()
@ -51,11 +51,11 @@ def enter_word(
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
layout = debug.wait_layout()
TR.assert_equals(layout.title(), title)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
@ -110,23 +110,20 @@ def select_number_of_words(
if wait:
debug.wait_layout()
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
TR.assert_equals(debug.read_layout().text_content(), "recovery__num_of_words")
layout = select_tt()
elif debug.model in (
models.T2B1,
models.T3B1,
):
elif debug.layout_type is LayoutType.TR:
layout = debug.press_right(wait=True)
TR.assert_equals(layout.title(), "word_count__title")
layout = select_tr()
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
layout = select_mercury()
else:
raise ValueError("Unknown model")
if unlock_repeated_backup:
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
TR.assert_in(layout.text_content(), "recovery__enter_backup")
else:
TR.assert_in_multiple(
@ -160,12 +157,12 @@ def enter_share(
is_first: bool = True,
before_title: str = "recovery__title_recover",
) -> "LayoutContent":
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
TR.assert_in(debug.read_layout().title(), before_title)
layout = debug.wait_layout()
for _ in range(layout.page_count()):
layout = debug.press_right(wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
layout = debug.swipe_up(wait=True)
else:
TR.assert_in(debug.read_layout().title(), before_title)
@ -243,11 +240,11 @@ def enter_seed_previous_correct(
if go_back:
go_back = False
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.swipe_right(wait=True)
for _ in range(len(bad_word)):
debug.click(buttons.RECOVERY_DELETE, wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
layout = debug.read_layout()
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
@ -258,7 +255,7 @@ def enter_seed_previous_correct(
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
layout = debug.press_left(wait=True)
layout = debug.press_middle(wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.click(buttons.RECOVERY_DELETE, wait=True) # Top-left
for _ in range(len(bad_word)):
debug.click(buttons.RECOVERY_DELETE, wait=True)
@ -288,12 +285,12 @@ def prepare_enter_seed(
layout_text,
],
)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
debug.swipe_up(wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
debug.press_right()
layout = debug.press_right(wait=True)

View File

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
from shamir_mnemonic import shamir # type: ignore
from trezorlib import models
from trezorlib.debuglink import LayoutType
from .. import buttons
from .. import translations as TR
@ -14,23 +14,23 @@ if TYPE_CHECKING:
def confirm_new_wallet(debug: "DebugLink") -> None:
TR.assert_equals(debug.read_layout().title(), "reset__title_create_wallet")
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
debug.click(buttons.TAP_TO_CONFIRM, wait=True)
debug.swipe_up(wait=True) # Wallet created
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
debug.press_right(wait=True)
def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None:
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
page_count = debug.read_layout().page_count()
if page_count > 1:
for _ in range(page_count - 1):
@ -44,30 +44,30 @@ def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None:
def cancel_backup(
debug: "DebugLink", middle_r: bool = False, confirm: bool = False
) -> None:
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.CANCEL, wait=True)
debug.click(buttons.CANCEL, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.click(buttons.CORNER_BUTTON, wait=True)
debug.click(buttons.VERTICAL_MENU[0], wait=True)
if confirm:
debug.swipe_up(wait=True)
debug.click(buttons.TAP_TO_CONFIRM)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_left(wait=True)
debug.press_left(wait=True)
def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> None:
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
assert "NumberInputDialog" in debug.read_layout().all_components()
for _ in range(diff):
debug.click(button, wait=True)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
else:
debug.swipe_up(wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
layout = debug.read_layout()
if layout.title() in TR.translate(
"reset__title_number_of_shares"
@ -87,9 +87,9 @@ def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> Non
def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
words: list[str] = []
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
# Swiping through all the pages and loading the words
@ -98,19 +98,19 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
words.extend(layout.seed_words())
layout = debug.swipe_up(wait=True)
assert layout is not None
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
words.extend(layout.seed_words())
if debug.model in (models.T3T1,):
if debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
# There is hold-to-confirm button
if do_htc:
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click_hold(buttons.OK, hold_ms=1500)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1500)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right_htc(1200)
else:
# It would take a very long time to test 16-of-16 with doing 1500 ms HTC after
@ -121,11 +121,11 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
def confirm_words(debug: "DebugLink", words: list[str]) -> None:
if debug.model in (models.T3T1,):
if debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
layout = debug.wait_layout()
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
TR.assert_template(layout.text_content(), "reset__select_word_x_of_y_template")
for _ in range(3):
# "Select word 3 of 20"
@ -140,7 +140,7 @@ 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)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
TR.assert_template(layout.subtitle(), "reset__select_word_x_of_y_template")
for _ in range(3):
# "Select word 3 of 20"
@ -155,7 +155,7 @@ 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.VERTICAL_MENU[button_pos], wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
TR.assert_in(layout.text_content(), "reset__select_correct_word")
layout = debug.press_right(wait=True)
for _ in range(3):

View File

@ -20,7 +20,8 @@ from typing import TYPE_CHECKING
import pytest
from trezorlib import btc, device, exceptions, messages, models
from trezorlib import btc, device, exceptions, messages
from trezorlib.debuglink import LayoutType
from trezorlib.protobuf import MessageType
from trezorlib.tools import parse_path
@ -70,7 +71,7 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int)
)
layout = go_next(debug, wait=True)
if debug.model in (models.T3T1,):
if debug.layout_type is LayoutType.Mercury:
layout = tap_to_confirm(debug, wait=True)
assert layout.main_component() == "Homescreen"
assert device_handler.result() == "Settings applied"
@ -104,17 +105,17 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
in debug.wait_layout().text_content().replace(" ", "")
)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
layout = debug.click(buttons.OK, wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
assert "0.0039 BTC" in layout.text_content()
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
layout = debug.swipe_up(wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
assert "0.0039 BTC" in layout.text_content()
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
layout = debug.press_right(wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
@ -156,18 +157,18 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
in debug.wait_layout().text_content().replace(" ", "")
)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
layout = debug.click(buttons.OK, wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
assert "0.0039 BTC" in layout.text_content()
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.swipe_up(wait=True)
layout = debug.swipe_up(wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
assert "0.0039 BTC" in layout.text_content()
debug.swipe_up(wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
layout = debug.press_right(wait=True)
TR.assert_in(layout.text_content(), "send__total_amount")
@ -181,11 +182,11 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
with device_handler.client:
device_handler.client.set_filter(messages.TxAck, sleepy_filter)
# confirm transaction
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.click(buttons.TAP_TO_CONFIRM)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_middle()
signatures, tx = device_handler.result()
@ -205,20 +206,20 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
assert "PassphraseKeyboard" in debug.wait_layout().all_components()
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
# Going into the selected character category
debug.press_middle()
# enter passphrase - slowly
# keep clicking for long enough to trigger the autolock if it incorrectly ignored key presses
for _ in range(math.ceil(11 / 1.5)):
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
# click at "j"
debug.click(CENTER_BUTTON)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
# click at "j"
debug.click((20, 120))
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
# just go right
# NOTE: because of passphrase randomization it would be a pain to input
# a specific passphrase, which is not in scope for this test.
@ -226,11 +227,11 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
time.sleep(1.5)
# Send the passphrase to the client (TT has it clicked already, TR needs to input it)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
debug.click(buttons.OK, wait=True)
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
debug.click(buttons.CORNER_BUTTON, wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.input("j" * 8, wait=True)
# address corresponding to "jjjjjjjj" passphrase
@ -247,16 +248,16 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
assert "PassphraseKeyboard" in debug.wait_layout().all_components()
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
# Going into the selected character category
debug.press_middle()
# enter passphrase - slowly
# autolock must activate even if we pressed some buttons
for _ in range(math.ceil(6 / 1.5)):
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
debug.click(CENTER_BUTTON)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_middle()
time.sleep(1.5)
@ -287,7 +288,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
layout = unlock_dry_run(debug)
TR.assert_in(debug.wait_layout().text_content(), "recovery__num_of_words")
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
debug.press_right(wait=True)
# wait for autolock to trigger
@ -321,10 +322,10 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"):
# select 20 words
recovery.select_number_of_words(debug, 20)
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
layout = go_next(debug, wait=True)
assert layout.main_component() == "MnemonicKeyboard"
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
layout = debug.press_right(wait=True)
assert "MnemonicKeyboard" in layout.all_components()
@ -347,7 +348,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
# select 20 words
recovery.select_number_of_words(debug, 20)
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
layout = debug.click(buttons.OK, wait=True)
assert layout.main_component() == "MnemonicKeyboard"
@ -358,7 +359,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
layout = debug.click(buttons.CONFIRM_WORD, wait=True)
# should not have locked, even though we took 9 seconds to type each letter
assert layout.main_component() == "MnemonicKeyboard"
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
layout = debug.swipe_up(wait=True)
assert layout.main_component() == "MnemonicKeyboard"
@ -369,7 +370,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
layout = debug.click(buttons.CONFIRM_WORD, wait=True)
# should not have locked, even though we took 9 seconds to type each letter
assert layout.main_component() == "MnemonicKeyboard"
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
layout = debug.press_right(wait=True)
assert "MnemonicKeyboard" in layout.all_components()

View File

@ -18,7 +18,8 @@ from typing import TYPE_CHECKING
import pytest
from trezorlib import device, messages, models
from trezorlib import device, messages
from trezorlib.debuglink import LayoutType
from ..common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy
from . import reset
@ -27,7 +28,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@pytest.mark.parametrize(
@ -96,9 +97,9 @@ def test_backup_slip39_custom(
all_words.append(" ".join(words))
# confirm backup done
if debug.model is models.T3T1 and share_count > 1:
if debug.layout_type is LayoutType.Mercury and share_count > 1:
reset.confirm_read(debug)
elif debug.model != models.T3T1:
elif debug.layout_type is not LayoutType.Mercury:
reset.confirm_read(debug)
# generate secret locally

View File

@ -20,6 +20,7 @@ from typing import TYPE_CHECKING
import pytest
from trezorlib import models
from trezorlib.debuglink import LayoutType
from .. import buttons, common
@ -37,18 +38,20 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
short_duration = {
models.T1B1: 500,
models.T2B1: 500,
models.T3B1: 500,
models.T2T1: 1000,
models.T3T1: 1000,
}[debug.model]
lock_duration = {
models.T1B1: 1200,
models.T2B1: 1200,
models.T3B1: 1200,
models.T2T1: 3500,
models.T3T1: 3500,
}[debug.model]
def hold(duration: int, wait: bool = True) -> None:
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
debug.press_right_htc(hold_ms=duration)
else:
debug.input(x=13, y=37, hold_ms=duration, wait=wait)
@ -75,7 +78,7 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
assert device_handler.features().unlocked is False
# unlock by touching
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
# Doing a short HTC to simulate a click
debug.press_right_htc(hold_ms=100)
layout = debug.wait_layout()

View File

@ -32,7 +32,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2b1, pytest.mark.skip_t2t1]
pytestmark = pytest.mark.models("mercury")
PASSPHRASE_CANCELLED = pytest.raises(exceptions.Cancelled, match="")

View File

@ -36,7 +36,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2t1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("safe3")
# Testing the maximum length is really 50
# TODO: show some UI message when length reaches 50?

View File

@ -30,7 +30,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("t2t1")
# TODO: it is not possible to cancel the passphrase entry on TT
# NOTE: the prompt (underscoring) is not there when a space is entered

View File

@ -20,7 +20,8 @@ from typing import TYPE_CHECKING, Generator
import pytest
from trezorlib import device, exceptions, models
from trezorlib import device, exceptions
from trezorlib.debuglink import LayoutType
from .. import buttons
from .. import translations as TR
@ -37,7 +38,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
PIN_CANCELLED = pytest.raises(exceptions.TrezorFailure, match="PIN entry cancelled")
PIN_INVALID = pytest.raises(exceptions.TrezorFailure, match="PIN invalid")
@ -105,9 +106,9 @@ def prepare(
TR.assert_in_multiple(
debug.wait_layout().text_content(), ["pin__turn_on", "pin__info"]
)
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
go_next(debug)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
go_next(debug, wait=True)
go_next(debug, wait=True)
go_next(debug, wait=True)
@ -126,7 +127,7 @@ def prepare(
_input_see_confirm(debug, old_pin)
TR.assert_in(debug.wait_layout().text_content(), "wipe_code__turn_on")
go_next(debug, wait=True)
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
go_next(debug, wait=True)
go_next(debug, wait=True)
go_next(debug, wait=True)
@ -138,7 +139,7 @@ def prepare(
_assert_pin_entry(debug)
yield debug
if debug.model in (models.T3T1,) and tap:
if debug.layout_type is LayoutType.Mercury and tap:
go_next(debug, wait=True)
debug.click(buttons.TAP_TO_CONFIRM)
else:
@ -156,13 +157,13 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None:
if check:
before = debug.read_layout().pin()
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
digits_order = debug.read_layout().tt_pin_digits_order()
for digit in pin:
digit_index = digits_order.index(digit)
coords = buttons.pin_passphrase_index(digit_index)
debug.click(coords, wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
for digit in pin:
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
@ -173,9 +174,9 @@ 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 in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
debug.click(buttons.TOP_ROW, wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
navigate_to_action_and_press(debug, SHOW, TR_PIN_ACTIONS)
@ -185,9 +186,9 @@ def _delete_pin(debug: "DebugLink", digits_to_delete: int, check: bool = True) -
before = debug.read_layout().pin()
for _ in range(digits_to_delete):
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
debug.click(buttons.pin_passphrase_grid(9), wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
if check:
@ -197,9 +198,9 @@ 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 in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
debug.click_hold(buttons.pin_passphrase_grid(9), hold_ms=1500)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS, hold_ms=1000)
if check:
@ -216,9 +217,9 @@ def _cancel_pin(debug: "DebugLink") -> None:
def _confirm_pin(debug: "DebugLink") -> None:
"""Navigate to "ENTER" and press it"""
if debug.model in (models.T2T1, models.T3T1):
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
debug.click(buttons.pin_passphrase_grid(11), wait=True)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
@ -231,7 +232,7 @@ def _input_see_confirm(debug: "DebugLink", pin: str) -> None:
def _enter_two_times(debug: "DebugLink", pin1: str, pin2: str) -> None:
_input_see_confirm(debug, pin1)
if debug.model in (models.T2B1,):
if debug.layout_type is LayoutType.TR:
# Please re-enter
go_next(debug, wait=True)
@ -300,7 +301,7 @@ def test_pin_incorrect(device_handler: "BackgroundDeviceHandler"):
_input_see_confirm(debug, PIN4)
@pytest.mark.skip_t2b1("TODO: will we support cancelling on T2B1?")
@pytest.mark.models(skip="safe3", reason="TODO: will we support cancelling on T2B1?")
@pytest.mark.setup_client(pin=PIN4)
def test_pin_cancel(device_handler: "BackgroundDeviceHandler"):
with PIN_CANCELLED, prepare(device_handler, Situation.PIN_INPUT_CANCEL) as debug:
@ -321,13 +322,13 @@ def test_pin_setup(device_handler: "BackgroundDeviceHandler"):
def test_pin_setup_mismatch(device_handler: "BackgroundDeviceHandler"):
with PIN_CANCELLED, prepare(device_handler, Situation.PIN_SETUP) as debug:
_enter_two_times(debug, "1", "2")
if debug.model in (models.T2T1,):
if debug.layout_type is LayoutType.TT:
go_next(debug)
_cancel_pin(debug)
elif debug.model in (models.T2B1,):
elif debug.layout_type is LayoutType.TR:
debug.press_middle()
debug.press_no()
elif debug.model in (models.T3T1,):
elif debug.layout_type is LayoutType.Mercury:
go_next(debug, wait=True)
_cancel_pin(debug)

View File

@ -19,7 +19,8 @@ from typing import TYPE_CHECKING, Generator
import pytest
from trezorlib import device, messages, models
from trezorlib import device, messages
from trezorlib.debuglink import LayoutType
from ..common import MNEMONIC12, MNEMONIC_SLIP39_BASIC_20_3of6
from . import recovery
@ -30,7 +31,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@contextmanager
@ -54,7 +55,7 @@ def prepare_recovery_and_evaluate(
def test_recovery_slip39_basic(device_handler: "BackgroundDeviceHandler"):
with prepare_recovery_and_evaluate(device_handler) as debug:
recovery.confirm_recovery(debug)
if debug.model is models.T2B1:
if debug.layout_type is LayoutType.TR:
recovery.confirm_recovery(debug)
recovery.select_number_of_words(debug)
@ -66,7 +67,7 @@ def test_recovery_slip39_basic(device_handler: "BackgroundDeviceHandler"):
def test_recovery_bip39(device_handler: "BackgroundDeviceHandler"):
with prepare_recovery_and_evaluate(device_handler) as debug:
recovery.confirm_recovery(debug)
if debug.model is models.T2B1:
if debug.layout_type is LayoutType.TR:
recovery.confirm_recovery(debug)
recovery.select_number_of_words(debug, num_of_words=12)
@ -78,7 +79,7 @@ def test_recovery_bip39(device_handler: "BackgroundDeviceHandler"):
def test_recovery_bip39_previous_word(device_handler: "BackgroundDeviceHandler"):
with prepare_recovery_and_evaluate(device_handler) as debug:
recovery.confirm_recovery(debug)
if debug.model is models.T2B1:
if debug.layout_type is LayoutType.TR:
recovery.confirm_recovery(debug)
recovery.select_number_of_words(debug, num_of_words=12)

View File

@ -29,7 +29,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)

View File

@ -28,7 +28,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)

View File

@ -28,7 +28,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)

View File

@ -28,7 +28,7 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
@pytest.mark.parametrize(

View File

@ -30,8 +30,9 @@ if TYPE_CHECKING:
from ..device_handler import BackgroundDeviceHandler
# T2B1-only
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2t1, pytest.mark.skip_t3t1]
# Safe3 only
# TODO extend to T3T1
pytestmark = pytest.mark.models("safe3")
@contextmanager

View File

@ -24,6 +24,7 @@ from unittest import mock
import pytest
from trezorlib import btc, messages, models, tools
from trezorlib.debuglink import LayoutType
from . import buttons
@ -99,16 +100,22 @@ def parametrize_using_common_fixtures(*paths: str) -> "MarkDecorator":
test_id = test_id.lower().replace(" ", "_")
skip_models = test.get("skip_models", [])
skip_marks = []
skiplist = []
# TODO: genericify this
for skip_model in skip_models:
if skip_model in ("t1", "t1b1"):
skip_marks.append(pytest.mark.skip_t1b1)
skiplist.append(models.T1B1)
if skip_model in ("t2", "t2t1"):
skip_marks.append(pytest.mark.skip_t2t1)
skiplist.append(models.T2T1)
if skip_model in ("tr", "t2b1"):
skip_marks.append(pytest.mark.skip_t2b1)
skiplist.append(models.T2B1)
skiplist.append(models.T3B1)
if skip_model == "t3t1":
skip_marks.append(pytest.mark.skip_t3t1)
skiplist.append(models.T3T1)
if skiplist:
skip_marks = [pytest.mark.models(skip=skiplist)]
else:
skip_marks = []
tests.append(
pytest.param(
@ -198,14 +205,14 @@ def read_and_confirm_mnemonic(
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
"""
if debug.model is models.T2T1:
if debug.layout_type is LayoutType.TT:
mnemonic = yield from read_mnemonic_from_screen_tt(debug)
elif debug.model is models.T2B1:
elif debug.layout_type is LayoutType.TR:
mnemonic = yield from read_mnemonic_from_screen_tr(debug)
elif debug.model is models.T3T1:
elif debug.layout_type is LayoutType.Mercury:
mnemonic = yield from read_mnemonic_from_screen_mercury(debug)
else:
raise ValueError(f"Unknown model: {debug.model}")
raise ValueError(f"Unknown model: {debug.layout_type}")
if not check_share(debug, mnemonic, choose_wrong):
return None
@ -282,15 +289,15 @@ def check_share(
"""
re_num_of_word = r"\d+"
for _ in range(3):
if debug.model is models.T2T1:
if debug.layout_type is LayoutType.TT:
# T2T1 has position as the first number in the text
word_pos_match = re.search(
re_num_of_word, debug.wait_layout().text_content()
)
elif debug.model is models.T2B1:
elif debug.layout_type is LayoutType.TR:
# other models have the instruction in the title/subtitle
word_pos_match = re.search(re_num_of_word, debug.wait_layout().title())
elif debug.model is models.T3T1:
elif debug.layout_type is LayoutType.Mercury:
word_pos_match = re.search(re_num_of_word, debug.wait_layout().subtitle())
else:
word_pos_match = None

View File

@ -17,8 +17,8 @@
from __future__ import annotations
import os
import typing as t
from pathlib import Path
from typing import TYPE_CHECKING, Generator, Iterator
import pytest
import xdist
@ -38,9 +38,11 @@ from . import translations, ui_tests
from .device_handler import BackgroundDeviceHandler
from .emulators import EmulatorWrapper
if TYPE_CHECKING:
if t.TYPE_CHECKING:
from _pytest.config import Config
from _pytest.config.argparsing import Parser
from _pytest.mark import Mark
from _pytest.nodes import Node
from _pytest.terminal import TerminalReporter
from trezorlib._internal.emulator import Emulator
@ -64,7 +66,7 @@ def _emulator_wrapper_main_args() -> list[str]:
@pytest.fixture
def core_emulator(request: pytest.FixtureRequest) -> Iterator[Emulator]:
def core_emulator(request: pytest.FixtureRequest) -> t.Iterator[Emulator]:
"""Fixture returning default core emulator with possibility of screen recording."""
with EmulatorWrapper("core", main_args=_emulator_wrapper_main_args()) as emu:
# Modifying emu.client to add screen recording (when --ui=test is used)
@ -73,7 +75,7 @@ def core_emulator(request: pytest.FixtureRequest) -> Iterator[Emulator]:
@pytest.fixture(scope="session")
def emulator(request: pytest.FixtureRequest) -> Generator["Emulator", None, None]:
def emulator(request: pytest.FixtureRequest) -> t.Generator["Emulator", None, None]:
"""Fixture for getting emulator connection in case tests should operate it on their own.
Is responsible for starting it at the start of the session and stopping
@ -139,13 +141,6 @@ def _raw_client(request: pytest.FixtureRequest) -> Client:
else:
client = _find_client(request, interact)
# Setting the appropriate language
# Not doing it for T1
if client.model is not models.T1B1:
lang = request.session.config.getoption("lang") or "en"
assert isinstance(lang, str)
translations.set_language(client, lang)
return client
@ -172,10 +167,78 @@ def _find_client(request: pytest.FixtureRequest, interact: bool) -> Client:
raise RuntimeError("No debuggable device found")
class ModelsFilter:
MODEL_SHORTCUTS = {
"core": models.TREZORS - {models.T1B1},
"legacy": {models.T1B1},
"t1": {models.T1B1},
"t2": {models.T2T1},
"tt": {models.T2T1},
"safe": {models.T2B1, models.T3T1, models.T3B1},
"safe3": {models.T2B1, models.T3B1},
"safe5": {models.T3T1},
"mercury": {models.T3T1},
}
def __init__(self, node: Node) -> None:
markers = node.iter_markers("models")
self.models = set(models.TREZORS)
for marker in markers:
self._refine_by_marker(marker)
def __contains__(self, model: models.TrezorModel) -> bool:
return model in self.models
def __bool__(self) -> bool:
return bool(self.models)
def _refine_by_marker(self, marker: Mark) -> None:
"""Apply the marker selector to the current models selection."""
if marker.args:
self.models &= self._set_from_marker_list(marker.args)
if "skip" in marker.kwargs:
self.models -= self._set_from_marker_list(marker.kwargs["skip"])
@classmethod
def _set_from_marker_list(
cls, marker_list: str | t.Sequence[str] | t.Sequence[models.TrezorModel]
) -> set[models.TrezorModel]:
"""Given either a possible value of pytest.mark.models positional args,
or a value of the `skip` kwarg, return a set of models specified by that value.
"""
if not marker_list:
raise ValueError("No models specified")
if isinstance(marker_list[0], models.TrezorModel):
# raw list of TrezorModels
return set(marker_list) # type: ignore [incompatible with return type]
if len(marker_list) == 1:
# @pytest.mark.models("t2t1,t2b1") -> ("t2t1,t2b1",) -> "t2t1,t2b1"
marker_list = marker_list[0]
if isinstance(marker_list, str):
# either a single model / shortcut, or a comma-separated text list
# @pytest.mark.models("t2t1,t2b1") -> "t2t1,t2b1" -> ["t2t1", "t2b1"]
marker_list = [s.strip() for s in marker_list.split(",")]
selected_models = set()
for marker in marker_list:
assert isinstance(marker, str)
if marker in cls.MODEL_SHORTCUTS:
selected_models |= cls.MODEL_SHORTCUTS[marker]
elif (model := models.by_internal_name(marker.upper())) is not None:
selected_models.add(model)
else:
raise ValueError(f"Unknown model: {marker}")
return selected_models
@pytest.fixture(scope="function")
def client(
request: pytest.FixtureRequest, _raw_client: Client
) -> Generator[Client, None, None]:
) -> t.Generator[Client, None, None]:
"""Client fixture.
Every test function that requires a client instance will get it from here.
@ -199,26 +262,9 @@ def client(
@pytest.mark.experimental
"""
if (
request.node.get_closest_marker("skip_t2t1")
and _raw_client.model is models.T2T1
):
pytest.skip("Test excluded on Trezor T")
if (
request.node.get_closest_marker("skip_t1b1")
and _raw_client.model is models.T1B1
):
pytest.skip("Test excluded on Trezor 1")
if (
request.node.get_closest_marker("skip_t2b1")
and _raw_client.model is models.T2B1
):
pytest.skip("Test excluded on Trezor T2B1")
if (
request.node.get_closest_marker("skip_t3t1")
and _raw_client.model is models.T3T1
):
pytest.skip("Test excluded on Trezor T3T1")
models_filter = ModelsFilter(request.node)
if _raw_client.model not in models_filter:
pytest.skip(f"Skipping test for model {_raw_client.model.internal_name}")
sd_marker = request.node.get_closest_marker("sd_card")
if sd_marker and not _raw_client.features.sd_card_present:
@ -399,10 +445,10 @@ def pytest_configure(config: "Config") -> None:
Registers known markers, enables verbose output if requested.
"""
# register known markers
config.addinivalue_line("markers", "skip_t1b1: skip the test on Trezor One")
config.addinivalue_line("markers", "skip_t2t1: skip the test on Trezor T")
config.addinivalue_line("markers", "skip_t2b1: skip the test on Trezor T2B1")
config.addinivalue_line("markers", "skip_t3t1: skip the test on Trezor T3T1")
config.addinivalue_line(
"markers",
'models("core", "t1b1", ..., skip=[...], reason="..."): select which models or families to run the test on',
)
config.addinivalue_line(
"markers", "experimental: enable experimental features on Trezor"
)
@ -424,10 +470,8 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
Ensures that altcoin tests are skipped, and that no test is skipped for all models.
"""
if all(
item.get_closest_marker(marker)
for marker in ("skip_t1b1", "skip_t2t1", "skip_t2b1", "skip_t3t1")
):
models_filter = ModelsFilter(item)
if not models_filter:
raise RuntimeError("Don't skip tests for all trezor models!")
skip_altcoins = int(os.environ.get("TREZOR_PYTEST_SKIP_ALTCOINS", 0))
@ -436,7 +480,7 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item: pytest.Item, call) -> Generator:
def pytest_runtest_makereport(item: pytest.Item, call) -> t.Generator:
# Make test results available in fixtures.
# See https://docs.pytest.org/en/latest/example/simple.html#making-test-result-information-available-in-fixtures
# The device_handler fixture uses this as 'request.node.rep_call.passed' attribute,
@ -461,7 +505,7 @@ def pytest_report_teststatus(
@pytest.fixture
def device_handler(client: Client, request: pytest.FixtureRequest) -> Generator:
def device_handler(client: Client, request: pytest.FixtureRequest) -> t.Generator:
device_handler = BackgroundDeviceHandler(client)
yield device_handler

View File

@ -25,7 +25,7 @@ from ...input_flows import InputFlowShowAddressQRCode
pytestmark = [
pytest.mark.altcoin,
pytest.mark.binance,
pytest.mark.skip_t1b1, # T1 support is not planned
pytest.mark.models("core"),
pytest.mark.setup_client(
mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin"
),

View File

@ -27,7 +27,7 @@ BINANCE_PATH = parse_path("m/44h/714h/0h/0/0")
@pytest.mark.altcoin
@pytest.mark.binance
@pytest.mark.skip_t1b1 # T1 support is not planned
@pytest.mark.models("core")
@pytest.mark.setup_client(
mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin"
)

View File

@ -103,7 +103,7 @@ BINANCE_TEST_VECTORS = [
@pytest.mark.altcoin
@pytest.mark.binance
@pytest.mark.skip_t1b1 # T1 support is not planned
@pytest.mark.models("core")
@pytest.mark.setup_client(
mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin"
)

View File

@ -467,7 +467,7 @@ def test_send_bch_multisig_change(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_send_bch_external_presigned(client: Client):
inp1 = messages.TxInputType(
# address_n=parse_path("44'/145'/0'/1/0"),

View File

@ -47,7 +47,7 @@ FAKE_TXHASH_a63dbe = bytes.fromhex(
"a63dbedd8cd284bf0d3c468e84b9b0eeb14c3a08824eab8f80e7723a299f30db"
)
pytestmark = [pytest.mark.altcoin, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = [pytest.mark.altcoin, pytest.mark.models("t1b1", "t2t1")]
# All data taken from T1
@ -548,7 +548,7 @@ def test_send_mixed_inputs(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_send_btg_external_presigned(client: Client):
# NOTE: fake input tx used

View File

@ -40,7 +40,7 @@ TXHASH_15575a = bytes.fromhex(
"15575a1c874bd60a819884e116c42e6791c8283ce1fc3b79f0d18531a61bbb8a"
)
pytestmark = [pytest.mark.altcoin, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = [pytest.mark.altcoin, pytest.mark.models("t1b1", "t2t1")]
def test_send_dash(client: Client):

View File

@ -53,8 +53,7 @@ FAKE_TXHASH_1f00fc = bytes.fromhex(
pytestmark = [
pytest.mark.altcoin,
pytest.mark.decred,
pytest.mark.skip_t2b1,
pytest.mark.skip_t3t1,
pytest.mark.models("t1b1", "t2t1"),
]
@ -105,7 +104,7 @@ def test_send_decred(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_purchase_ticket_decred(client: Client):
# NOTE: fake input tx used
@ -168,7 +167,7 @@ def test_purchase_ticket_decred(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_spend_from_stake_generation_and_revocation_decred(client: Client):
# NOTE: fake input tx used

View File

@ -161,7 +161,7 @@ def _address_n(purpose, coin, account, script_type):
return res
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize(
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
)

View File

@ -138,7 +138,7 @@ def test_elements(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_address_mac(client: Client):
resp = btc.get_authenticated_address(
client, "Bitcoin", parse_path("m/44h/0h/0h/1/0")
@ -165,7 +165,7 @@ def test_address_mac(client: Client):
assert resp.mac is None
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.altcoin
def test_altcoin_address_mac(client: Client):
resp = btc.get_authenticated_address(

View File

@ -52,9 +52,7 @@ VECTORS = ( # path, script_type, address
)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_t1(
client: Client, path: str, script_type: messages.InputScriptType, address: str
@ -80,7 +78,7 @@ def test_show_t1(
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("chunkify", (True, False))
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_tt(
@ -106,7 +104,7 @@ def test_show_tt(
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("path, script_type, address", VECTORS)
def test_show_cancel(
client: Client, path: str, script_type: messages.InputScriptType, address: str
@ -237,7 +235,7 @@ VECTORS_MULTISIG = ( # script_type, bip48_type, address, xpubs, ignore_xpub_mag
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.multisig
@pytest.mark.parametrize(
"script_type, bip48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG

View File

@ -116,7 +116,7 @@ def test_get_public_node(client: Client, coin_name, xpub_magic, path, xpub):
assert bip32.serialize(res.node, xpub_magic) == xpub
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
def test_get_public_node_show(client: Client, coin_name, xpub_magic, path, xpub):
with client:

View File

@ -18,7 +18,8 @@ from typing import Any
import pytest
from trezorlib import btc, messages, models
from trezorlib import btc, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import message_filters
from trezorlib.exceptions import Cancelled
@ -37,20 +38,14 @@ S = messages.InputScriptType
def case(
id: str,
*args: Any,
models: str | None = None,
altcoin: bool = False,
skip_t1b1: bool = False,
skip_t2b1: bool = False,
skip_t3t1: bool = False
):
marks = []
if altcoin:
marks.append(pytest.mark.altcoin)
if skip_t1b1:
marks.append(pytest.mark.skip_t1b1)
if skip_t2b1:
marks.append(pytest.mark.skip_t2b1)
if skip_t3t1:
marks.append(pytest.mark.skip_t3t1)
if models:
marks.append(pytest.mark.models(models))
return pytest.param(*args, id=id, marks=marks)
@ -182,7 +177,7 @@ VECTORS = ( # case name, coin_name, path, script_type, address, message, signat
"1FoHjQT6bAEu2FQGzTgqj4PBneoiCAk4ZN",
b"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
"1f40ae58dd68480a2f39eecf4decfe79ceacde3f865502db67c083b8465b33535c0750d5377b7ac62e534f71c922cd029f659761f8ac99e859df36322c5b320eff",
skip_t1b1=True,
models="core",
),
# ==== Testnet script types ====
case(
@ -270,8 +265,7 @@ VECTORS = ( # case name, coin_name, path, script_type, address, message, signat
"This is an example of a signed message.",
"206b1f8ba47ef9eaf87aa900e41ab1e97f67e8c09292faa4acf825228d074c4b774484046dcb1d9bbf0603045dbfb328c3e1b0c09c5ae133e89e604a67a1fc6cca",
altcoin=True,
skip_t2b1=True,
skip_t3t1=True,
models="t1b1,t2t1",
),
case(
"decred-empty",
@ -283,8 +277,7 @@ VECTORS = ( # case name, coin_name, path, script_type, address, message, signat
"",
"1fd2d57490b44a0361c7809768cad032d41ba1d4b7a297f935fc65ae05f71de7ea0c6c6fd265cc5154f1fa4acd7006b6a00ddd67fb7333c1594aff9120b3ba8024",
altcoin=True,
skip_t2b1=True,
skip_t3t1=True,
models="t1b1,t2t1",
),
)
@ -314,9 +307,9 @@ def test_signmessage(
assert sig.signature.hex() == signature
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1(reason="Not yet implemented in new UI")
@pytest.mark.models(
"core", skip=["safe3", "mercury"], reason="Not yet implemented in new UI"
)
@pytest.mark.parametrize(
"coin_name, path, script_type, no_script_type, address, message, signature", VECTORS
)
@ -359,7 +352,7 @@ MESSAGE_LENGTHS = (
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("message", MESSAGE_LENGTHS)
def test_signmessage_pagination(client: Client, message: str):
with client:
@ -374,15 +367,13 @@ def test_signmessage_pagination(client: Client, message: str):
# We cannot differentiate between a newline and space in the message read from Trezor.
# TODO: do the check also for T2B1
if client.model in (models.T2T1, models.T3T1):
if client.layout_type in (LayoutType.TT, LayoutType.Mercury):
message_read = IF.message_read.replace(" ", "").replace("...", "")
signed_message = message.replace("\n", "").replace(" ", "")
assert signed_message in message_read
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1(reason="Different screen size")
@pytest.mark.skip_t3t1(reason="Different fonts")
@pytest.mark.models("t2t1", reason="Tailored to TT fonts and screen size")
def test_signmessage_pagination_trailing_newline(client: Client):
message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n"
# The trailing newline must not cause a new paginated screen to appear.

View File

@ -641,7 +641,7 @@ def test_fee_high_warning(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_fee_high_hardfail(client: Client):
# input tx: 25fee583181847cbe9d9fd9a483a8b8626c99854a72d01de848ef40508d0f3bc
# (The "25fee" tx hash is very suitable for testing high fees)
@ -1445,7 +1445,7 @@ def test_lock_time(client: Client, lock_time: int, sequence: int):
)
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_lock_time_blockheight(client: Client):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
@ -1477,7 +1477,7 @@ def test_lock_time_blockheight(client: Client):
)
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models("core", reason="Cannot test layouts on T1")
@pytest.mark.parametrize(
"lock_time_str", ("1985-11-05 00:53:20", "2048-08-16 22:14:00")
)
@ -1516,7 +1516,7 @@ def test_lock_time_datetime(client: Client, lock_time_str: str):
)
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information(client: Client):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
@ -1547,7 +1547,7 @@ def test_information(client: Client):
)
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information_mixed(client: Client):
inp1 = messages.TxInputType(
address_n=parse_path("m/44h/1h/0h/0/0"), # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
@ -1582,7 +1582,7 @@ def test_information_mixed(client: Client):
)
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models("core", reason="Cannot test layouts on T1")
def test_information_cancel(client: Client):
# input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5
@ -1613,8 +1613,11 @@ def test_information_cancel(client: Client):
)
@pytest.mark.skip_t3t1(reason="Not yet implemented in new UI")
@pytest.mark.skip_t1b1(reason="Cannot test layouts on T1")
@pytest.mark.models(
"core",
skip="mercury",
reason="Cannot test layouts on T1, not implemented in mercury UI",
)
def test_information_replacement(client: Client):
# Use the change output and an external output to bump the fee.
# Originally fee was 3780, now 108060 (94280 from change and 10000 from external).

View File

@ -81,7 +81,7 @@ TXHASH_1010b2 = bytes.fromhex(
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2pkh_presigned(client: Client):
inp1 = messages.TxInputType(
# mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
@ -178,7 +178,7 @@ def test_p2pkh_presigned(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2wpkh_in_p2sh_presigned(client: Client):
inp1 = messages.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
@ -301,7 +301,7 @@ def test_p2wpkh_in_p2sh_presigned(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2wpkh_presigned(client: Client):
inp1 = messages.TxInputType(
# tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9
@ -366,7 +366,7 @@ def test_p2wpkh_presigned(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2wsh_external_presigned(client: Client):
inp1 = messages.TxInputType(
address_n=parse_path("m/84h/1h/0h/0/0"),
@ -474,7 +474,7 @@ def test_p2wsh_external_presigned(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2tr_external_presigned(client: Client):
inp1 = messages.TxInputType(
# tb1p8tvmvsvhsee73rhym86wt435qrqm92psfsyhy6a3n5gw455znnpqm8wald
@ -566,13 +566,13 @@ def test_p2tr_external_presigned(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2pkh_with_proof(client: Client):
# TODO
pass
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_p2wpkh_in_p2sh_with_proof(client: Client):
# TODO
pass

View File

@ -18,7 +18,7 @@ from collections import namedtuple
import pytest
from trezorlib import btc, messages, misc, models
from trezorlib import btc, messages, misc
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -33,19 +33,15 @@ PREV_HASH, PREV_TX = forge_prevtx([(INPUT_ADDRESS, 12_300_000)], network="testne
PREV_TXES = {PREV_HASH: PREV_TX}
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.experimental]
pytestmark = [pytest.mark.models("core"), pytest.mark.experimental]
def case(
id, *args, altcoin: bool = False, skip_t2b1: bool = False, skip_t3t1: bool = False
):
def case(id, *args, altcoin: bool = False, models: str | None = None):
marks = []
if altcoin:
marks.append(pytest.mark.altcoin)
if skip_t2b1:
marks.append(pytest.mark.skip_t2b1)
if skip_t3t1:
marks.append(pytest.mark.skip_t3t1)
if models:
marks.append(pytest.mark.models(models))
return pytest.param(*args, id=id, marks=marks)
@ -118,15 +114,13 @@ SERIALIZED_TX = "01000000000101e29305e85821ea86f2bca1fcfe45e7cb0c8de87b612479ee6
"out0",
(PaymentRequestParams([0], memos1, get_nonce=True),),
altcoin=True,
skip_t2b1=True,
skip_t3t1=True,
models="t2t1",
),
case(
"out1",
(PaymentRequestParams([1], memos2, get_nonce=True),),
altcoin=True,
skip_t2b1=True,
skip_t3t1=True,
models="t2t1",
),
case("out2", (PaymentRequestParams([2], [], get_nonce=True),)),
case(
@ -189,10 +183,8 @@ def test_payment_request(client: Client, payment_request_params):
)
@pytest.mark.models(skip="safe3")
def test_payment_request_details(client: Client):
if client.model is models.T2B1:
pytest.skip("Details not implemented on T2B1")
# Test that payment request details are shown when requested.
outputs[0].payment_req_index = 0
outputs[1].payment_req_index = 0
@ -281,8 +273,7 @@ def test_payment_req_wrong_mac_refund(client: Client):
@pytest.mark.altcoin
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("t2t1", reason="Dash not supported on Safe family")
def test_payment_req_wrong_mac_purchase(client: Client):
# Test wrong MAC in payment request memo.
memo = CoinPurchaseMemo(

View File

@ -354,7 +354,7 @@ def test_p2wpkh_finalize(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize(
"out1_amount, out2_amount, copayer_witness, fee_confirm, expected_tx",
(
@ -648,7 +648,7 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_tx_meld(client: Client):
# Meld two original transactions into one, joining the change-outputs into a different one.
@ -869,7 +869,7 @@ def test_attack_steal_change(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_attack_false_internal(client: Client):
# Falsely claim that an external input is internal in the original transaction.
# If this were possible, it would allow an attacker to make it look like the
@ -976,7 +976,7 @@ def test_attack_fake_int_input_amount(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_attack_fake_ext_input_amount(client: Client):
# Give a fake input amount for an original external input while giving the correct
# amount for the replacement input. If an attacker could decrease the amount of an

View File

@ -228,7 +228,7 @@ def test_spend_old_versions(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_external_presigned(client: Client):
inp1 = messages.TxInputType(
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu

View File

@ -32,7 +32,7 @@ from ...input_flows import InputFlowShowXpubQRCode
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]

View File

@ -27,7 +27,7 @@ from ...common import MNEMONIC_SLIP39_BASIC_20_3of6
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]
ADDRESS_N = parse_path("m/1852h/1815h/0h")

View File

@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]

View File

@ -16,7 +16,8 @@
import pytest
from trezorlib import cardano, device, messages, models
from trezorlib import cardano, device, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
@ -26,7 +27,7 @@ from ...input_flows import InputFlowConfirmAllWarnings
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]
@ -34,10 +35,10 @@ def show_details_input_flow(client: Client):
yield
client.debug.wait_layout()
# Touch screen click vs pressing right for T2B1
if client.model in (models.T2T1, models.T3T1):
if client.layout_type in (LayoutType.TT, LayoutType.Mercury):
SHOW_ALL_BUTTON_POSITION = (143, 167)
client.debug.click(SHOW_ALL_BUTTON_POSITION)
elif client.model is models.T2B1:
elif client.layout_type is LayoutType.TR:
client.debug.press_yes()
else:
raise NotImplementedError
@ -62,7 +63,7 @@ def test_cardano_sign_tx(client: Client, parameters, result):
assert response == _transform_expected_result(result)
@pytest.mark.skip_t3t1(reason="Not yet implemented in new UI")
@pytest.mark.models(skip="mercury", reason="Not yet implemented in new UI")
@parametrize_using_common_fixtures("cardano/sign_tx.show_details.json")
def test_cardano_sign_tx_show_details(client: Client, parameters, result):
response = call_sign_tx(client, parameters, show_details_input_flow, chunkify=True)

View File

@ -26,9 +26,7 @@ from ...input_flows import InputFlowShowXpubQRCode
@pytest.mark.altcoin
@pytest.mark.eos
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1 # coin not supported
@pytest.mark.skip_t3t1
@pytest.mark.models("t2t1")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_eos_get_public_key(client: Client):
with client:

View File

@ -29,9 +29,7 @@ ADDRESS_N = parse_path("m/44h/194h/0h/0/0")
pytestmark = [
pytest.mark.altcoin,
pytest.mark.eos,
pytest.mark.skip_t1b1,
pytest.mark.skip_t2b1, # coin not supported
pytest.mark.skip_t3t1,
pytest.mark.models("t2t1"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -197,11 +197,8 @@ MethodType = Callable[[Client, int, "bytes | None"], None]
METHODS = (
_call_getaddress,
_call_signmessage,
pytest.param(_call_sign_typed_data, marks=pytest.mark.skip_t1b1),
pytest.param(
_call_sign_typed_data_hash,
marks=[pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1],
),
pytest.param(_call_sign_typed_data, marks=pytest.mark.models("core")),
pytest.param(_call_sign_typed_data_hash, marks=pytest.mark.models("legacy")),
)

View File

@ -34,7 +34,7 @@ def test_getaddress(client: Client, parameters, result):
)
@pytest.mark.skip_t1b1("No input flow for T1")
@pytest.mark.models("core", reason="No input flow for T1")
@parametrize_using_common_fixtures("ethereum/getaddress.json")
def test_getaddress_chunkify_details(client: Client, parameters, result):
with client:

View File

@ -44,9 +44,7 @@ def test_slip25_disallowed(client: Client):
ethereum.get_public_node(client, path)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_legacy_restrictions(client: Client):
path = parse_path("m/46'")
with pytest.raises(TrezorFailure, match="Invalid path for EthereumGetPublicKey"):

View File

@ -26,7 +26,7 @@ from ...input_flows import InputFlowEIP712Cancel, InputFlowEIP712ShowMore
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
def test_ethereum_sign_typed_data(client: Client, parameters, result):
with client:
@ -41,9 +41,7 @@ def test_ethereum_sign_typed_data(client: Client, parameters, result):
assert f"0x{ret.signature.hex()}" == result["sig"]
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
def test_ethereum_sign_typed_data_blind(client: Client, parameters, result):
with client:
@ -97,8 +95,7 @@ DATA = {
}
@pytest.mark.skip_t3t1(reason="Not yet implemented in new UI")
@pytest.mark.skip_t1b1
@pytest.mark.models("core", skip="mercury", reason="Not yet implemented in new UI")
def test_ethereum_sign_typed_data_show_more_button(client: Client):
with client:
client.watch_layout()
@ -112,7 +109,7 @@ def test_ethereum_sign_typed_data_show_more_button(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_ethereum_sign_typed_data_cancel(client: Client):
with client, pytest.raises(exceptions.Cancelled):
client.watch_layout()

View File

@ -113,7 +113,7 @@ example_input_data = {
}
@pytest.mark.skip_t1b1("T1 does not support input flows")
@pytest.mark.models("core", reason="T1 does not support input flows")
def test_signtx_fee_info(client: Client):
input_flow = InputFlowEthereumSignTxShowFeeInfo(client).get()
_do_test_signtx(
@ -124,8 +124,11 @@ def test_signtx_fee_info(client: Client):
)
@pytest.mark.skip_t1b1("T1 does not support input flows")
@pytest.mark.skip_t3t1("Cancel on Summary means Cancel Sign. No going back here!")
@pytest.mark.models(
"core",
skip="mercury",
reason="T1 does not support input flows; Mercury can't send Cancel on Summary",
)
def test_signtx_go_back_from_summary(client: Client):
input_flow = InputFlowEthereumSignTxGoBackFromSummary(client).get()
_do_test_signtx(
@ -431,8 +434,7 @@ HEXDATA = "0123456789abcd000023456789abcd010003456789abcd020000456789abcd0300000
@pytest.mark.parametrize(
"flow", (input_flow_data_skip, input_flow_data_scroll_down, input_flow_data_go_back)
)
@pytest.mark.skip_t3t1(reason="Not yet implemented in new UI")
@pytest.mark.skip_t1b1
@pytest.mark.models("core", skip="mercury", reason="Not yet implemented in new UI")
def test_signtx_data_pagination(client: Client, flow):
def _sign_tx_call():
ethereum.sign_tx(
@ -459,7 +461,7 @@ def test_signtx_data_pagination(client: Client, flow):
_sign_tx_call()
@pytest.mark.skip_t1b1("T1 does not support Everstake")
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking.json")
@pytest.mark.parametrize("chunkify", (True, False))
def test_signtx_staking(client: Client, chunkify: bool, parameters: dict, result: dict):
@ -469,7 +471,7 @@ def test_signtx_staking(client: Client, chunkify: bool, parameters: dict, result
)
@pytest.mark.skip_t1b1("T1 does not support Everstake")
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking_data_error.json")
def test_signtx_staking_bad_inputs(client: Client, parameters: dict, result: dict):
# result not needed
@ -490,7 +492,7 @@ def test_signtx_staking_bad_inputs(client: Client, parameters: dict, result: dic
)
@pytest.mark.skip_t1b1("T1 does not support Everstake")
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking_eip1559.json")
def test_signtx_staking_eip1559(client: Client, parameters: dict, result: dict):
with client:

View File

@ -41,7 +41,7 @@ TEST_VECTORS = [
pytestmark = [
pytest.mark.altcoin,
pytest.mark.monero,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -25,7 +25,7 @@ from ...common import MNEMONIC12
@pytest.mark.altcoin
@pytest.mark.monero
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_monero_getwatchkey(client: Client):
res = monero.get_watch_key(client, parse_path("m/44h/128h/0h"))

View File

@ -25,8 +25,7 @@ from ...common import MNEMONIC12
@pytest.mark.altcoin
@pytest.mark.nem
@pytest.mark.skip_t2b1 # coin not supported,
@pytest.mark.skip_t3t1
@pytest.mark.models("t1b1", "t2t1")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
@pytest.mark.parametrize("chunkify", (True, False))
def test_nem_getaddress(client: Client, chunkify: bool):

View File

@ -27,8 +27,7 @@ ADDRESS_N = parse_path("m/44h/1h/0h/0h/0h")
pytestmark = [
pytest.mark.altcoin,
pytest.mark.nem,
pytest.mark.skip_t2b1, # coin not supported,
pytest.mark.skip_t3t1,
pytest.mark.models("t1b1", "t2t1"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -25,8 +25,7 @@ from ...common import MNEMONIC12
pytestmark = [
pytest.mark.altcoin,
pytest.mark.nem,
pytest.mark.skip_t2b1, # coin not supported,
pytest.mark.skip_t3t1,
pytest.mark.models("t1b1", "t2t1"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -25,8 +25,7 @@ from ...common import MNEMONIC12
pytestmark = [
pytest.mark.altcoin,
pytest.mark.nem,
pytest.mark.skip_t2b1, # coin not supported,
pytest.mark.skip_t3t1,
pytest.mark.models("t1b1", "t2t1"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -25,8 +25,7 @@ from ...common import MNEMONIC12, is_core
pytestmark = [
pytest.mark.altcoin,
pytest.mark.nem,
pytest.mark.skip_t2b1, # coin not supported,
pytest.mark.skip_t3t1,
pytest.mark.models("t1b1", "t2t1"),
pytest.mark.setup_client(mnemonic=MNEMONIC12),
]

View File

@ -79,15 +79,13 @@ def test_seed_mismatch(client: Client):
do_recover(client, ["all"] * 12, mismatch=True)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_invalid_seed_t1(client: Client):
with pytest.raises(exceptions.TrezorFailure, match="Invalid seed"):
do_recover(client, ["stick"] * 12)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_invalid_seed_core(client: Client):
with client:
client.watch_layout()

View File

@ -25,7 +25,7 @@ from ...common import MNEMONIC12
PIN4 = "1234"
PIN6 = "789456"
pytestmark = [pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("legacy")
@pytest.mark.setup_client(uninitialized=True)

View File

@ -22,7 +22,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
from ...common import MNEMONIC12
from ...input_flows import InputFlowBip39Recovery
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)

View File

@ -28,7 +28,7 @@ from ...input_flows import (
InputFlowSlip39AdvancedRecoveryThresholdReached,
)
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
EXTRA_GROUP_SHARE = [
"eraser senior decision smug corner ruin rescue cubic angel tackle skin skunk program roster trash rumor slush angel flea amazing"

View File

@ -23,7 +23,7 @@ from trezorlib.exceptions import TrezorFailure
from ...common import MNEMONIC_SLIP39_ADVANCED_20
from ...input_flows import InputFlowSlip39AdvancedRecoveryDryRun
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
INVALID_SHARES_SLIP39_ADVANCED_20 = [
"chest garlic acrobat leaf diploma thank soul predator grant laundry camera license language likely slim twice amount rich total carve",

View File

@ -36,7 +36,7 @@ from ...input_flows import (
InputFlowSlip39BasicRecoveryWrongNthWord,
)
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
MNEMONIC_SLIP39_BASIC_20_1of1 = [
"academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic academic rebuild aquatic spew"

View File

@ -22,7 +22,7 @@ from trezorlib.exceptions import TrezorFailure
from ...input_flows import InputFlowSlip39BasicRecoveryDryRun
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
SHARES_20_2of3 = [
"crush merchant academic acid dream decision orbit smug trend trust painting slice glad crunch veteran lunch friar satoshi engage aquatic",

View File

@ -71,7 +71,7 @@ VECTORS = [
]
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("backup_type, backup_flow", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
def test_skip_backup_msg(client: Client, backup_type, backup_flow):
@ -104,7 +104,7 @@ def test_skip_backup_msg(client: Client, backup_type, backup_flow):
assert state.mnemonic_secret == secret
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.parametrize("backup_type, backup_flow", VECTORS)
@pytest.mark.setup_client(uninitialized=True)
def test_skip_backup_manual(client: Client, backup_type: BackupType, backup_flow):

View File

@ -22,7 +22,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
from ...common import EXTERNAL_ENTROPY, generate_entropy
pytestmark = [pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("legacy")
STRENGTH = 128

View File

@ -23,7 +23,7 @@ from trezorlib.tools import parse_path
from ...common import EXTERNAL_ENTROPY, generate_entropy
pytestmark = [pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("legacy")
def reset_device(client: Client, strength: int):

View File

@ -17,7 +17,8 @@
import pytest
from mnemonic import Mnemonic
from trezorlib import device, messages, models
from trezorlib import device, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
@ -28,7 +29,7 @@ from ...input_flows import (
InputFlowBip39ResetPIN,
)
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
def reset_device(client: Client, strength: int):
@ -161,7 +162,7 @@ def test_failed_pin(client: Client):
ret = client.call_raw(messages.ButtonAck())
# Re-enter PIN for TR
if client.model is models.T2B1:
if client.layout_type is LayoutType.TR:
assert isinstance(ret, messages.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(messages.ButtonAck())

View File

@ -25,7 +25,7 @@ from ...common import WITH_MOCK_URANDOM
from ...input_flows import InputFlowBip39Recovery, InputFlowBip39ResetBackup
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
def test_reset_recovery(client: Client):
mnemonic = reset(client)

View File

@ -28,7 +28,7 @@ from ...input_flows import (
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
def test_reset_recovery(client: Client):
mnemonics = reset(client)

View File

@ -30,7 +30,7 @@ from ...input_flows import (
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(uninitialized=True)
@WITH_MOCK_URANDOM
def test_reset_recovery(client: Client):

View File

@ -25,7 +25,7 @@ from trezorlib.messages import BackupAvailability, BackupType
from ...common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy
from ...input_flows import InputFlowSlip39AdvancedResetRecovery
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
# TODO: test with different options

View File

@ -27,7 +27,7 @@ from trezorlib.messages import BackupAvailability, BackupType
from ...common import EXTERNAL_ENTROPY, WITH_MOCK_URANDOM, generate_entropy
from ...input_flows import InputFlowSlip39BasicResetRecovery
pytestmark = [pytest.mark.skip_t1b1]
pytestmark = pytest.mark.models("core")
def reset_device(client: Client, strength: int):

View File

@ -31,7 +31,7 @@ CUSTOM_MNEMONIC = (
pytestmark = [
pytest.mark.altcoin,
pytest.mark.ripple,
pytest.mark.skip_t1b1, # T1 support is not planned
pytest.mark.models("core"),
]
# data from https://iancoleman.io/bip39/

View File

@ -24,7 +24,7 @@ from trezorlib.tools import parse_path
pytestmark = [
pytest.mark.altcoin,
pytest.mark.ripple,
pytest.mark.skip_t1b1, # T1 support is not planned
pytest.mark.models("core"),
]

View File

@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
pytestmark = [
pytest.mark.altcoin,
pytest.mark.solana,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]

View File

@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
pytestmark = [
pytest.mark.altcoin,
pytest.mark.solana,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]

View File

@ -28,7 +28,7 @@ from .construct.transaction import Message, RawInstruction
pytestmark = [
pytest.mark.altcoin,
pytest.mark.solana,
pytest.mark.skip_t1b1,
pytest.mark.models("core"),
]

View File

@ -119,7 +119,7 @@ def test_get_address(client: Client, parameters, result):
assert address == result["address"]
@pytest.mark.skip_t1b1("No input flow for T1")
@pytest.mark.models("core")
@parametrize_using_common_fixtures("stellar/get_address.json")
def test_get_address_chunkify_details(client: Client, parameters, result):
with client:

View File

@ -9,7 +9,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
from ..common import compact_size
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2t1]
pytestmark = pytest.mark.models("safe")
ROOT_PUBLIC_KEY = {
models.T2B1: bytes.fromhex(
@ -18,6 +18,9 @@ ROOT_PUBLIC_KEY = {
models.T3T1: bytes.fromhex(
"04e48b69cd7962068d3cca3bcc6b1747ef496c1e28b5529e34ad7295215ea161dbe8fb08ae0479568f9d2cb07630cb3e52f4af0692102da5873559e45e9fa72959"
),
models.T3B1: bytes.fromhex(
"047f77368dea2d4d61e989f474a56723c3212dacf8a808d8795595ef38441427c4389bc454f02089d7f08b873005e4c28d432468997871c0bf286fd3861e21e96a"
),
}
@ -75,7 +78,12 @@ def test_authenticate_device(client: Client, challenge: bytes) -> None:
# Verify that the common name matches the Trezor model.
common_name = cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0]
assert common_name.value.startswith(client.features.internal_model)
if client.model == models.T3B1:
# XXX TODO replace as soon as we have T3B1 staging
internal_model = "T2B1"
else:
internal_model = client.model.internal_name
assert common_name.value.startswith(internal_model)
# Verify the signature of the challenge.
data = b"\x13AuthenticateDevice:" + compact_size(len(challenge)) + challenge

View File

@ -111,7 +111,7 @@ def test_apply_auto_lock_delay_out_of_range(client: Client, seconds):
device.apply_settings(client, auto_lock_delay_ms=delay)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_autolock_cancels_ui(client: Client):
set_autolock_delay(client, 10 * 1000)

View File

@ -24,9 +24,7 @@ from trezorlib.messages import SafetyCheckLevel
from trezorlib.tools import H_
pytestmark = [
pytest.mark.skip_t2t1,
pytest.mark.skip_t2b1,
pytest.mark.skip_t3t1,
pytest.mark.models("legacy"),
pytest.mark.flaky(max_runs=5),
]

View File

@ -18,7 +18,8 @@ import time
import pytest
from trezorlib import btc, device, models
from trezorlib import btc, device
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.tools import parse_path
@ -27,7 +28,7 @@ PIN = "1234"
def _assert_busy(client: Client, should_be_busy: bool, screen: str = "Homescreen"):
assert client.features.busy is should_be_busy
if client.model in (models.T2T1, models.T2B1, models.T3T1):
if client.layout_type is not LayoutType.T1:
if should_be_busy:
assert "CoinJoinProgress" in client.debug.read_layout().all_components()
else:

View File

@ -17,7 +17,7 @@
import pytest
import trezorlib.messages as m
from trezorlib import models
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import Cancelled
@ -71,7 +71,7 @@ def test_cancel_message_via_initialize(client: Client, message):
assert isinstance(resp, m.Features)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_cancel_on_paginated(client: Client):
"""Check that device is responsive on paginated screen. See #1708."""
# In #1708, the device would ignore USB (or UDP) events while waiting for the user
@ -94,7 +94,7 @@ def test_cancel_on_paginated(client: Client):
# In T2B1, confirm message is no longer paginated by default,
# user needs to click info button
if client.model is models.T2B1:
if client.layout_type is LayoutType.TR:
client._raw_write(m.ButtonAck())
client.debug.press_right()
resp = client._raw_read()

View File

@ -24,17 +24,13 @@ from trezorlib.transport import udp
from ..common import MNEMONIC12
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_layout(client: Client):
layout = client.debug.state().layout
assert len(layout) == 1024
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_mnemonic(client: Client):
client.ensure_unlocked()
@ -42,9 +38,7 @@ def test_mnemonic(client: Client):
assert mnemonic == MNEMONIC12.encode()
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
@pytest.mark.setup_client(mnemonic=MNEMONIC12, pin="1234", passphrase="")
def test_pin(client: Client):
resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
@ -62,7 +56,7 @@ def test_pin(client: Client):
assert isinstance(resp, messages.Address)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_softlock_instability(client: Client):
def load_device():
debuglink.load_device(

View File

@ -11,6 +11,7 @@ FIRMWARE_LENGTHS = {
models.T2T1: 13 * 128 * 1024,
models.T2B1: 13 * 128 * 1024,
models.T3T1: 208 * 8 * 1024,
models.T3B1: 208 * 8 * 1024,
}

View File

@ -35,13 +35,14 @@ from ..translations import (
sign_blob,
)
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
MAX_DATA_LENGTH = {
models.T2T1: 48 * 1024,
models.T2B1: 32 * 1024,
models.T3T1: 256 * 1024,
models.T3B1: 256 * 1024,
}

View File

@ -68,7 +68,7 @@ def test_apply_settings(client: Client):
assert client.features.label == "new label"
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_apply_settings_rotation(client: Client):
assert client.features.display_rotation is None
@ -101,7 +101,7 @@ def test_apply_settings_passphrase(client: Client):
@pytest.mark.setup_client(passphrase=False)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_apply_settings_passphrase_on_device(client: Client):
# enable passphrase
with client:
@ -135,9 +135,7 @@ def test_apply_settings_passphrase_on_device(client: Client):
assert client.features.passphrase_always_on_device is False
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_good(client: Client):
with client:
_set_expected_responses(client)
@ -148,9 +146,7 @@ def test_apply_homescreen_tr_toif_good(client: Client):
device.apply_settings(client, homescreen=b"")
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
@pytest.mark.setup_client(pin=None) # so that "PIN NOT SET" is shown in the header
def test_apply_homescreen_tr_toif_with_notification(client: Client):
with client:
@ -158,9 +154,7 @@ def test_apply_homescreen_tr_toif_with_notification(client: Client):
device.apply_settings(client, homescreen=TR_HOMESCREEN)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_with_long_label(client: Client):
with client:
_set_expected_responses(client)
@ -175,9 +169,7 @@ def test_apply_homescreen_tr_toif_with_long_label(client: Client):
device.apply_settings(client, label="My even longer label")
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_toif_wrong_size(client: Client):
# 64x64 img
img = b"TOIG@\x00@\x009\x02\x00\x00}R\xdb\x81$A\x08\"\x03\xf3\xcf\xd2\x0c<\x01-{\xefc\xe6\xd5\xbbU\xa2\x08T\xd6\xcfw\xf4\xe7\xc7\xb7X\xf1\xe3\x1bl\xf0\xf7\x1b\xf8\x1f\xcf\xe7}\xe1\x83\xcf|>\x8d%\x14\xa5\xb3\xe9p5\xa1;~4:\xcd\xe0&\x11\x1d\xe9\xf6\xa1\x1fw\xf54\x95eWx\xda\xd0u\x91\x86\xb8\xbc\xdf\xdc\x008f\x15\xc6\xf6\x7f\xf0T\xb8\xc1\xa3\xc5_A\xc0G\x930\xe7\xdc=\xd5\xa7\xc1\xbcI\x16\xb8s\x9c&\xaa\x06\xc1}\x8b\x19\x9d'c\xc3\xe3^\xc3m\xb6n\xb0(\x16\xf6\xdeg\xb3\x96:i\xe5\x9c\x02\x93\x9fF\x9f-\xa7\"w\xf3X\x9f\x87\x08\x84\"v,\xab!9:<j+\xcb\xf3_\xc7\xd6^<\xce\xc1\xb8!\xec\x8f/\xb1\xc1\x8f\xbd\xcc\x06\x90\x0e\x98)[\xdb\x15\x99\xaf\xf2~\x8e\xd0\xdb\xcd\xfd\x90\x12\xb6\xdd\xc3\xdd|\x96$\x01P\x86H\xbc\xc0}\xa2\x08\xe5\x82\x06\xd2\xeb\x07[\r\xe4\xdeP\xf4\x86;\xa5\x14c\x12\xe3\xb16x\xad\xc7\x1d\x02\xef\x86<\xc6\x95\xd3/\xc4 \xa1\xf5V\xe2\t\xb2\x8a\xd6`\xf2\xcf\xb7\xd6\x07\xdf8X\xa7\x18\x03\x96\x82\xa4 \xeb.*kP\xceu\x9d~}H\xe9\xb8\x04<4\xff\xf8\xcf\xf6\xa0\xf2\xfcM\xe3/?k\xff\x18\x1d\xb1\xee\xc5\xf5\x1f\x01\x14\x03;\x1bU\x1f~\xcf\xb3\xf7w\xe5\nMfd/\xb93\x9fq\x9bQ\xb7'\xbfvq\x1d\xce\r\xbaDo\x90\xbc\xc5:?;\x84y\x8a\x1e\xad\xe9\xb7\x14\x10~\x9b@\xf8\x82\xdc\x89\xe7\xf0\xe0k4o\x9a\xa0\xc4\xb9\xba\xc56\x01i\x85EO'e6\xb7\x15\xb4G\x05\xe1\xe7%\xd3&\x93\x91\xc9CTQ\xeb\xcc\xd0\xd7E9\xa9JK\xcc\x00\x95(\xdc.\xd2#7:Yo}y_*\x1a\xae6)\x97\x9d\xc0\x80vl\x02\\M\xfe\xc9sW\xa8\xfbD\x99\xb8\xb0:\xbc\x80\xfd\xef\xd3\x94\xbe\x18j9z\x12S\xa1\xec$\x1c\xe3\xd1\xd0\xf4\xdd\xbfI\xf1rBj\x0f\x1cz\x1d\xf7\xa5tR\xb3\xfc\xa4\xd0\xfah\xc3Mj\xbe\x14r\x9d\x84z\xd2\x7f\x13\xb4w\xce\xa0\xaeW\xa4\x18\x0b\xe4\x8f\xe6\xc3\xbeQ\x93\xb0L<J\xe3g9\xb5W#f\xd1\x0b\x96|\xd6z1;\x85\x7f\xe3\xe6[\x02A\xdc\xa4\x02\x1b\x91\x88\x7f"
@ -186,9 +178,7 @@ def test_apply_homescreen_tr_toif_wrong_size(client: Client):
device.apply_settings(client, homescreen=img)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_upload_jpeg_fail(client: Client):
with open(HERE / "test_bg.jpg", "rb") as f:
img = f.read()
@ -197,17 +187,14 @@ def test_apply_homescreen_tr_upload_jpeg_fail(client: Client):
device.apply_settings(client, homescreen=img)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2t1
@pytest.mark.skip_t3t1
@pytest.mark.models("safe3")
def test_apply_homescreen_tr_upload_t1_fail(client: Client):
with pytest.raises(exceptions.TrezorFailure), client:
_set_expected_responses(client)
device.apply_settings(client, homescreen=T1_HOMESCREEN)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_toif(client: Client):
img = b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
@ -216,8 +203,7 @@ def test_apply_homescreen_toif(client: Client):
device.apply_settings(client, homescreen=img)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg(client: Client):
with open(HERE / "test_bg.jpg", "rb") as f:
img = f.read()
@ -229,8 +215,7 @@ def test_apply_homescreen_jpeg(client: Client):
device.apply_settings(client, homescreen=b"")
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg_progressive(client: Client):
img = (
b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x01,\x01,"
@ -286,8 +271,7 @@ def test_apply_homescreen_jpeg_progressive(client: Client):
device.apply_settings(client, homescreen=img)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.models(skip=["legacy", "safe3"])
def test_apply_homescreen_jpeg_wrong_size(client: Client):
img = (
b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x01,\x01,"
@ -333,9 +317,7 @@ def test_apply_homescreen_jpeg_wrong_size(client: Client):
device.apply_settings(client, homescreen=img)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_apply_homescreen(client: Client):
with client:
_set_expected_responses(client)
@ -398,7 +380,7 @@ def test_safety_checks(client: Client):
get_bad_address()
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_experimental_features(client: Client):
def experimental_call():
misc.get_nonce(client)

View File

@ -18,7 +18,8 @@
import pytest
import shamir_mnemonic as shamir
from trezorlib import device, messages, models
from trezorlib import device, messages
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
@ -37,7 +38,7 @@ from ..input_flows import (
)
@pytest.mark.skip_t1b1 # TODO we want this for t1 too
@pytest.mark.models("core") # TODO we want this for t1 too
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC12)
def test_backup_bip39(client: Client):
assert client.features.backup_availability == messages.BackupAvailability.Required
@ -58,13 +59,13 @@ def test_backup_bip39(client: Client):
assert client.features.backup_type is messages.BackupType.Bip39
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.parametrize(
"click_info", [True, False], ids=["click_info", "no_click_info"]
)
def test_backup_slip39_basic(client: Client, click_info: bool):
if click_info and client.model is models.T2B1:
if click_info and client.layout_type is LayoutType.TR:
pytest.skip("click_info not implemented on T2B1")
assert client.features.backup_availability == messages.BackupAvailability.Required
@ -88,13 +89,13 @@ def test_backup_slip39_basic(client: Client, click_info: bool):
assert expected_ms == actual_ms
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_ADVANCED_20)
@pytest.mark.parametrize(
"click_info", [True, False], ids=["click_info", "no_click_info"]
)
def test_backup_slip39_advanced(client: Client, click_info: bool):
if click_info and client.model is models.T2B1:
if click_info and client.layout_type is LayoutType.TR:
pytest.skip("click_info not implemented on T2B1")
assert client.features.backup_availability == messages.BackupAvailability.Required
@ -120,7 +121,7 @@ def test_backup_slip39_advanced(client: Client, click_info: bool):
assert expected_ms == actual_ms
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_CUSTOM_1of1[0])
@pytest.mark.parametrize(
"share_threshold,share_count",

View File

@ -29,7 +29,7 @@ WIPE_CODE6 = "456789"
WIPE_CODE_MAX = "".join(chr((i % 9) + ord("1")) for i in range(MAX_PIN_LENGTH))
WIPE_CODE_TOO_LONG = WIPE_CODE_MAX + "1"
pytestmark = [pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("legacy")
def _set_wipe_code(client: Client, pin, wipe_code):

View File

@ -16,8 +16,9 @@
import pytest
from trezorlib import btc, device, messages, models
from trezorlib import btc, device, messages
from trezorlib.client import MAX_PIN_LENGTH, PASSPHRASE_TEST_PATH
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
@ -28,7 +29,7 @@ WIPE_CODE4 = "4321"
WIPE_CODE6 = "456789"
WIPE_CODE_MAX = "".join(chr((i % 10) + ord("0")) for i in range(MAX_PIN_LENGTH))
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
def _check_wipe_code(client: Client, pin: str, wipe_code: str):
@ -38,11 +39,10 @@ def _check_wipe_code(client: Client, pin: str, wipe_code: str):
# Try to change the PIN to the current wipe code value. The operation should fail.
with client, pytest.raises(TrezorFailure):
client.use_pin_sequence([pin, wipe_code, wipe_code])
br_count = {
models.T2T1: 5,
models.T2B1: 6,
models.T3T1: 5,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 6
else:
br_count = 5
client.set_expected_responses(
[messages.ButtonRequest()] * br_count
+ [messages.Failure(code=messages.FailureType.PinInvalid)]
@ -66,11 +66,10 @@ def test_set_remove_wipe_code(client: Client):
_ensure_unlocked(client, PIN4)
assert client.features.wipe_code_protection is False
br_count = {
models.T2T1: 5,
models.T2B1: 6,
models.T3T1: 5,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 6
else:
br_count = 5
with client:
client.set_expected_responses(
@ -126,11 +125,10 @@ def test_set_wipe_code_to_pin(client: Client):
_ensure_unlocked(client, PIN4)
with client:
br_count = {
models.T2T1: 7,
models.T2B1: 8,
models.T3T1: 7,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 8
else:
br_count = 7
client.set_expected_responses(
[messages.ButtonRequest()] * br_count
+ [messages.Success, messages.Features],
@ -146,11 +144,10 @@ def test_set_wipe_code_to_pin(client: Client):
def test_set_pin_to_wipe_code(client: Client):
# Set wipe code.
with client:
br_count = {
models.T2T1: 4,
models.T2B1: 5,
models.T3T1: 4,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 5
else:
br_count = 4
client.set_expected_responses(
[messages.ButtonRequest()] * br_count
+ [messages.Success, messages.Features]
@ -160,11 +157,10 @@ def test_set_pin_to_wipe_code(client: Client):
# Try to set the PIN to the current wipe code value.
with client, pytest.raises(TrezorFailure):
br_count = {
models.T2T1: 4,
models.T2B1: 6,
models.T3T1: 4,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 6
else:
br_count = 4
client.set_expected_responses(
[messages.ButtonRequest()] * br_count
+ [messages.Failure(code=messages.FailureType.PinInvalid)]

View File

@ -28,7 +28,7 @@ PIN6 = "789456"
PIN_MAX = "".join(chr((i % 9) + ord("1")) for i in range(MAX_PIN_LENGTH))
PIN_TOO_LONG = PIN_MAX + "1"
pytestmark = [pytest.mark.skip_t2t1, pytest.mark.skip_t2b1, pytest.mark.skip_t3t1]
pytestmark = pytest.mark.models("legacy")
def _check_pin(client: Client, pin):

View File

@ -16,8 +16,9 @@
import pytest
from trezorlib import btc, device, messages, models
from trezorlib import btc, device, messages
from trezorlib.client import MAX_PIN_LENGTH, PASSPHRASE_TEST_PATH
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import Cancelled, TrezorFailure
@ -32,7 +33,7 @@ PIN4 = "1234"
PIN60 = "789456" * 10
PIN_MAX = "".join(chr((i % 10) + ord("0")) for i in range(MAX_PIN_LENGTH))
pytestmark = pytest.mark.skip_t1b1
pytestmark = pytest.mark.models("core")
def _check_pin(client: Client, pin: str):
@ -63,11 +64,10 @@ def test_set_pin(client: Client):
# Let's set new PIN
with client:
br_count = {
models.T2T1: 4,
models.T2B1: 6,
models.T3T1: 4,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 6
else:
br_count = 4
client.use_pin_sequence([PIN_MAX, PIN_MAX])
client.set_expected_responses(
[messages.ButtonRequest] * br_count + [messages.Success, messages.Features]
@ -89,11 +89,10 @@ def test_change_pin(client: Client):
# Let's change PIN
with client:
client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX])
br_count = {
models.T2T1: 5,
models.T2B1: 6,
models.T3T1: 5,
}[client.model]
if client.layout_type is LayoutType.TR:
br_count = 6
else:
br_count = 5
client.set_expected_responses(
[messages.ButtonRequest] * br_count + [messages.Success, messages.Features]
)
@ -183,8 +182,7 @@ def test_change_invalid_current(client: Client):
_check_pin(client, PIN4)
@pytest.mark.skip_t2b1()
@pytest.mark.skip_t2t1()
@pytest.mark.models("mercury")
@pytest.mark.setup_client(pin=None)
def test_pin_menu_cancel_setup(client: Client):
def cancel_pin_setup_input_flow():

View File

@ -68,7 +68,7 @@ def test_load_device_2(client: Client):
assert address == "mx77VZjTVixVsU7nCtAKHnGFdsyNCnsWWw"
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_load_device_slip39_basic(client: Client):
debuglink.load_device(
client,
@ -80,7 +80,7 @@ def test_load_device_slip39_basic(client: Client):
assert client.features.backup_type == BackupType.Slip39_Basic
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_load_device_slip39_advanced(client: Client):
debuglink.load_device(
client,

View File

@ -23,7 +23,7 @@ from trezorlib.messages import SdProtectOperationType as Op
from ..common import MNEMONIC12
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2b1, pytest.mark.sd_card]
pytestmark = [pytest.mark.models("core", skip="safe3"), pytest.mark.sd_card]
def test_enable_disable(client: Client):

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib import device
from trezorlib import device, exceptions
from trezorlib.debuglink import TrezorClientDebugLink as Client
from ..input_flows import InputFlowTutorial
@ -24,14 +24,23 @@ from ..input_flows import InputFlowTutorial
# TODO not initialized?
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.skip_t1b1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t2t1
@pytest.mark.parametrize("cancel", (True, False))
def test_tutorial_t3t1(client: Client, cancel: bool):
@pytest.mark.models("safe")
def test_tutorial(client: Client):
with client:
IF = InputFlowTutorial(client, cancel=cancel)
IF = InputFlowTutorial(client, cancel=False)
client.set_input_flow(IF.get())
device.show_device_tutorial(client)
assert client.features.initialized is False
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.models("safe")
def test_tutorial_cancel(client: Client):
with client:
IF = InputFlowTutorial(client, cancel=True)
client.set_input_flow(IF.get())
with pytest.raises(exceptions.Cancelled):
device.show_device_tutorial(client)
assert client.features.initialized is False

View File

@ -26,7 +26,7 @@ from ..common import (
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_20, passphrase=True)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_128bit_passphrase(client: Client):
"""
BIP32 Root Key for passphrase TREZOR:
@ -45,7 +45,7 @@ def test_128bit_passphrase(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_33, passphrase=True)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_256bit_passphrase(client: Client):
"""
BIP32 Root Key for passphrase TREZOR:

View File

@ -24,9 +24,10 @@ from ..common import (
get_test_address,
)
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6, passphrase="TREZOR")
@pytest.mark.skip_t1b1
def test_3of6_passphrase(client: Client):
"""
BIP32 Root Key for passphrase TREZOR:
@ -45,7 +46,6 @@ def test_3of6_passphrase(client: Client):
),
passphrase="TREZOR",
)
@pytest.mark.skip_t1b1
def test_2of5_passphrase(client: Client):
"""
BIP32 Root Key for passphrase TREZOR:
@ -60,7 +60,6 @@ def test_2of5_passphrase(client: Client):
@pytest.mark.setup_client(
mnemonic=MNEMONIC_SLIP39_BASIC_EXT_20_2of3, passphrase="TREZOR"
)
@pytest.mark.skip_t1b1
def test_2of3_ext_passphrase(client: Client):
"""
BIP32 Root Key for passphrase TREZOR:

View File

@ -57,16 +57,14 @@ def test_correct_pin(client: Client):
get_test_address(client)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_incorrect_pin_t1(client: Client):
with pytest.raises(PinException):
client.use_pin_sequence([BAD_PIN])
get_test_address(client)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_incorrect_pin_t2(client: Client):
with client:
# After first incorrect attempt, TT will not raise an error, but instead ask for another attempt
@ -81,9 +79,7 @@ def test_incorrect_pin_t2(client: Client):
get_test_address(client)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_exponential_backoff_t1(client: Client):
for attempt in range(3):
start = time.time()
@ -93,7 +89,7 @@ def test_exponential_backoff_t1(client: Client):
check_pin_backoff_time(attempt, start)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_exponential_backoff_t2(client: Client):
with client:
IF = InputFlowPINBackoff(client, BAD_PIN, PIN4)

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import btc, device, messages, misc, models
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -69,7 +70,7 @@ def test_initialize(client: Client):
client.init_device()
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
@pytest.mark.setup_client(pin=PIN4)
@pytest.mark.parametrize("passphrase", (True, False))
def test_passphrase_reporting(client: Client, passphrase):
@ -110,9 +111,7 @@ def test_apply_settings(client: Client):
device.apply_settings(client, label="nazdar")
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_change_pin_t1(client: Client):
_assert_protection(client)
with client:
@ -130,7 +129,7 @@ def test_change_pin_t1(client: Client):
device.change_pin(client)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_change_pin_t2(client: Client):
_assert_protection(client)
with client:
@ -141,7 +140,7 @@ def test_change_pin_t2(client: Client):
messages.ButtonRequest,
_pin_request(client),
_pin_request(client),
(client.model is models.T2B1, messages.ButtonRequest),
(client.layout_type is LayoutType.TR, messages.ButtonRequest),
_pin_request(client),
messages.ButtonRequest,
messages.Success,
@ -211,9 +210,7 @@ def test_wipe_device(client: Client):
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_reset_device(client: Client):
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
@ -246,9 +243,7 @@ def test_reset_device(client: Client):
@pytest.mark.setup_client(uninitialized=True)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_recovery_device(client: Client):
assert client.features.pin_protection is False
assert client.features.passphrase_protection is False
@ -300,9 +295,7 @@ def test_sign_message(client: Client):
)
@pytest.mark.skip_t2t1
@pytest.mark.skip_t2b1
@pytest.mark.skip_t3t1
@pytest.mark.models("legacy")
def test_verify_message_t1(client: Client):
_assert_protection(client)
with client:
@ -325,7 +318,7 @@ def test_verify_message_t1(client: Client):
)
@pytest.mark.skip_t1b1
@pytest.mark.models("core")
def test_verify_message_t2(client: Client):
_assert_protection(client)
with client:

View File

@ -30,9 +30,10 @@ from ..common import (
)
from ..input_flows import InputFlowSlip39BasicBackup, InputFlowSlip39BasicRecoveryDryRun
pytestmark = pytest.mark.models("core")
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.skip_t1b1
@WITH_MOCK_URANDOM
def test_repeated_backup(client: Client):
assert client.features.backup_availability == messages.BackupAvailability.Required
@ -85,7 +86,6 @@ def test_repeated_backup(client: Client):
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_SINGLE_EXT_20)
@pytest.mark.skip_t1b1
@WITH_MOCK_URANDOM
def test_repeated_backup_upgrade_single(client: Client):
assert (
@ -125,7 +125,6 @@ def test_repeated_backup_upgrade_single(client: Client):
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.skip_t1b1
@WITH_MOCK_URANDOM
def test_repeated_backup_cancel(client: Client):
assert client.features.backup_availability == messages.BackupAvailability.Required
@ -181,7 +180,6 @@ def test_repeated_backup_cancel(client: Client):
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.skip_t1b1
@WITH_MOCK_URANDOM
def test_repeated_backup_send_disallowed_message(client: Client):
assert client.features.backup_availability == messages.BackupAvailability.Required

View File

@ -23,7 +23,7 @@ from trezorlib.messages import SdProtectOperationType as Op
from .. import translations as TR
pytestmark = [pytest.mark.skip_t1b1, pytest.mark.skip_t2b1]
pytestmark = pytest.mark.models("core", skip="safe3")
@pytest.mark.sd_card(formatted=False)

Some files were not shown because too many files have changed in this diff Show More