mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-19 05:58:09 +00:00
refactor(tests): introduce a better model selection mechanism
This commit is contained in:
parent
6506b02e2e
commit
b3bd85b1fb
@ -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.
|
||||
|
||||
|
@ -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/
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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="")
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
),
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"),
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -32,7 +32,7 @@ from ...input_flows import InputFlowShowXpubQRCode
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.cardano,
|
||||
pytest.mark.skip_t1b1,
|
||||
pytest.mark.models("core"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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")),
|
||||
)
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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"):
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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):
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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/
|
||||
|
@ -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"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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),
|
||||
]
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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):
|
||||
|
@ -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)]
|
||||
|
@ -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):
|
||||
|
@ -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():
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user