mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 01:18:28 +00:00
feat(tests): simplify asserts on translated strings
This commit is contained in:
parent
5c8edfaac6
commit
a1033c0e5f
@ -1,16 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import typing as t
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezorlib.debuglink import LayoutType
|
||||
|
||||
from .. import buttons
|
||||
from .. import translations as TR
|
||||
|
||||
if TYPE_CHECKING:
|
||||
if t.TYPE_CHECKING:
|
||||
from trezorlib.debuglink import DebugLink, LayoutContent
|
||||
|
||||
AllActionsType = t.List[t.Union[str, t.Tuple[str, ...]]]
|
||||
|
||||
|
||||
# Passphrases and addresses for both models
|
||||
class CommonPass:
|
||||
@ -82,7 +84,7 @@ def go_back(debug: "DebugLink", r_middle: bool = False) -> LayoutContent:
|
||||
def navigate_to_action_and_press(
|
||||
debug: "DebugLink",
|
||||
wanted_action: str,
|
||||
all_actions: list[str],
|
||||
all_actions: AllActionsType,
|
||||
is_carousel: bool = True,
|
||||
hold_ms: int = 0,
|
||||
) -> None:
|
||||
@ -129,16 +131,19 @@ def unlock_gesture(debug: "DebugLink") -> LayoutContent:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def _get_action_index(wanted_action: str, all_actions: list[str]) -> int:
|
||||
def _get_action_index(wanted_action: str, all_actions: AllActionsType) -> int:
|
||||
"""Get index of the action in the list of all actions"""
|
||||
if wanted_action in all_actions:
|
||||
return all_actions.index(wanted_action)
|
||||
else:
|
||||
# It may happen that one action item can mean multiple actions
|
||||
# (e.g. "CANCEL|DELETE" in the passphrase layout - both actions are on the same button)
|
||||
for index, action in enumerate(all_actions):
|
||||
subactions = action.split("|")
|
||||
if wanted_action in subactions:
|
||||
for index, action in enumerate(all_actions):
|
||||
if not isinstance(action, tuple):
|
||||
action = (action,)
|
||||
for subaction in action:
|
||||
try:
|
||||
tr = TR.translate(subaction)
|
||||
except KeyError:
|
||||
continue
|
||||
if tr == wanted_action:
|
||||
return index
|
||||
|
||||
raise ValueError(f"Action {wanted_action} is not supported in {all_actions}")
|
||||
@ -148,7 +153,7 @@ def _move_one_closer(
|
||||
debug: "DebugLink",
|
||||
wanted_action: str,
|
||||
current_action: str,
|
||||
all_actions: list[str],
|
||||
all_actions: AllActionsType,
|
||||
is_carousel: bool,
|
||||
) -> LayoutContent:
|
||||
"""Pressing either left or right regarding to the current situation"""
|
||||
@ -169,7 +174,3 @@ def _move_one_closer(
|
||||
return debug.press_left()
|
||||
else:
|
||||
return debug.press_right()
|
||||
|
||||
|
||||
def get_possible_btn_texts(path: str) -> str:
|
||||
return "|".join(TR.translate(path))
|
||||
|
@ -4,15 +4,13 @@ from trezorlib.debuglink import LayoutType
|
||||
|
||||
from .. import buttons
|
||||
from .. import translations as TR
|
||||
from .common import get_possible_btn_texts, go_next
|
||||
from .common import go_next
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from trezorlib.debuglink import DebugLink, LayoutContent
|
||||
|
||||
|
||||
DELETE_BTN_TEXTS = get_possible_btn_texts("inputs__delete") + get_possible_btn_texts(
|
||||
"inputs__previous"
|
||||
)
|
||||
DELETE_BTN_TEXTS = ("inputs__delete", "inputs__previous")
|
||||
|
||||
|
||||
def enter_word(
|
||||
@ -50,7 +48,7 @@ def enter_word(
|
||||
|
||||
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), title)
|
||||
assert TR.translate(title) == layout.title()
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
debug.click(buttons.OK)
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
@ -108,11 +106,11 @@ def select_number_of_words(
|
||||
return debug.click(coords)
|
||||
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
TR.assert_equals(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||
assert debug.read_layout().text_content() == TR.recovery__num_of_words
|
||||
layout = select_tt()
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
layout = debug.press_right()
|
||||
TR.assert_equals(layout.title(), "word_count__title")
|
||||
assert layout.title() == TR.word_count__title
|
||||
layout = select_tr()
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
layout = select_mercury()
|
||||
@ -121,30 +119,24 @@ def select_number_of_words(
|
||||
|
||||
if unlock_repeated_backup:
|
||||
if debug.layout_type is LayoutType.TR:
|
||||
TR.assert_in(layout.text_content(), "recovery__enter_backup")
|
||||
assert TR.recovery__enter_backup in layout.text_content()
|
||||
else:
|
||||
TR.assert_in_multiple(
|
||||
layout.text_content(),
|
||||
["recovery__only_first_n_letters", "recovery__enter_each_word"],
|
||||
assert (
|
||||
TR.recovery__only_first_n_letters in layout.text_content()
|
||||
or TR.recovery__enter_each_word in layout.text_content()
|
||||
)
|
||||
elif num_of_words in (20, 33):
|
||||
TR.assert_in_multiple(
|
||||
layout.text_content(),
|
||||
[
|
||||
"recovery__enter_backup",
|
||||
"recovery__enter_any_share",
|
||||
"recovery__only_first_n_letters",
|
||||
"recovery__enter_each_word",
|
||||
],
|
||||
assert (
|
||||
TR.recovery__enter_backup in layout.text_content()
|
||||
or TR.recovery__enter_any_share in layout.text_content()
|
||||
or TR.recovery__only_first_n_letters in layout.text_content()
|
||||
or TR.recovery__enter_each_word in layout.text_content()
|
||||
)
|
||||
else: # BIP-39
|
||||
TR.assert_in_multiple(
|
||||
layout.text_content(),
|
||||
[
|
||||
"recovery__enter_backup",
|
||||
"recovery__only_first_n_letters",
|
||||
"recovery__enter_each_word",
|
||||
],
|
||||
assert (
|
||||
TR.recovery__enter_backup in layout.text_content()
|
||||
or TR.recovery__only_first_n_letters in layout.text_content()
|
||||
or TR.recovery__enter_each_word in layout.text_content()
|
||||
)
|
||||
|
||||
|
||||
@ -155,14 +147,14 @@ def enter_share(
|
||||
before_title: str = "recovery__title_recover",
|
||||
) -> "LayoutContent":
|
||||
if debug.layout_type is LayoutType.TR:
|
||||
TR.assert_in(debug.read_layout().title(), before_title)
|
||||
assert TR.translate(before_title) in debug.read_layout().title()
|
||||
layout = debug.read_layout()
|
||||
for _ in range(layout.page_count()):
|
||||
layout = debug.press_right()
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
layout = debug.swipe_up()
|
||||
else:
|
||||
TR.assert_in(debug.read_layout().title(), before_title)
|
||||
assert TR.translate(before_title) in debug.read_layout().title()
|
||||
layout = debug.click(buttons.OK)
|
||||
|
||||
assert "MnemonicKeyboard" in layout.all_components()
|
||||
@ -180,15 +172,12 @@ def enter_shares(
|
||||
text: str = "recovery__enter_any_share",
|
||||
after_layout_text: str = "recovery__wallet_recovered",
|
||||
) -> None:
|
||||
TR.assert_in_multiple(
|
||||
debug.read_layout().text_content(),
|
||||
[
|
||||
"recovery__enter_backup",
|
||||
"recovery__enter_any_share",
|
||||
"recovery__only_first_n_letters",
|
||||
"recovery__enter_each_word",
|
||||
text,
|
||||
],
|
||||
assert (
|
||||
TR.recovery__enter_backup in debug.read_layout().text_content()
|
||||
or TR.recovery__enter_any_share in debug.read_layout().text_content()
|
||||
or TR.recovery__only_first_n_letters in debug.read_layout().text_content()
|
||||
or TR.recovery__enter_each_word in debug.read_layout().text_content()
|
||||
or TR.translate(text) in debug.read_layout().text_content()
|
||||
)
|
||||
for index, share in enumerate(shares):
|
||||
enter_share(
|
||||
@ -196,14 +185,14 @@ def enter_shares(
|
||||
)
|
||||
if index < len(shares) - 1:
|
||||
# FIXME: when ui-t3t1 done for shamir, we want to check the template below
|
||||
TR.assert_in(debug.read_layout().title(), enter_share_before_title)
|
||||
assert TR.translate(enter_share_before_title) in debug.read_layout().title()
|
||||
# TR.assert_in(
|
||||
# debug.read_layout().text_content(),
|
||||
# "recovery__x_of_y_entered_template",
|
||||
# template=(index + 1, len(shares)),
|
||||
# )
|
||||
|
||||
TR.assert_in(debug.read_layout().text_content(), after_layout_text)
|
||||
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
||||
|
||||
|
||||
def enter_seed(
|
||||
@ -218,7 +207,7 @@ def enter_seed(
|
||||
for word in seed_words:
|
||||
enter_word(debug, word, is_slip39=is_slip39)
|
||||
|
||||
TR.assert_in(debug.read_layout().text_content(), after_layout_text)
|
||||
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
||||
|
||||
|
||||
def enter_seed_previous_correct(
|
||||
@ -244,12 +233,18 @@ def enter_seed_previous_correct(
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
layout = debug.read_layout()
|
||||
|
||||
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
||||
middle_choice = layout.get_middle_choice()
|
||||
while not any(
|
||||
TR.translate(btn) == middle_choice for btn in DELETE_BTN_TEXTS
|
||||
):
|
||||
layout = debug.press_right()
|
||||
layout = debug.press_middle()
|
||||
|
||||
for _ in range(len(bad_word)):
|
||||
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
||||
middle_choice = layout.get_middle_choice()
|
||||
while not any(
|
||||
TR.translate(btn) == middle_choice for btn in DELETE_BTN_TEXTS
|
||||
):
|
||||
layout = debug.press_left()
|
||||
layout = debug.press_middle()
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
@ -273,14 +268,11 @@ def enter_seed_previous_correct(
|
||||
def prepare_enter_seed(
|
||||
debug: "DebugLink", layout_text: str = "recovery__enter_backup"
|
||||
) -> None:
|
||||
TR.assert_in_multiple(
|
||||
debug.read_layout().text_content(),
|
||||
[
|
||||
"recovery__enter_backup",
|
||||
"recovery__only_first_n_letters",
|
||||
"recovery__enter_each_word",
|
||||
layout_text,
|
||||
],
|
||||
assert (
|
||||
TR.recovery__enter_backup in debug.read_layout().text_content()
|
||||
or TR.recovery__only_first_n_letters in debug.read_layout().text_content()
|
||||
or TR.recovery__enter_each_word in debug.read_layout().text_content()
|
||||
or TR.translate(layout_text) in debug.read_layout().text_content()
|
||||
)
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
debug.click(buttons.OK)
|
||||
|
@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||
TR.assert_equals(debug.read_layout().title(), "reset__title_create_wallet")
|
||||
assert debug.read_layout().title() == TR.reset__title_create_wallet
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
debug.click(buttons.OK)
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
@ -22,9 +22,9 @@ def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
debug.press_right()
|
||||
debug.press_right()
|
||||
TR.assert_in_multiple(
|
||||
debug.read_layout().text_content(),
|
||||
["backup__new_wallet_successfully_created", "backup__new_wallet_created"],
|
||||
assert (
|
||||
TR.backup__new_wallet_successfully_created in debug.read_layout().text_content()
|
||||
or TR.backup__new_wallet_created in debug.read_layout().text_content()
|
||||
)
|
||||
if debug.layout_type is LayoutType.Mercury:
|
||||
debug.swipe_up()
|
||||
@ -74,9 +74,10 @@ def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> Non
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
layout = debug.read_layout()
|
||||
if layout.title() in TR.translate(
|
||||
"reset__title_number_of_shares"
|
||||
) + TR.translate("words__title_threshold"):
|
||||
if (
|
||||
layout.title()
|
||||
in TR.reset__title_number_of_shares + TR.words__title_threshold
|
||||
):
|
||||
# Special info screens
|
||||
layout = debug.press_right()
|
||||
assert "NumberInput" in layout.all_components()
|
||||
@ -131,7 +132,9 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
|
||||
layout = debug.read_layout()
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
TR.assert_template(layout.text_content(), "reset__select_word_x_of_y_template")
|
||||
assert TR.regexp("reset__select_word_x_of_y_template").match(
|
||||
layout.text_content()
|
||||
)
|
||||
for _ in range(3):
|
||||
# "Select word 3 of 20"
|
||||
# ^
|
||||
@ -146,7 +149,7 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
layout = debug.click(buttons.RESET_WORD_CHECK[button_pos])
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
TR.assert_template(layout.subtitle(), "reset__select_word_x_of_y_template")
|
||||
assert TR.regexp("reset__select_word_x_of_y_template").match(layout.subtitle())
|
||||
for _ in range(3):
|
||||
# "Select word 3 of 20"
|
||||
# ^
|
||||
@ -161,7 +164,7 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
layout = debug.click(buttons.VERTICAL_MENU[button_pos])
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
TR.assert_in(layout.text_content(), "reset__select_correct_word")
|
||||
assert TR.reset__select_correct_word in layout.text_content()
|
||||
layout = debug.press_right()
|
||||
for _ in range(3):
|
||||
# "SELECT 2ND WORD"
|
||||
|
@ -65,9 +65,8 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int)
|
||||
|
||||
debug.input("1234")
|
||||
|
||||
TR.assert_template(
|
||||
debug.read_layout().text_content(),
|
||||
"auto_lock__change_template",
|
||||
assert TR.regexp("auto_lock__change_template").match(
|
||||
debug.read_layout().text_content()
|
||||
)
|
||||
|
||||
layout = go_next(debug)
|
||||
@ -108,17 +107,17 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
debug.click(buttons.OK)
|
||||
layout = debug.click(buttons.OK)
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
debug.swipe_up()
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
debug.press_right()
|
||||
layout = debug.press_right()
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
|
||||
# wait for autolock to kick in
|
||||
@ -160,18 +159,18 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
||||
if debug.layout_type is LayoutType.TT:
|
||||
debug.click(buttons.OK)
|
||||
layout = debug.click(buttons.OK)
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
elif debug.layout_type is LayoutType.Mercury:
|
||||
debug.swipe_up()
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.TR:
|
||||
debug.press_right()
|
||||
layout = debug.press_right()
|
||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
|
||||
def sleepy_filter(msg: MessageType) -> MessageType:
|
||||
@ -274,7 +273,7 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
||||
|
||||
|
||||
def unlock_dry_run(debug: "DebugLink") -> "LayoutContent":
|
||||
TR.assert_in(debug.read_layout().text_content(), "recovery__check_dry_run")
|
||||
assert TR.recovery__check_dry_run in debug.read_layout().text_content()
|
||||
layout = go_next(debug)
|
||||
assert "PinKeyboard" in layout.all_components()
|
||||
|
||||
@ -291,7 +290,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
|
||||
device_handler.run(device.recover, dry_run=True) # type: ignore
|
||||
|
||||
layout = unlock_dry_run(debug)
|
||||
TR.assert_in(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||
assert TR.recovery__num_of_words in debug.read_layout().text_content()
|
||||
|
||||
if debug.layout_type is LayoutType.TR:
|
||||
debug.press_right()
|
||||
@ -312,7 +311,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
|
||||
assert layout is not None
|
||||
|
||||
# we are back at homescreen
|
||||
TR.assert_in(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||
assert TR.recovery__num_of_words in debug.read_layout().text_content()
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4)
|
||||
|
@ -76,18 +76,17 @@ def test_backup_slip39_custom(
|
||||
|
||||
# confirm backup configuration
|
||||
if share_count > 1:
|
||||
TR.assert_template(
|
||||
debug.read_layout().text_content(),
|
||||
"reset__create_x_of_y_multi_share_backup_template",
|
||||
assert TR.regexp("reset__create_x_of_y_multi_share_backup_template").match(
|
||||
debug.read_layout().text_content()
|
||||
)
|
||||
else:
|
||||
TR.assert_template(
|
||||
debug.read_layout().text_content(), "backup__info_single_share_backup"
|
||||
assert TR.regexp("backup__info_single_share_backup").match(
|
||||
debug.read_layout().text_content()
|
||||
)
|
||||
reset.confirm_read(debug)
|
||||
|
||||
# confirm backup intro
|
||||
TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy")
|
||||
assert TR.reset__never_make_digital_copy in debug.read_layout().text_content()
|
||||
reset.confirm_read(debug, middle_r=True)
|
||||
|
||||
all_words: list[str] = []
|
||||
|
@ -21,7 +21,6 @@ import pytest
|
||||
|
||||
from trezorlib import exceptions
|
||||
|
||||
from .. import translations as TR
|
||||
from ..common import get_test_address
|
||||
from .common import (
|
||||
CommonPass,
|
||||
@ -56,20 +55,11 @@ assert len(AAA_51) == 51
|
||||
assert AAA_51_ADDRESS == AAA_50_ADDRESS
|
||||
|
||||
|
||||
def _get_possible_btns(path: str) -> str:
|
||||
return "|".join(TR.translate(path))
|
||||
|
||||
|
||||
def _get_cancel_or_delete() -> str:
|
||||
paths = ["inputs__cancel", "inputs__delete"]
|
||||
return "|".join(_get_possible_btns(path) for path in paths)
|
||||
|
||||
|
||||
BACK = _get_possible_btns("inputs__back")
|
||||
SHOW = _get_possible_btns("inputs__show")
|
||||
ENTER = _get_possible_btns("inputs__enter")
|
||||
SPACE = _get_possible_btns("inputs__space")
|
||||
CANCEL_OR_DELETE = _get_cancel_or_delete()
|
||||
BACK = "inputs__back"
|
||||
SHOW = "inputs__show"
|
||||
ENTER = "inputs__enter"
|
||||
SPACE = "inputs__space"
|
||||
CANCEL_OR_DELETE = ("inputs__cancel", "inputs__delete")
|
||||
# fmt: off
|
||||
MENU_ACTIONS = [SHOW, CANCEL_OR_DELETE, ENTER, "abc", "ABC", "123", "#$!", SPACE]
|
||||
DIGITS_ACTIONS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", BACK]
|
||||
|
@ -25,12 +25,7 @@ from trezorlib.debuglink import LayoutType
|
||||
|
||||
from .. import buttons
|
||||
from .. import translations as TR
|
||||
from .common import (
|
||||
get_possible_btn_texts,
|
||||
go_back,
|
||||
go_next,
|
||||
navigate_to_action_and_press,
|
||||
)
|
||||
from .common import go_back, go_next, navigate_to_action_and_press
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from trezorlib.debuglink import DebugLink
|
||||
@ -48,9 +43,9 @@ PIN24 = "875163065288639289952973"
|
||||
PIN50 = "31415926535897932384626433832795028841971693993751"
|
||||
PIN60 = PIN50 + "9" * 10
|
||||
|
||||
DELETE = get_possible_btn_texts("inputs__delete")
|
||||
SHOW = get_possible_btn_texts("inputs__show")
|
||||
ENTER = get_possible_btn_texts("inputs__enter")
|
||||
DELETE = "inputs__delete"
|
||||
SHOW = "inputs__show"
|
||||
ENTER = "inputs__enter"
|
||||
|
||||
|
||||
TR_PIN_ACTIONS = [
|
||||
@ -103,8 +98,9 @@ def prepare(
|
||||
elif situation == Situation.PIN_SETUP:
|
||||
# Set new PIN
|
||||
device_handler.run(device.change_pin) # type: ignore
|
||||
TR.assert_in_multiple(
|
||||
debug.read_layout().text_content(), ["pin__turn_on", "pin__info"]
|
||||
assert (
|
||||
TR.pin__turn_on in debug.read_layout().text_content()
|
||||
or TR.pin__info in debug.read_layout().text_content()
|
||||
)
|
||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||
go_next(debug)
|
||||
@ -117,7 +113,7 @@ def prepare(
|
||||
# Change PIN
|
||||
device_handler.run(device.change_pin) # type: ignore
|
||||
_input_see_confirm(debug, old_pin)
|
||||
TR.assert_in(debug.read_layout().text_content(), "pin__change")
|
||||
assert TR.pin__change in debug.read_layout().text_content()
|
||||
go_next(debug)
|
||||
_input_see_confirm(debug, old_pin)
|
||||
elif situation == Situation.WIPE_CODE_SETUP:
|
||||
@ -125,7 +121,7 @@ def prepare(
|
||||
device_handler.run(device.change_wipe_code) # type: ignore
|
||||
if old_pin:
|
||||
_input_see_confirm(debug, old_pin)
|
||||
TR.assert_in(debug.read_layout().text_content(), "wipe_code__turn_on")
|
||||
assert TR.wipe_code__turn_on in debug.read_layout().text_content()
|
||||
go_next(debug)
|
||||
if debug.layout_type is LayoutType.TR:
|
||||
go_next(debug)
|
||||
|
@ -59,13 +59,13 @@ def test_reset_bip39(device_handler: "BackgroundDeviceHandler"):
|
||||
|
||||
# confirm backup intro
|
||||
# parametrized string
|
||||
TR.assert_template(
|
||||
debug.read_layout().text_content(), "backup__info_single_share_backup"
|
||||
assert TR.regexp("backup__info_single_share_backup").match(
|
||||
debug.read_layout().text_content()
|
||||
)
|
||||
reset.confirm_read(debug)
|
||||
|
||||
# confirm backup warning
|
||||
TR.assert_in(debug.read_layout().text_content(), "reset__never_make_digital_copy")
|
||||
assert TR.reset__never_make_digital_copy in debug.read_layout().text_content()
|
||||
reset.confirm_read(debug, middle_r=True)
|
||||
|
||||
# read words
|
||||
|
@ -39,17 +39,17 @@ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
||||
device_handler.run(device.show_device_tutorial)
|
||||
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||
assert layout.title() == TR.tutorial__welcome_safe5
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||
assert layout.title() == TR.tutorial__title_hold
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||
assert layout.title() == TR.tutorial__title_well_done
|
||||
debug.swipe_up()
|
||||
|
||||
device_handler.result()
|
||||
@ -60,23 +60,23 @@ def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"):
|
||||
device_handler.run(device.show_device_tutorial)
|
||||
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||
assert layout.title() == TR.tutorial__welcome_safe5
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||
assert TR.tutorial__did_you_know in layout.text_content()
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||
assert layout.title() == TR.tutorial__title_hold
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||
assert layout.title() == TR.tutorial__title_well_done
|
||||
debug.swipe_up()
|
||||
|
||||
device_handler.result()
|
||||
@ -87,20 +87,20 @@ def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"):
|
||||
device_handler.run(device.show_device_tutorial)
|
||||
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||
assert layout.title() == TR.tutorial__welcome_safe5
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||
assert TR.tutorial__did_you_know in layout.text_content()
|
||||
layout = debug.click(buttons.VERTICAL_MENU[2])
|
||||
TR.assert_in(layout.footer(), "instructions__hold_to_exit_tutorial")
|
||||
assert TR.instructions__hold_to_exit_tutorial in layout.footer()
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||
assert layout.title() == TR.tutorial__title_well_done
|
||||
debug.swipe_up()
|
||||
|
||||
device_handler.result()
|
||||
@ -111,27 +111,27 @@ def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
||||
device_handler.run(device.show_device_tutorial)
|
||||
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||
assert layout.title() == TR.tutorial__welcome_safe5
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||
assert TR.tutorial__did_you_know in layout.text_content()
|
||||
layout = debug.click(buttons.VERTICAL_MENU[1])
|
||||
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||
assert layout.title() == TR.tutorial__title_hold
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||
assert layout.title() == TR.tutorial__title_well_done
|
||||
debug.swipe_up()
|
||||
|
||||
device_handler.result()
|
||||
@ -142,31 +142,29 @@ def test_tutorial_menu_funfact(device_handler: "BackgroundDeviceHandler"):
|
||||
device_handler.run(device.show_device_tutorial)
|
||||
|
||||
layout = debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||
assert layout.title() == TR.tutorial__welcome_safe5
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||
assert layout.title() == TR.tutorial__title_lets_begin
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||
assert layout.title() == TR.tutorial__title_easy_navigation
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||
assert TR.tutorial__did_you_know in layout.text_content()
|
||||
layout = debug.click(buttons.VERTICAL_MENU[0])
|
||||
text_content = [
|
||||
s.replace("\n", " ") for s in TR.translate("tutorial__first_wallet")
|
||||
]
|
||||
text_content = [s.replace("\n", " ") for s in TR.tutorial__first_wallet]
|
||||
assert layout.text_content() in text_content
|
||||
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||
assert TR.tutorial__did_you_know in layout.text_content()
|
||||
layout = debug.click(buttons.CORNER_BUTTON)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||
assert layout.title() == TR.tutorial__title_handy_menu
|
||||
|
||||
layout = debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||
assert layout.title() == TR.tutorial__title_hold
|
||||
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||
assert layout.title() == TR.tutorial__title_well_done
|
||||
debug.swipe_up()
|
||||
|
||||
device_handler.result()
|
||||
|
@ -57,7 +57,7 @@ def go_through_tutorial_tr(debug: "DebugLink") -> None:
|
||||
debug.press_right()
|
||||
debug.press_right()
|
||||
layout = debug.press_middle()
|
||||
TR.assert_equals(layout.title(), "tutorial__title_tutorial_complete")
|
||||
assert layout.title() == TR.tutorial__title_tutorial_complete
|
||||
|
||||
|
||||
def test_tutorial_finish(device_handler: "BackgroundDeviceHandler"):
|
||||
|
@ -309,8 +309,7 @@ def client(
|
||||
if _raw_client.model is not models.T1B1:
|
||||
lang = request.session.config.getoption("lang") or "en"
|
||||
assert isinstance(lang, str)
|
||||
if lang != "en":
|
||||
translations.set_language(_raw_client, lang)
|
||||
translations.set_language(_raw_client, lang)
|
||||
|
||||
setup_params = dict(
|
||||
uninitialized=False,
|
||||
|
@ -23,6 +23,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import WITH_MOCK_URANDOM
|
||||
from ...input_flows import InputFlowBip39Recovery, InputFlowBip39ResetBackup
|
||||
from ...translations import set_language
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@ -31,7 +32,9 @@ def test_reset_recovery(client: Client):
|
||||
mnemonic = reset(client)
|
||||
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||
|
||||
lang = client.features.language or "en"
|
||||
device.wipe(client)
|
||||
set_language(client, lang[:2])
|
||||
recover(client, mnemonic)
|
||||
address_after = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||
assert address_before == address_after
|
||||
|
@ -26,6 +26,7 @@ from ...input_flows import (
|
||||
InputFlowSlip39AdvancedRecovery,
|
||||
InputFlowSlip39AdvancedResetRecovery,
|
||||
)
|
||||
from ...translations import set_language
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@ -49,7 +50,10 @@ def test_reset_recovery(client: Client):
|
||||
+ mnemonics[22:25],
|
||||
]
|
||||
for combination in test_combinations:
|
||||
lang = client.features.language or "en"
|
||||
device.wipe(client)
|
||||
set_language(client, lang[:2])
|
||||
|
||||
recover(client, combination)
|
||||
address_after = btc.get_address(
|
||||
client, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
|
||||
|
@ -28,6 +28,7 @@ from ...input_flows import (
|
||||
InputFlowSlip39BasicRecovery,
|
||||
InputFlowSlip39BasicResetRecovery,
|
||||
)
|
||||
from ...translations import set_language
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@ -38,7 +39,9 @@ def test_reset_recovery(client: Client):
|
||||
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||
|
||||
for share_subset in itertools.combinations(mnemonics, 3):
|
||||
lang = client.features.language or "en"
|
||||
device.wipe(client)
|
||||
set_language(client, lang[:2])
|
||||
selected_mnemonics = share_subset
|
||||
recover(client, selected_mnemonics)
|
||||
address_after = btc.get_address(
|
||||
|
@ -162,7 +162,7 @@ def test_repeated_backup_cancel(client: Client):
|
||||
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
layout = client.debug.read_layout()
|
||||
TR.assert_in(layout.text_content(), "recovery__unlock_repeated_backup")
|
||||
assert TR.recovery__unlock_repeated_backup in layout.text_content()
|
||||
|
||||
# send a Cancel message
|
||||
|
||||
@ -218,7 +218,7 @@ def test_repeated_backup_send_disallowed_message(client: Client):
|
||||
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
layout = client.debug.read_layout()
|
||||
TR.assert_in(layout.text_content(), "recovery__unlock_repeated_backup")
|
||||
assert TR.recovery__unlock_repeated_backup in layout.text_content()
|
||||
|
||||
# send a GetAddress message
|
||||
|
||||
@ -237,6 +237,6 @@ def test_repeated_backup_send_disallowed_message(client: Client):
|
||||
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
# we are still on the confirmation screen!
|
||||
TR.assert_in(
|
||||
client.debug.read_layout().text_content(), "recovery__unlock_repeated_backup"
|
||||
assert (
|
||||
TR.recovery__unlock_repeated_backup in client.debug.read_layout().text_content()
|
||||
)
|
||||
|
@ -59,7 +59,7 @@ def test_sd_protect_unlock(client: Client):
|
||||
client.debug.input("1234")
|
||||
|
||||
yield # do you really want to enable SD protection
|
||||
TR.assert_in(layout().text_content(), "sd_card__enable")
|
||||
assert TR.sd_card__enable in layout().text_content()
|
||||
client.debug.press_yes()
|
||||
|
||||
yield # enter current PIN
|
||||
@ -67,7 +67,7 @@ def test_sd_protect_unlock(client: Client):
|
||||
client.debug.input("1234")
|
||||
|
||||
yield # you have successfully enabled SD protection
|
||||
TR.assert_in(layout().text_content(), "sd_card__enabled")
|
||||
assert TR.sd_card__enabled in layout().text_content()
|
||||
client.debug.press_yes()
|
||||
|
||||
with client:
|
||||
@ -77,7 +77,7 @@ def test_sd_protect_unlock(client: Client):
|
||||
|
||||
def input_flow_change_pin():
|
||||
yield # do you really want to change PIN?
|
||||
TR.assert_equals(layout().title(), "pin__title_settings")
|
||||
assert layout().title() == TR.pin__title_settings
|
||||
client.debug.press_yes()
|
||||
|
||||
yield # enter current PIN
|
||||
@ -93,7 +93,7 @@ def test_sd_protect_unlock(client: Client):
|
||||
client.debug.input("1234")
|
||||
|
||||
yield # Pin change successful
|
||||
TR.assert_in(layout().text_content(), "pin__changed")
|
||||
assert TR.pin__changed in layout().text_content()
|
||||
client.debug.press_yes()
|
||||
|
||||
with client:
|
||||
@ -105,7 +105,7 @@ def test_sd_protect_unlock(client: Client):
|
||||
|
||||
def input_flow_change_pin_format():
|
||||
yield # do you really want to change PIN?
|
||||
TR.assert_equals(layout().title(), "pin__title_settings")
|
||||
assert layout().title() == TR.pin__title_settings
|
||||
client.debug.press_yes()
|
||||
|
||||
yield # enter current PIN
|
||||
@ -113,9 +113,9 @@ def test_sd_protect_unlock(client: Client):
|
||||
client.debug.input("1234")
|
||||
|
||||
yield # SD card problem
|
||||
TR.assert_in_multiple(
|
||||
layout().text_content(),
|
||||
["sd_card__unplug_and_insert_correct", "sd_card__insert_correct_card"],
|
||||
assert (
|
||||
TR.sd_card__unplug_and_insert_correct in layout().text_content()
|
||||
or TR.sd_card__insert_correct_card in layout().text_content()
|
||||
)
|
||||
client.debug.press_no() # close
|
||||
|
||||
|
@ -398,10 +398,7 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
def input_flow():
|
||||
yield
|
||||
content = client.debug.read_layout().text_content().lower()
|
||||
assert any(
|
||||
(s[:50].lower() in content)
|
||||
for s in TR.translate("passphrase__from_host_not_shown")
|
||||
)
|
||||
assert TR.passphrase__from_host_not_shown[:50].lower() in content
|
||||
if client.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||
client.debug.press_yes()
|
||||
elif client.layout_type is LayoutType.TR:
|
||||
@ -435,17 +432,14 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
|
||||
def input_flow():
|
||||
yield
|
||||
TR.assert_in(
|
||||
client.debug.read_layout().text_content(),
|
||||
"passphrase__next_screen_will_show_passphrase",
|
||||
assert (
|
||||
TR.passphrase__next_screen_will_show_passphrase
|
||||
in client.debug.read_layout().text_content()
|
||||
)
|
||||
client.debug.press_yes()
|
||||
|
||||
yield
|
||||
TR.assert_equals(
|
||||
client.debug.read_layout().title(),
|
||||
"passphrase__title_confirm",
|
||||
)
|
||||
assert client.debug.read_layout().title() == TR.passphrase__title_confirm
|
||||
assert passphrase in client.debug.read_layout().text_content()
|
||||
client.debug.press_yes()
|
||||
|
||||
|
@ -428,9 +428,9 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
expected_title = f"MULTISIG XPUB #{xpub_num + 1}"
|
||||
assert expected_title in title
|
||||
if self.index == xpub_num:
|
||||
TR.assert_in(title, "address__title_yours")
|
||||
assert TR.address__title_yours in title
|
||||
else:
|
||||
TR.assert_in(title, "address__title_cosigner")
|
||||
assert TR.address__title_cosigner in title
|
||||
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
yield # multisig address warning
|
||||
@ -438,7 +438,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
|
||||
yield # show address
|
||||
layout = self.debug.read_layout()
|
||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||
assert TR.address__title_receive_address in layout.title()
|
||||
assert "(MULTISIG)" in layout.title()
|
||||
assert layout.text_content().replace(" ", "") == self.address
|
||||
|
||||
@ -448,7 +448,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
layout = self.debug.swipe_left()
|
||||
# address details
|
||||
assert "Multisig 2 of 3" in layout.screen_content()
|
||||
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
||||
assert TR.address_details__derivation_path in layout.screen_content()
|
||||
|
||||
# Three xpub pages with the same testing logic
|
||||
for xpub_num in range(3):
|
||||
@ -471,7 +471,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
|
||||
yield # show address
|
||||
layout = self.debug.read_layout()
|
||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||
assert TR.address__title_receive_address in layout.title()
|
||||
assert "(MULTISIG)" in layout.title()
|
||||
assert layout.text_content().replace(" ", "") == self.address
|
||||
|
||||
@ -512,7 +512,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
|
||||
yield # show address
|
||||
layout = self.debug.read_layout()
|
||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||
assert TR.address__title_receive_address in layout.title()
|
||||
assert layout.text_content().replace(" ", "") == self.address
|
||||
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
@ -529,7 +529,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||
layout = self.debug.synchronize_at("AddressDetails")
|
||||
# address details
|
||||
assert "Multisig 2 of 3" in layout.screen_content()
|
||||
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
||||
assert TR.address_details__derivation_path in layout.screen_content()
|
||||
|
||||
# three xpub pages with the same testing logic
|
||||
for _xpub_num in range(3):
|
||||
@ -629,7 +629,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
||||
br = yield
|
||||
layout = self.debug.read_layout()
|
||||
|
||||
assert layout.title() in TR.translate("address__public_key") + ["XPUB"]
|
||||
assert layout.title() in (TR.address__public_key, ["XPUB"])
|
||||
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
assert "VerticalMenu" in self.all_components()
|
||||
@ -644,7 +644,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
||||
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||
layout = self.debug.synchronize_at("AddressDetails")
|
||||
# address details
|
||||
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
||||
assert TR.address_details__derivation_path in layout.screen_content()
|
||||
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
layout = self.debug.synchronize_at("VerticalMenu")
|
||||
@ -859,9 +859,9 @@ class InputFlowSignTxInformation(InputFlowBase):
|
||||
super().__init__(client)
|
||||
|
||||
def assert_content(self, content: str, title_path: str) -> None:
|
||||
TR.assert_in(content, title_path)
|
||||
assert TR.translate(title_path) in content
|
||||
assert "Legacy #6" in content
|
||||
TR.assert_in(content, "confirm_total__fee_rate")
|
||||
assert TR.confirm_total__fee_rate in content
|
||||
assert "71.56 sat" in content
|
||||
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
@ -887,9 +887,9 @@ class InputFlowSignTxInformationMixed(InputFlowBase):
|
||||
super().__init__(client)
|
||||
|
||||
def assert_content(self, content: str, title_path: str) -> None:
|
||||
TR.assert_in(content, title_path)
|
||||
TR.assert_in(content, "bitcoin__multiple_accounts")
|
||||
TR.assert_in(content, "confirm_total__fee_rate")
|
||||
assert TR.translate(title_path) in content
|
||||
assert TR.bitcoin__multiple_accounts in content
|
||||
assert TR.confirm_total__fee_rate in content
|
||||
assert "18.33 sat" in content
|
||||
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
@ -1049,7 +1049,7 @@ class InputFlowLockTimeBlockHeight(InputFlowBase):
|
||||
|
||||
def assert_func(self, debug: DebugLink, br: messages.ButtonRequest) -> None:
|
||||
layout_text = get_text_possible_pagination(debug, br)
|
||||
TR.assert_in(layout_text, "bitcoin__locktime_set_to_blockheight")
|
||||
assert TR.bitcoin__locktime_set_to_blockheight in layout_text
|
||||
assert self.block_height in layout_text
|
||||
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
@ -1073,7 +1073,7 @@ class InputFlowLockTimeDatetime(InputFlowBase):
|
||||
|
||||
def assert_func(self, debug: DebugLink, br: messages.ButtonRequest) -> None:
|
||||
layout_text = get_text_possible_pagination(debug, br)
|
||||
TR.assert_in(layout_text, "bitcoin__locktime_set_to")
|
||||
assert TR.bitcoin__locktime_set_to in layout_text
|
||||
assert self.lock_time_str.replace(" ", "") in layout_text.replace(" ", "")
|
||||
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
@ -2207,26 +2207,26 @@ class InputFlowResetSkipBackup(InputFlowBase):
|
||||
def input_flow_tt(self) -> BRGeneratorType:
|
||||
yield from self.BAK.confirm_new_wallet()
|
||||
yield # Skip Backup
|
||||
TR.assert_in(self.text_content(), "backup__new_wallet_successfully_created")
|
||||
assert TR.backup__new_wallet_successfully_created in self.text_content()
|
||||
self.debug.press_no()
|
||||
yield # Confirm skip backup
|
||||
TR.assert_in(self.text_content(), "backup__want_to_skip")
|
||||
assert TR.backup__want_to_skip in self.text_content()
|
||||
self.debug.press_no()
|
||||
|
||||
def input_flow_tr(self) -> BRGeneratorType:
|
||||
yield from self.BAK.confirm_new_wallet()
|
||||
yield # Skip Backup
|
||||
TR.assert_in(self.text_content(), "backup__new_wallet_created")
|
||||
assert TR.backup__new_wallet_created in self.text_content()
|
||||
self.debug.press_right()
|
||||
self.debug.press_no()
|
||||
yield # Confirm skip backup
|
||||
TR.assert_in(self.text_content(), "backup__want_to_skip")
|
||||
assert TR.backup__want_to_skip in self.text_content()
|
||||
self.debug.press_no()
|
||||
|
||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||
yield from self.BAK.confirm_new_wallet()
|
||||
yield # Skip Backup
|
||||
TR.assert_in(self.text_content(), "backup__new_wallet_created")
|
||||
assert TR.backup__new_wallet_created in self.text_content()
|
||||
self.debug.swipe_up()
|
||||
yield
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
@ -2266,14 +2266,12 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
||||
text = layout.text_content().lower()
|
||||
# hi priority warning
|
||||
hi_prio = (
|
||||
TR.translate("ethereum__unknown_contract_address")
|
||||
+ TR.translate("addr_mismatch__wrong_derivation_path")
|
||||
+ TR.translate("send__receiving_to_multisig")
|
||||
+ [
|
||||
"witness path",
|
||||
"certificate path",
|
||||
"pool owner staking path",
|
||||
]
|
||||
TR.ethereum__unknown_contract_address,
|
||||
TR.addr_mismatch__wrong_derivation_path,
|
||||
TR.send__receiving_to_multisig,
|
||||
"witness path",
|
||||
"certificate path",
|
||||
"pool owner staking path",
|
||||
)
|
||||
if any(needle.lower() in text for needle in hi_prio):
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
|
@ -28,8 +28,9 @@ class PinFlow:
|
||||
self.debug.input(pin)
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
assert (yield).name == f"reenter_{what}" # Reenter PIN
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), f"{what}__reenter_to_confirm"
|
||||
assert (
|
||||
TR.translate(f"{what}__reenter_to_confirm")
|
||||
in self.debug.read_layout().text_content()
|
||||
)
|
||||
self.debug.press_yes()
|
||||
assert (yield).name == "pin_device" # Enter PIN again
|
||||
@ -47,7 +48,7 @@ class BackupFlow:
|
||||
|
||||
def confirm_new_wallet(self) -> BRGeneratorType:
|
||||
yield
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "reset__by_continuing")
|
||||
assert TR.reset__by_continuing in self.debug.read_layout().text_content()
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
self.debug.press_right()
|
||||
self.debug.press_yes()
|
||||
@ -64,14 +65,14 @@ class RecoveryFlow:
|
||||
|
||||
def confirm_recovery(self) -> BRGeneratorType:
|
||||
assert (yield).name == "recover_device"
|
||||
TR.assert_in(self._text_content(), "reset__by_continuing")
|
||||
assert TR.reset__by_continuing in self._text_content()
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
self.debug.press_right()
|
||||
self.debug.press_yes()
|
||||
|
||||
def confirm_dry_run(self) -> BRGeneratorType:
|
||||
assert (yield).name == "confirm_seedcheck"
|
||||
TR.assert_in(self._text_content(), "recovery__check_dry_run")
|
||||
assert TR.recovery__check_dry_run in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def setup_slip39_recovery(self, num_words: int) -> BRGeneratorType:
|
||||
@ -94,18 +95,18 @@ class RecoveryFlow:
|
||||
|
||||
def tr_recovery_homescreen(self) -> BRGeneratorType:
|
||||
yield
|
||||
TR.assert_in(self._text_content(), "recovery__num_of_words")
|
||||
assert TR.recovery__num_of_words in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def enter_your_backup(self) -> BRGeneratorType:
|
||||
assert (yield).name == "recovery"
|
||||
if self.debug.layout_type is LayoutType.Mercury:
|
||||
TR.assert_in(self._text_content(), "recovery__enter_each_word")
|
||||
assert TR.recovery__enter_each_word in self._text_content()
|
||||
else:
|
||||
TR.assert_in(self._text_content(), "recovery__enter_backup")
|
||||
is_dry_run = any(
|
||||
title in self.debug.read_layout().title().lower()
|
||||
for title in TR.translate("recovery__title_dry_run", lower=True)
|
||||
assert TR.recovery__enter_backup in self._text_content()
|
||||
is_dry_run = (
|
||||
TR.recovery__title_dry_run.lower()
|
||||
in self.debug.read_layout().title().lower()
|
||||
)
|
||||
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
||||
# Normal recovery has extra info (not dry run)
|
||||
@ -115,13 +116,13 @@ class RecoveryFlow:
|
||||
|
||||
def enter_any_share(self) -> BRGeneratorType:
|
||||
assert (yield).name == "recovery"
|
||||
TR.assert_in_multiple(
|
||||
self._text_content(),
|
||||
["recovery__enter_any_share", "recovery__enter_each_word"],
|
||||
assert (
|
||||
TR.recovery__enter_any_share in self._text_content()
|
||||
or TR.recovery__enter_each_word in self._text_content()
|
||||
)
|
||||
is_dry_run = any(
|
||||
title in self.debug.read_layout().title().lower()
|
||||
for title in TR.translate("recovery__title_dry_run", lower=True)
|
||||
is_dry_run = (
|
||||
TR.recovery__title_dry_run.lower()
|
||||
in self.debug.read_layout().title().lower()
|
||||
)
|
||||
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
||||
# Normal recovery has extra info (not dry run)
|
||||
@ -132,17 +133,17 @@ class RecoveryFlow:
|
||||
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
||||
yield
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
TR.assert_in(self._text_content(), "recovery__num_of_words")
|
||||
assert TR.recovery__num_of_words in self._text_content()
|
||||
self.debug.press_no()
|
||||
yield
|
||||
TR.assert_in(self._text_content(), "recovery__wanna_cancel_recovery")
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
self.debug.press_right()
|
||||
if confirm:
|
||||
self.debug.press_yes()
|
||||
else:
|
||||
self.debug.press_no()
|
||||
elif self.client.layout_type is LayoutType.Mercury:
|
||||
TR.assert_in(self._text_content(), "recovery__enter_each_word")
|
||||
assert TR.recovery__enter_each_word in self._text_content()
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
if confirm:
|
||||
@ -150,10 +151,10 @@ class RecoveryFlow:
|
||||
else:
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
else:
|
||||
TR.assert_in(self._text_content(), "recovery__enter_any_share")
|
||||
assert TR.recovery__enter_any_share in self._text_content()
|
||||
self.debug.press_no()
|
||||
yield
|
||||
TR.assert_in(self._text_content(), "recovery__wanna_cancel_recovery")
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
if confirm:
|
||||
self.debug.press_yes()
|
||||
else:
|
||||
@ -162,32 +163,32 @@ class RecoveryFlow:
|
||||
def abort_recovery_between_shares(self) -> BRGeneratorType:
|
||||
yield
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
TR.assert_template(
|
||||
self._text_content(), "recovery__x_of_y_entered_template"
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.press_no()
|
||||
assert (yield).name == "abort_recovery"
|
||||
TR.assert_in(self._text_content(), "recovery__wanna_cancel_recovery")
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
self.debug.press_right()
|
||||
self.debug.press_yes()
|
||||
elif self.client.layout_type is LayoutType.Mercury:
|
||||
TR.assert_template(
|
||||
self._text_content(), "recovery__x_of_y_entered_template"
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||
assert (yield).name == "abort_recovery"
|
||||
layout = self.debug.swipe_up()
|
||||
TR.assert_equals(layout.title(), "recovery__title_cancel_recovery")
|
||||
assert layout.title() == TR.recovery__title_cancel_recovery
|
||||
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||
else:
|
||||
TR.assert_template(
|
||||
self._text_content(), "recovery__x_of_y_entered_template"
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.press_no()
|
||||
assert (yield).name == "abort_recovery"
|
||||
TR.assert_in(self._text_content(), "recovery__wanna_cancel_recovery")
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def input_number_of_words(self, num_words: int) -> BRGeneratorType:
|
||||
@ -195,52 +196,52 @@ class RecoveryFlow:
|
||||
assert br.code == B.MnemonicWordCount
|
||||
assert br.name == "recovery_word_count"
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
TR.assert_in(self.debug.read_layout().title(), "word_count__title")
|
||||
assert TR.word_count__title in self.debug.read_layout().title()
|
||||
else:
|
||||
TR.assert_in(self._text_content(), "recovery__num_of_words")
|
||||
assert TR.recovery__num_of_words in self._text_content()
|
||||
self.debug.input(str(num_words))
|
||||
|
||||
def warning_invalid_recovery_seed(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Warning
|
||||
TR.assert_in(self._text_content(), "recovery__invalid_wallet_backup_entered")
|
||||
assert TR.recovery__invalid_wallet_backup_entered in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_invalid_recovery_share(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Warning
|
||||
TR.assert_in(self._text_content(), "recovery__invalid_share_entered")
|
||||
assert TR.recovery__invalid_share_entered in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_group_threshold_reached(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Warning
|
||||
TR.assert_in(self._text_content(), "recovery__group_threshold_reached")
|
||||
assert TR.recovery__group_threshold_reached in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_share_already_entered(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Warning
|
||||
TR.assert_in(self._text_content(), "recovery__share_already_entered")
|
||||
assert TR.recovery__share_already_entered in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_share_from_another_shamir(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Warning
|
||||
TR.assert_in(
|
||||
self._text_content(), "recovery__share_from_another_multi_share_backup"
|
||||
assert (
|
||||
TR.recovery__share_from_another_multi_share_backup in self._text_content()
|
||||
)
|
||||
self.debug.press_yes()
|
||||
|
||||
def success_share_group_entered(self) -> BRGeneratorType:
|
||||
assert (yield).name == "share_success"
|
||||
TR.assert_in(self._text_content(), "recovery__you_have_entered")
|
||||
assert TR.recovery__you_have_entered in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def success_wallet_recovered(self) -> BRGeneratorType:
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
TR.assert_in(self._text_content(), "recovery__wallet_recovered")
|
||||
assert TR.recovery__wallet_recovered in self._text_content()
|
||||
self.debug.press_yes()
|
||||
|
||||
def success_bip39_dry_run_valid(self) -> BRGeneratorType:
|
||||
@ -249,7 +250,7 @@ class RecoveryFlow:
|
||||
text = get_text_possible_pagination(self.debug, br)
|
||||
# TODO: make sure the translations fit on one page
|
||||
if self.client.layout_type not in (LayoutType.TT, LayoutType.Mercury):
|
||||
TR.assert_in(text, "recovery__dry_run_bip39_valid_match")
|
||||
assert TR.recovery__dry_run_bip39_valid_match in text
|
||||
self.debug.press_yes()
|
||||
|
||||
def success_slip39_dryrun_valid(self) -> BRGeneratorType:
|
||||
@ -258,7 +259,7 @@ class RecoveryFlow:
|
||||
text = get_text_possible_pagination(self.debug, br)
|
||||
# TODO: make sure the translations fit on one page
|
||||
if self.client.layout_type not in (LayoutType.TT, LayoutType.Mercury):
|
||||
TR.assert_in(text, "recovery__dry_run_slip39_valid_match")
|
||||
assert TR.recovery__dry_run_slip39_valid_match in text
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_slip39_dryrun_mismatch(self) -> BRGeneratorType:
|
||||
@ -267,7 +268,7 @@ class RecoveryFlow:
|
||||
text = get_text_possible_pagination(self.debug, br)
|
||||
# TODO: make sure the translations fit on one page on TT
|
||||
if self.client.layout_type not in (LayoutType.TT, LayoutType.Mercury):
|
||||
TR.assert_in(text, "recovery__dry_run_slip39_valid_mismatch")
|
||||
assert TR.recovery__dry_run_slip39_valid_mismatch in text
|
||||
self.debug.press_yes()
|
||||
|
||||
def warning_bip39_dryrun_mismatch(self) -> BRGeneratorType:
|
||||
@ -276,7 +277,7 @@ class RecoveryFlow:
|
||||
text = get_text_possible_pagination(self.debug, br)
|
||||
# TODO: make sure the translations fit on one page
|
||||
if self.client.layout_type not in (LayoutType.TT, LayoutType.Mercury):
|
||||
TR.assert_in(text, "recovery__dry_run_bip39_valid_mismatch")
|
||||
assert TR.recovery__dry_run_bip39_valid_mismatch in text
|
||||
self.debug.press_yes()
|
||||
|
||||
def success_more_shares_needed(
|
||||
@ -352,7 +353,7 @@ class EthereumFlow:
|
||||
|
||||
def confirm_data(self, info: bool = False, cancel: bool = False) -> BRGeneratorType:
|
||||
assert (yield).name == "confirm_data"
|
||||
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||
assert self.debug.read_layout().title() == TR.ethereum__title_input_data
|
||||
if info:
|
||||
self.debug.press_info()
|
||||
elif cancel:
|
||||
@ -364,7 +365,7 @@ class EthereumFlow:
|
||||
br = yield
|
||||
assert br.name == "confirm_data"
|
||||
assert br.pages is not None
|
||||
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||
assert self.debug.read_layout().title() == TR.ethereum__title_input_data
|
||||
for _ in range(br.pages):
|
||||
self.debug.read_layout()
|
||||
go_next(self.debug)
|
||||
@ -380,7 +381,7 @@ class EthereumFlow:
|
||||
assert br.name == "confirm_data"
|
||||
assert br.pages is not None
|
||||
assert br.pages > 2
|
||||
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||
assert self.debug.read_layout().title() == TR.ethereum__title_input_data
|
||||
if self.client.layout_type is LayoutType.TR:
|
||||
self.debug.press_right()
|
||||
self.debug.press_right()
|
||||
@ -398,15 +399,15 @@ class EthereumFlow:
|
||||
self, cancel: bool, info: bool, go_back_from_summary: bool
|
||||
) -> BRGeneratorType:
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
TR.assert_equals(self.debug.read_layout().title(), "words__address")
|
||||
assert self.debug.read_layout().title() == TR.words__address
|
||||
if cancel:
|
||||
self.debug.press_no()
|
||||
return
|
||||
|
||||
self.debug.press_yes()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
TR.assert_equals(self.debug.read_layout().title(), "words__title_summary")
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "send__maximum_fee")
|
||||
assert self.debug.read_layout().title() == TR.words__title_summary
|
||||
assert TR.send__maximum_fee in self.debug.read_layout().text_content()
|
||||
if go_back_from_summary:
|
||||
self.debug.press_no()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
@ -414,8 +415,8 @@ class EthereumFlow:
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
if info:
|
||||
self.debug.press_info()
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "ethereum__gas_limit")
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "ethereum__gas_price")
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_no()
|
||||
self.debug.press_yes()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
@ -424,16 +425,16 @@ class EthereumFlow:
|
||||
self, cancel: bool, info: bool, go_back_from_summary: bool
|
||||
) -> BRGeneratorType:
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
TR.assert_in_multiple(
|
||||
self.debug.read_layout().title(),
|
||||
["ethereum__interaction_contract", "words__recipient"],
|
||||
assert (
|
||||
TR.ethereum__interaction_contract in self.debug.read_layout().title()
|
||||
or TR.words__recipient in self.debug.read_layout().title()
|
||||
)
|
||||
if cancel:
|
||||
self.debug.press_left()
|
||||
return
|
||||
self.debug.press_right()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "send__maximum_fee")
|
||||
assert TR.send__maximum_fee in self.debug.read_layout().text_content()
|
||||
if go_back_from_summary:
|
||||
self.debug.press_left()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
@ -441,9 +442,9 @@ class EthereumFlow:
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "ethereum__gas_limit")
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
self.debug.press_right()
|
||||
TR.assert_in(self.debug.read_layout().text_content(), "ethereum__gas_price")
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_left()
|
||||
self.debug.press_left()
|
||||
self.debug.press_middle()
|
||||
@ -454,8 +455,8 @@ class EthereumFlow:
|
||||
) -> BRGeneratorType:
|
||||
assert (yield).name == "confirm_output"
|
||||
title = self.debug.read_layout().title()
|
||||
TR.assert_in(title, "words__address")
|
||||
TR.assert_in(title, "words__recipient")
|
||||
assert TR.words__address in title
|
||||
assert TR.words__recipient in title
|
||||
|
||||
if cancel:
|
||||
self.debug.press_no()
|
||||
@ -464,8 +465,8 @@ class EthereumFlow:
|
||||
self.debug.swipe_up()
|
||||
assert (yield).name == "confirm_total"
|
||||
layout = self.debug.read_layout()
|
||||
TR.assert_equals(layout.title(), "words__title_summary")
|
||||
TR.assert_in(layout.text_content(), "send__maximum_fee")
|
||||
assert layout.title() == TR.words__title_summary
|
||||
assert TR.send__maximum_fee in layout.text_content()
|
||||
if go_back_from_summary:
|
||||
self.debug.press_no()
|
||||
assert (yield).name == "confirm_ethereum_tx"
|
||||
@ -476,8 +477,8 @@ class EthereumFlow:
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||
text = self.debug.read_layout().text_content()
|
||||
TR.assert_in(text, "ethereum__gas_limit")
|
||||
TR.assert_in(text, "ethereum__gas_price")
|
||||
assert TR.ethereum__gas_limit in text
|
||||
assert TR.ethereum__gas_price in text
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.swipe_up()
|
||||
@ -507,21 +508,15 @@ class EthereumFlow:
|
||||
br = yield
|
||||
assert br.code == B.SignTx
|
||||
assert br.name == "confirm_ethereum_staking_tx"
|
||||
TR.assert_equals_multiple(
|
||||
self.debug.read_layout().title(),
|
||||
[
|
||||
"ethereum__staking_stake",
|
||||
"ethereum__staking_unstake",
|
||||
"ethereum__staking_claim",
|
||||
],
|
||||
assert self.debug.read_layout().title() in (
|
||||
TR.ethereum__staking_stake,
|
||||
TR.ethereum__staking_unstake,
|
||||
TR.ethereum__staking_claim,
|
||||
)
|
||||
TR.assert_equals_multiple(
|
||||
self.debug.read_layout().text_content(),
|
||||
[
|
||||
"ethereum__staking_stake_intro",
|
||||
"ethereum__staking_unstake_intro",
|
||||
"ethereum__staking_claim_intro",
|
||||
],
|
||||
assert self.debug.read_layout().text_content() in (
|
||||
TR.ethereum__staking_stake_intro,
|
||||
TR.ethereum__staking_unstake_intro,
|
||||
TR.ethereum__staking_claim_intro,
|
||||
)
|
||||
if self.client.layout_type is LayoutType.TT:
|
||||
# confirm intro
|
||||
@ -529,12 +524,9 @@ class EthereumFlow:
|
||||
self.debug.click(
|
||||
buttons.CORNER_BUTTON,
|
||||
)
|
||||
TR.assert_equals_multiple(
|
||||
self.debug.read_layout().title(),
|
||||
[
|
||||
"ethereum__staking_stake_address",
|
||||
"ethereum__staking_claim_address",
|
||||
],
|
||||
assert self.debug.read_layout().title() in (
|
||||
TR.ethereum__staking_stake_address,
|
||||
TR.ethereum__staking_claim_address,
|
||||
)
|
||||
self.debug.press_no()
|
||||
self.debug.press_yes()
|
||||
@ -543,12 +535,8 @@ class EthereumFlow:
|
||||
# confirm summary
|
||||
if info:
|
||||
self.debug.press_info()
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||
)
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||
)
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_no()
|
||||
self.debug.press_yes()
|
||||
yield
|
||||
@ -561,12 +549,9 @@ class EthereumFlow:
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||
TR.assert_equals_multiple(
|
||||
self.debug.read_layout().title(),
|
||||
[
|
||||
"ethereum__staking_stake_address",
|
||||
"ethereum__staking_claim_address",
|
||||
],
|
||||
assert self.debug.read_layout().title() in (
|
||||
TR.ethereum__staking_stake_address,
|
||||
TR.ethereum__staking_claim_address,
|
||||
)
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
@ -581,12 +566,8 @@ class EthereumFlow:
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||
)
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||
)
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.click(buttons.CORNER_BUTTON)
|
||||
self.debug.swipe_up()
|
||||
@ -598,12 +579,9 @@ class EthereumFlow:
|
||||
# confirm intro
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
TR.assert_equals_multiple(
|
||||
self.debug.read_layout().title(),
|
||||
[
|
||||
"ethereum__staking_stake_address",
|
||||
"ethereum__staking_claim_address",
|
||||
],
|
||||
assert self.debug.read_layout().title() in (
|
||||
TR.ethereum__staking_stake_address,
|
||||
TR.ethereum__staking_claim_address,
|
||||
)
|
||||
self.debug.press_left()
|
||||
self.debug.press_middle()
|
||||
@ -612,13 +590,9 @@ class EthereumFlow:
|
||||
# confirm summary
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||
)
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
self.debug.press_right()
|
||||
TR.assert_in(
|
||||
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||
)
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_left()
|
||||
self.debug.press_left()
|
||||
self.debug.press_middle()
|
||||
|
@ -1,4 +1,6 @@
|
||||
import json
|
||||
import re
|
||||
import threading
|
||||
import typing as t
|
||||
from hashlib import sha256
|
||||
from pathlib import Path
|
||||
@ -12,11 +14,13 @@ from . import common
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parent
|
||||
|
||||
TRANSLATIONS = ROOT / "core" / "translations"
|
||||
FONTS_DIR = TRANSLATIONS / "fonts"
|
||||
ORDER_FILE = TRANSLATIONS / "order.json"
|
||||
TRANSLATIONS_DIR = ROOT / "core" / "translations"
|
||||
FONTS_DIR = TRANSLATIONS_DIR / "fonts"
|
||||
ORDER_FILE = TRANSLATIONS_DIR / "order.json"
|
||||
|
||||
LANGUAGES = [file.stem for file in TRANSLATIONS.glob("??.json")]
|
||||
LANGUAGES = [file.stem for file in TRANSLATIONS_DIR.glob("??.json")]
|
||||
|
||||
_CURRENT_TRANSLATION = threading.local()
|
||||
|
||||
|
||||
def prepare_blob(
|
||||
@ -66,110 +70,57 @@ def set_language(client: Client, lang: str):
|
||||
language_data = build_and_sign_blob(lang, client)
|
||||
with client:
|
||||
device.change_language(client, language_data) # type: ignore
|
||||
_CURRENT_TRANSLATION.TR = TRANSLATIONS[lang]
|
||||
|
||||
|
||||
def get_lang_json(lang: str) -> translations.JsonDef:
|
||||
assert lang in LANGUAGES
|
||||
lang_json = json.loads((TRANSLATIONS / f"{lang}.json").read_text())
|
||||
lang_json = json.loads((TRANSLATIONS_DIR / f"{lang}.json").read_text())
|
||||
if (fonts_safe3 := lang_json.get("fonts", {}).get("##Safe3")) is not None:
|
||||
lang_json["fonts"]["T2B1"] = fonts_safe3
|
||||
lang_json["fonts"]["T3B1"] = fonts_safe3
|
||||
return lang_json
|
||||
|
||||
|
||||
def _get_all_language_data() -> list[dict[str, str]]:
|
||||
return [_get_language_data(language) for language in LANGUAGES]
|
||||
class Translation:
|
||||
FORMAT_STR_RE = re.compile(r"\\{\d+\\}")
|
||||
|
||||
def __init__(self, lang: str) -> None:
|
||||
self.lang = lang
|
||||
self.lang_json = get_lang_json(lang)
|
||||
|
||||
@property
|
||||
def translations(self) -> dict[str, str]:
|
||||
return self.lang_json["translations"]
|
||||
|
||||
def _translate_raw(self, key: str) -> str:
|
||||
tr = self.translations.get(key)
|
||||
if tr is not None:
|
||||
return tr
|
||||
if self.lang != "en":
|
||||
return TRANSLATIONS["en"]._translate_raw(key)
|
||||
raise KeyError(key)
|
||||
|
||||
def translate(self, key: str) -> str:
|
||||
tr = self._translate_raw(key)
|
||||
return tr.replace("\xa0", " ").strip()
|
||||
|
||||
def as_regexp(self, key: str) -> re.Pattern:
|
||||
tr = self.translate(key)
|
||||
re_safe = re.escape(tr)
|
||||
return re.compile(self.FORMAT_STR_RE.sub(r".*?", re_safe))
|
||||
|
||||
|
||||
def _get_language_data(lang: str) -> dict[str, str]:
|
||||
return get_lang_json(lang)["translations"]
|
||||
TRANSLATIONS = {lang: Translation(lang) for lang in LANGUAGES}
|
||||
|
||||
|
||||
all_language_data = _get_all_language_data()
|
||||
def translate(key: str) -> str:
|
||||
return _CURRENT_TRANSLATION.TR.translate(key)
|
||||
|
||||
|
||||
def _resolve_path_to_texts(
|
||||
path: str, template: t.Iterable[t.Any] = (), lower: bool = True
|
||||
) -> list[str]:
|
||||
texts: list[str] = []
|
||||
lookups = path.split(".")
|
||||
for language_data in all_language_data:
|
||||
language_data_missing = False
|
||||
data: dict[str, t.Any] | str = language_data
|
||||
for lookup in lookups:
|
||||
assert isinstance(data, dict), f"{lookup} is not a dict"
|
||||
if lookup not in data:
|
||||
language_data_missing = True
|
||||
break
|
||||
data = data[lookup]
|
||||
if language_data_missing:
|
||||
continue
|
||||
assert isinstance(data, str), f"{path} is not a string"
|
||||
if template:
|
||||
data = data.format(*template)
|
||||
texts.append(data)
|
||||
|
||||
if lower:
|
||||
texts = [t.lower() for t in texts]
|
||||
texts = [t.replace("\xa0", " ").strip() for t in texts]
|
||||
return texts
|
||||
def regexp(key: str) -> re.Pattern:
|
||||
return _CURRENT_TRANSLATION.TR.as_regexp(key)
|
||||
|
||||
|
||||
def assert_equals(text: str, path: str, template: t.Iterable[t.Any] = ()) -> None:
|
||||
# TODO: we can directly pass in the current device language
|
||||
texts = _resolve_path_to_texts(path, template)
|
||||
assert text.lower() in texts, f"{text} not found in {texts}"
|
||||
|
||||
|
||||
def assert_equals_multiple(
|
||||
text: str, paths: list[str], template: t.Iterable[t.Any] = ()
|
||||
) -> None:
|
||||
texts: list[str] = []
|
||||
for path in paths:
|
||||
texts += _resolve_path_to_texts(path, template)
|
||||
assert text.lower() in texts, f"{text} not found in {texts}"
|
||||
|
||||
|
||||
def assert_in(text: str, path: str, template: t.Iterable[t.Any] = ()) -> None:
|
||||
texts = _resolve_path_to_texts(path, template)
|
||||
for tt in texts:
|
||||
if tt in text.lower():
|
||||
return
|
||||
assert False, f"{text} not found in {texts}"
|
||||
|
||||
|
||||
def assert_in_multiple(
|
||||
text: str, paths: list[str], template: t.Iterable[t.Any] = ()
|
||||
) -> None:
|
||||
texts: list[str] = []
|
||||
for path in paths:
|
||||
texts += _resolve_path_to_texts(path, template)
|
||||
for tt in texts:
|
||||
if tt in text.lower():
|
||||
return
|
||||
assert False, f"{text} not found in {texts}"
|
||||
|
||||
|
||||
def assert_startswith(text: str, path: str, template: t.Iterable[t.Any] = ()) -> None:
|
||||
texts = _resolve_path_to_texts(path, template)
|
||||
for tt in texts:
|
||||
if text.lower().startswith(tt):
|
||||
return
|
||||
assert False, f"{text} not found in {texts}"
|
||||
|
||||
|
||||
def assert_template(text: str, template_path: str) -> None:
|
||||
templates = _resolve_path_to_texts(template_path)
|
||||
for tt in templates:
|
||||
# Checking at least the first part
|
||||
first_part = tt.split("{")[0]
|
||||
if text.lower().startswith(first_part):
|
||||
return
|
||||
assert False, f"{text} not found in {templates}"
|
||||
|
||||
|
||||
def translate(
|
||||
path: str, template: t.Iterable[t.Any] = (), lower: bool = False
|
||||
) -> list[str]:
|
||||
# Do not converting to lowercase, we want the exact value
|
||||
return _resolve_path_to_texts(path, template, lower=lower)
|
||||
def __getattr__(key: str) -> str:
|
||||
return translate(key)
|
||||
|
@ -2140,9 +2140,9 @@
|
||||
"T2T1_cs_reset_recovery-test_reset_bip39_t2.py::test_reset_device_192": "c3b4126112107622a4ae14343700000e67787f175c7273c0b81fc30320fd4659",
|
||||
"T2T1_cs_reset_recovery-test_reset_bip39_t2.py::test_reset_device_pin": "2e261c7367373888adc9d30baf7be99f89da114364a54dd096305ac76f5b02eb",
|
||||
"T2T1_cs_reset_recovery-test_reset_bip39_t2.py::test_reset_failed_check": "c15845c4d1a46c654b5bb4babed93974d4b7c68b6bb120c74d46a1ec924152ce",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_bip39.py::test_reset_recovery": "3d3c9ddad06542ed169c761779f8bd6a65484c23462aefba05b90df6135421c2",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_slip39_advanced.py::test_reset_recovery": "2d9efb84f2d69506875061f833cdf2dc5d717c006d4e021346c4c1b15a77fe17",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_slip39_basic.py::test_reset_recovery": "5af5fa1fb4e69036a2cb77234059253f539bc2024d2f5895559950876897eab8",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_bip39.py::test_reset_recovery": "7423b5a3985389a8d290b1bf46a63e895c1d10f5506c62db963cae47dc29ef54",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_slip39_advanced.py::test_reset_recovery": "3dd4bfeb88c50e5cd8cef1930c152b0d00f65a4ceed8ab47ab1915dc02c9064d",
|
||||
"T2T1_cs_reset_recovery-test_reset_recovery_slip39_basic.py::test_reset_recovery": "13432d5369619793e6d362259b004a249b00ef0d0505e15b65b0b2d9f1181653",
|
||||
"T2T1_cs_reset_recovery-test_reset_slip39_advanced.py::test_reset_device_slip39_advanced": "747fa7c7cea4b886102440f1b56f84f00f60609243c7044c42a1d65261d6b93b",
|
||||
"T2T1_cs_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic": "d9f64781fddcd204ec6be552593edfbf6a9f680f6f4fd79058b94317ed29fa23",
|
||||
"T2T1_cs_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic_256": "8d61ac2c62b0009340d7c2a3559440a24f74af3c0a783a35df26ab72f12f7bf7",
|
||||
|
Loading…
Reference in New Issue
Block a user