mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-22 18:19:03 +00:00
feat(tests): eckhart tests
add Eckhart screen buttons rename passphrase click test file + fixtures eckhart click tests eckhart persistance tests eckhart device tests skip tests for unimplemented features
This commit is contained in:
parent
ca421dbabc
commit
69004f450f
@ -120,6 +120,7 @@ Arguments can be a list of internal model names, or one of the following shortcu
|
||||
* `safe` - Trezor Safe family
|
||||
* `safe3` - Trezor Safe 3 (covers T2B1 and T2T1)
|
||||
* `delizia` - covers the `delizia` UI (currently T3T1 only)
|
||||
* `eckhart` - covers the `eckhart` UI (currently T3W1 only)
|
||||
|
||||
You can specify a list as positional arguments, and exclude from it via `skip` keyword argument.
|
||||
|
||||
|
@ -403,6 +403,20 @@ class LayoutContent(UnstructuredJSONReader):
|
||||
return ""
|
||||
return footer.get("description", "") + " " + footer.get("instruction", "")
|
||||
|
||||
def action_bar(self) -> str:
|
||||
action_bar = self.find_unique_object_with_key_and_value(
|
||||
"component", "ActionBar"
|
||||
)
|
||||
if not action_bar:
|
||||
return ""
|
||||
right_button = action_bar.get("right_button", "")
|
||||
left_button = action_bar.get("left_button", "")
|
||||
if isinstance(left_button, dict):
|
||||
left_button = left_button.get("text", "")
|
||||
if isinstance(right_button, dict):
|
||||
right_button = right_button.get("text", "")
|
||||
return left_button + " " + right_button
|
||||
|
||||
|
||||
def multipage_content(layouts: list[LayoutContent]) -> str:
|
||||
"""Get overall content from multiple-page layout."""
|
||||
@ -829,7 +843,10 @@ class DebugUI:
|
||||
# Paginating (going as further as possible) and pressing Yes
|
||||
if br.pages is not None:
|
||||
for _ in range(br.pages - 1):
|
||||
self.debuglink.swipe_up()
|
||||
if self.debuglink.model is models.T3W1:
|
||||
self.debuglink.click(self.debuglink.screen_buttons.ok())
|
||||
else:
|
||||
self.debuglink.swipe_up()
|
||||
|
||||
if self.debuglink.model is models.T3T1:
|
||||
layout = self.debuglink.read_layout()
|
||||
@ -839,6 +856,12 @@ class DebugUI:
|
||||
self.debuglink.swipe_up()
|
||||
else:
|
||||
self.debuglink.press_yes()
|
||||
elif self.debuglink.model is models.T3W1:
|
||||
layout = self.debuglink.read_layout()
|
||||
if "TextComponent" in layout.all_components():
|
||||
self.debuglink.click(self.debuglink.screen_buttons.ok())
|
||||
else:
|
||||
self.debuglink.press_yes()
|
||||
else:
|
||||
self.debuglink.press_yes()
|
||||
|
||||
@ -1413,14 +1436,24 @@ def optiga_set_sec_max(client: "TrezorClient") -> None:
|
||||
|
||||
class ScreenButtons:
|
||||
def __init__(self, layout_type: LayoutType):
|
||||
assert layout_type in (LayoutType.Bolt, LayoutType.Delizia)
|
||||
assert layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart)
|
||||
self.layout_type = layout_type
|
||||
|
||||
def _width(self) -> int:
|
||||
return 240
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return 240
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return 380
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
def _height(self) -> int:
|
||||
return 240
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return 240
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return 520
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
def _grid(self, dim: int, grid_cells: int, cell: int) -> int:
|
||||
assert cell < grid_cells
|
||||
@ -1430,13 +1463,24 @@ class ScreenButtons:
|
||||
|
||||
# 3 columns, 4 rows, 1st row is input area
|
||||
def _grid35(self, x: int, y: int) -> Coords:
|
||||
assert x < 3, y < 5
|
||||
return self._grid(self._width(), 3, x), self._grid(self._height(), 5, y)
|
||||
|
||||
def _grid55(self, x: int, y: int) -> Coords:
|
||||
assert x < 5, y < 5
|
||||
return self._grid(self._width(), 5, x), self._grid(self._height(), 5, y)
|
||||
|
||||
# TODO: do not expose this
|
||||
# 3 columns, 3 rows, 1st row is input area
|
||||
def grid34(self, x: int, y: int) -> Coords:
|
||||
assert x < 3, y < 4
|
||||
return self._grid(self._width(), 3, x), self._grid(self._height(), 4, y)
|
||||
|
||||
# 2 columns, 3 rows, first two are header and description
|
||||
def _grid25(self, x: int, y: int) -> Coords:
|
||||
assert x < 2, y < 5
|
||||
return self._grid(self._width(), 2, x), self._grid(self._height(), 5, y)
|
||||
|
||||
# Horizontal coordinates
|
||||
def _left(self) -> int:
|
||||
return self._grid(self._width(), 3, 0)
|
||||
@ -1470,10 +1514,7 @@ class ScreenButtons:
|
||||
|
||||
# Menu/close menu button
|
||||
def menu(self) -> Coords:
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return (215, 25)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
return self._grid55(4, 0)
|
||||
|
||||
# Center of the screen
|
||||
def tap_to_confirm(self) -> Coords:
|
||||
@ -1482,12 +1523,20 @@ class ScreenButtons:
|
||||
|
||||
# Yes/No decision component
|
||||
def ui_yes(self) -> Coords:
|
||||
assert self.layout_type is LayoutType.Delizia
|
||||
return self.grid34(2, 2)
|
||||
if self.layout_type is LayoutType.Delizia:
|
||||
return self.grid34(2, 2)
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self.ok()
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
def ui_no(self) -> Coords:
|
||||
assert self.layout_type is LayoutType.Delizia
|
||||
return self.grid34(0, 2)
|
||||
if self.layout_type is LayoutType.Delizia:
|
||||
return self.grid34(0, 2)
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self.cancel()
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
# +/- buttons in number input component
|
||||
def number_input_minus(self) -> Coords:
|
||||
@ -1495,6 +1544,8 @@ class ScreenButtons:
|
||||
return (self._left(), self._grid(self._height(), 5, 1))
|
||||
elif self.layout_type is LayoutType.Delizia:
|
||||
return (self._left(), self._grid(self._height(), 5, 3))
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self.grid34(0, 2)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1503,6 +1554,8 @@ class ScreenButtons:
|
||||
return (self._right(), self._grid(self._height(), 5, 1))
|
||||
elif self.layout_type is LayoutType.Delizia:
|
||||
return (self._right(), self._grid(self._height(), 5, 3))
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self.grid34(2, 2)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1524,6 +1577,14 @@ class ScreenButtons:
|
||||
24: self.grid34(2, 2),
|
||||
33: self.grid34(2, 3),
|
||||
}
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
coords_map = {
|
||||
12: self._grid35(0, 2),
|
||||
18: self._grid35(2, 2),
|
||||
20: self._grid35(0, 3),
|
||||
24: self._grid35(2, 3),
|
||||
33: self._grid35(2, 4),
|
||||
}
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1532,10 +1593,10 @@ class ScreenButtons:
|
||||
def word_count_all_cancel(self) -> Coords:
|
||||
if self.layout_type is LayoutType.Bolt:
|
||||
return self.grid34(0, 3)
|
||||
|
||||
elif self.layout_type is LayoutType.Delizia:
|
||||
return self.grid34(0, 3)
|
||||
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self._grid35(0, 4)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1551,6 +1612,11 @@ class ScreenButtons:
|
||||
20: self.grid34(0, 1),
|
||||
33: self.grid34(2, 1),
|
||||
}
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
coords_map = {
|
||||
20: self._grid35(1, 2),
|
||||
33: self._grid35(1, 3),
|
||||
}
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1559,16 +1625,22 @@ class ScreenButtons:
|
||||
def word_count_repeated_cancel(self) -> Coords:
|
||||
if self.layout_type is LayoutType.Bolt:
|
||||
return self.grid34(0, 2)
|
||||
|
||||
elif self.layout_type is LayoutType.Delizia:
|
||||
return self.grid34(0, 3)
|
||||
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self._grid35(1, 4)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
# select word component buttons
|
||||
def word_check_words(self) -> "list[Coords]":
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return [
|
||||
(self._mid(), self._grid(self._height(), 4, 1)),
|
||||
(self._mid(), self._grid(self._height(), 4, 2)),
|
||||
(self._mid(), self._grid(self._height(), 4, 3)),
|
||||
]
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return [
|
||||
(self._mid(), self._grid(self._height(), 5, 2)),
|
||||
(self._mid(), self._grid(self._height(), 5, 3)),
|
||||
@ -1579,13 +1651,20 @@ class ScreenButtons:
|
||||
|
||||
# vertical menu buttons
|
||||
def vertical_menu_items(self) -> "list[Coords]":
|
||||
assert self.layout_type is LayoutType.Delizia
|
||||
|
||||
return [
|
||||
(self._mid(), self._grid(self._height(), 4, 1)),
|
||||
(self._mid(), self._grid(self._height(), 4, 2)),
|
||||
(self._mid(), self._grid(self._height(), 4, 3)),
|
||||
]
|
||||
if self.layout_type is LayoutType.Delizia:
|
||||
return [
|
||||
(self._mid(), self._grid(self._height(), 4, 1)),
|
||||
(self._mid(), self._grid(self._height(), 4, 2)),
|
||||
(self._mid(), self._grid(self._height(), 4, 3)),
|
||||
]
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return [
|
||||
(self._mid(), self._grid(self._height(), 5, 1)),
|
||||
(self._mid(), self._grid(self._height(), 5, 2)),
|
||||
(self._mid(), self._grid(self._height(), 5, 3)),
|
||||
]
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
# Pin/passphrase keyboards
|
||||
def pin_passphrase_index(self, idx: int) -> Coords:
|
||||
@ -1595,7 +1674,6 @@ class ScreenButtons:
|
||||
return self.pin_passphrase_grid(idx % 3, idx // 3)
|
||||
|
||||
def pin_passphrase_grid(self, x: int, y: int) -> Coords:
|
||||
assert x < 3, y < 4
|
||||
y += 1 # first line is empty
|
||||
return self._grid35(x, y)
|
||||
|
||||
@ -1607,10 +1685,10 @@ class ScreenButtons:
|
||||
return self.pin_passphrase_grid(0, 3)
|
||||
|
||||
def passphrase_confirm(self) -> Coords:
|
||||
if self.layout_type is LayoutType.Bolt:
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
return self.pin_passphrase_grid(2, 3)
|
||||
elif self.layout_type is LayoutType.Delizia:
|
||||
return (215, 25)
|
||||
return self._grid55(4, 0)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -1619,19 +1697,34 @@ class ScreenButtons:
|
||||
|
||||
# Mnemonic keyboard
|
||||
def mnemonic_from_index(self, idx: int) -> Coords:
|
||||
assert idx < 9
|
||||
return self.mnemonic_grid(idx)
|
||||
|
||||
def mnemonic_grid(self, idx: int) -> Coords:
|
||||
assert idx < 9
|
||||
grid_x = idx % 3
|
||||
grid_y = idx // 3 + 1 # first line is empty
|
||||
return self.grid34(grid_x, grid_y)
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return self.grid34(grid_x, grid_y)
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self._grid35(grid_x, grid_y)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
def mnemonic_erase(self) -> Coords:
|
||||
return (self._left(), self._top())
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return (self._left(), self._top())
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self._grid35(0, 4)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
def mnemonic_confirm(self) -> Coords:
|
||||
return (self._mid(), self._top())
|
||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
return (self._mid(), self._top())
|
||||
elif self.layout_type is LayoutType.Eckhart:
|
||||
return self._grid35(2, 4)
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
|
||||
BUTTON_LETTERS_BIP39 = ("abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz")
|
||||
@ -1639,9 +1732,9 @@ BUTTON_LETTERS_SLIP39 = ("ab", "cd", "ef", "ghij", "klm", "nopq", "rs", "tuv", "
|
||||
|
||||
# fmt: off
|
||||
PASSPHRASE_LOWERCASE_BOLT = (" ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", "*#")
|
||||
PASSPHRASE_LOWERCASE_DELIZIA = ("abc", "def", "ghi", "jkl", "mno", "pq", "rst", "uvw", "xyz", " *#")
|
||||
PASSPHRASE_LOWERCASE_DE = ("abc", "def", "ghi", "jkl", "mno", "pq", "rst", "uvw", "xyz", " *#")
|
||||
PASSPHRASE_UPPERCASE_BOLT = (" ", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ", "*#")
|
||||
PASSPHRASE_UPPERCASE_DELIZIA = ("ABC", "DEF", "GHI", "JKL", "MNO", "PQ", "RST", "UVW", "XYZ", " *#")
|
||||
PASSPHRASE_UPPERCASE_DE = ("ABC", "DEF", "GHI", "JKL", "MNO", "PQ", "RST", "UVW", "XYZ", " *#")
|
||||
PASSPHRASE_DIGITS = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||
PASSPHRASE_SPECIAL = ("_<>", ".:@", "/|\\", "!()", "+%&", "-[]", "?{}", ",'`", ";\"~", "$^=")
|
||||
# fmt: on
|
||||
@ -1655,15 +1748,15 @@ class ButtonActions:
|
||||
if char in " *#" or char.islower():
|
||||
if self.buttons.layout_type is LayoutType.Bolt:
|
||||
return PASSPHRASE_LOWERCASE_BOLT
|
||||
elif self.buttons.layout_type is LayoutType.Delizia:
|
||||
return PASSPHRASE_LOWERCASE_DELIZIA
|
||||
elif self.buttons.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
return PASSPHRASE_LOWERCASE_DE
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
elif char.isupper():
|
||||
if self.buttons.layout_type is LayoutType.Bolt:
|
||||
return PASSPHRASE_UPPERCASE_BOLT
|
||||
elif self.buttons.layout_type is LayoutType.Delizia:
|
||||
return PASSPHRASE_UPPERCASE_DELIZIA
|
||||
elif self.buttons.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
return PASSPHRASE_UPPERCASE_DE
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
elif char.isdigit():
|
||||
|
@ -91,7 +91,7 @@ T3B1 = TrezorModel(
|
||||
)
|
||||
|
||||
T3W1 = TrezorModel(
|
||||
name="T3W1",
|
||||
name="Safe 7",
|
||||
internal_name="T3W1",
|
||||
minimum_version=(2, 1, 0),
|
||||
vendors=VENDORS,
|
||||
|
@ -47,7 +47,7 @@ def get_char_category(char: str) -> PassphraseCategory:
|
||||
|
||||
|
||||
def go_next(debug: "DebugLink") -> LayoutContent:
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_right()
|
||||
@ -59,7 +59,7 @@ def go_next(debug: "DebugLink") -> LayoutContent:
|
||||
|
||||
|
||||
def go_back(debug: "DebugLink", r_middle: bool = False) -> LayoutContent:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.cancel())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
if r_middle:
|
||||
@ -114,7 +114,7 @@ def _carousel_steps(current_index: int, wanted_index: int, length: int) -> int:
|
||||
|
||||
|
||||
def unlock_gesture(debug: "DebugLink") -> LayoutContent:
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_right()
|
||||
|
@ -15,11 +15,15 @@ DELETE_BTN_TEXTS = ("inputs__delete", "inputs__previous")
|
||||
def enter_word(
|
||||
debug: "DebugLink", word: str, is_slip39: bool = False
|
||||
) -> "LayoutContent":
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
typed_word = word[:4]
|
||||
for coords in debug.button_actions.type_word(typed_word, is_slip39=is_slip39):
|
||||
debug.click(coords)
|
||||
if debug.layout_type is LayoutType.Delizia and not is_slip39 and len(word) > 4:
|
||||
if (
|
||||
debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart)
|
||||
and not is_slip39
|
||||
and len(word) > 4
|
||||
):
|
||||
# T3T1 (delizia) BIP39 keyboard allows to "confirm" only if the word is fully written, you need to click the word to auto-complete
|
||||
debug.click(debug.screen_buttons.mnemonic_confirm())
|
||||
debug.click(debug.screen_buttons.mnemonic_confirm())
|
||||
@ -53,7 +57,7 @@ def enter_word(
|
||||
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
|
||||
layout = debug.read_layout()
|
||||
assert TR.translate(title) == layout.title()
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
@ -80,7 +84,7 @@ def cancel_select_number_of_words(
|
||||
assert layout.title() == TR.word_count__title
|
||||
# navigate to the number and confirm it
|
||||
debug.press_left()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
# click the button from ValuePad
|
||||
if unlock_repeated_backup:
|
||||
coords = debug.screen_buttons.word_count_repeated_cancel()
|
||||
@ -99,7 +103,12 @@ def select_number_of_words(
|
||||
layout = debug.read_layout()
|
||||
assert TR.recovery__num_of_words in layout.text_content()
|
||||
|
||||
def select_bolt() -> "LayoutContent":
|
||||
def select_bde() -> "LayoutContent":
|
||||
assert debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
)
|
||||
# click the button from ValuePad
|
||||
if unlock_repeated_backup:
|
||||
coords = debug.screen_buttons.word_count_repeated_word(num_of_words)
|
||||
@ -110,6 +119,7 @@ def select_number_of_words(
|
||||
return debug.read_layout()
|
||||
|
||||
def select_caesar() -> "LayoutContent":
|
||||
assert debug.layout_type is LayoutType.Caesar
|
||||
# navigate to the number and confirm it
|
||||
word_options = (20, 33) if unlock_repeated_backup else (12, 18, 20, 24, 33)
|
||||
index = word_options.index(num_of_words)
|
||||
@ -118,24 +128,13 @@ def select_number_of_words(
|
||||
debug.press_middle()
|
||||
return debug.read_layout()
|
||||
|
||||
def select_delizia() -> "LayoutContent":
|
||||
# click the button from ValuePad
|
||||
if unlock_repeated_backup:
|
||||
coords = debug.screen_buttons.word_count_repeated_word(num_of_words)
|
||||
else:
|
||||
coords = debug.screen_buttons.word_count_all_word(num_of_words)
|
||||
debug.click(coords)
|
||||
return debug.read_layout()
|
||||
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
layout = select_bolt()
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
layout = select_bde()
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_right()
|
||||
layout = debug.read_layout()
|
||||
assert layout.title() == TR.word_count__title
|
||||
layout = select_caesar()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
layout = select_delizia()
|
||||
else:
|
||||
raise ValueError("Unknown model")
|
||||
|
||||
@ -168,7 +167,11 @@ def enter_share(
|
||||
is_first: bool = True,
|
||||
before_title: str = "recovery__title_recover",
|
||||
) -> "LayoutContent":
|
||||
if debug.layout_type is LayoutType.Caesar:
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
assert TR.translate(before_title) in debug.read_layout().title()
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
assert TR.translate(before_title) in debug.read_layout().title()
|
||||
layout = debug.read_layout()
|
||||
for _ in range(layout.page_count()):
|
||||
@ -177,10 +180,11 @@ def enter_share(
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
layout = debug.read_layout()
|
||||
else:
|
||||
assert TR.translate(before_title) in debug.read_layout().title()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
layout = debug.read_layout()
|
||||
else:
|
||||
raise ValueError("Unknown model")
|
||||
|
||||
assert "MnemonicKeyboard" in layout.all_components()
|
||||
|
||||
@ -210,12 +214,18 @@ def enter_shares(
|
||||
)
|
||||
if index < len(shares) - 1:
|
||||
# FIXME: when ui-t3t1 done for shamir, we want to check the template below
|
||||
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)),
|
||||
# )
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
assert (
|
||||
TR.translate("recovery__x_of_y_entered_template").format(
|
||||
index + 1, len(shares)
|
||||
)
|
||||
in debug.read_layout().text_content()
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
TR.translate(enter_share_before_title)
|
||||
in debug.read_layout().title()
|
||||
)
|
||||
|
||||
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
||||
|
||||
@ -231,7 +241,6 @@ def enter_seed(
|
||||
|
||||
for word in seed_words:
|
||||
enter_word(debug, word, is_slip39=is_slip39)
|
||||
|
||||
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
||||
|
||||
|
||||
@ -272,8 +281,8 @@ def enter_seed_previous_correct(
|
||||
layout = debug.read_layout()
|
||||
debug.press_middle()
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.click(debug.screen_buttons.mnemonic_erase()) # Top-left
|
||||
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.mnemonic_erase())
|
||||
for _ in range(len(bad_word)):
|
||||
debug.click(debug.screen_buttons.mnemonic_erase())
|
||||
continue
|
||||
@ -299,7 +308,7 @@ def prepare_enter_seed(
|
||||
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.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
@ -310,6 +319,8 @@ def prepare_enter_seed(
|
||||
debug.press_right()
|
||||
layout = debug.read_layout()
|
||||
assert "MnemonicKeyboard" in layout.all_components()
|
||||
else:
|
||||
raise ValueError("Unknown model")
|
||||
|
||||
|
||||
def finalize(debug: "DebugLink") -> None:
|
||||
@ -336,7 +347,7 @@ def cancel_recovery(debug: "DebugLink", recovery_type: str = "dry_run") -> None:
|
||||
assert cancel_title in layout.title()
|
||||
for _ in range(layout.page_count()):
|
||||
debug.press_right()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
# go to menu
|
||||
debug.click(debug.screen_buttons.menu())
|
||||
layout = debug.read_layout()
|
||||
|
@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
||||
|
||||
def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||
assert debug.read_layout().title() == TR.reset__title_create_wallet
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
@ -27,13 +27,13 @@ def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||
)
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
|
||||
def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None:
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
page_count = debug.read_layout().page_count()
|
||||
if page_count > 1:
|
||||
@ -43,6 +43,10 @@ def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None:
|
||||
debug.press_middle()
|
||||
else:
|
||||
debug.press_right()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def cancel_backup(
|
||||
@ -51,20 +55,29 @@ def cancel_backup(
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
debug.click(debug.screen_buttons.cancel())
|
||||
debug.click(debug.screen_buttons.cancel())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_left()
|
||||
debug.press_left()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.click(debug.screen_buttons.menu())
|
||||
debug.click(debug.screen_buttons.vertical_menu_items()[0])
|
||||
if confirm:
|
||||
debug.swipe_up()
|
||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_left()
|
||||
debug.press_left()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.menu())
|
||||
debug.click(debug.screen_buttons.vertical_menu_items()[0])
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def set_selection(debug: "DebugLink", diff: int) -> None:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
assert "NumberInputDialog" in debug.read_layout().all_components()
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
assert "NumberInputScreen" in debug.read_layout().all_components()
|
||||
else:
|
||||
assert "NumberInputDialog" in debug.read_layout().all_components()
|
||||
|
||||
button = (
|
||||
debug.screen_buttons.number_input_minus()
|
||||
@ -75,7 +88,7 @@ def set_selection(debug: "DebugLink", diff: int) -> None:
|
||||
|
||||
for _ in range(diff):
|
||||
debug.click(button)
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
else:
|
||||
debug.swipe_up()
|
||||
@ -96,6 +109,8 @@ def set_selection(debug: "DebugLink", diff: int) -> None:
|
||||
for _ in range(diff):
|
||||
debug.press_right()
|
||||
debug.press_middle()
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
||||
@ -105,23 +120,31 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
||||
debug.press_right()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
# Swiping through all the pages and loading the words
|
||||
layout = debug.read_layout()
|
||||
for _ in range(layout.page_count() - 1):
|
||||
words.extend(layout.seed_words())
|
||||
debug.swipe_up()
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
else:
|
||||
debug.swipe_up()
|
||||
|
||||
layout = debug.read_layout()
|
||||
assert layout is not None
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
words.extend(layout.seed_words())
|
||||
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
# There is hold-to-confirm button
|
||||
if do_htc:
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok(), hold_ms=1500)
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||
@ -138,6 +161,12 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
||||
def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
debug.swipe_up()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
# Press ok if the select word screen is not yet present
|
||||
if not TR.regexp("reset__select_word_template").match(
|
||||
debug.read_layout().subtitle()
|
||||
):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
layout = debug.read_layout()
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
@ -158,22 +187,6 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
debug.click(debug.screen_buttons.word_check_words()[button_pos])
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
assert TR.regexp("reset__select_word_x_of_y_template").match(layout.subtitle())
|
||||
for _ in range(3):
|
||||
# "Select word 3 of 20"
|
||||
# ^
|
||||
word_pos_match = re.search(r"\d+", debug.read_layout().subtitle())
|
||||
assert word_pos_match is not None
|
||||
word_pos = int(word_pos_match.group(0))
|
||||
# Unifying both the buttons and words to lowercase
|
||||
btn_texts = [
|
||||
text.lower() for text in layout.tt_check_seed_button_contents()
|
||||
]
|
||||
wanted_word = words[word_pos - 1].lower()
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
debug.click(debug.screen_buttons.vertical_menu_items()[button_pos])
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
assert TR.reset__select_correct_word in layout.text_content()
|
||||
debug.press_right()
|
||||
@ -193,6 +206,43 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||
|
||||
debug.press_middle()
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
assert TR.regexp("reset__select_word_x_of_y_template").match(layout.subtitle())
|
||||
for _ in range(3):
|
||||
# "Select word 3 of 20"
|
||||
# ^
|
||||
word_pos_match = re.search(r"\d+", debug.read_layout().subtitle())
|
||||
assert word_pos_match is not None
|
||||
word_pos = int(word_pos_match.group(0))
|
||||
# Unifying both the buttons and words to lowercase
|
||||
btn_texts = [
|
||||
text.lower() for text in layout.tt_check_seed_button_contents()
|
||||
]
|
||||
wanted_word = words[word_pos - 1].lower()
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
debug.click(debug.screen_buttons.word_check_words()[button_pos])
|
||||
layout = debug.read_layout()
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
assert TR.regexp("reset__select_word_template").match(
|
||||
debug.read_layout().subtitle()
|
||||
)
|
||||
|
||||
for _ in range(3):
|
||||
# "Select word 3 of 20"
|
||||
# ^
|
||||
word_pos_match = re.search(r"\d+", debug.read_layout().subtitle())
|
||||
assert word_pos_match is not None
|
||||
word_pos = int(word_pos_match.group(0))
|
||||
# Unifying both the buttons and words to lowercase
|
||||
btn_texts = [
|
||||
text.lower() for text in layout.tt_check_seed_button_contents()
|
||||
]
|
||||
wanted_word = words[word_pos - 1].lower()
|
||||
button_pos = btn_texts.index(wanted_word)
|
||||
debug.click(debug.screen_buttons.word_check_words()[button_pos])
|
||||
layout = debug.read_layout()
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def validate_mnemonics(mnemonics: list[str], expected_ems: bytes) -> None:
|
||||
|
@ -74,7 +74,7 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int)
|
||||
debug.input("1234")
|
||||
|
||||
assert TR.regexp("auto_lock__change_template").match(
|
||||
debug.read_layout().text_content()
|
||||
debug.read_layout().text_content().strip()
|
||||
)
|
||||
|
||||
layout = go_next(debug)
|
||||
@ -113,7 +113,7 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
||||
in debug.read_layout().text_content().replace(" ", "")
|
||||
)
|
||||
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
layout = debug.read_layout()
|
||||
@ -131,6 +131,8 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
||||
layout = debug.read_layout()
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
|
||||
# wait for autolock to kick in
|
||||
time.sleep(10.1)
|
||||
@ -168,7 +170,7 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
||||
in debug.read_layout().text_content().replace(" ", "")
|
||||
)
|
||||
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
layout = debug.read_layout()
|
||||
@ -187,6 +189,8 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
||||
layout = debug.read_layout()
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
|
||||
def sleepy_filter(msg: MessageType) -> MessageType:
|
||||
time.sleep(10.1)
|
||||
@ -196,12 +200,14 @@ 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.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_middle()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
|
||||
signatures, tx = device_handler.result()
|
||||
assert len(signatures) == 1
|
||||
@ -227,7 +233,11 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
||||
# 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.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
# click at "j"
|
||||
debug.click(_passphrase_j(debug))
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
@ -235,10 +245,13 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
||||
# NOTE: because of passphrase randomization it would be a pain to input
|
||||
# a specific passphrase, which is not in scope for this test.
|
||||
debug.press_right()
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
|
||||
time.sleep(1.5)
|
||||
|
||||
# Send the passphrase to the client (TT has it clicked already, TR needs to input it)
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.passphrase_confirm())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.input("j" * 8)
|
||||
@ -264,15 +277,24 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
||||
# enter passphrase - slowly
|
||||
# autolock must activate even if we pressed some buttons
|
||||
for _ in range(math.ceil(6 / 1.5)):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
debug.click(_center_button(debug))
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_middle()
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
time.sleep(1.5)
|
||||
|
||||
# wait for autolock to kick in
|
||||
time.sleep(10.1)
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
assert debug.read_layout().main_component() == "Homescreen"
|
||||
else:
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device_handler.result()
|
||||
|
||||
@ -303,7 +325,10 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
|
||||
|
||||
# wait for autolock to trigger
|
||||
time.sleep(10.1)
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
assert debug.read_layout().main_component() == "Homescreen"
|
||||
else:
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device_handler.result()
|
||||
|
||||
@ -333,17 +358,22 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"):
|
||||
# select 20 words
|
||||
recovery.select_number_of_words(debug, 20)
|
||||
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
layout = go_next(debug)
|
||||
assert layout.main_component() == "MnemonicKeyboard"
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_right()
|
||||
layout = debug.read_layout()
|
||||
assert "MnemonicKeyboard" in layout.all_components()
|
||||
else:
|
||||
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||
|
||||
# make sure keyboard locks
|
||||
time.sleep(10.1)
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
if debug.layout_type is LayoutType.Eckhart:
|
||||
assert debug.read_layout().main_component() == "Homescreen"
|
||||
else:
|
||||
assert debug.read_layout().main_component() == "Lockscreen"
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device_handler.result()
|
||||
|
||||
@ -360,7 +390,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
|
||||
# select 20 words
|
||||
recovery.select_number_of_words(debug, 20)
|
||||
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
layout = debug.read_layout()
|
||||
assert layout.main_component() == "MnemonicKeyboard"
|
||||
@ -409,6 +439,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4)
|
||||
@pytest.mark.models(skip=["eckhart"])
|
||||
def test_autolock_does_not_interrupt_preauthorized(
|
||||
device_handler: "BackgroundDeviceHandler",
|
||||
):
|
||||
|
@ -80,7 +80,7 @@ def test_backup_slip39_custom(
|
||||
# confirm backup configuration
|
||||
if share_count > 1:
|
||||
assert TR.regexp("reset__create_x_of_y_multi_share_backup_template").match(
|
||||
debug.read_layout().text_content()
|
||||
debug.read_layout().text_content().strip()
|
||||
)
|
||||
else:
|
||||
assert TR.regexp("backup__info_single_share_backup").match(
|
||||
@ -106,9 +106,12 @@ def test_backup_slip39_custom(
|
||||
all_words.append(" ".join(words))
|
||||
|
||||
# confirm backup done
|
||||
if debug.layout_type is LayoutType.Delizia and share_count > 1:
|
||||
if (
|
||||
debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart)
|
||||
and share_count > 1
|
||||
):
|
||||
reset.confirm_read(debug)
|
||||
elif debug.layout_type is not LayoutType.Delizia:
|
||||
elif debug.layout_type not in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
reset.confirm_read(debug)
|
||||
|
||||
# generate secret locally
|
||||
|
@ -49,14 +49,14 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
||||
models.T3B1: 1200,
|
||||
models.T2T1: 3500,
|
||||
models.T3T1: 3500,
|
||||
models.T3W1: 3500,
|
||||
models.T3W1: 2000,
|
||||
}[debug.model]
|
||||
|
||||
def hold(duration: int) -> None:
|
||||
if debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_right(hold_ms=duration)
|
||||
else:
|
||||
debug.click((13, 37), hold_ms=duration)
|
||||
debug.click(debug.screen_buttons.grid34(1, 1), hold_ms=duration)
|
||||
|
||||
assert device_handler.features().unlocked is False
|
||||
|
||||
|
@ -31,7 +31,7 @@ if TYPE_CHECKING:
|
||||
from ..device_handler import BackgroundDeviceHandler
|
||||
|
||||
|
||||
pytestmark = pytest.mark.models("t2t1", "delizia")
|
||||
pytestmark = pytest.mark.models("t2t1", "delizia", "eckhart")
|
||||
|
||||
KEYBOARD_CATEGORIES_BOLT = [
|
||||
PassphraseCategory.DIGITS,
|
||||
@ -40,7 +40,8 @@ KEYBOARD_CATEGORIES_BOLT = [
|
||||
PassphraseCategory.SPECIAL,
|
||||
]
|
||||
|
||||
KEYBOARD_CATEGORIES_DELIZIA = [
|
||||
# Common for Delizia and Eckhart
|
||||
KEYBOARD_CATEGORIES_DE = [
|
||||
PassphraseCategory.LOWERCASE,
|
||||
PassphraseCategory.UPPERCASE,
|
||||
PassphraseCategory.DIGITS,
|
||||
@ -90,8 +91,8 @@ def prepare_passphrase_dialogue(
|
||||
def keyboard_categories(layout_type: LayoutType) -> list[PassphraseCategory]:
|
||||
if layout_type is LayoutType.Bolt:
|
||||
return KEYBOARD_CATEGORIES_BOLT
|
||||
elif layout_type is LayoutType.Delizia:
|
||||
return KEYBOARD_CATEGORIES_DELIZIA
|
||||
elif layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
return KEYBOARD_CATEGORIES_DE
|
||||
else:
|
||||
raise ValueError("Wrong layout type")
|
||||
|
||||
@ -157,7 +158,7 @@ def enter_passphrase(debug: "DebugLink") -> None:
|
||||
"""Enter a passphrase"""
|
||||
is_empty: bool = len(debug.read_layout().passphrase()) == 0
|
||||
debug.click(debug.screen_buttons.passphrase_confirm())
|
||||
if is_empty and debug.layout_type is LayoutType.Delizia:
|
||||
if is_empty and debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.ui_yes())
|
||||
|
||||
|
||||
@ -200,7 +201,7 @@ def test_passphrase_delete(device_handler: "BackgroundDeviceHandler"):
|
||||
|
||||
for _ in range(4):
|
||||
delete_char(debug)
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.read_layout()
|
||||
|
||||
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
||||
@ -231,7 +232,7 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
||||
PassphraseCategory.SPECIAL,
|
||||
):
|
||||
go_to_category(debug, category)
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.read_layout()
|
||||
|
||||
enter_passphrase(debug)
|
@ -95,7 +95,7 @@ def prepare(
|
||||
# Any action triggering the PIN dialogue
|
||||
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
||||
tap = True
|
||||
if situation == Situation.PIN_INPUT_CANCEL:
|
||||
elif situation == Situation.PIN_INPUT_CANCEL:
|
||||
# Any action triggering the PIN dialogue
|
||||
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
||||
elif situation == Situation.PIN_SETUP:
|
||||
@ -105,13 +105,19 @@ def prepare(
|
||||
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.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
go_next(debug)
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
go_next(debug)
|
||||
go_next(debug)
|
||||
go_next(debug)
|
||||
go_next(debug)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
elif situation == Situation.PIN_CHANGE:
|
||||
# Change PIN
|
||||
device_handler.run(device.change_pin) # type: ignore
|
||||
@ -153,7 +159,7 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None:
|
||||
"""Input the PIN"""
|
||||
if check:
|
||||
before = debug.read_layout().pin()
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
digits_order = debug.read_layout().tt_pin_digits_order()
|
||||
for digit in pin:
|
||||
digit_index = digits_order.index(digit)
|
||||
@ -162,6 +168,8 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None:
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
for digit in pin:
|
||||
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
if check:
|
||||
after = debug.read_layout().pin()
|
||||
@ -170,10 +178,12 @@ 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.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.pin_passphrase_input())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
navigate_to_action_and_press(debug, SHOW, TR_PIN_ACTIONS)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def _delete_pin(debug: "DebugLink", digits_to_delete: int, check: bool = True) -> None:
|
||||
@ -182,10 +192,16 @@ 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.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
debug.click(debug.screen_buttons.pin_passphrase_erase())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
if check:
|
||||
after = debug.read_layout().pin()
|
||||
@ -194,13 +210,15 @@ 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.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(
|
||||
debug.screen_buttons.pin_passphrase_erase(),
|
||||
hold_ms=1500,
|
||||
)
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS, hold_ms=1000)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
if check:
|
||||
after = debug.read_layout().pin()
|
||||
@ -221,10 +239,12 @@ def _cancel_pin(debug: "DebugLink") -> None:
|
||||
|
||||
def _confirm_pin(debug: "DebugLink") -> None:
|
||||
"""Navigate to "ENTER" and press it"""
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
debug.click(debug.screen_buttons.pin_confirm())
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
def _input_see_confirm(debug: "DebugLink", pin: str) -> None:
|
||||
@ -326,15 +346,18 @@ 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.layout_type is LayoutType.Bolt:
|
||||
if debug.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
go_next(debug)
|
||||
_cancel_pin(debug)
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
debug.press_middle()
|
||||
debug.press_no()
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
go_next(debug)
|
||||
_cancel_pin(debug)
|
||||
else:
|
||||
raise RuntimeError("Unknown model")
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin="1")
|
||||
|
@ -210,6 +210,8 @@ def read_and_confirm_mnemonic(
|
||||
mnemonic = yield from read_mnemonic_from_screen_caesar(debug)
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
mnemonic = yield from read_mnemonic_from_screen_delizia(debug)
|
||||
elif debug.layout_type is LayoutType.Eckhart:
|
||||
mnemonic = yield from read_mnemonic_from_screen_eckhart(debug)
|
||||
else:
|
||||
raise ValueError(f"Unknown model: {debug.layout_type}")
|
||||
|
||||
@ -277,6 +279,25 @@ def read_mnemonic_from_screen_delizia(
|
||||
return mnemonic
|
||||
|
||||
|
||||
def read_mnemonic_from_screen_eckhart(
|
||||
debug: "DebugLink",
|
||||
) -> Generator[None, "ButtonRequest", list[str]]:
|
||||
mnemonic: list[str] = []
|
||||
br = yield
|
||||
assert br.pages is not None
|
||||
|
||||
debug.read_layout()
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
for _ in range(br.pages - 2):
|
||||
words = debug.read_layout().seed_words()
|
||||
mnemonic.extend(words)
|
||||
debug.click(debug.screen_buttons.ok())
|
||||
|
||||
debug.press_yes()
|
||||
return mnemonic
|
||||
|
||||
|
||||
def check_share(
|
||||
debug: "DebugLink", mnemonic: list[str], choose_wrong: bool = False
|
||||
) -> bool:
|
||||
@ -294,7 +315,7 @@ def check_share(
|
||||
elif debug.layout_type is LayoutType.Caesar:
|
||||
# other models have the instruction in the title/subtitle
|
||||
word_pos_match = re.search(re_num_of_word, debug.read_layout().title())
|
||||
elif debug.layout_type is LayoutType.Delizia:
|
||||
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
word_pos_match = re.search(re_num_of_word, debug.read_layout().subtitle())
|
||||
else:
|
||||
word_pos_match = None
|
||||
@ -319,7 +340,7 @@ def click_info_button_bolt(debug: "DebugLink") -> Generator[Any, Any, ButtonRequ
|
||||
return (yield)
|
||||
|
||||
|
||||
def click_info_button_delizia(debug: "DebugLink"):
|
||||
def click_info_button_delizia_eckhart(debug: "DebugLink"):
|
||||
"""Click Shamir backup info button and return back."""
|
||||
debug.click(debug.screen_buttons.menu())
|
||||
layout = debug.read_layout()
|
||||
|
@ -178,7 +178,7 @@ class ModelsFilter:
|
||||
"t1": {models.T1B1},
|
||||
"t2": {models.T2T1},
|
||||
"tt": {models.T2T1},
|
||||
"safe": {models.T2B1, models.T3T1, models.T3B1},
|
||||
"safe": {models.T2B1, models.T3T1, models.T3B1, models.T3W1},
|
||||
"safe3": {models.T2B1, models.T3B1},
|
||||
"safe5": {models.T3T1},
|
||||
"delizia": {models.T3T1},
|
||||
|
@ -27,7 +27,7 @@ BINANCE_PATH = parse_path("m/44h/714h/0h/0/0")
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.binance
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
@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.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
@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"
|
||||
)
|
||||
|
@ -34,6 +34,8 @@ from .signtx import (
|
||||
request_output,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
B = messages.ButtonRequestType
|
||||
|
||||
TX_CACHE_TESTNET = TxCache("Testnet")
|
||||
|
@ -153,6 +153,9 @@ VECTORS_DESCRIPTORS = ( # coin, account, script_type, descriptors
|
||||
)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
|
||||
def _address_n(purpose, coin, account, script_type):
|
||||
res = [H_(purpose), H_(0) if coin == "Bitcoin" else H_(1), H_(account)]
|
||||
if purpose == 10025 and script_type == messages.InputScriptType.SPENDTAPROOT:
|
||||
|
@ -244,7 +244,7 @@ VECTORS_MULTISIG = ( # script_type, bip48_type, address, xpubs, ignore_xpub_mag
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize(
|
||||
"script_type, bip48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG
|
||||
|
@ -24,6 +24,8 @@ from ...common import is_core
|
||||
from ...input_flows import InputFlowConfirmAllWarnings
|
||||
from .signtx import forge_prevtx
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
VECTORS = ( # path, script_types
|
||||
# GreenAddress A m/[1,4]/address_index
|
||||
(
|
||||
|
@ -35,6 +35,8 @@ from ...input_flows import (
|
||||
|
||||
S = messages.InputScriptType
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
|
||||
def case(
|
||||
id: str,
|
||||
@ -406,7 +408,7 @@ def test_signmessage_pagination(client: Client, message: str, is_long: bool):
|
||||
|
||||
# We cannot differentiate between a newline and space in the message read from Trezor.
|
||||
# TODO: do the check also for T2B1
|
||||
if client.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if client.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||
message_read = IF.message_read.replace(" ", "").replace("...", "")
|
||||
signed_message = message.replace("\n", "").replace(" ", "")
|
||||
assert signed_message in message_read
|
||||
|
@ -1613,7 +1613,7 @@ def test_information_cancel(client: Client):
|
||||
|
||||
@pytest.mark.models(
|
||||
"core",
|
||||
skip="delizia",
|
||||
skip=["delizia", "eckhart"],
|
||||
reason="Cannot test layouts on T1, not implemented in Delizia UI",
|
||||
)
|
||||
def test_information_replacement(client: Client):
|
||||
|
@ -33,7 +33,7 @@ PREV_HASH, PREV_TX = forge_prevtx([(INPUT_ADDRESS, 12_300_000)], network="testne
|
||||
PREV_TXES = {PREV_HASH: PREV_TX}
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.models("core"), pytest.mark.experimental]
|
||||
pytestmark = [pytest.mark.models("core", skip=["eckhart"]), pytest.mark.experimental]
|
||||
|
||||
|
||||
def case(id, *args, altcoin: bool = False, models: str | None = None):
|
||||
|
@ -32,6 +32,8 @@ from .signtx import (
|
||||
request_output,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
B = messages.ButtonRequestType
|
||||
|
||||
TX_CACHE_TESTNET = TxCache("Testnet")
|
||||
|
@ -23,6 +23,8 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
from ...input_flows import InputFlowSignVerifyMessageLong
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
|
||||
@pytest.mark.models("legacy")
|
||||
def test_message_long_legacy(client: Client):
|
||||
|
@ -14,9 +14,13 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
|
||||
def test_message_long(client: Client):
|
||||
ret = btc.verify_message(
|
||||
|
@ -14,9 +14,13 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
|
||||
def test_message_long(client: Client):
|
||||
ret = btc.verify_message(
|
||||
|
@ -32,7 +32,7 @@ from ...input_flows import InputFlowShowXpubQRCode
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.cardano,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ from ...common import MNEMONIC_SLIP39_BASIC_20_3of6
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.cardano,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
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.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ from ...input_flows import InputFlowConfirmAllWarnings
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.cardano,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ def show_details_input_flow(client: Client):
|
||||
elif client.layout_type is LayoutType.Caesar:
|
||||
# Caesar - right button for "Show all"
|
||||
client.debug.press_yes()
|
||||
elif client.layout_type is LayoutType.Delizia:
|
||||
elif client.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
# Delizia - "Show all" button from context menu
|
||||
client.debug.click(client.debug.screen_buttons.menu())
|
||||
client.debug.click(client.debug.screen_buttons.vertical_menu_items()[0])
|
||||
|
@ -26,7 +26,7 @@ from ...input_flows import InputFlowShowXpubQRCode
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.eos
|
||||
@pytest.mark.models("t2t1")
|
||||
@pytest.mark.models("t2t1", skip=["eckhart"])
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_eos_get_public_key(client: Client):
|
||||
with client:
|
||||
|
@ -29,7 +29,7 @@ ADDRESS_N = parse_path("m/44h/194h/0h/0/0")
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.eos,
|
||||
pytest.mark.models("t2t1"),
|
||||
pytest.mark.models("t2t1", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -13,7 +13,11 @@ from ...input_flows import InputFlowConfirmAllWarnings
|
||||
from . import common
|
||||
from .test_sign_typed_data import DATA as TYPED_DATA
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
ERC20_OPERATION = "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b0000000000000000000000000000000000000000000000000000000000000123"
|
||||
ERC20_BUILTIN_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7" # USDT
|
||||
|
@ -13,7 +13,11 @@ from trezorlib.tools import parse_path
|
||||
from .common import make_defs, make_network, make_payload, make_token, sign_payload
|
||||
from .test_definitions import DEFAULT_ERC20_PARAMS, ERC20_FAKE_ADDRESS
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
def fails(client: Client, network: bytes, match: str) -> None:
|
||||
|
@ -23,7 +23,11 @@ from trezorlib.tools import parse_path
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
from ...input_flows import InputFlowShowAddressQRCode
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures("ethereum/getaddress.json")
|
||||
|
@ -23,7 +23,11 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures("ethereum/getpublickey.json")
|
||||
|
@ -23,7 +23,11 @@ from trezorlib.tools import parse_path
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
from ...input_flows import InputFlowEIP712Cancel, InputFlowEIP712ShowMore
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
|
@ -24,7 +24,11 @@ from trezorlib.tools import parse_path
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
from ...input_flows import InputFlowSignVerifyMessageLong
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures("ethereum/signmessage.json")
|
||||
|
@ -37,7 +37,11 @@ from .common import encode_network
|
||||
TO_ADDR = "0x1d1c328764a41bda0492b66baa30c4a339ff85ef"
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ethereum,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
def make_defs(parameters: dict) -> messages.EthereumDefinitions:
|
||||
|
@ -28,7 +28,10 @@ from ...common import MNEMONIC12
|
||||
def test_encrypt(client: Client):
|
||||
def input_flow():
|
||||
assert (yield).name == "cipher_key_value"
|
||||
assert client.debug.read_layout().text_content() == TR.misc__enable_labeling
|
||||
assert (
|
||||
client.debug.read_layout().text_content().strip()
|
||||
== TR.misc__enable_labeling
|
||||
)
|
||||
client.debug.swipe_up()
|
||||
client.debug.press_yes()
|
||||
|
||||
|
@ -41,7 +41,7 @@ TEST_VECTORS = [
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.monero,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.monero
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
@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,7 +25,7 @@ from ...common import MNEMONIC12
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.models("t1b1", "t2t1")
|
||||
@pytest.mark.models("t1b1", "t2t1", skip=["eckhart"])
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
@pytest.mark.parametrize("chunkify", (True, False))
|
||||
def test_nem_getaddress(client: Client, chunkify: bool):
|
||||
|
@ -27,7 +27,7 @@ ADDRESS_N = parse_path("m/44h/1h/0h/0h/0h")
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.models("t1b1", "t2t1"),
|
||||
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.models("t1b1", "t2t1"),
|
||||
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.models("t1b1", "t2t1"),
|
||||
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12, is_core
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.models("t1b1", "t2t1"),
|
||||
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
@ -22,7 +22,7 @@ import pytest
|
||||
from trezorlib import messages, nostr
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.models("core")]
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.models("core", skip=["eckhart"])]
|
||||
|
||||
# test data from NIP-06: https://github.com/nostr-protocol/nips/blob/master/06.md
|
||||
|
||||
|
@ -34,6 +34,7 @@ from ...input_flows import (
|
||||
InputFlowSlip39BasicRecoveryInvalidSecondShare,
|
||||
InputFlowSlip39BasicRecoveryNoAbort,
|
||||
InputFlowSlip39BasicRecoverySameShare,
|
||||
InputFlowSlip39BasicRecoveryShareInfoBetweenShares,
|
||||
InputFlowSlip39BasicRecoveryWrongNthWord,
|
||||
)
|
||||
|
||||
@ -147,6 +148,20 @@ def test_abort_between_shares(client: Client):
|
||||
assert client.features.recovery_status is messages.RecoveryStatus.Nothing
|
||||
|
||||
|
||||
@pytest.mark.models("eckhart")
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_share_info_between_shares(client: Client):
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicRecoveryShareInfoBetweenShares(
|
||||
client, MNEMONIC_SLIP39_BASIC_20_3of6
|
||||
)
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(client, pin_protection=False, label="label")
|
||||
client.init_device()
|
||||
assert client.features.initialized is False
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_noabort(client: Client):
|
||||
with client:
|
||||
|
@ -255,6 +255,10 @@ def test_already_initialized(client: Client):
|
||||
def test_entropy_check(client: Client):
|
||||
with client:
|
||||
delizia = client.debug.layout_type is LayoutType.Delizia
|
||||
delizia_eckhart = client.debug.layout_type in (
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(name="setup_device"),
|
||||
@ -271,7 +275,7 @@ def test_entropy_check(client: Client):
|
||||
messages.EntropyCheckReady,
|
||||
messages.PublicKey,
|
||||
messages.PublicKey,
|
||||
(delizia, messages.ButtonRequest(name="backup_device")),
|
||||
(delizia_eckhart, messages.ButtonRequest(name="backup_device")),
|
||||
messages.Success,
|
||||
messages.Features,
|
||||
]
|
||||
@ -291,13 +295,17 @@ def test_entropy_check(client: Client):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_no_entropy_check(client: Client):
|
||||
with client:
|
||||
delizia_eckhart = client.debug.layout_type in (
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
)
|
||||
delizia = client.debug.layout_type is LayoutType.Delizia
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(name="setup_device"),
|
||||
(delizia, messages.ButtonRequest(name="confirm_setup_device")),
|
||||
messages.EntropyRequest,
|
||||
(delizia, messages.ButtonRequest(name="backup_device")),
|
||||
(delizia_eckhart, messages.ButtonRequest(name="backup_device")),
|
||||
messages.Success,
|
||||
messages.Features,
|
||||
]
|
||||
|
@ -31,7 +31,7 @@ CUSTOM_MNEMONIC = (
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ripple,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
# 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.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.solana,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.solana,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -29,7 +29,7 @@ from .construct.transaction import Message, RawInstruction
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.solana,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -64,6 +64,7 @@ from ...input_flows import InputFlowShowAddressQRCode
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.stellar,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
from ..common import compact_size
|
||||
|
||||
pytestmark = pytest.mark.models("safe")
|
||||
pytestmark = pytest.mark.models("safe", skip=["eckhart"])
|
||||
|
||||
ROOT_PUBLIC_KEY = {
|
||||
models.T2B1: bytes.fromhex(
|
||||
|
@ -23,6 +23,8 @@ from trezorlib.debuglink import LayoutType
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
PIN = "1234"
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ def test_cancel_message_via_initialize(client: Client, message):
|
||||
assert isinstance(resp, m.Features)
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
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
|
||||
|
@ -5,6 +5,8 @@ import pytest
|
||||
from trezorlib import firmware, models
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||
|
||||
# size of FIRMWARE_AREA, see core/embed/models/model_*_layout.c
|
||||
FIRMWARE_LENGTHS = {
|
||||
models.T1B1: 7 * 128 * 1024 + 64 * 1024,
|
||||
|
@ -35,7 +35,7 @@ from ..translations import (
|
||||
sign_blob,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.models("core")
|
||||
pytestmark = pytest.mark.models("core", skip=["eckhart"])
|
||||
|
||||
|
||||
MAX_DATA_LENGTH = {
|
||||
|
@ -203,7 +203,7 @@ def test_apply_homescreen_toif(client: Client):
|
||||
device.apply_settings(client, homescreen=img)
|
||||
|
||||
|
||||
@pytest.mark.models(skip=["legacy", "safe3"])
|
||||
@pytest.mark.models(skip=["legacy", "safe3", "eckhart"])
|
||||
def test_apply_homescreen_jpeg(client: Client):
|
||||
with open(HERE / "test_bg.jpg", "rb") as f:
|
||||
img = f.read()
|
||||
@ -325,6 +325,7 @@ def test_apply_homescreen(client: Client):
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
@pytest.mark.models(skip="eckhart")
|
||||
def test_safety_checks(client: Client):
|
||||
def get_bad_address():
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44h"), show_display=True)
|
||||
@ -423,7 +424,7 @@ def test_label_too_long(client: Client):
|
||||
device.apply_settings(client, label="A" * 33)
|
||||
|
||||
|
||||
@pytest.mark.models(skip=["legacy", "safe3"])
|
||||
@pytest.mark.models(skip=["legacy", "safe3", "eckhart"])
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_set_brightness(client: Client):
|
||||
device.set_brightness(client, None)
|
||||
|
@ -68,6 +68,8 @@ def test_backup_bip39(client: Client):
|
||||
def test_backup_slip39_basic(client: Client, click_info: bool):
|
||||
if click_info and client.layout_type is LayoutType.Caesar:
|
||||
pytest.skip("click_info not implemented on T2B1")
|
||||
if click_info and client.layout_type is LayoutType.Eckhart:
|
||||
pytest.skip("click_info not yet implemented on T3W1")
|
||||
|
||||
assert client.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
@ -97,7 +99,10 @@ def test_backup_slip39_single(client: Client):
|
||||
|
||||
with client:
|
||||
IF = InputFlowBip39Backup(
|
||||
client, confirm_success=(client.layout_type is not LayoutType.Delizia)
|
||||
client,
|
||||
confirm_success=(
|
||||
client.layout_type not in (LayoutType.Delizia, LayoutType.Eckhart)
|
||||
),
|
||||
)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(client)
|
||||
@ -124,6 +129,8 @@ def test_backup_slip39_single(client: Client):
|
||||
def test_backup_slip39_advanced(client: Client, click_info: bool):
|
||||
if click_info and client.layout_type is LayoutType.Caesar:
|
||||
pytest.skip("click_info not implemented on T2B1")
|
||||
if click_info and client.layout_type is LayoutType.Eckhart:
|
||||
pytest.skip("click_info not yet implemented on T3W1")
|
||||
|
||||
assert client.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
|
@ -23,7 +23,10 @@ from trezorlib.messages import SdProtectOperationType as Op
|
||||
|
||||
from ..common import MNEMONIC12
|
||||
|
||||
pytestmark = [pytest.mark.models("core", skip="safe3"), pytest.mark.sd_card]
|
||||
pytestmark = [
|
||||
pytest.mark.models("core", skip=["safe3", "eckhart"]),
|
||||
pytest.mark.sd_card,
|
||||
]
|
||||
|
||||
|
||||
def test_enable_disable(client: Client):
|
||||
|
@ -21,7 +21,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
@pytest.mark.models("safe")
|
||||
@pytest.mark.models("safe", skip=["eckhart"])
|
||||
def test_tutorial(client: Client):
|
||||
device.show_device_tutorial(client)
|
||||
assert client.features.initialized is False
|
||||
|
@ -279,6 +279,7 @@ def test_recovery_device(client: Client):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.models(skip=["eckhart"])
|
||||
def test_sign_message(client: Client):
|
||||
_assert_protection(client)
|
||||
with client:
|
||||
@ -320,7 +321,7 @@ def test_verify_message_t1(client: Client):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
def test_verify_message_t2(client: Client):
|
||||
_assert_protection(client)
|
||||
with client:
|
||||
|
@ -23,7 +23,7 @@ from trezorlib.messages import SdProtectOperationType as Op
|
||||
|
||||
from .. import translations as TR
|
||||
|
||||
pytestmark = pytest.mark.models("core", skip="safe3")
|
||||
pytestmark = pytest.mark.models("core", skip=["safe3", "eckhart"])
|
||||
|
||||
|
||||
@pytest.mark.sd_card(formatted=False)
|
||||
|
@ -399,7 +399,11 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
yield
|
||||
content = client.debug.read_layout().text_content().lower()
|
||||
assert TR.passphrase__from_host_not_shown[:50].lower() in content
|
||||
if client.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||
if client.layout_type in (
|
||||
LayoutType.Bolt,
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
client.debug.press_yes()
|
||||
elif client.layout_type is LayoutType.Caesar:
|
||||
client.debug.press_right()
|
||||
|
@ -25,7 +25,7 @@ from ...input_flows import InputFlowShowAddressQRCode
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.tezos,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
TEST_VECTORS = [
|
||||
|
@ -23,7 +23,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.tezos
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
def test_tezos_get_public_key(client: Client):
|
||||
path = parse_path("m/44h/1729h/0h")
|
||||
pk = get_public_key(client, path)
|
||||
|
@ -28,7 +28,7 @@ TEZOS_PATH_15 = parse_path("m/44h/1729h/15h")
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.tezos,
|
||||
pytest.mark.models("core"),
|
||||
pytest.mark.models("core", skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ from .data_webauthn import CRED1, CRED2, CRED3, CREDS
|
||||
RK_CAPACITY = 100
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.models("core", skip=["eckhart"])
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_add_remove(client: Client):
|
||||
|
@ -21,6 +21,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.models(skip=["eckhart"])
|
||||
def test_u2f_counter(client: Client):
|
||||
assert fido.get_next_counter(client) == 0
|
||||
assert fido.get_next_counter(client) == 1
|
||||
|
@ -50,7 +50,11 @@ TXHASH_4b6cec = bytes.fromhex(
|
||||
VERSION_GROUP_ID = 0x26A7270A
|
||||
BRANCH_ID = 0xC2D6D0B4
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.zcash]
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.zcash,
|
||||
pytest.mark.models(skip=["eckhart"]),
|
||||
]
|
||||
|
||||
|
||||
def test_version_group_id_missing(client: Client):
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -99,7 +99,7 @@ class RecoveryFlow:
|
||||
|
||||
def enter_your_backup(self) -> BRGeneratorType:
|
||||
assert (yield).name == "recovery"
|
||||
if self.debug.layout_type is LayoutType.Delizia:
|
||||
if self.debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
assert TR.recovery__enter_each_word in self._text_content()
|
||||
else:
|
||||
assert TR.recovery__enter_backup in self._text_content()
|
||||
@ -131,7 +131,16 @@ class RecoveryFlow:
|
||||
|
||||
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
||||
yield
|
||||
if self.client.layout_type is LayoutType.Caesar:
|
||||
if self.client.layout_type is LayoutType.Bolt:
|
||||
assert TR.recovery__enter_any_share in self._text_content()
|
||||
self.debug.press_no()
|
||||
yield
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
if confirm:
|
||||
self.debug.press_yes()
|
||||
else:
|
||||
self.debug.press_no()
|
||||
elif self.client.layout_type is LayoutType.Caesar:
|
||||
assert TR.recovery__num_of_words in self._text_content()
|
||||
self.debug.press_no()
|
||||
yield
|
||||
@ -141,7 +150,7 @@ class RecoveryFlow:
|
||||
self.debug.press_yes()
|
||||
else:
|
||||
self.debug.press_no()
|
||||
elif self.client.layout_type is LayoutType.Delizia:
|
||||
elif self.client.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
assert TR.recovery__enter_each_word in self._text_content()
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
@ -150,18 +159,19 @@ class RecoveryFlow:
|
||||
else:
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
else:
|
||||
assert TR.recovery__enter_any_share in self._text_content()
|
||||
self.debug.press_no()
|
||||
yield
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
if confirm:
|
||||
self.debug.press_yes()
|
||||
else:
|
||||
self.debug.press_no()
|
||||
raise ValueError("Unknown model!")
|
||||
|
||||
def abort_recovery_between_shares(self) -> BRGeneratorType:
|
||||
yield
|
||||
if self.client.layout_type is LayoutType.Caesar:
|
||||
if self.client.layout_type is LayoutType.Bolt:
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.press_no()
|
||||
assert (yield).name == "abort_recovery"
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
self.debug.press_yes()
|
||||
elif self.client.layout_type is LayoutType.Caesar:
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
@ -182,14 +192,36 @@ class RecoveryFlow:
|
||||
layout = self.debug.read_layout()
|
||||
assert layout.title() == TR.recovery__title_cancel_recovery
|
||||
self.debug.click(self.debug.screen_buttons.tap_to_confirm())
|
||||
else:
|
||||
elif self.client.layout_type is LayoutType.Eckhart:
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.press_no()
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[1])
|
||||
assert (yield).name == "abort_recovery"
|
||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
||||
self.debug.press_yes()
|
||||
layout = self.debug.read_layout()
|
||||
assert layout.title() == TR.recovery__title
|
||||
self.debug.click(self.debug.screen_buttons.ok())
|
||||
else:
|
||||
raise ValueError("Unknown model!")
|
||||
|
||||
def share_info_between_shares(self) -> BRGeneratorType:
|
||||
yield
|
||||
if self.client.layout_type is LayoutType.Eckhart:
|
||||
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||
self._text_content()
|
||||
)
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[0])
|
||||
assert (yield).name == "recovery_share"
|
||||
layout = self.debug.read_layout()
|
||||
assert layout.title() == TR.words__recovery_share
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
else:
|
||||
raise ValueError("Unsupported model!")
|
||||
|
||||
def input_number_of_words(self, num_words: int | None) -> BRGeneratorType:
|
||||
br = yield
|
||||
@ -321,10 +353,11 @@ class RecoveryFlow:
|
||||
if click_info:
|
||||
if self.client.layout_type is LayoutType.Bolt:
|
||||
yield from self.click_info_bolt()
|
||||
elif self.client.layout_type is LayoutType.Delizia:
|
||||
yield from self.click_info_delizia()
|
||||
else:
|
||||
raise ValueError("Unknown model!")
|
||||
elif self.client.layout_type in (
|
||||
LayoutType.Delizia,
|
||||
LayoutType.Eckhart,
|
||||
):
|
||||
yield from self.click_info_delizia_eckhart()
|
||||
yield from self.success_more_shares_needed()
|
||||
|
||||
def click_info_bolt(self) -> t.Generator[t.Any, t.Any, None]:
|
||||
@ -335,7 +368,7 @@ class RecoveryFlow:
|
||||
self.debug.swipe_up()
|
||||
self.debug.press_yes()
|
||||
|
||||
def click_info_delizia(self) -> BRGeneratorType:
|
||||
def click_info_delizia_eckhart(self) -> BRGeneratorType:
|
||||
# Moving through the menu into the show_shares screen
|
||||
self.debug.click(self.debug.screen_buttons.menu())
|
||||
self.debug.synchronize_at("VerticalMenu")
|
||||
@ -550,6 +583,31 @@ class EthereumFlow:
|
||||
|
||||
self.debug.press_yes()
|
||||
|
||||
elif self.client.layout_type is LayoutType.Caesar:
|
||||
# confirm intro
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
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()
|
||||
yield
|
||||
|
||||
# confirm summary
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
self.debug.press_right()
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_left()
|
||||
self.debug.press_left()
|
||||
self.debug.press_middle()
|
||||
yield
|
||||
|
||||
self.debug.press_yes()
|
||||
|
||||
elif self.client.layout_type is LayoutType.Delizia:
|
||||
# confirm intro
|
||||
if info:
|
||||
@ -582,30 +640,5 @@ class EthereumFlow:
|
||||
|
||||
self.debug.press_yes()
|
||||
|
||||
elif self.client.layout_type is LayoutType.Caesar:
|
||||
# confirm intro
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
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()
|
||||
yield
|
||||
|
||||
# confirm summary
|
||||
if info:
|
||||
self.debug.press_right()
|
||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||
self.debug.press_right()
|
||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||
self.debug.press_left()
|
||||
self.debug.press_left()
|
||||
self.debug.press_middle()
|
||||
yield
|
||||
|
||||
self.debug.press_yes()
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown model!")
|
||||
|
@ -40,7 +40,7 @@ def test_abort(core_emulator: Emulator):
|
||||
debug = device_handler.debuglink()
|
||||
features = device_handler.features()
|
||||
|
||||
if debug.layout_type is LayoutType.Delizia:
|
||||
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
pytest.skip("abort not supported on T3T1")
|
||||
|
||||
assert features.recovery_status == RecoveryStatus.Nothing
|
||||
@ -187,7 +187,7 @@ def test_recovery_multiple_resets(core_emulator: Emulator):
|
||||
shares = MNEMONIC_SLIP39_ADVANCED_20
|
||||
layout = debug.read_layout()
|
||||
expected_text = "Enter any share"
|
||||
if debug.layout_type == LayoutType.Delizia:
|
||||
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||
expected_text = "Enter each word"
|
||||
remaining = len(shares)
|
||||
for share in shares:
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user