mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-24 17:58:45 +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
1da20c8c07
commit
0d7605f3e4
@ -120,6 +120,7 @@ Arguments can be a list of internal model names, or one of the following shortcu
|
|||||||
* `safe` - Trezor Safe family
|
* `safe` - Trezor Safe family
|
||||||
* `safe3` - Trezor Safe 3 (covers T2B1 and T2T1)
|
* `safe3` - Trezor Safe 3 (covers T2B1 and T2T1)
|
||||||
* `delizia` - covers the `delizia` UI (currently T3T1 only)
|
* `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.
|
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 ""
|
||||||
return footer.get("description", "") + " " + footer.get("instruction", "")
|
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:
|
def multipage_content(layouts: list[LayoutContent]) -> str:
|
||||||
"""Get overall content from multiple-page layout."""
|
"""Get overall content from multiple-page layout."""
|
||||||
@ -829,6 +843,9 @@ class DebugUI:
|
|||||||
# Paginating (going as further as possible) and pressing Yes
|
# Paginating (going as further as possible) and pressing Yes
|
||||||
if br.pages is not None:
|
if br.pages is not None:
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
|
if self.debuglink.model is models.T3W1:
|
||||||
|
self.debuglink.click(self.debuglink.screen_buttons.ok())
|
||||||
|
else:
|
||||||
self.debuglink.swipe_up()
|
self.debuglink.swipe_up()
|
||||||
|
|
||||||
if self.debuglink.model is models.T3T1:
|
if self.debuglink.model is models.T3T1:
|
||||||
@ -839,6 +856,12 @@ class DebugUI:
|
|||||||
self.debuglink.swipe_up()
|
self.debuglink.swipe_up()
|
||||||
else:
|
else:
|
||||||
self.debuglink.press_yes()
|
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:
|
else:
|
||||||
self.debuglink.press_yes()
|
self.debuglink.press_yes()
|
||||||
|
|
||||||
@ -1413,14 +1436,24 @@ def optiga_set_sec_max(client: "TrezorClient") -> None:
|
|||||||
|
|
||||||
class ScreenButtons:
|
class ScreenButtons:
|
||||||
def __init__(self, layout_type: LayoutType):
|
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
|
self.layout_type = layout_type
|
||||||
|
|
||||||
def _width(self) -> int:
|
def _width(self) -> int:
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return 240
|
return 240
|
||||||
|
elif self.layout_type is LayoutType.Eckhart:
|
||||||
|
return 380
|
||||||
|
else:
|
||||||
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
def _height(self) -> int:
|
def _height(self) -> int:
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return 240
|
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:
|
def _grid(self, dim: int, grid_cells: int, cell: int) -> int:
|
||||||
assert cell < grid_cells
|
assert cell < grid_cells
|
||||||
@ -1430,13 +1463,24 @@ class ScreenButtons:
|
|||||||
|
|
||||||
# 3 columns, 4 rows, 1st row is input area
|
# 3 columns, 4 rows, 1st row is input area
|
||||||
def _grid35(self, x: int, y: int) -> Coords:
|
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)
|
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
|
# TODO: do not expose this
|
||||||
# 3 columns, 3 rows, 1st row is input area
|
# 3 columns, 3 rows, 1st row is input area
|
||||||
def grid34(self, x: int, y: int) -> Coords:
|
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)
|
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
|
# Horizontal coordinates
|
||||||
def _left(self) -> int:
|
def _left(self) -> int:
|
||||||
return self._grid(self._width(), 3, 0)
|
return self._grid(self._width(), 3, 0)
|
||||||
@ -1470,10 +1514,7 @@ class ScreenButtons:
|
|||||||
|
|
||||||
# Menu/close menu button
|
# Menu/close menu button
|
||||||
def menu(self) -> Coords:
|
def menu(self) -> Coords:
|
||||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
return self._grid55(4, 0)
|
||||||
return (215, 25)
|
|
||||||
else:
|
|
||||||
raise ValueError("Wrong layout type")
|
|
||||||
|
|
||||||
# Center of the screen
|
# Center of the screen
|
||||||
def tap_to_confirm(self) -> Coords:
|
def tap_to_confirm(self) -> Coords:
|
||||||
@ -1482,12 +1523,20 @@ class ScreenButtons:
|
|||||||
|
|
||||||
# Yes/No decision component
|
# Yes/No decision component
|
||||||
def ui_yes(self) -> Coords:
|
def ui_yes(self) -> Coords:
|
||||||
assert self.layout_type is LayoutType.Delizia
|
if self.layout_type is LayoutType.Delizia:
|
||||||
return self.grid34(2, 2)
|
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:
|
def ui_no(self) -> Coords:
|
||||||
assert self.layout_type is LayoutType.Delizia
|
if self.layout_type is LayoutType.Delizia:
|
||||||
return self.grid34(0, 2)
|
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
|
# +/- buttons in number input component
|
||||||
def number_input_minus(self) -> Coords:
|
def number_input_minus(self) -> Coords:
|
||||||
@ -1495,6 +1544,8 @@ class ScreenButtons:
|
|||||||
return (self._left(), self._grid(self._height(), 5, 1))
|
return (self._left(), self._grid(self._height(), 5, 1))
|
||||||
elif self.layout_type is LayoutType.Delizia:
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
return (self._left(), self._grid(self._height(), 5, 3))
|
return (self._left(), self._grid(self._height(), 5, 3))
|
||||||
|
elif self.layout_type is LayoutType.Eckhart:
|
||||||
|
return self.grid34(0, 2)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1503,6 +1554,8 @@ class ScreenButtons:
|
|||||||
return (self._right(), self._grid(self._height(), 5, 1))
|
return (self._right(), self._grid(self._height(), 5, 1))
|
||||||
elif self.layout_type is LayoutType.Delizia:
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
return (self._right(), self._grid(self._height(), 5, 3))
|
return (self._right(), self._grid(self._height(), 5, 3))
|
||||||
|
elif self.layout_type is LayoutType.Eckhart:
|
||||||
|
return self.grid34(2, 2)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1524,6 +1577,14 @@ class ScreenButtons:
|
|||||||
24: self.grid34(2, 2),
|
24: self.grid34(2, 2),
|
||||||
33: self.grid34(2, 3),
|
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:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1532,10 +1593,10 @@ class ScreenButtons:
|
|||||||
def word_count_all_cancel(self) -> Coords:
|
def word_count_all_cancel(self) -> Coords:
|
||||||
if self.layout_type is LayoutType.Bolt:
|
if self.layout_type is LayoutType.Bolt:
|
||||||
return self.grid34(0, 3)
|
return self.grid34(0, 3)
|
||||||
|
|
||||||
elif self.layout_type is LayoutType.Delizia:
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
return self.grid34(0, 3)
|
return self.grid34(0, 3)
|
||||||
|
elif self.layout_type is LayoutType.Eckhart:
|
||||||
|
return self._grid35(0, 4)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1551,6 +1612,11 @@ class ScreenButtons:
|
|||||||
20: self.grid34(0, 1),
|
20: self.grid34(0, 1),
|
||||||
33: self.grid34(2, 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:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1559,16 +1625,22 @@ class ScreenButtons:
|
|||||||
def word_count_repeated_cancel(self) -> Coords:
|
def word_count_repeated_cancel(self) -> Coords:
|
||||||
if self.layout_type is LayoutType.Bolt:
|
if self.layout_type is LayoutType.Bolt:
|
||||||
return self.grid34(0, 2)
|
return self.grid34(0, 2)
|
||||||
|
|
||||||
elif self.layout_type is LayoutType.Delizia:
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
return self.grid34(0, 3)
|
return self.grid34(0, 3)
|
||||||
|
elif self.layout_type is LayoutType.Eckhart:
|
||||||
|
return self._grid35(1, 4)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
# select word component buttons
|
# select word component buttons
|
||||||
def word_check_words(self) -> "list[Coords]":
|
def word_check_words(self) -> "list[Coords]":
|
||||||
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
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 [
|
return [
|
||||||
(self._mid(), self._grid(self._height(), 5, 2)),
|
(self._mid(), self._grid(self._height(), 5, 2)),
|
||||||
(self._mid(), self._grid(self._height(), 5, 3)),
|
(self._mid(), self._grid(self._height(), 5, 3)),
|
||||||
@ -1579,13 +1651,20 @@ class ScreenButtons:
|
|||||||
|
|
||||||
# vertical menu buttons
|
# vertical menu buttons
|
||||||
def vertical_menu_items(self) -> "list[Coords]":
|
def vertical_menu_items(self) -> "list[Coords]":
|
||||||
assert self.layout_type is LayoutType.Delizia
|
if self.layout_type is LayoutType.Delizia:
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(self._mid(), self._grid(self._height(), 4, 1)),
|
(self._mid(), self._grid(self._height(), 4, 1)),
|
||||||
(self._mid(), self._grid(self._height(), 4, 2)),
|
(self._mid(), self._grid(self._height(), 4, 2)),
|
||||||
(self._mid(), self._grid(self._height(), 4, 3)),
|
(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
|
# Pin/passphrase keyboards
|
||||||
def pin_passphrase_index(self, idx: int) -> Coords:
|
def pin_passphrase_index(self, idx: int) -> Coords:
|
||||||
@ -1595,7 +1674,6 @@ class ScreenButtons:
|
|||||||
return self.pin_passphrase_grid(idx % 3, idx // 3)
|
return self.pin_passphrase_grid(idx % 3, idx // 3)
|
||||||
|
|
||||||
def pin_passphrase_grid(self, x: int, y: int) -> Coords:
|
def pin_passphrase_grid(self, x: int, y: int) -> Coords:
|
||||||
assert x < 3, y < 4
|
|
||||||
y += 1 # first line is empty
|
y += 1 # first line is empty
|
||||||
return self._grid35(x, y)
|
return self._grid35(x, y)
|
||||||
|
|
||||||
@ -1607,10 +1685,10 @@ class ScreenButtons:
|
|||||||
return self.pin_passphrase_grid(0, 3)
|
return self.pin_passphrase_grid(0, 3)
|
||||||
|
|
||||||
def passphrase_confirm(self) -> Coords:
|
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)
|
return self.pin_passphrase_grid(2, 3)
|
||||||
elif self.layout_type is LayoutType.Delizia:
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
return (215, 25)
|
return self._grid55(4, 0)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -1619,19 +1697,34 @@ class ScreenButtons:
|
|||||||
|
|
||||||
# Mnemonic keyboard
|
# Mnemonic keyboard
|
||||||
def mnemonic_from_index(self, idx: int) -> Coords:
|
def mnemonic_from_index(self, idx: int) -> Coords:
|
||||||
|
assert idx < 9
|
||||||
return self.mnemonic_grid(idx)
|
return self.mnemonic_grid(idx)
|
||||||
|
|
||||||
def mnemonic_grid(self, idx: int) -> Coords:
|
def mnemonic_grid(self, idx: int) -> Coords:
|
||||||
assert idx < 9
|
|
||||||
grid_x = idx % 3
|
grid_x = idx % 3
|
||||||
grid_y = idx // 3 + 1 # first line is empty
|
grid_y = idx // 3 + 1 # first line is empty
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return self.grid34(grid_x, grid_y)
|
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:
|
def mnemonic_erase(self) -> Coords:
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return (self._left(), self._top())
|
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:
|
def mnemonic_confirm(self) -> Coords:
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return (self._mid(), self._top())
|
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")
|
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
|
# fmt: off
|
||||||
PASSPHRASE_LOWERCASE_BOLT = (" ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", "*#")
|
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_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_DIGITS = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||||
PASSPHRASE_SPECIAL = ("_<>", ".:@", "/|\\", "!()", "+%&", "-[]", "?{}", ",'`", ";\"~", "$^=")
|
PASSPHRASE_SPECIAL = ("_<>", ".:@", "/|\\", "!()", "+%&", "-[]", "?{}", ",'`", ";\"~", "$^=")
|
||||||
# fmt: on
|
# fmt: on
|
||||||
@ -1655,15 +1748,15 @@ class ButtonActions:
|
|||||||
if char in " *#" or char.islower():
|
if char in " *#" or char.islower():
|
||||||
if self.buttons.layout_type is LayoutType.Bolt:
|
if self.buttons.layout_type is LayoutType.Bolt:
|
||||||
return PASSPHRASE_LOWERCASE_BOLT
|
return PASSPHRASE_LOWERCASE_BOLT
|
||||||
elif self.buttons.layout_type is LayoutType.Delizia:
|
elif self.buttons.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
return PASSPHRASE_LOWERCASE_DELIZIA
|
return PASSPHRASE_LOWERCASE_DE
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
elif char.isupper():
|
elif char.isupper():
|
||||||
if self.buttons.layout_type is LayoutType.Bolt:
|
if self.buttons.layout_type is LayoutType.Bolt:
|
||||||
return PASSPHRASE_UPPERCASE_BOLT
|
return PASSPHRASE_UPPERCASE_BOLT
|
||||||
elif self.buttons.layout_type is LayoutType.Delizia:
|
elif self.buttons.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
return PASSPHRASE_UPPERCASE_DELIZIA
|
return PASSPHRASE_UPPERCASE_DE
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
elif char.isdigit():
|
elif char.isdigit():
|
||||||
|
@ -91,7 +91,7 @@ T3B1 = TrezorModel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
T3W1 = TrezorModel(
|
T3W1 = TrezorModel(
|
||||||
name="T3W1",
|
name="Safe 7",
|
||||||
internal_name="T3W1",
|
internal_name="T3W1",
|
||||||
minimum_version=(2, 1, 0),
|
minimum_version=(2, 1, 0),
|
||||||
vendors=VENDORS,
|
vendors=VENDORS,
|
||||||
|
@ -47,7 +47,7 @@ def get_char_category(char: str) -> PassphraseCategory:
|
|||||||
|
|
||||||
|
|
||||||
def go_next(debug: "DebugLink") -> LayoutContent:
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
@ -59,7 +59,7 @@ def go_next(debug: "DebugLink") -> LayoutContent:
|
|||||||
|
|
||||||
|
|
||||||
def go_back(debug: "DebugLink", r_middle: bool = False) -> 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())
|
debug.click(debug.screen_buttons.cancel())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
if r_middle:
|
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:
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
|
@ -15,11 +15,15 @@ DELETE_BTN_TEXTS = ("inputs__delete", "inputs__previous")
|
|||||||
def enter_word(
|
def enter_word(
|
||||||
debug: "DebugLink", word: str, is_slip39: bool = False
|
debug: "DebugLink", word: str, is_slip39: bool = False
|
||||||
) -> "LayoutContent":
|
) -> "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]
|
typed_word = word[:4]
|
||||||
for coords in debug.button_actions.type_word(typed_word, is_slip39=is_slip39):
|
for coords in debug.button_actions.type_word(typed_word, is_slip39=is_slip39):
|
||||||
debug.click(coords)
|
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
|
# 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())
|
||||||
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:
|
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert TR.translate(title) == layout.title()
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -80,7 +84,7 @@ def cancel_select_number_of_words(
|
|||||||
assert layout.title() == TR.word_count__title
|
assert layout.title() == TR.word_count__title
|
||||||
# navigate to the number and confirm it
|
# navigate to the number and confirm it
|
||||||
debug.press_left()
|
debug.press_left()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
if unlock_repeated_backup:
|
if unlock_repeated_backup:
|
||||||
coords = debug.screen_buttons.word_count_repeated_cancel()
|
coords = debug.screen_buttons.word_count_repeated_cancel()
|
||||||
@ -99,7 +103,12 @@ def select_number_of_words(
|
|||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert TR.recovery__num_of_words in layout.text_content()
|
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
|
# click the button from ValuePad
|
||||||
if unlock_repeated_backup:
|
if unlock_repeated_backup:
|
||||||
coords = debug.screen_buttons.word_count_repeated_word(num_of_words)
|
coords = debug.screen_buttons.word_count_repeated_word(num_of_words)
|
||||||
@ -110,6 +119,7 @@ def select_number_of_words(
|
|||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
|
||||||
def select_caesar() -> "LayoutContent":
|
def select_caesar() -> "LayoutContent":
|
||||||
|
assert debug.layout_type is LayoutType.Caesar
|
||||||
# navigate to the number and confirm it
|
# navigate to the number and confirm it
|
||||||
word_options = (20, 33) if unlock_repeated_backup else (12, 18, 20, 24, 33)
|
word_options = (20, 33) if unlock_repeated_backup else (12, 18, 20, 24, 33)
|
||||||
index = word_options.index(num_of_words)
|
index = word_options.index(num_of_words)
|
||||||
@ -118,24 +128,13 @@ def select_number_of_words(
|
|||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
|
||||||
def select_delizia() -> "LayoutContent":
|
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
# click the button from ValuePad
|
layout = select_bde()
|
||||||
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()
|
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout.title() == TR.word_count__title
|
assert layout.title() == TR.word_count__title
|
||||||
layout = select_caesar()
|
layout = select_caesar()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
|
||||||
layout = select_delizia()
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown model")
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
@ -168,7 +167,11 @@ def enter_share(
|
|||||||
is_first: bool = True,
|
is_first: bool = True,
|
||||||
before_title: str = "recovery__title_recover",
|
before_title: str = "recovery__title_recover",
|
||||||
) -> "LayoutContent":
|
) -> "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()
|
assert TR.translate(before_title) in debug.read_layout().title()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
for _ in range(layout.page_count()):
|
for _ in range(layout.page_count()):
|
||||||
@ -177,10 +180,11 @@ def enter_share(
|
|||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
else:
|
elif debug.layout_type is LayoutType.Eckhart:
|
||||||
assert TR.translate(before_title) in debug.read_layout().title()
|
|
||||||
debug.click(debug.screen_buttons.ok())
|
debug.click(debug.screen_buttons.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
@ -210,12 +214,18 @@ def enter_shares(
|
|||||||
)
|
)
|
||||||
if index < len(shares) - 1:
|
if index < len(shares) - 1:
|
||||||
# FIXME: when ui-t3t1 done for shamir, we want to check the template below
|
# 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()
|
if debug.layout_type is LayoutType.Eckhart:
|
||||||
# TR.assert_in(
|
assert (
|
||||||
# debug.read_layout().text_content(),
|
TR.translate("recovery__x_of_y_entered_template").format(
|
||||||
# "recovery__x_of_y_entered_template",
|
index + 1, len(shares)
|
||||||
# template=(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()
|
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
||||||
|
|
||||||
@ -231,7 +241,6 @@ def enter_seed(
|
|||||||
|
|
||||||
for word in seed_words:
|
for word in seed_words:
|
||||||
enter_word(debug, word, is_slip39=is_slip39)
|
enter_word(debug, word, is_slip39=is_slip39)
|
||||||
|
|
||||||
assert TR.translate(after_layout_text) in debug.read_layout().text_content()
|
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()
|
layout = debug.read_layout()
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
debug.click(debug.screen_buttons.mnemonic_erase()) # Top-left
|
debug.click(debug.screen_buttons.mnemonic_erase())
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
debug.click(debug.screen_buttons.mnemonic_erase())
|
debug.click(debug.screen_buttons.mnemonic_erase())
|
||||||
continue
|
continue
|
||||||
@ -299,7 +308,7 @@ def prepare_enter_seed(
|
|||||||
or TR.recovery__enter_each_word 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()
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -310,6 +319,8 @@ def prepare_enter_seed(
|
|||||||
debug.press_right()
|
debug.press_right()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def finalize(debug: "DebugLink") -> None:
|
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()
|
assert cancel_title in layout.title()
|
||||||
for _ in range(layout.page_count()):
|
for _ in range(layout.page_count()):
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
# go to menu
|
# go to menu
|
||||||
debug.click(debug.screen_buttons.menu())
|
debug.click(debug.screen_buttons.menu())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
def confirm_new_wallet(debug: "DebugLink") -> None:
|
def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||||
assert debug.read_layout().title() == TR.reset__title_create_wallet
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -27,13 +27,13 @@ def confirm_new_wallet(debug: "DebugLink") -> None:
|
|||||||
)
|
)
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
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:
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
|
||||||
debug.swipe_up()
|
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
page_count = debug.read_layout().page_count()
|
page_count = debug.read_layout().page_count()
|
||||||
if page_count > 1:
|
if page_count > 1:
|
||||||
@ -43,6 +43,10 @@ def confirm_read(debug: "DebugLink", middle_r: bool = False) -> None:
|
|||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
else:
|
else:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
|
debug.swipe_up()
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def cancel_backup(
|
def cancel_backup(
|
||||||
@ -51,19 +55,28 @@ def cancel_backup(
|
|||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
debug.click(debug.screen_buttons.cancel())
|
debug.click(debug.screen_buttons.cancel())
|
||||||
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:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(debug.screen_buttons.menu())
|
debug.click(debug.screen_buttons.menu())
|
||||||
debug.click(debug.screen_buttons.vertical_menu_items()[0])
|
debug.click(debug.screen_buttons.vertical_menu_items()[0])
|
||||||
if confirm:
|
if confirm:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Eckhart:
|
||||||
debug.press_left()
|
debug.click(debug.screen_buttons.menu())
|
||||||
debug.press_left()
|
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:
|
def set_selection(debug: "DebugLink", diff: int) -> None:
|
||||||
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
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()
|
assert "NumberInputDialog" in debug.read_layout().all_components()
|
||||||
|
|
||||||
button = (
|
button = (
|
||||||
@ -75,7 +88,7 @@ def set_selection(debug: "DebugLink", diff: int) -> None:
|
|||||||
|
|
||||||
for _ in range(diff):
|
for _ in range(diff):
|
||||||
debug.click(button)
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
else:
|
else:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -96,6 +109,8 @@ def set_selection(debug: "DebugLink", diff: int) -> None:
|
|||||||
for _ in range(diff):
|
for _ in range(diff):
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
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()
|
debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
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
|
# Swiping through all the pages and loading the words
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
for _ in range(layout.page_count() - 1):
|
for _ in range(layout.page_count() - 1):
|
||||||
words.extend(layout.seed_words())
|
words.extend(layout.seed_words())
|
||||||
|
if debug.layout_type is LayoutType.Eckhart:
|
||||||
|
debug.click(debug.screen_buttons.ok())
|
||||||
|
else:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout is not None
|
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())
|
words.extend(layout.seed_words())
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
elif debug.layout_type is LayoutType.Eckhart:
|
||||||
|
debug.click(debug.screen_buttons.ok())
|
||||||
|
|
||||||
# There is hold-to-confirm button
|
# There is hold-to-confirm button
|
||||||
if do_htc:
|
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)
|
debug.click(debug.screen_buttons.ok(), hold_ms=1500)
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
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:
|
def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
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()
|
layout = debug.read_layout()
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
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)
|
button_pos = btn_texts.index(wanted_word)
|
||||||
debug.click(debug.screen_buttons.word_check_words()[button_pos])
|
debug.click(debug.screen_buttons.word_check_words()[button_pos])
|
||||||
layout = debug.read_layout()
|
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:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
assert TR.reset__select_correct_word in layout.text_content()
|
assert TR.reset__select_correct_word in layout.text_content()
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
@ -193,6 +206,43 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
|||||||
|
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
layout = debug.read_layout()
|
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:
|
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")
|
debug.input("1234")
|
||||||
|
|
||||||
assert TR.regexp("auto_lock__change_template").match(
|
assert TR.regexp("auto_lock__change_template").match(
|
||||||
debug.read_layout().text_content()
|
debug.read_layout().text_content().strip()
|
||||||
)
|
)
|
||||||
|
|
||||||
layout = go_next(debug)
|
layout = go_next(debug)
|
||||||
@ -113,7 +113,7 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
|||||||
in debug.read_layout().text_content().replace(" ", "")
|
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())
|
||||||
debug.click(debug.screen_buttons.ok())
|
debug.click(debug.screen_buttons.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
@ -131,6 +131,8 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
|||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert TR.send__total_amount in layout.text_content()
|
assert TR.send__total_amount in layout.text_content()
|
||||||
assert "0.0039 BTC" 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
|
# wait for autolock to kick in
|
||||||
time.sleep(10.1)
|
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(" ", "")
|
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())
|
||||||
debug.click(debug.screen_buttons.ok())
|
debug.click(debug.screen_buttons.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
@ -187,6 +189,8 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
|||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert TR.send__total_amount in layout.text_content()
|
assert TR.send__total_amount in layout.text_content()
|
||||||
assert "0.0039 BTC" 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:
|
def sleepy_filter(msg: MessageType) -> MessageType:
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
@ -196,12 +200,14 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
|||||||
with device_handler.client:
|
with device_handler.client:
|
||||||
device_handler.client.set_filter(messages.TxAck, sleepy_filter)
|
device_handler.client.set_filter(messages.TxAck, sleepy_filter)
|
||||||
# confirm transaction
|
# confirm transaction
|
||||||
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())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
|
||||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_middle()
|
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()
|
signatures, tx = device_handler.result()
|
||||||
assert len(signatures) == 1
|
assert len(signatures) == 1
|
||||||
@ -227,7 +233,11 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
|||||||
# enter passphrase - slowly
|
# enter passphrase - slowly
|
||||||
# keep clicking for long enough to trigger the autolock if it incorrectly ignored key presses
|
# keep clicking for long enough to trigger the autolock if it incorrectly ignored key presses
|
||||||
for _ in range(math.ceil(11 / 1.5)):
|
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"
|
# click at "j"
|
||||||
debug.click(_passphrase_j(debug))
|
debug.click(_passphrase_j(debug))
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
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
|
# NOTE: because of passphrase randomization it would be a pain to input
|
||||||
# a specific passphrase, which is not in scope for this test.
|
# a specific passphrase, which is not in scope for this test.
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||||
|
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
|
|
||||||
# Send the passphrase to the client (TT has it clicked already, TR needs to input it)
|
# 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())
|
debug.click(debug.screen_buttons.passphrase_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.input("j" * 8)
|
debug.input("j" * 8)
|
||||||
@ -264,14 +277,23 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
|||||||
# enter passphrase - slowly
|
# enter passphrase - slowly
|
||||||
# autolock must activate even if we pressed some buttons
|
# autolock must activate even if we pressed some buttons
|
||||||
for _ in range(math.ceil(6 / 1.5)):
|
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))
|
debug.click(_center_button(debug))
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
|
|
||||||
# wait for autolock to kick in
|
# wait for autolock to kick in
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
|
if debug.layout_type is LayoutType.Eckhart:
|
||||||
|
assert debug.read_layout().main_component() == "Homescreen"
|
||||||
|
else:
|
||||||
assert debug.read_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
@ -303,6 +325,9 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
|
|||||||
|
|
||||||
# wait for autolock to trigger
|
# wait for autolock to trigger
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
|
if debug.layout_type is LayoutType.Eckhart:
|
||||||
|
assert debug.read_layout().main_component() == "Homescreen"
|
||||||
|
else:
|
||||||
assert debug.read_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
@ -333,16 +358,21 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"):
|
|||||||
# select 20 words
|
# select 20 words
|
||||||
recovery.select_number_of_words(debug, 20)
|
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)
|
layout = go_next(debug)
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||||
|
|
||||||
# make sure keyboard locks
|
# make sure keyboard locks
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
|
if debug.layout_type is LayoutType.Eckhart:
|
||||||
|
assert debug.read_layout().main_component() == "Homescreen"
|
||||||
|
else:
|
||||||
assert debug.read_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
@ -360,7 +390,7 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
|
|||||||
# select 20 words
|
# select 20 words
|
||||||
recovery.select_number_of_words(debug, 20)
|
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())
|
debug.click(debug.screen_buttons.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
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.setup_client(pin=PIN4)
|
||||||
|
@pytest.mark.models(skip=["eckhart"])
|
||||||
def test_autolock_does_not_interrupt_preauthorized(
|
def test_autolock_does_not_interrupt_preauthorized(
|
||||||
device_handler: "BackgroundDeviceHandler",
|
device_handler: "BackgroundDeviceHandler",
|
||||||
):
|
):
|
||||||
|
@ -80,7 +80,7 @@ def test_backup_slip39_custom(
|
|||||||
# confirm backup configuration
|
# confirm backup configuration
|
||||||
if share_count > 1:
|
if share_count > 1:
|
||||||
assert TR.regexp("reset__create_x_of_y_multi_share_backup_template").match(
|
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:
|
else:
|
||||||
assert TR.regexp("backup__info_single_share_backup").match(
|
assert TR.regexp("backup__info_single_share_backup").match(
|
||||||
@ -106,9 +106,12 @@ def test_backup_slip39_custom(
|
|||||||
all_words.append(" ".join(words))
|
all_words.append(" ".join(words))
|
||||||
|
|
||||||
# confirm backup done
|
# 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)
|
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)
|
reset.confirm_read(debug)
|
||||||
|
|
||||||
# generate secret locally
|
# generate secret locally
|
||||||
|
@ -49,7 +49,7 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
|||||||
models.T3B1: 1200,
|
models.T3B1: 1200,
|
||||||
models.T2T1: 3500,
|
models.T2T1: 3500,
|
||||||
models.T3T1: 3500,
|
models.T3T1: 3500,
|
||||||
models.T3W1: 3500,
|
models.T3W1: 2000,
|
||||||
}[debug.model]
|
}[debug.model]
|
||||||
|
|
||||||
def hold(duration: int) -> None:
|
def hold(duration: int) -> None:
|
||||||
@ -58,7 +58,7 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
|||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(debug.screen_buttons.tap_to_confirm(), hold_ms=duration)
|
debug.click(debug.screen_buttons.tap_to_confirm(), hold_ms=duration)
|
||||||
else:
|
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
|
assert device_handler.features().unlocked is False
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ if TYPE_CHECKING:
|
|||||||
from ..device_handler import BackgroundDeviceHandler
|
from ..device_handler import BackgroundDeviceHandler
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.models("t2t1", "delizia")
|
pytestmark = pytest.mark.models("t2t1", "delizia", "eckhart")
|
||||||
|
|
||||||
KEYBOARD_CATEGORIES_BOLT = [
|
KEYBOARD_CATEGORIES_BOLT = [
|
||||||
PassphraseCategory.DIGITS,
|
PassphraseCategory.DIGITS,
|
||||||
@ -40,7 +40,8 @@ KEYBOARD_CATEGORIES_BOLT = [
|
|||||||
PassphraseCategory.SPECIAL,
|
PassphraseCategory.SPECIAL,
|
||||||
]
|
]
|
||||||
|
|
||||||
KEYBOARD_CATEGORIES_DELIZIA = [
|
# Common for Delizia and Eckhart
|
||||||
|
KEYBOARD_CATEGORIES_DE = [
|
||||||
PassphraseCategory.LOWERCASE,
|
PassphraseCategory.LOWERCASE,
|
||||||
PassphraseCategory.UPPERCASE,
|
PassphraseCategory.UPPERCASE,
|
||||||
PassphraseCategory.DIGITS,
|
PassphraseCategory.DIGITS,
|
||||||
@ -90,8 +91,8 @@ def prepare_passphrase_dialogue(
|
|||||||
def keyboard_categories(layout_type: LayoutType) -> list[PassphraseCategory]:
|
def keyboard_categories(layout_type: LayoutType) -> list[PassphraseCategory]:
|
||||||
if layout_type is LayoutType.Bolt:
|
if layout_type is LayoutType.Bolt:
|
||||||
return KEYBOARD_CATEGORIES_BOLT
|
return KEYBOARD_CATEGORIES_BOLT
|
||||||
elif layout_type is LayoutType.Delizia:
|
elif layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
return KEYBOARD_CATEGORIES_DELIZIA
|
return KEYBOARD_CATEGORIES_DE
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ def enter_passphrase(debug: "DebugLink") -> None:
|
|||||||
"""Enter a passphrase"""
|
"""Enter a passphrase"""
|
||||||
is_empty: bool = len(debug.read_layout().passphrase()) == 0
|
is_empty: bool = len(debug.read_layout().passphrase()) == 0
|
||||||
debug.click(debug.screen_buttons.passphrase_confirm())
|
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())
|
debug.click(debug.screen_buttons.ui_yes())
|
||||||
|
|
||||||
|
|
||||||
@ -200,7 +201,7 @@ def test_passphrase_delete(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
for _ in range(4):
|
for _ in range(4):
|
||||||
delete_char(debug)
|
delete_char(debug)
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
debug.read_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
||||||
@ -231,7 +232,7 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
|||||||
PassphraseCategory.SPECIAL,
|
PassphraseCategory.SPECIAL,
|
||||||
):
|
):
|
||||||
go_to_category(debug, category)
|
go_to_category(debug, category)
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type in (LayoutType.Delizia, LayoutType.Eckhart):
|
||||||
debug.read_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
@ -95,7 +95,7 @@ def prepare(
|
|||||||
# Any action triggering the PIN dialogue
|
# Any action triggering the PIN dialogue
|
||||||
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
||||||
tap = True
|
tap = True
|
||||||
if situation == Situation.PIN_INPUT_CANCEL:
|
elif situation == Situation.PIN_INPUT_CANCEL:
|
||||||
# Any action triggering the PIN dialogue
|
# Any action triggering the PIN dialogue
|
||||||
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore
|
||||||
elif situation == Situation.PIN_SETUP:
|
elif situation == Situation.PIN_SETUP:
|
||||||
@ -105,13 +105,19 @@ def prepare(
|
|||||||
TR.pin__turn_on in debug.read_layout().text_content()
|
TR.pin__turn_on in debug.read_layout().text_content()
|
||||||
or TR.pin__info 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)
|
go_next(debug)
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
elif situation == Situation.PIN_CHANGE:
|
elif situation == Situation.PIN_CHANGE:
|
||||||
# Change PIN
|
# Change PIN
|
||||||
device_handler.run(device.change_pin) # type: ignore
|
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"""
|
"""Input the PIN"""
|
||||||
if check:
|
if check:
|
||||||
before = debug.read_layout().pin()
|
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()
|
digits_order = debug.read_layout().tt_pin_digits_order()
|
||||||
for digit in pin:
|
for digit in pin:
|
||||||
digit_index = digits_order.index(digit)
|
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:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
for digit in pin:
|
for digit in pin:
|
||||||
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
after = debug.read_layout().pin()
|
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:
|
def _see_pin(debug: "DebugLink") -> None:
|
||||||
"""Navigate to "SHOW" and press it"""
|
"""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())
|
debug.click(debug.screen_buttons.pin_passphrase_input())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
navigate_to_action_and_press(debug, SHOW, TR_PIN_ACTIONS)
|
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:
|
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()
|
before = debug.read_layout().pin()
|
||||||
|
|
||||||
for _ in range(digits_to_delete):
|
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())
|
debug.click(debug.screen_buttons.pin_passphrase_erase())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
after = debug.read_layout().pin()
|
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:
|
def _delete_all(debug: "DebugLink", check: bool = True) -> None:
|
||||||
"""Navigate to "DELETE" and hold it until all digits are deleted"""
|
"""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.click(
|
||||||
debug.screen_buttons.pin_passphrase_erase(),
|
debug.screen_buttons.pin_passphrase_erase(),
|
||||||
hold_ms=1500,
|
hold_ms=1500,
|
||||||
)
|
)
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS, hold_ms=1000)
|
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS, hold_ms=1000)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
after = debug.read_layout().pin()
|
after = debug.read_layout().pin()
|
||||||
@ -221,10 +239,12 @@ def _cancel_pin(debug: "DebugLink") -> None:
|
|||||||
|
|
||||||
def _confirm_pin(debug: "DebugLink") -> None:
|
def _confirm_pin(debug: "DebugLink") -> None:
|
||||||
"""Navigate to "ENTER" and press it"""
|
"""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())
|
debug.click(debug.screen_buttons.pin_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def _input_see_confirm(debug: "DebugLink", pin: str) -> None:
|
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"):
|
def test_pin_setup_mismatch(device_handler: "BackgroundDeviceHandler"):
|
||||||
with PIN_CANCELLED, prepare(device_handler, Situation.PIN_SETUP) as debug:
|
with PIN_CANCELLED, prepare(device_handler, Situation.PIN_SETUP) as debug:
|
||||||
_enter_two_times(debug, "1", "2")
|
_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)
|
go_next(debug)
|
||||||
_cancel_pin(debug)
|
_cancel_pin(debug)
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
debug.press_no()
|
debug.press_no()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
else:
|
||||||
go_next(debug)
|
raise RuntimeError("Unknown model")
|
||||||
_cancel_pin(debug)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin="1")
|
@pytest.mark.setup_client(pin="1")
|
||||||
|
@ -210,6 +210,8 @@ def read_and_confirm_mnemonic(
|
|||||||
mnemonic = yield from read_mnemonic_from_screen_caesar(debug)
|
mnemonic = yield from read_mnemonic_from_screen_caesar(debug)
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
mnemonic = yield from read_mnemonic_from_screen_delizia(debug)
|
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:
|
else:
|
||||||
raise ValueError(f"Unknown model: {debug.layout_type}")
|
raise ValueError(f"Unknown model: {debug.layout_type}")
|
||||||
|
|
||||||
@ -277,6 +279,25 @@ def read_mnemonic_from_screen_delizia(
|
|||||||
return mnemonic
|
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(
|
def check_share(
|
||||||
debug: "DebugLink", mnemonic: list[str], choose_wrong: bool = False
|
debug: "DebugLink", mnemonic: list[str], choose_wrong: bool = False
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@ -294,7 +315,7 @@ def check_share(
|
|||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
# other models have the instruction in the title/subtitle
|
# other models have the instruction in the title/subtitle
|
||||||
word_pos_match = re.search(re_num_of_word, debug.read_layout().title())
|
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())
|
word_pos_match = re.search(re_num_of_word, debug.read_layout().subtitle())
|
||||||
else:
|
else:
|
||||||
word_pos_match = None
|
word_pos_match = None
|
||||||
@ -319,7 +340,7 @@ def click_info_button_bolt(debug: "DebugLink") -> Generator[Any, Any, ButtonRequ
|
|||||||
return (yield)
|
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."""
|
"""Click Shamir backup info button and return back."""
|
||||||
debug.click(debug.screen_buttons.menu())
|
debug.click(debug.screen_buttons.menu())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
@ -180,7 +180,7 @@ class ModelsFilter:
|
|||||||
"t1": {models.T1B1},
|
"t1": {models.T1B1},
|
||||||
"t2": {models.T2T1},
|
"t2": {models.T2T1},
|
||||||
"tt": {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},
|
"safe3": {models.T2B1, models.T3B1},
|
||||||
"safe5": {models.T3T1},
|
"safe5": {models.T3T1},
|
||||||
"delizia": {models.T3T1},
|
"delizia": {models.T3T1},
|
||||||
|
@ -34,6 +34,8 @@ from .signtx import (
|
|||||||
request_output,
|
request_output,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
B = messages.ButtonRequestType
|
B = messages.ButtonRequestType
|
||||||
|
|
||||||
TX_CACHE_TESTNET = TxCache("Testnet")
|
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):
|
def _address_n(purpose, coin, account, script_type):
|
||||||
res = [H_(purpose), H_(0) if coin == "Bitcoin" else H_(1), H_(account)]
|
res = [H_(purpose), H_(0) if coin == "Bitcoin" else H_(1), H_(account)]
|
||||||
if purpose == 10025 and script_type == messages.InputScriptType.SPENDTAPROOT:
|
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.multisig
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"script_type, bip48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG
|
"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 ...input_flows import InputFlowConfirmAllWarnings
|
||||||
from .signtx import forge_prevtx
|
from .signtx import forge_prevtx
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
VECTORS = ( # path, script_types
|
VECTORS = ( # path, script_types
|
||||||
# GreenAddress A m/[1,4]/address_index
|
# GreenAddress A m/[1,4]/address_index
|
||||||
(
|
(
|
||||||
|
@ -35,6 +35,8 @@ from ...input_flows import (
|
|||||||
|
|
||||||
S = messages.InputScriptType
|
S = messages.InputScriptType
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
|
|
||||||
def case(
|
def case(
|
||||||
id: str,
|
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.
|
# We cannot differentiate between a newline and space in the message read from Trezor.
|
||||||
# TODO: do the check also for T2B1
|
# 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("...", "")
|
message_read = IF.message_read.replace(" ", "").replace("...", "")
|
||||||
signed_message = message.replace("\n", "").replace(" ", "")
|
signed_message = message.replace("\n", "").replace(" ", "")
|
||||||
assert signed_message in message_read
|
assert signed_message in message_read
|
||||||
|
@ -1611,9 +1611,7 @@ def test_information_cancel(client: Client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.models(
|
@pytest.mark.models("core")
|
||||||
"core",
|
|
||||||
)
|
|
||||||
def test_information_replacement(client: Client):
|
def test_information_replacement(client: Client):
|
||||||
# Use the change output and an external output to bump the fee.
|
# Use the change output and an external output to bump the fee.
|
||||||
# Originally fee was 3780, now 108060 (94280 from change and 10000 from external).
|
# Originally fee was 3780, now 108060 (94280 from change and 10000 from external).
|
||||||
|
@ -33,7 +33,7 @@ PREV_HASH, PREV_TX = forge_prevtx([(INPUT_ADDRESS, 12_300_000)], network="testne
|
|||||||
PREV_TXES = {PREV_HASH: PREV_TX}
|
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):
|
def case(id, *args, altcoin: bool = False, models: str | None = None):
|
||||||
|
@ -32,6 +32,8 @@ from .signtx import (
|
|||||||
request_output,
|
request_output,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
B = messages.ButtonRequestType
|
B = messages.ButtonRequestType
|
||||||
|
|
||||||
TX_CACHE_TESTNET = TxCache("Testnet")
|
TX_CACHE_TESTNET = TxCache("Testnet")
|
||||||
|
@ -23,6 +23,8 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
|||||||
|
|
||||||
from ...input_flows import InputFlowSignVerifyMessageLong
|
from ...input_flows import InputFlowSignVerifyMessageLong
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.models("legacy")
|
@pytest.mark.models("legacy")
|
||||||
def test_message_long_legacy(client: Client):
|
def test_message_long_legacy(client: Client):
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
# You should have received a copy of the License along with this library.
|
# 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>.
|
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc
|
from trezorlib import btc
|
||||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
|
|
||||||
def test_message_long(client: Client):
|
def test_message_long(client: Client):
|
||||||
ret = btc.verify_message(
|
ret = btc.verify_message(
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
# You should have received a copy of the License along with this library.
|
# 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>.
|
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc
|
from trezorlib import btc
|
||||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
|
|
||||||
def test_message_long(client: Client):
|
def test_message_long(client: Client):
|
||||||
ret = btc.verify_message(
|
ret = btc.verify_message(
|
||||||
|
@ -32,7 +32,7 @@ from ...input_flows import InputFlowShowXpubQRCode
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.cardano,
|
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 = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.cardano,
|
pytest.mark.cardano,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
ADDRESS_N = parse_path("m/1852h/1815h/0h")
|
ADDRESS_N = parse_path("m/1852h/1815h/0h")
|
||||||
|
@ -25,7 +25,7 @@ from ...common import parametrize_using_common_fixtures
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.cardano,
|
pytest.mark.cardano,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ from ...input_flows import InputFlowConfirmAllWarnings
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.cardano,
|
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:
|
elif client.layout_type is LayoutType.Caesar:
|
||||||
# Caesar - right button for "Show all"
|
# Caesar - right button for "Show all"
|
||||||
client.debug.press_yes()
|
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
|
# Delizia - "Show all" button from context menu
|
||||||
client.debug.click(client.debug.screen_buttons.menu())
|
client.debug.click(client.debug.screen_buttons.menu())
|
||||||
client.debug.click(client.debug.screen_buttons.vertical_menu_items()[0])
|
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.altcoin
|
||||||
@pytest.mark.eos
|
@pytest.mark.eos
|
||||||
@pytest.mark.models("t2t1")
|
@pytest.mark.models("t2t1", skip=["eckhart"])
|
||||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||||
def test_eos_get_public_key(client: Client):
|
def test_eos_get_public_key(client: Client):
|
||||||
with client:
|
with client:
|
||||||
|
@ -29,7 +29,7 @@ ADDRESS_N = parse_path("m/44h/194h/0h/0/0")
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.eos,
|
pytest.mark.eos,
|
||||||
pytest.mark.models("t2t1"),
|
pytest.mark.models("t2t1", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -13,7 +13,11 @@ from ... import definitions
|
|||||||
from ...input_flows import InputFlowConfirmAllWarnings
|
from ...input_flows import InputFlowConfirmAllWarnings
|
||||||
from .test_sign_typed_data import DATA as TYPED_DATA
|
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_OPERATION = "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b0000000000000000000000000000000000000000000000000000000000000123"
|
||||||
ERC20_BUILTIN_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7" # USDT
|
ERC20_BUILTIN_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7" # USDT
|
||||||
|
@ -19,7 +19,11 @@ from ...definitions import (
|
|||||||
)
|
)
|
||||||
from .test_definitions import DEFAULT_ERC20_PARAMS, ERC20_FAKE_ADDRESS
|
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:
|
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 ...common import parametrize_using_common_fixtures
|
||||||
from ...input_flows import InputFlowShowAddressQRCode
|
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")
|
@parametrize_using_common_fixtures("ethereum/getaddress.json")
|
||||||
|
@ -23,7 +23,11 @@ from trezorlib.tools import parse_path
|
|||||||
|
|
||||||
from ...common import parametrize_using_common_fixtures
|
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")
|
@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 ...common import parametrize_using_common_fixtures
|
||||||
from ...input_flows import InputFlowEIP712Cancel, InputFlowEIP712ShowMore
|
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")
|
@pytest.mark.models("core")
|
||||||
|
@ -24,7 +24,11 @@ from trezorlib.tools import parse_path
|
|||||||
from ...common import parametrize_using_common_fixtures
|
from ...common import parametrize_using_common_fixtures
|
||||||
from ...input_flows import InputFlowSignVerifyMessageLong
|
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")
|
@parametrize_using_common_fixtures("ethereum/signmessage.json")
|
||||||
|
@ -37,7 +37,11 @@ from ...input_flows import (
|
|||||||
TO_ADDR = "0x1d1c328764a41bda0492b66baa30c4a339ff85ef"
|
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:
|
def make_defs(parameters: dict) -> messages.EthereumDefinitions:
|
||||||
|
@ -28,7 +28,10 @@ from ...common import MNEMONIC12
|
|||||||
def test_encrypt(client: Client):
|
def test_encrypt(client: Client):
|
||||||
def input_flow():
|
def input_flow():
|
||||||
assert (yield).name == "cipher_key_value"
|
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.swipe_up()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ TEST_VECTORS = [
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.monero,
|
pytest.mark.monero,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
|||||||
|
|
||||||
@pytest.mark.altcoin
|
@pytest.mark.altcoin
|
||||||
@pytest.mark.monero
|
@pytest.mark.monero
|
||||||
@pytest.mark.models("core")
|
@pytest.mark.models("core", skip=["eckhart"])
|
||||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||||
def test_monero_getwatchkey(client: Client):
|
def test_monero_getwatchkey(client: Client):
|
||||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/0h"))
|
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.altcoin
|
||||||
@pytest.mark.nem
|
@pytest.mark.nem
|
||||||
@pytest.mark.models("t1b1", "t2t1")
|
@pytest.mark.models("t1b1", "t2t1", skip=["eckhart"])
|
||||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||||
@pytest.mark.parametrize("chunkify", (True, False))
|
@pytest.mark.parametrize("chunkify", (True, False))
|
||||||
def test_nem_getaddress(client: Client, chunkify: bool):
|
def test_nem_getaddress(client: Client, chunkify: bool):
|
||||||
|
@ -27,7 +27,7 @@ ADDRESS_N = parse_path("m/44h/1h/0h/0h/0h")
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.nem,
|
pytest.mark.nem,
|
||||||
pytest.mark.models("t1b1", "t2t1"),
|
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.nem,
|
pytest.mark.nem,
|
||||||
pytest.mark.models("t1b1", "t2t1"),
|
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.nem,
|
pytest.mark.nem,
|
||||||
pytest.mark.models("t1b1", "t2t1"),
|
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from ...common import MNEMONIC12, is_core
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.nem,
|
pytest.mark.nem,
|
||||||
pytest.mark.models("t1b1", "t2t1"),
|
pytest.mark.models("t1b1", "t2t1", skip=["eckhart"]),
|
||||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import pytest
|
|||||||
from trezorlib import messages, nostr
|
from trezorlib import messages, nostr
|
||||||
from trezorlib.tools import parse_path
|
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
|
# test data from NIP-06: https://github.com/nostr-protocol/nips/blob/master/06.md
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ from ...input_flows import (
|
|||||||
InputFlowSlip39BasicRecoveryInvalidSecondShare,
|
InputFlowSlip39BasicRecoveryInvalidSecondShare,
|
||||||
InputFlowSlip39BasicRecoveryNoAbort,
|
InputFlowSlip39BasicRecoveryNoAbort,
|
||||||
InputFlowSlip39BasicRecoverySameShare,
|
InputFlowSlip39BasicRecoverySameShare,
|
||||||
|
InputFlowSlip39BasicRecoveryShareInfoBetweenShares,
|
||||||
InputFlowSlip39BasicRecoveryWrongNthWord,
|
InputFlowSlip39BasicRecoveryWrongNthWord,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -147,6 +148,20 @@ def test_abort_between_shares(client: Client):
|
|||||||
assert client.features.recovery_status is messages.RecoveryStatus.Nothing
|
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)
|
@pytest.mark.setup_client(uninitialized=True)
|
||||||
def test_noabort(client: Client):
|
def test_noabort(client: Client):
|
||||||
with client:
|
with client:
|
||||||
|
@ -255,6 +255,10 @@ def test_already_initialized(client: Client):
|
|||||||
def test_entropy_check(client: Client):
|
def test_entropy_check(client: Client):
|
||||||
with client:
|
with client:
|
||||||
delizia = client.debug.layout_type is LayoutType.Delizia
|
delizia = client.debug.layout_type is LayoutType.Delizia
|
||||||
|
delizia_eckhart = client.debug.layout_type in (
|
||||||
|
LayoutType.Delizia,
|
||||||
|
LayoutType.Eckhart,
|
||||||
|
)
|
||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
messages.ButtonRequest(name="setup_device"),
|
messages.ButtonRequest(name="setup_device"),
|
||||||
@ -271,7 +275,7 @@ def test_entropy_check(client: Client):
|
|||||||
messages.EntropyCheckReady,
|
messages.EntropyCheckReady,
|
||||||
messages.PublicKey,
|
messages.PublicKey,
|
||||||
messages.PublicKey,
|
messages.PublicKey,
|
||||||
(delizia, messages.ButtonRequest(name="backup_device")),
|
(delizia_eckhart, messages.ButtonRequest(name="backup_device")),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
]
|
]
|
||||||
@ -291,13 +295,17 @@ def test_entropy_check(client: Client):
|
|||||||
@pytest.mark.setup_client(uninitialized=True)
|
@pytest.mark.setup_client(uninitialized=True)
|
||||||
def test_no_entropy_check(client: Client):
|
def test_no_entropy_check(client: Client):
|
||||||
with client:
|
with client:
|
||||||
|
delizia_eckhart = client.debug.layout_type in (
|
||||||
|
LayoutType.Delizia,
|
||||||
|
LayoutType.Eckhart,
|
||||||
|
)
|
||||||
delizia = client.debug.layout_type is LayoutType.Delizia
|
delizia = client.debug.layout_type is LayoutType.Delizia
|
||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
messages.ButtonRequest(name="setup_device"),
|
messages.ButtonRequest(name="setup_device"),
|
||||||
(delizia, messages.ButtonRequest(name="confirm_setup_device")),
|
(delizia, messages.ButtonRequest(name="confirm_setup_device")),
|
||||||
messages.EntropyRequest,
|
messages.EntropyRequest,
|
||||||
(delizia, messages.ButtonRequest(name="backup_device")),
|
(delizia_eckhart, messages.ButtonRequest(name="backup_device")),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
]
|
]
|
||||||
|
@ -31,7 +31,7 @@ CUSTOM_MNEMONIC = (
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.ripple,
|
pytest.mark.ripple,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
# data from https://iancoleman.io/bip39/
|
# data from https://iancoleman.io/bip39/
|
||||||
|
@ -24,7 +24,7 @@ from trezorlib.tools import parse_path
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.ripple,
|
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 = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.solana,
|
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 = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.solana,
|
pytest.mark.solana,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ from .construct.transaction import Message, RawInstruction
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.solana,
|
pytest.mark.solana,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ from ...input_flows import InputFlowShowAddressQRCode
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.stellar,
|
pytest.mark.stellar,
|
||||||
|
pytest.mark.models(skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
|||||||
|
|
||||||
from ..common import compact_size
|
from ..common import compact_size
|
||||||
|
|
||||||
pytestmark = pytest.mark.models("safe")
|
pytestmark = pytest.mark.models("safe", skip=["eckhart"])
|
||||||
|
|
||||||
ROOT_PUBLIC_KEY = {
|
ROOT_PUBLIC_KEY = {
|
||||||
models.T2B1: bytes.fromhex(
|
models.T2B1: bytes.fromhex(
|
||||||
|
@ -23,6 +23,8 @@ from trezorlib.debuglink import LayoutType
|
|||||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
PIN = "1234"
|
PIN = "1234"
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ def test_cancel_message_via_initialize(client: Client, message):
|
|||||||
assert isinstance(resp, m.Features)
|
assert isinstance(resp, m.Features)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.models("core")
|
@pytest.mark.models("core", skip=["eckhart"])
|
||||||
def test_cancel_on_paginated(client: Client):
|
def test_cancel_on_paginated(client: Client):
|
||||||
"""Check that device is responsive on paginated screen. See #1708."""
|
"""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
|
# 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 import firmware, models
|
||||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.models(skip=["eckhart"])
|
||||||
|
|
||||||
# size of FIRMWARE_AREA, see core/embed/models/model_*_layout.c
|
# size of FIRMWARE_AREA, see core/embed/models/model_*_layout.c
|
||||||
FIRMWARE_LENGTHS = {
|
FIRMWARE_LENGTHS = {
|
||||||
models.T1B1: 7 * 128 * 1024 + 64 * 1024,
|
models.T1B1: 7 * 128 * 1024 + 64 * 1024,
|
||||||
|
@ -35,7 +35,7 @@ from ..translations import (
|
|||||||
sign_blob,
|
sign_blob,
|
||||||
)
|
)
|
||||||
|
|
||||||
pytestmark = pytest.mark.models("core")
|
pytestmark = pytest.mark.models("core", skip=["eckhart"])
|
||||||
|
|
||||||
|
|
||||||
MAX_DATA_LENGTH = {
|
MAX_DATA_LENGTH = {
|
||||||
|
@ -222,7 +222,7 @@ def test_apply_homescreen_toif(client: Client):
|
|||||||
device.apply_settings(client, homescreen=img)
|
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):
|
def test_apply_homescreen_jpeg(client: Client):
|
||||||
with open(HERE / "test_bg.jpg", "rb") as f:
|
with open(HERE / "test_bg.jpg", "rb") as f:
|
||||||
img = f.read()
|
img = f.read()
|
||||||
@ -360,6 +360,7 @@ def test_apply_homescreen(client: Client):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin=None)
|
@pytest.mark.setup_client(pin=None)
|
||||||
|
@pytest.mark.models(skip="eckhart")
|
||||||
def test_safety_checks(client: Client):
|
def test_safety_checks(client: Client):
|
||||||
def get_bad_address():
|
def get_bad_address():
|
||||||
btc.get_address(client, "Bitcoin", parse_path("m/44h"), show_display=True)
|
btc.get_address(client, "Bitcoin", parse_path("m/44h"), show_display=True)
|
||||||
@ -458,7 +459,7 @@ def test_label_too_long(client: Client):
|
|||||||
device.apply_settings(client, label="A" * 33)
|
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)
|
@pytest.mark.setup_client(pin=None)
|
||||||
def test_set_brightness(client: Client):
|
def test_set_brightness(client: Client):
|
||||||
device.set_brightness(client, None)
|
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):
|
def test_backup_slip39_basic(client: Client, click_info: bool):
|
||||||
if click_info and client.layout_type is LayoutType.Caesar:
|
if click_info and client.layout_type is LayoutType.Caesar:
|
||||||
pytest.skip("click_info not implemented on T2B1")
|
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
|
assert client.features.backup_availability == messages.BackupAvailability.Required
|
||||||
|
|
||||||
@ -97,7 +99,10 @@ def test_backup_slip39_single(client: Client):
|
|||||||
|
|
||||||
with client:
|
with client:
|
||||||
IF = InputFlowBip39Backup(
|
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())
|
client.set_input_flow(IF.get())
|
||||||
device.backup(client)
|
device.backup(client)
|
||||||
@ -124,6 +129,8 @@ def test_backup_slip39_single(client: Client):
|
|||||||
def test_backup_slip39_advanced(client: Client, click_info: bool):
|
def test_backup_slip39_advanced(client: Client, click_info: bool):
|
||||||
if click_info and client.layout_type is LayoutType.Caesar:
|
if click_info and client.layout_type is LayoutType.Caesar:
|
||||||
pytest.skip("click_info not implemented on T2B1")
|
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
|
assert client.features.backup_availability == messages.BackupAvailability.Required
|
||||||
|
|
||||||
|
@ -23,7 +23,10 @@ from trezorlib.messages import SdProtectOperationType as Op
|
|||||||
|
|
||||||
from ..common import MNEMONIC12
|
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):
|
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.setup_client(uninitialized=True)
|
||||||
@pytest.mark.models("safe")
|
@pytest.mark.models("safe", skip=["eckhart"])
|
||||||
def test_tutorial(client: Client):
|
def test_tutorial(client: Client):
|
||||||
device.show_device_tutorial(client)
|
device.show_device_tutorial(client)
|
||||||
assert client.features.initialized is False
|
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):
|
def test_sign_message(client: Client):
|
||||||
_assert_protection(client)
|
_assert_protection(client)
|
||||||
with 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):
|
def test_verify_message_t2(client: Client):
|
||||||
_assert_protection(client)
|
_assert_protection(client)
|
||||||
with client:
|
with client:
|
||||||
|
@ -23,7 +23,7 @@ from trezorlib.messages import SdProtectOperationType as Op
|
|||||||
|
|
||||||
from .. import translations as TR
|
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)
|
@pytest.mark.sd_card(formatted=False)
|
||||||
|
@ -399,7 +399,11 @@ def test_hide_passphrase_from_host(client: Client):
|
|||||||
yield
|
yield
|
||||||
content = client.debug.read_layout().text_content().lower()
|
content = client.debug.read_layout().text_content().lower()
|
||||||
assert TR.passphrase__from_host_not_shown[:50].lower() in content
|
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()
|
client.debug.press_yes()
|
||||||
elif client.layout_type is LayoutType.Caesar:
|
elif client.layout_type is LayoutType.Caesar:
|
||||||
client.debug.press_right()
|
client.debug.press_right()
|
||||||
|
@ -25,7 +25,7 @@ from ...input_flows import InputFlowShowAddressQRCode
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.tezos,
|
pytest.mark.tezos,
|
||||||
pytest.mark.models("core"),
|
pytest.mark.models("core", skip=["eckhart"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
TEST_VECTORS = [
|
TEST_VECTORS = [
|
||||||
|
@ -23,7 +23,7 @@ from trezorlib.tools import parse_path
|
|||||||
|
|
||||||
@pytest.mark.altcoin
|
@pytest.mark.altcoin
|
||||||
@pytest.mark.tezos
|
@pytest.mark.tezos
|
||||||
@pytest.mark.models("core")
|
@pytest.mark.models("core", skip=["eckhart"])
|
||||||
def test_tezos_get_public_key(client: Client):
|
def test_tezos_get_public_key(client: Client):
|
||||||
path = parse_path("m/44h/1729h/0h")
|
path = parse_path("m/44h/1729h/0h")
|
||||||
pk = get_public_key(client, path)
|
pk = get_public_key(client, path)
|
||||||
|
@ -28,7 +28,7 @@ TEZOS_PATH_15 = parse_path("m/44h/1729h/15h")
|
|||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.altcoin,
|
pytest.mark.altcoin,
|
||||||
pytest.mark.tezos,
|
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
|
RK_CAPACITY = 100
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.models("core")
|
@pytest.mark.models("core", skip=["eckhart"])
|
||||||
@pytest.mark.altcoin
|
@pytest.mark.altcoin
|
||||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||||
def test_add_remove(client: Client):
|
def test_add_remove(client: Client):
|
||||||
|
@ -21,6 +21,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.altcoin
|
@pytest.mark.altcoin
|
||||||
|
@pytest.mark.models(skip=["eckhart"])
|
||||||
def test_u2f_counter(client: Client):
|
def test_u2f_counter(client: Client):
|
||||||
assert fido.get_next_counter(client) == 0
|
assert fido.get_next_counter(client) == 0
|
||||||
assert fido.get_next_counter(client) == 1
|
assert fido.get_next_counter(client) == 1
|
||||||
|
@ -50,7 +50,11 @@ TXHASH_4b6cec = bytes.fromhex(
|
|||||||
VERSION_GROUP_ID = 0x26A7270A
|
VERSION_GROUP_ID = 0x26A7270A
|
||||||
BRANCH_ID = 0xC2D6D0B4
|
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):
|
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:
|
def enter_your_backup(self) -> BRGeneratorType:
|
||||||
assert (yield).name == "recovery"
|
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()
|
assert TR.recovery__enter_each_word in self._text_content()
|
||||||
else:
|
else:
|
||||||
assert TR.recovery__enter_backup in self._text_content()
|
assert TR.recovery__enter_backup in self._text_content()
|
||||||
@ -131,7 +131,16 @@ class RecoveryFlow:
|
|||||||
|
|
||||||
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
||||||
yield
|
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()
|
assert TR.recovery__num_of_words in self._text_content()
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
yield
|
yield
|
||||||
@ -141,7 +150,7 @@ class RecoveryFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
else:
|
else:
|
||||||
self.debug.press_no()
|
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()
|
assert TR.recovery__enter_each_word in self._text_content()
|
||||||
self.debug.click(self.debug.screen_buttons.menu())
|
self.debug.click(self.debug.screen_buttons.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
@ -150,18 +159,19 @@ class RecoveryFlow:
|
|||||||
else:
|
else:
|
||||||
self.debug.click(self.debug.screen_buttons.menu())
|
self.debug.click(self.debug.screen_buttons.menu())
|
||||||
else:
|
else:
|
||||||
assert TR.recovery__enter_any_share in self._text_content()
|
raise ValueError("Unknown model!")
|
||||||
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()
|
|
||||||
|
|
||||||
def abort_recovery_between_shares(self) -> BRGeneratorType:
|
def abort_recovery_between_shares(self) -> BRGeneratorType:
|
||||||
yield
|
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(
|
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||||
self._text_content()
|
self._text_content()
|
||||||
)
|
)
|
||||||
@ -182,14 +192,36 @@ class RecoveryFlow:
|
|||||||
layout = self.debug.read_layout()
|
layout = self.debug.read_layout()
|
||||||
assert layout.title() == TR.recovery__title_cancel_recovery
|
assert layout.title() == TR.recovery__title_cancel_recovery
|
||||||
self.debug.click(self.debug.screen_buttons.tap_to_confirm())
|
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(
|
assert TR.regexp("recovery__x_of_y_entered_template").search(
|
||||||
self._text_content()
|
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 (yield).name == "abort_recovery"
|
||||||
assert TR.recovery__wanna_cancel_recovery in self._text_content()
|
layout = self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
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:
|
def input_number_of_words(self, num_words: int | None) -> BRGeneratorType:
|
||||||
br = yield
|
br = yield
|
||||||
@ -325,10 +357,11 @@ class RecoveryFlow:
|
|||||||
if click_info:
|
if click_info:
|
||||||
if self.client.layout_type is LayoutType.Bolt:
|
if self.client.layout_type is LayoutType.Bolt:
|
||||||
yield from self.click_info_bolt()
|
yield from self.click_info_bolt()
|
||||||
elif self.client.layout_type is LayoutType.Delizia:
|
elif self.client.layout_type in (
|
||||||
yield from self.click_info_delizia()
|
LayoutType.Delizia,
|
||||||
else:
|
LayoutType.Eckhart,
|
||||||
raise ValueError("Unknown model!")
|
):
|
||||||
|
yield from self.click_info_delizia_eckhart()
|
||||||
yield from self.success_more_shares_needed()
|
yield from self.success_more_shares_needed()
|
||||||
|
|
||||||
def click_info_bolt(self) -> t.Generator[t.Any, t.Any, None]:
|
def click_info_bolt(self) -> t.Generator[t.Any, t.Any, None]:
|
||||||
@ -339,7 +372,7 @@ class RecoveryFlow:
|
|||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.press_yes()
|
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
|
# Moving through the menu into the show_shares screen
|
||||||
self.debug.click(self.debug.screen_buttons.menu())
|
self.debug.click(self.debug.screen_buttons.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
@ -575,6 +608,31 @@ class EthereumFlow:
|
|||||||
|
|
||||||
self.debug.press_yes()
|
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:
|
elif self.client.layout_type is LayoutType.Delizia:
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
@ -607,30 +665,5 @@ class EthereumFlow:
|
|||||||
|
|
||||||
self.debug.press_yes()
|
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:
|
else:
|
||||||
raise ValueError("Unknown model!")
|
raise ValueError("Unknown model!")
|
||||||
|
@ -40,7 +40,7 @@ def test_abort(core_emulator: Emulator):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
features = device_handler.features()
|
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")
|
pytest.skip("abort not supported on T3T1")
|
||||||
|
|
||||||
assert features.recovery_status == RecoveryStatus.Nothing
|
assert features.recovery_status == RecoveryStatus.Nothing
|
||||||
@ -187,7 +187,7 @@ def test_recovery_multiple_resets(core_emulator: Emulator):
|
|||||||
shares = MNEMONIC_SLIP39_ADVANCED_20
|
shares = MNEMONIC_SLIP39_ADVANCED_20
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
expected_text = "Enter any share"
|
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"
|
expected_text = "Enter each word"
|
||||||
remaining = len(shares)
|
remaining = len(shares)
|
||||||
for share in shares:
|
for share in shares:
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user