mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-05 16:39:08 +00:00
refactor(tests): split buttons module functionality into buttons and actions
This commit is contained in:
parent
4d52f7805f
commit
a4cd4ddaa5
344
tests/buttons.py
344
tests/buttons.py
@ -6,167 +6,227 @@ from trezorlib.debuglink import LayoutType
|
|||||||
Coords = Tuple[int, int]
|
Coords = Tuple[int, int]
|
||||||
|
|
||||||
|
|
||||||
# display dimensions
|
class ScreenButtons:
|
||||||
def display_height(layout_type):
|
def __init__(self, layout_type: LayoutType):
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
assert layout_type in (LayoutType.Bolt, LayoutType.Delizia)
|
||||||
|
self.layout_type = layout_type
|
||||||
|
|
||||||
|
def _width(self) -> int:
|
||||||
return 240
|
return 240
|
||||||
else:
|
|
||||||
raise ValueError("Wrong layout type")
|
|
||||||
|
|
||||||
|
def _height(self) -> int:
|
||||||
def display_width(layout_type):
|
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
|
||||||
return 240
|
return 240
|
||||||
else:
|
|
||||||
raise ValueError("Wrong layout type")
|
|
||||||
|
|
||||||
|
def _grid(self, dim: int, grid_cells: int, cell: int) -> int:
|
||||||
# grid coordinates
|
assert cell < grid_cells
|
||||||
def grid(dim: int, grid_cells: int, cell: int) -> int:
|
|
||||||
step = dim // grid_cells
|
step = dim // grid_cells
|
||||||
ofs = step // 2
|
ofs = step // 2
|
||||||
return cell * step + ofs
|
return cell * step + ofs
|
||||||
|
|
||||||
|
# 3 columns, 4 rows, 1st row is input area
|
||||||
|
def _grid35(self, x: int, y: int) -> Coords:
|
||||||
|
return self._grid(self._width(), 3, x), self._grid(self._height(), 5, y)
|
||||||
|
|
||||||
def grid35(x: int, y: int, layout_type: LayoutType) -> Coords:
|
# TODO: do not expose this
|
||||||
return grid(display_width(layout_type), 3, x), grid(
|
# 3 columns, 3 rows, 1st row is input area
|
||||||
display_height(layout_type), 5, y
|
def grid34(self, x: int, y: int) -> Coords:
|
||||||
)
|
return self._grid(self._width(), 3, x), self._grid(self._height(), 4, y)
|
||||||
|
|
||||||
|
# Horizontal coordinates
|
||||||
|
def _left(self) -> int:
|
||||||
|
return self._grid(self._width(), 3, 0)
|
||||||
|
|
||||||
def grid34(x: int, y: int, layout_type: LayoutType) -> Coords:
|
def _mid(self) -> int:
|
||||||
assert layout_type in (LayoutType.Bolt, LayoutType.Delizia)
|
return self._grid(self._width(), 3, 1)
|
||||||
return grid(display_width(layout_type), 3, x), grid(
|
|
||||||
display_height(layout_type), 4, y
|
|
||||||
)
|
|
||||||
|
|
||||||
|
def _right(self) -> int:
|
||||||
|
return self._grid(self._width(), 3, 2)
|
||||||
|
|
||||||
def _grid34_from_index(idx: int, layout_type: LayoutType) -> Coords:
|
# Vertical coordinates
|
||||||
grid_x = idx % 3
|
def _top(self) -> int:
|
||||||
grid_y = idx // 3 + 1 # first line is empty
|
return self._grid(self._height(), 6, 0)
|
||||||
return grid34(grid_x, grid_y, layout_type)
|
|
||||||
|
|
||||||
|
def _bottom(self) -> int:
|
||||||
|
return self._grid(self._height(), 6, 5)
|
||||||
|
|
||||||
# Horizontal coordinates
|
# Buttons
|
||||||
def left(layout_type: LayoutType):
|
|
||||||
return grid(display_width(layout_type), 3, 0)
|
|
||||||
|
|
||||||
|
# Right bottom
|
||||||
|
def ok(self) -> Coords:
|
||||||
|
return (self._right(), self._bottom())
|
||||||
|
|
||||||
def mid(layout_type: LayoutType):
|
# Left bottom
|
||||||
return grid(display_width(layout_type), 3, 1)
|
def cancel(self) -> Coords:
|
||||||
|
return (self._left(), self._bottom())
|
||||||
|
|
||||||
|
# Mid bottom
|
||||||
|
def info(self) -> Coords:
|
||||||
|
return (self._mid(), self._bottom())
|
||||||
|
|
||||||
def right(layout_type: LayoutType):
|
# Menu/close menu button
|
||||||
return grid(display_width(layout_type), 3, 2)
|
def menu(self) -> Coords:
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
|
|
||||||
# Vertical coordinates
|
|
||||||
def top(layout_type: LayoutType):
|
|
||||||
return grid(display_height(layout_type), 6, 0)
|
|
||||||
|
|
||||||
|
|
||||||
def bottom(layout_type: LayoutType):
|
|
||||||
return grid(display_height(layout_type), 6, 5)
|
|
||||||
|
|
||||||
|
|
||||||
# Buttons
|
|
||||||
|
|
||||||
|
|
||||||
def ok(layout_type: LayoutType) -> Coords:
|
|
||||||
return (right(layout_type), bottom(layout_type))
|
|
||||||
|
|
||||||
|
|
||||||
def cancel(layout_type: LayoutType) -> Coords:
|
|
||||||
return (left(layout_type), bottom(layout_type))
|
|
||||||
|
|
||||||
|
|
||||||
def info(layout_type: LayoutType) -> Coords:
|
|
||||||
return (mid(layout_type), bottom(layout_type))
|
|
||||||
|
|
||||||
|
|
||||||
def recovery_delete(layout_type: LayoutType) -> Coords:
|
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
|
||||||
return (left(layout_type), top(layout_type))
|
|
||||||
else:
|
|
||||||
raise ValueError("Wrong layout type")
|
|
||||||
|
|
||||||
|
|
||||||
def corner_button(layout_type: LayoutType) -> Coords:
|
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
|
||||||
return (215, 25)
|
return (215, 25)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
# Center of the screen
|
||||||
|
def tap_to_confirm(self) -> Coords:
|
||||||
|
assert self.layout_type is LayoutType.Delizia
|
||||||
|
return (self._grid(self._width(), 1, 0), self._grid(self._width(), 1, 0))
|
||||||
|
|
||||||
def confirm_word(layout_type: LayoutType) -> Coords:
|
# Yes/No decision component
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
def ui_yes(self) -> Coords:
|
||||||
return (mid(layout_type), top(layout_type))
|
assert self.layout_type is LayoutType.Delizia
|
||||||
|
return self.grid34(2, 2)
|
||||||
|
|
||||||
|
def ui_no(self) -> Coords:
|
||||||
|
assert self.layout_type is LayoutType.Delizia
|
||||||
|
return self.grid34(0, 2)
|
||||||
|
|
||||||
|
# +/- buttons in number input component
|
||||||
|
def number_input_minus(self) -> Coords:
|
||||||
|
if self.layout_type is LayoutType.Bolt:
|
||||||
|
return (self._left(), self._grid(self._height(), 5, 1))
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
return (self._left(), self._grid(self._height(), 5, 3))
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
def number_input_plus(self) -> Coords:
|
||||||
# PIN/passphrase input
|
if self.layout_type is LayoutType.Bolt:
|
||||||
def input(layout_type: LayoutType) -> Coords:
|
return (self._right(), self._grid(self._height(), 5, 1))
|
||||||
return (mid(layout_type), top(layout_type))
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
return (self._right(), self._grid(self._height(), 5, 3))
|
||||||
|
|
||||||
# Yes/No decision component
|
|
||||||
def ui_yes(layout_type: LayoutType) -> Coords:
|
|
||||||
assert layout_type is LayoutType.Delizia
|
|
||||||
return grid34(2, 2, layout_type)
|
|
||||||
|
|
||||||
|
|
||||||
def ui_no(layout_type: LayoutType) -> Coords:
|
|
||||||
assert layout_type is LayoutType.Delizia
|
|
||||||
return grid34(0, 2, layout_type)
|
|
||||||
|
|
||||||
|
|
||||||
# +/- buttons in number input component
|
|
||||||
def reset_minus(layout_type: LayoutType) -> Coords:
|
|
||||||
if layout_type is LayoutType.Bolt:
|
|
||||||
return (left(layout_type), grid(display_height(layout_type), 5, 1))
|
|
||||||
elif layout_type is LayoutType.Delizia:
|
|
||||||
return (left(layout_type), grid(display_height(layout_type), 5, 3))
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
def word_count_all_word(self, word_count: int) -> Coords:
|
||||||
def reset_plus(layout_type: LayoutType) -> Coords:
|
assert word_count in (12, 18, 20, 24, 33)
|
||||||
if layout_type is LayoutType.Bolt:
|
if self.layout_type is LayoutType.Bolt:
|
||||||
return (right(layout_type), grid(display_height(layout_type), 5, 1))
|
coords_map = {
|
||||||
elif layout_type is LayoutType.Delizia:
|
12: self.grid34(0, 2),
|
||||||
return (right(layout_type), grid(display_height(layout_type), 5, 3))
|
18: self.grid34(1, 2),
|
||||||
|
20: self.grid34(2, 2),
|
||||||
|
24: self.grid34(1, 3),
|
||||||
|
33: self.grid34(2, 3),
|
||||||
|
}
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
coords_map = {
|
||||||
|
12: self.grid34(0, 1),
|
||||||
|
18: self.grid34(2, 1),
|
||||||
|
20: self.grid34(0, 2),
|
||||||
|
24: self.grid34(2, 2),
|
||||||
|
33: self.grid34(2, 3),
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
return coords_map[word_count]
|
||||||
|
|
||||||
# select word component buttons
|
def word_count_all_cancel(self) -> Coords:
|
||||||
def reset_word_check(layout_type: LayoutType) -> Coords:
|
if self.layout_type is LayoutType.Bolt:
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
return self.grid34(0, 3)
|
||||||
|
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
return self.grid34(0, 3)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
def word_count_repeated_word(self, word_count: int) -> Coords:
|
||||||
|
assert word_count in (20, 33)
|
||||||
|
if self.layout_type is LayoutType.Bolt:
|
||||||
|
coords_map = {
|
||||||
|
20: self.grid34(1, 2),
|
||||||
|
33: self.grid34(2, 2),
|
||||||
|
}
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
coords_map = {
|
||||||
|
20: self.grid34(0, 1),
|
||||||
|
33: self.grid34(2, 1),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
return coords_map[word_count]
|
||||||
|
|
||||||
|
def word_count_repeated_cancel(self) -> Coords:
|
||||||
|
if self.layout_type is LayoutType.Bolt:
|
||||||
|
return self.grid34(0, 2)
|
||||||
|
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
return self.grid34(0, 3)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
# select word component buttons
|
||||||
|
def word_check_words(self) -> "list[Coords]":
|
||||||
|
if self.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
return [
|
return [
|
||||||
(mid(layout_type), grid(display_height(layout_type), 5, 2)),
|
(self._mid(), self._grid(self._height(), 5, 2)),
|
||||||
(mid(layout_type), grid(display_height(layout_type), 5, 3)),
|
(self._mid(), self._grid(self._height(), 5, 3)),
|
||||||
(mid(layout_type), grid(display_height(layout_type), 5, 4)),
|
(self._mid(), self._grid(self._height(), 5, 4)),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
# vertical menu buttons
|
||||||
|
def vertical_menu_items(self) -> "list[Coords]":
|
||||||
|
assert self.layout_type is LayoutType.Delizia
|
||||||
|
|
||||||
# vertical menu buttons
|
|
||||||
def vertical_menu(layout_type: LayoutType) -> Coords:
|
|
||||||
if layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
|
||||||
return [
|
return [
|
||||||
(mid(layout_type), grid(display_height(layout_type), 4, 1)),
|
(self._mid(), self._grid(self._height(), 4, 1)),
|
||||||
(mid(layout_type), grid(display_height(layout_type), 4, 2)),
|
(self._mid(), self._grid(self._height(), 4, 2)),
|
||||||
(mid(layout_type), grid(display_height(layout_type), 4, 3)),
|
(self._mid(), self._grid(self._height(), 4, 3)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Pin/passphrase keyboards
|
||||||
|
def pin_passphrase_index(self, idx: int) -> Coords:
|
||||||
|
assert idx < 10
|
||||||
|
if idx == 9:
|
||||||
|
idx = 10 # last digit is in the middle
|
||||||
|
return self.pin_passphrase_grid(idx % 3, idx // 3)
|
||||||
|
|
||||||
|
def pin_passphrase_grid(self, x: int, y: int) -> Coords:
|
||||||
|
assert x < 3, y < 4
|
||||||
|
y += 1 # first line is empty
|
||||||
|
return self._grid35(x, y)
|
||||||
|
|
||||||
|
# PIN/passphrase input
|
||||||
|
def pin_passphrase_input(self) -> Coords:
|
||||||
|
return (self._mid(), self._top())
|
||||||
|
|
||||||
|
def pin_passphrase_erase(self) -> Coords:
|
||||||
|
return self.pin_passphrase_grid(0, 3)
|
||||||
|
|
||||||
|
def passphrase_confirm(self) -> Coords:
|
||||||
|
if self.layout_type is LayoutType.Bolt:
|
||||||
|
return self.pin_passphrase_grid(2, 3)
|
||||||
|
elif self.layout_type is LayoutType.Delizia:
|
||||||
|
return (215, 25)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Wrong layout type")
|
raise ValueError("Wrong layout type")
|
||||||
|
|
||||||
|
def pin_confirm(self) -> Coords:
|
||||||
|
return self.pin_passphrase_grid(2, 3)
|
||||||
|
|
||||||
def tap_to_confirm(layout_type: LayoutType) -> Coords:
|
# Mnemonic keyboard
|
||||||
assert layout_type is LayoutType.Delizia
|
def mnemonic_from_index(self, idx: int) -> Coords:
|
||||||
return vertical_menu(layout_type)[1]
|
return self.mnemonic_grid(idx)
|
||||||
|
|
||||||
|
def mnemonic_grid(self, idx: int) -> Coords:
|
||||||
|
assert idx < 9
|
||||||
|
grid_x = idx % 3
|
||||||
|
grid_y = idx // 3 + 1 # first line is empty
|
||||||
|
return self.grid34(grid_x, grid_y)
|
||||||
|
|
||||||
|
def mnemonic_erase(self) -> Coords:
|
||||||
|
return (self._left(), self._top())
|
||||||
|
|
||||||
|
def mnemonic_confirm(self) -> Coords:
|
||||||
|
return (self._mid(), self._top())
|
||||||
|
|
||||||
|
|
||||||
BUTTON_LETTERS_BIP39 = ("abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz")
|
BUTTON_LETTERS_BIP39 = ("abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz")
|
||||||
@ -194,45 +254,34 @@ def get_passphrase_choices(char: str) -> tuple[str, ...]:
|
|||||||
return PASSPHRASE_SPECIAL
|
return PASSPHRASE_SPECIAL
|
||||||
|
|
||||||
|
|
||||||
def passphrase(char: str, layout_type: LayoutType) -> Tuple[Coords, int]:
|
class ButtonActions:
|
||||||
|
def __init__(self, layout_type: LayoutType):
|
||||||
|
self.buttons = ScreenButtons(layout_type)
|
||||||
|
|
||||||
|
def passphrase(self, char: str) -> Tuple[Coords, int]:
|
||||||
choices = get_passphrase_choices(char)
|
choices = get_passphrase_choices(char)
|
||||||
idx = next(i for i, letters in enumerate(choices) if char in letters)
|
idx = next(i for i, letters in enumerate(choices) if char in letters)
|
||||||
click_amount = choices[idx].index(char) + 1
|
click_amount = choices[idx].index(char) + 1
|
||||||
return pin_passphrase_index(idx, layout_type), click_amount
|
return self.buttons.pin_passphrase_index(idx), click_amount
|
||||||
|
|
||||||
|
def type_word(self, word: str, is_slip39: bool = False) -> Iterator[Coords]:
|
||||||
def pin_passphrase_index(idx: int, layout_type: LayoutType) -> Coords:
|
|
||||||
if idx == 9:
|
|
||||||
idx = 10 # last digit is in the middle
|
|
||||||
return pin_passphrase_grid(idx, layout_type)
|
|
||||||
|
|
||||||
|
|
||||||
def pin_passphrase_grid(idx: int, layout_type: LayoutType) -> Coords:
|
|
||||||
grid_x = idx % 3
|
|
||||||
grid_y = idx // 3 + 1 # first line is empty
|
|
||||||
return grid35(grid_x, grid_y, layout_type)
|
|
||||||
|
|
||||||
|
|
||||||
def type_word(
|
|
||||||
word: str, layout_type: LayoutType, is_slip39: bool = False
|
|
||||||
) -> Iterator[Coords]:
|
|
||||||
if is_slip39:
|
if is_slip39:
|
||||||
yield from _type_word_slip39(word, layout_type)
|
yield from self._type_word_slip39(word)
|
||||||
else:
|
else:
|
||||||
yield from _type_word_bip39(word, layout_type)
|
yield from self._type_word_bip39(word)
|
||||||
|
|
||||||
|
def _type_word_slip39(self, word: str) -> Iterator[Coords]:
|
||||||
def _type_word_slip39(word: str, layout_type: LayoutType) -> Iterator[Coords]:
|
|
||||||
for l in word:
|
for l in word:
|
||||||
idx = next(i for i, letters in enumerate(BUTTON_LETTERS_SLIP39) if l in letters)
|
idx = next(
|
||||||
yield _grid34_from_index(idx, layout_type)
|
i for i, letters in enumerate(BUTTON_LETTERS_SLIP39) if l in letters
|
||||||
|
)
|
||||||
|
yield self.buttons.mnemonic_from_index(idx)
|
||||||
|
|
||||||
|
def _type_word_bip39(self, word: str) -> Iterator[Coords]:
|
||||||
def _type_word_bip39(word: str, layout_type: LayoutType) -> Iterator[Coords]:
|
|
||||||
coords_prev: Coords | None = None
|
coords_prev: Coords | None = None
|
||||||
for letter in word:
|
for letter in word:
|
||||||
time.sleep(0.1) # not being so quick to miss something
|
time.sleep(0.1) # not being so quick to miss something
|
||||||
coords, amount = _letter_coords_and_amount(letter, layout_type)
|
coords, amount = self._letter_coords_and_amount(letter)
|
||||||
# If the button is the same as for the previous letter,
|
# If the button is the same as for the previous letter,
|
||||||
# waiting a second before pressing it again.
|
# waiting a second before pressing it again.
|
||||||
if coords == coords_prev:
|
if coords == coords_prev:
|
||||||
@ -241,10 +290,9 @@ def _type_word_bip39(word: str, layout_type: LayoutType) -> Iterator[Coords]:
|
|||||||
for _ in range(amount):
|
for _ in range(amount):
|
||||||
yield coords
|
yield coords
|
||||||
|
|
||||||
|
def _letter_coords_and_amount(self, letter: str) -> Tuple[Coords, int]:
|
||||||
def _letter_coords_and_amount(
|
idx = next(
|
||||||
letter: str, layout_type: LayoutType
|
i for i, letters in enumerate(BUTTON_LETTERS_BIP39) if letter in letters
|
||||||
) -> Tuple[Coords, int]:
|
)
|
||||||
idx = next(i for i, letters in enumerate(BUTTON_LETTERS_BIP39) if letter in letters)
|
|
||||||
click_amount = BUTTON_LETTERS_BIP39[idx].index(letter) + 1
|
click_amount = BUTTON_LETTERS_BIP39[idx].index(letter) + 1
|
||||||
return _grid34_from_index(idx, layout_type), click_amount
|
return self.buttons.mnemonic_from_index(idx), click_amount
|
||||||
|
@ -49,7 +49,8 @@ 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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
@ -61,7 +62,8 @@ 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):
|
||||||
debug.click(buttons.cancel(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.cancel())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
if r_middle:
|
if r_middle:
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
@ -116,11 +118,13 @@ 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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.tap_to_confirm())
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown model")
|
raise RuntimeError("Unknown model")
|
||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
@ -91,7 +91,8 @@ CLICKS_HELP = """\
|
|||||||
Type 'y' or just press Enter to click the right button (usually "OK")
|
Type 'y' or just press Enter to click the right button (usually "OK")
|
||||||
Type 'n' to click the left button (usually "Cancel")
|
Type 'n' to click the left button (usually "Cancel")
|
||||||
Type a digit (0-9) to click the appropriate button as if on a numpad.
|
Type a digit (0-9) to click the appropriate button as if on a numpad.
|
||||||
Type 'g1,2' to click button in column 1 and row 2 of 3x5 grid (letter A on mnemonic keyboard).
|
Type 'm1,2' to click button in column 1 and row 2 of mnemonic keyboard (letter J).
|
||||||
|
Type 'p2,1' to click button in column 2 and row 1 of pin/passphrase keyboard (letter D).
|
||||||
Type 'i 1234' to send text "1234" without clicking (useful for PIN, passphrase, etc.)
|
Type 'i 1234' to send text "1234" without clicking (useful for PIN, passphrase, etc.)
|
||||||
Type 'u' or 'j' to swipe up, 'd' or 'k' to swipe down.
|
Type 'u' or 'j' to swipe up, 'd' or 'k' to swipe down.
|
||||||
Type 'confirm' for hold-to-confirm (or a confirmation signal without clicking).
|
Type 'confirm' for hold-to-confirm (or a confirmation signal without clicking).
|
||||||
@ -138,29 +139,37 @@ def send_clicks(dest):
|
|||||||
input_str = key[2:]
|
input_str = key[2:]
|
||||||
output = f"debug.input({input_str!r})"
|
output = f"debug.input({input_str!r})"
|
||||||
DEBUGLINK.input(input_str)
|
DEBUGLINK.input(input_str)
|
||||||
elif key.startswith("g"):
|
elif key.startswith("m"):
|
||||||
x, y = [int(s) - 1 for s in key[1:].split(",")]
|
x, y = [int(s) - 1 for s in key[1:].split(",")]
|
||||||
output = (
|
output = (
|
||||||
f"debug.click(buttons.grid35({x}, {y}, {DEBUGLINK.layout_type}))"
|
f"debug.click(ScreenButtons(layout_type).mnemonic_grid({x}, {y}))"
|
||||||
|
)
|
||||||
|
DEBUGLINK.click(
|
||||||
|
buttons.ScreenButtons(DEBUGLINK.layout_type).mnemonic_grid(x, y)
|
||||||
|
)
|
||||||
|
|
||||||
|
elif key.startswith("p"):
|
||||||
|
x, y = [int(s) - 1 for s in key[1:].split(",")]
|
||||||
|
output = f"debug.click(ScreenButtons(layout_type).pin_passphrase_grid({x}, {y}))"
|
||||||
|
DEBUGLINK.click(
|
||||||
|
buttons.ScreenButtons(DEBUGLINK.layout_type).pin_passphrase_grid(
|
||||||
|
x, y
|
||||||
|
)
|
||||||
)
|
)
|
||||||
DEBUGLINK.click(buttons.grid35(x, y, DEBUGLINK.layout_type))
|
|
||||||
elif key == "y":
|
elif key == "y":
|
||||||
output = "debug.click(buttons.ok(layout_type))"
|
output = "debug.click(ScreenButtons(layout_type).ok())"
|
||||||
DEBUGLINK.click(buttons.ok(DEBUGLINK.layout_type))
|
DEBUGLINK.click(buttons.ScreenButtons(DEBUGLINK.layout_type).ok())
|
||||||
elif key == "n":
|
elif key == "n":
|
||||||
output = "debug.click(buttons.cancel(layout_type))"
|
output = "debug.click(ScreenButtons(layout_type).cancel())"
|
||||||
DEBUGLINK.click(buttons.cancel(DEBUGLINK.layout_type))
|
DEBUGLINK.click(buttons.ScreenButtons(DEBUGLINK.layout_type).cancel())
|
||||||
elif key in "0123456789":
|
elif key in "0123456789":
|
||||||
if key == "0":
|
index = int(key)
|
||||||
x, y = 1, 4
|
output = f"debug.click(ScreenButtons(layout_type).pin_passphrase_index({index}))"
|
||||||
else:
|
DEBUGLINK.click(
|
||||||
i = int(key) - 1
|
buttons.ScreenButtons(DEBUGLINK.layout_type).pin_passphrase_index(
|
||||||
x = i % 3
|
index
|
||||||
y = 3 - (i // 3) # trust me
|
)
|
||||||
output = (
|
|
||||||
f"debug.click(buttons.grid35({x}, {y}, {DEBUGLINK.layout_type}))"
|
|
||||||
)
|
)
|
||||||
DEBUGLINK.click(buttons.grid35(x, y, DEBUGLINK.layout_type))
|
|
||||||
elif key == "stop":
|
elif key == "stop":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -17,15 +17,15 @@ 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):
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
typed_word = word[:4]
|
typed_word = word[:4]
|
||||||
for coords in buttons.type_word(
|
for coords in actions.type_word(typed_word, is_slip39=is_slip39):
|
||||||
typed_word, debug.layout_type, 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 is LayoutType.Delizia 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(buttons.input(debug.layout_type))
|
debug.click(btns.mnemonic_confirm())
|
||||||
debug.click(buttons.input(debug.layout_type))
|
debug.click(btns.mnemonic_confirm())
|
||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
letter_index = 0
|
letter_index = 0
|
||||||
@ -57,7 +57,8 @@ 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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
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.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
@ -70,12 +71,13 @@ def cancel_select_number_of_words(
|
|||||||
unlock_repeated_backup=False,
|
unlock_repeated_backup=False,
|
||||||
) -> None:
|
) -> None:
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
assert debug.read_layout().text_content() == TR.recovery__num_of_words
|
assert debug.read_layout().text_content() == TR.recovery__num_of_words
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
if unlock_repeated_backup:
|
if unlock_repeated_backup:
|
||||||
coords = buttons.grid34(0, 2, debug.layout_type)
|
coords = btns.word_count_repeated_cancel()
|
||||||
else:
|
else:
|
||||||
coords = buttons.grid34(0, 3, debug.layout_type)
|
coords = btns.word_count_all_cancel()
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
@ -84,8 +86,13 @@ def cancel_select_number_of_words(
|
|||||||
# 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 is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
debug.click(buttons.grid34(0, 3, debug.layout_type))
|
if unlock_repeated_backup:
|
||||||
|
coords = btns.word_count_repeated_cancel()
|
||||||
|
else:
|
||||||
|
coords = btns.word_count_all_cancel()
|
||||||
|
debug.click(coords)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown model")
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
@ -99,23 +106,13 @@ def select_number_of_words(
|
|||||||
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_bolt() -> "LayoutContent":
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
if unlock_repeated_backup:
|
if unlock_repeated_backup:
|
||||||
coords_map = {
|
coords = btns.word_count_repeated_word(num_of_words)
|
||||||
20: buttons.grid34(1, 2, debug.layout_type),
|
|
||||||
33: buttons.grid34(2, 2, debug.layout_type),
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
coords_map = {
|
coords = btns.word_count_all_word(num_of_words)
|
||||||
12: buttons.grid34(0, 2, debug.layout_type),
|
|
||||||
18: buttons.grid34(1, 2, debug.layout_type),
|
|
||||||
20: buttons.grid34(2, 2, debug.layout_type),
|
|
||||||
24: buttons.grid34(1, 3, debug.layout_type),
|
|
||||||
33: buttons.grid34(2, 3, debug.layout_type),
|
|
||||||
}
|
|
||||||
coords = coords_map.get(num_of_words)
|
|
||||||
if coords is None:
|
|
||||||
raise ValueError("Invalid num_of_words")
|
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
|
||||||
@ -129,23 +126,12 @@ def select_number_of_words(
|
|||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
|
||||||
def select_delizia() -> "LayoutContent":
|
def select_delizia() -> "LayoutContent":
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
if unlock_repeated_backup:
|
if unlock_repeated_backup:
|
||||||
coords_map = {
|
coords = btns.word_count_repeated_word(num_of_words)
|
||||||
20: buttons.grid34(0, 1, debug.layout_type),
|
|
||||||
33: buttons.grid34(2, 1, debug.layout_type),
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
coords_map = {
|
coords = btns.word_count_all_word(num_of_words)
|
||||||
12: buttons.grid34(0, 1, debug.layout_type),
|
|
||||||
18: buttons.grid34(2, 1, debug.layout_type),
|
|
||||||
20: buttons.grid34(0, 2, debug.layout_type),
|
|
||||||
24: buttons.grid34(2, 2, debug.layout_type),
|
|
||||||
33: buttons.grid34(2, 3, debug.layout_type),
|
|
||||||
}
|
|
||||||
coords = coords_map.get(num_of_words)
|
|
||||||
if coords is None:
|
|
||||||
raise ValueError("Invalid num_of_words")
|
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
return debug.read_layout()
|
return debug.read_layout()
|
||||||
|
|
||||||
@ -200,8 +186,9 @@ def enter_share(
|
|||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
else:
|
else:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
assert TR.translate(before_title) in debug.read_layout().title()
|
assert TR.translate(before_title) in debug.read_layout().title()
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
@ -276,9 +263,10 @@ def enter_seed_previous_correct(
|
|||||||
if go_back:
|
if go_back:
|
||||||
go_back = False
|
go_back = False
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.swipe_right()
|
debug.swipe_right()
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
debug.click(buttons.recovery_delete(debug.layout_type))
|
debug.click(btns.mnemonic_erase())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
|
||||||
@ -295,9 +283,10 @@ def enter_seed_previous_correct(
|
|||||||
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 is LayoutType.Delizia:
|
||||||
debug.click(buttons.recovery_delete(debug.layout_type)) # Top-left
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.mnemonic_erase()) # Top-left
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
debug.click(buttons.recovery_delete(debug.layout_type))
|
debug.click(btns.mnemonic_erase())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if i in bad_indexes:
|
if i in bad_indexes:
|
||||||
@ -322,7 +311,8 @@ def prepare_enter_seed(
|
|||||||
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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -348,10 +338,11 @@ def cancel_recovery(debug: "DebugLink", recovery_type: str = "dry_run") -> None:
|
|||||||
assert title in layout.title()
|
assert title in layout.title()
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
debug.click(buttons.cancel(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.cancel())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert cancel_title in layout.title()
|
assert cancel_title in layout.title()
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_left()
|
debug.press_left()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
@ -359,13 +350,14 @@ def cancel_recovery(debug: "DebugLink", recovery_type: str = "dry_run") -> None:
|
|||||||
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 is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
# go to menu
|
# go to menu
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert (
|
assert (
|
||||||
TR.translate(f"recovery__cancel_{recovery_type}") in layout.text_content()
|
TR.translate(f"recovery__cancel_{recovery_type}") in layout.text_content()
|
||||||
)
|
)
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[0])
|
debug.click(btns.vertical_menu_items()[0])
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown model")
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
|
@ -15,10 +15,12 @@ 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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
@ -32,7 +34,8 @@ def confirm_new_wallet(debug: "DebugLink") -> None:
|
|||||||
|
|
||||||
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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
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.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
@ -50,14 +53,16 @@ def cancel_backup(
|
|||||||
debug: "DebugLink", middle_r: bool = False, confirm: bool = False
|
debug: "DebugLink", middle_r: bool = False, confirm: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
debug.click(buttons.cancel(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(buttons.cancel(debug.layout_type))
|
debug.click(btns.cancel())
|
||||||
|
debug.click(btns.cancel())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[0])
|
debug.click(btns.menu())
|
||||||
|
debug.click(btns.vertical_menu_items()[0])
|
||||||
if confirm:
|
if confirm:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_left()
|
debug.press_left()
|
||||||
debug.press_left()
|
debug.press_left()
|
||||||
@ -65,19 +70,16 @@ def cancel_backup(
|
|||||||
|
|
||||||
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):
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
assert "NumberInputDialog" in debug.read_layout().all_components()
|
assert "NumberInputDialog" in debug.read_layout().all_components()
|
||||||
|
|
||||||
button = (
|
button = btns.number_input_minus() if diff < 0 else btns.number_input_plus()
|
||||||
buttons.reset_minus(debug.layout_type)
|
|
||||||
if diff < 0
|
|
||||||
else buttons.reset_plus(debug.layout_type)
|
|
||||||
)
|
|
||||||
diff = abs(diff)
|
diff = abs(diff)
|
||||||
|
|
||||||
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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
else:
|
else:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
@ -123,9 +125,11 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
|||||||
# 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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type), hold_ms=1500)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok(), hold_ms=1500)
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.tap_to_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right(hold_ms=1200)
|
debug.press_right(hold_ms=1200)
|
||||||
else:
|
else:
|
||||||
@ -142,6 +146,7 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
|||||||
|
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
assert TR.regexp("reset__select_word_x_of_y_template").match(
|
assert TR.regexp("reset__select_word_x_of_y_template").match(
|
||||||
layout.text_content()
|
layout.text_content()
|
||||||
)
|
)
|
||||||
@ -157,9 +162,10 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
|||||||
]
|
]
|
||||||
wanted_word = words[word_pos - 1].lower()
|
wanted_word = words[word_pos - 1].lower()
|
||||||
button_pos = btn_texts.index(wanted_word)
|
button_pos = btn_texts.index(wanted_word)
|
||||||
debug.click(buttons.reset_word_check(debug.layout_type)[button_pos])
|
debug.click(btns.word_check_words()[button_pos])
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
assert TR.regexp("reset__select_word_x_of_y_template").match(layout.subtitle())
|
assert TR.regexp("reset__select_word_x_of_y_template").match(layout.subtitle())
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
# "Select word 3 of 20"
|
# "Select word 3 of 20"
|
||||||
@ -173,7 +179,7 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
|||||||
]
|
]
|
||||||
wanted_word = words[word_pos - 1].lower()
|
wanted_word = words[word_pos - 1].lower()
|
||||||
button_pos = btn_texts.index(wanted_word)
|
button_pos = btn_texts.index(wanted_word)
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[button_pos])
|
debug.click(btns.vertical_menu_items()[button_pos])
|
||||||
layout = debug.read_layout()
|
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()
|
||||||
|
@ -21,7 +21,7 @@ from typing import TYPE_CHECKING, Tuple
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc, device, exceptions, messages
|
from trezorlib import btc, device, exceptions, messages
|
||||||
from trezorlib.debuglink import LayoutType
|
from trezorlib.debuglink import DebugLink, LayoutType
|
||||||
from trezorlib.protobuf import MessageType
|
from trezorlib.protobuf import MessageType
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ from . import recovery
|
|||||||
from .common import go_next, unlock_gesture
|
from .common import go_next, unlock_gesture
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezorlib.debuglink import DebugLink, LayoutContent
|
from trezorlib.debuglink import LayoutContent
|
||||||
|
|
||||||
from ..device_handler import BackgroundDeviceHandler
|
from ..device_handler import BackgroundDeviceHandler
|
||||||
|
|
||||||
@ -53,8 +53,17 @@ TXHASH_d5f65e = bytes.fromhex(
|
|||||||
PIN4 = "1234"
|
PIN4 = "1234"
|
||||||
|
|
||||||
|
|
||||||
def _center_button(layout_type: LayoutType) -> Tuple[int, int]:
|
def _passphrase_j(debug: DebugLink) -> Tuple[int, int]:
|
||||||
return buttons.grid35(1, 2, layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
|
return btns.pin_passphrase_grid(1, 1)
|
||||||
|
else:
|
||||||
|
return btns.pin_passphrase_grid(0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def _center_button(debug: DebugLink) -> Tuple[int, int]:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
return btns.pin_passphrase_grid(1, 1)
|
||||||
|
|
||||||
|
|
||||||
def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int):
|
def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int):
|
||||||
@ -72,7 +81,8 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int)
|
|||||||
|
|
||||||
layout = go_next(debug)
|
layout = go_next(debug)
|
||||||
if debug.layout_type is LayoutType.Delizia:
|
if debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.tap_to_confirm())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout.main_component() == "Homescreen"
|
assert layout.main_component() == "Homescreen"
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
@ -107,8 +117,9 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
|
debug.click(btns.ok())
|
||||||
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()
|
||||||
@ -162,12 +173,14 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
|||||||
)
|
)
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Bolt:
|
if debug.layout_type is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
|
debug.click(btns.ok())
|
||||||
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()
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
@ -190,9 +203,9 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
|||||||
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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
|
|
||||||
@ -220,12 +233,9 @@ 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 is LayoutType.Bolt:
|
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
# click at "j"
|
# click at "j"
|
||||||
debug.click(_center_button(debug.layout_type))
|
debug.click(_passphrase_j(debug))
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
|
||||||
# click at "j"
|
|
||||||
debug.click((20, 120))
|
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
# just go right
|
# just go right
|
||||||
# NOTE: because of passphrase randomization it would be a pain to input
|
# NOTE: because of passphrase randomization it would be a pain to input
|
||||||
@ -234,10 +244,9 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
|||||||
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 is LayoutType.Bolt:
|
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
debug.click(btns.passphrase_confirm())
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
debug.input("j" * 8)
|
debug.input("j" * 8)
|
||||||
|
|
||||||
@ -263,7 +272,7 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
|||||||
# 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):
|
||||||
debug.click(_center_button(debug.layout_type))
|
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()
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
@ -359,29 +368,33 @@ def test_dryrun_enter_word_slowly(device_handler: "BackgroundDeviceHandler"):
|
|||||||
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 is LayoutType.Bolt:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
|
|
||||||
# type the word OCEAN slowly
|
# type the word OCEAN slowly
|
||||||
for coords in buttons.type_word("ocea", debug.layout_type, is_slip39=True):
|
for coords in actions.type_word("ocea", is_slip39=True):
|
||||||
time.sleep(9)
|
time.sleep(9)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
debug.click(buttons.input(debug.layout_type))
|
debug.click(btns.mnemonic_confirm())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
# should not have locked, even though we took 9 seconds to type each letter
|
# should not have locked, even though we took 9 seconds to type each letter
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
|
|
||||||
elif debug.layout_type is LayoutType.Delizia:
|
elif debug.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
|
|
||||||
# type the word OCEAN slowly
|
# type the word OCEAN slowly
|
||||||
for coords in buttons.type_word("ocea", debug.layout_type, is_slip39=True):
|
for coords in actions.type_word("ocea", is_slip39=True):
|
||||||
time.sleep(9)
|
time.sleep(9)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
debug.click(buttons.input(debug.layout_type))
|
debug.click(btns.mnemonic_confirm())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
# should not have locked, even though we took 9 seconds to type each letter
|
# should not have locked, even though we took 9 seconds to type each letter
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
|
@ -81,7 +81,8 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
|||||||
if debug.layout_type is LayoutType.Caesar:
|
if debug.layout_type is LayoutType.Caesar:
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
else:
|
else:
|
||||||
debug.click(buttons.info(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.info())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert "PinKeyboard" in layout.all_components()
|
assert "PinKeyboard" in layout.all_components()
|
||||||
debug.input("1234")
|
debug.input("1234")
|
||||||
|
@ -117,7 +117,8 @@ def press_char(debug: "DebugLink", char: str) -> None:
|
|||||||
|
|
||||||
go_to_category(debug, char_category)
|
go_to_category(debug, char_category)
|
||||||
|
|
||||||
coords, amount = buttons.passphrase(char, debug.layout_type)
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
|
coords, amount = actions.passphrase(char)
|
||||||
# If the button is the same as for the previous char,
|
# If the button is the same as for the previous char,
|
||||||
# waiting a second before pressing it again.
|
# waiting a second before pressing it again.
|
||||||
# (not for a space)
|
# (not for a space)
|
||||||
@ -141,13 +142,15 @@ def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) ->
|
|||||||
|
|
||||||
def enter_passphrase(debug: "DebugLink") -> None:
|
def enter_passphrase(debug: "DebugLink") -> None:
|
||||||
"""Enter a passphrase"""
|
"""Enter a passphrase"""
|
||||||
coords = buttons.pin_passphrase_grid(11, debug.layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
coords = btns.passphrase_confirm()
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
def delete_char(debug: "DebugLink") -> None:
|
def delete_char(debug: "DebugLink") -> None:
|
||||||
"""Deletes the last char"""
|
"""Deletes the last char"""
|
||||||
coords = buttons.pin_passphrase_grid(9, debug.layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
coords = btns.pin_passphrase_erase()
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
@ -216,8 +219,8 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
|||||||
go_to_category(debug, category)
|
go_to_category(debug, category)
|
||||||
|
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
coords = buttons.pin_passphrase_grid(11, debug.layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(coords)
|
debug.click(btns.passphrase_confirm())
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(passphrase=True)
|
@pytest.mark.setup_client(passphrase=True)
|
||||||
@ -225,7 +228,8 @@ def test_passphrase_click_same_button_many_times(
|
|||||||
device_handler: "BackgroundDeviceHandler",
|
device_handler: "BackgroundDeviceHandler",
|
||||||
):
|
):
|
||||||
with prepare_passphrase_dialogue(device_handler) as debug:
|
with prepare_passphrase_dialogue(device_handler) as debug:
|
||||||
a_coords, _ = buttons.passphrase("a", debug.layout_type)
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
|
a_coords, _ = actions.passphrase("a")
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
debug.click(a_coords)
|
debug.click(a_coords)
|
||||||
|
|
||||||
|
@ -87,10 +87,11 @@ def get_passphrase_choices(char: str) -> tuple[str, ...]:
|
|||||||
|
|
||||||
|
|
||||||
def passphrase(char: str, layout_type: LayoutType) -> Tuple[buttons.Coords, int]:
|
def passphrase(char: str, layout_type: LayoutType) -> Tuple[buttons.Coords, int]:
|
||||||
|
btns = buttons.ScreenButtons(layout_type)
|
||||||
choices = get_passphrase_choices(char)
|
choices = get_passphrase_choices(char)
|
||||||
idx = next(i for i, letters in enumerate(choices) if char in letters)
|
idx = next(i for i, letters in enumerate(choices) if char in letters)
|
||||||
click_amount = choices[idx].index(char) + 1
|
click_amount = choices[idx].index(char) + 1
|
||||||
return buttons.pin_passphrase_index(idx, layout_type), click_amount
|
return btns.pin_passphrase_index(idx), click_amount
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@ -171,16 +172,16 @@ def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) ->
|
|||||||
def enter_passphrase(debug: "DebugLink") -> None:
|
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
|
||||||
coords = buttons.corner_button(debug.layout_type) # top-right corner
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(coords)
|
debug.click(btns.passphrase_confirm())
|
||||||
if is_empty:
|
if is_empty:
|
||||||
debug.click(buttons.ui_yes(debug.layout_type))
|
debug.click(btns.ui_yes())
|
||||||
|
|
||||||
|
|
||||||
def delete_char(debug: "DebugLink") -> None:
|
def delete_char(debug: "DebugLink") -> None:
|
||||||
"""Deletes the last char"""
|
"""Deletes the last char"""
|
||||||
coords = buttons.pin_passphrase_grid(9, debug.layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(coords)
|
debug.click(btns.pin_passphrase_erase())
|
||||||
|
|
||||||
|
|
||||||
VECTORS = ( # passphrase, address
|
VECTORS = ( # passphrase, address
|
||||||
@ -250,8 +251,8 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
|||||||
debug.read_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
coords = buttons.pin_passphrase_grid(11, debug.layout_type)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
debug.click(coords)
|
debug.click(btns.passphrase_confirm())
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(passphrase=True)
|
@pytest.mark.setup_client(passphrase=True)
|
||||||
@ -259,7 +260,8 @@ def test_passphrase_click_same_button_many_times(
|
|||||||
device_handler: "BackgroundDeviceHandler",
|
device_handler: "BackgroundDeviceHandler",
|
||||||
):
|
):
|
||||||
with prepare_passphrase_dialogue(device_handler) as debug:
|
with prepare_passphrase_dialogue(device_handler) as debug:
|
||||||
a_coords, _ = buttons.passphrase("a", debug.layout_type)
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
|
a_coords, _ = actions.passphrase("a")
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
debug.click(a_coords)
|
debug.click(a_coords)
|
||||||
|
|
||||||
|
@ -138,8 +138,9 @@ def prepare(
|
|||||||
yield debug
|
yield debug
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Delizia and tap:
|
if debug.layout_type is LayoutType.Delizia and tap:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
else:
|
else:
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
|
|
||||||
@ -154,12 +155,12 @@ 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):
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
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)
|
||||||
coords = buttons.pin_passphrase_index(digit_index, debug.layout_type)
|
coords = btns.pin_passphrase_index(digit_index)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
elif debug.layout_type is LayoutType.Caesar:
|
elif debug.layout_type is LayoutType.Caesar:
|
||||||
for digit in pin:
|
for digit in pin:
|
||||||
@ -173,7 +174,8 @@ 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):
|
||||||
debug.click(buttons.input(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.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)
|
||||||
|
|
||||||
@ -185,7 +187,8 @@ def _delete_pin(debug: "DebugLink", digits_to_delete: int, check: bool = True) -
|
|||||||
|
|
||||||
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):
|
||||||
debug.click(buttons.pin_passphrase_grid(9, debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.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)
|
||||||
|
|
||||||
@ -197,7 +200,11 @@ 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):
|
||||||
debug.click(buttons.pin_passphrase_grid(9, debug.layout_type), hold_ms=1500)
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(
|
||||||
|
btns.pin_passphrase_erase(),
|
||||||
|
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)
|
||||||
|
|
||||||
@ -221,7 +228,8 @@ 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):
|
||||||
debug.click(buttons.pin_passphrase_grid(11, debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.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)
|
||||||
|
|
||||||
|
@ -36,10 +36,11 @@ pytestmark = [
|
|||||||
|
|
||||||
def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
||||||
@ -47,7 +48,7 @@ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
|||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_hold
|
assert debug.read_layout().title() == TR.tutorial__title_hold
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
@ -56,24 +57,25 @@ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"):
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_hold
|
assert debug.read_layout().title() == TR.tutorial__title_hold
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
@ -82,21 +84,22 @@ def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"):
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[2])
|
debug.click(btns.vertical_menu_items()[2])
|
||||||
assert TR.instructions__hold_to_exit_tutorial in debug.read_layout().footer()
|
assert TR.instructions__hold_to_exit_tutorial in debug.read_layout().footer()
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
@ -105,19 +108,20 @@ def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[1])
|
debug.click(btns.vertical_menu_items()[1])
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
@ -126,7 +130,7 @@ def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
|||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_hold
|
assert debug.read_layout().title() == TR.tutorial__title_hold
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
@ -135,31 +139,32 @@ def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
def test_tutorial_menu_funfact(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_menu_funfact(device_handler: "BackgroundDeviceHandler"):
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
assert debug.read_layout().title() == TR.tutorial__welcome_safe5
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
assert debug.read_layout().title() == TR.tutorial__title_lets_begin
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
assert debug.read_layout().title() == TR.tutorial__title_easy_navigation
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[0])
|
debug.click(btns.vertical_menu_items()[0])
|
||||||
assert debug.read_layout().text_content() in TR.tutorial__first_wallet.replace(
|
assert debug.read_layout().text_content() in TR.tutorial__first_wallet.replace(
|
||||||
"\n", " "
|
"\n", " "
|
||||||
)
|
)
|
||||||
|
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
assert TR.tutorial__did_you_know in debug.read_layout().text_content()
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
assert debug.read_layout().title() == TR.tutorial__title_handy_menu
|
||||||
|
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_hold
|
assert debug.read_layout().title() == TR.tutorial__title_hold
|
||||||
debug.click(buttons.tap_to_confirm(debug.layout_type))
|
debug.click(btns.tap_to_confirm())
|
||||||
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
assert debug.read_layout().title() == TR.tutorial__title_well_done
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
|
@ -323,12 +323,13 @@ def click_info_button_bolt(debug: "DebugLink") -> Generator[Any, Any, ButtonRequ
|
|||||||
|
|
||||||
def click_info_button_delizia(debug: "DebugLink"):
|
def click_info_button_delizia(debug: "DebugLink"):
|
||||||
"""Click Shamir backup info button and return back."""
|
"""Click Shamir backup info button and return back."""
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.menu())
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
assert "VerticalMenu" in layout.all_components()
|
assert "VerticalMenu" in layout.all_components()
|
||||||
debug.click(buttons.vertical_menu(debug.layout_type)[0])
|
debug.click(btns.vertical_menu_items()[0])
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
debug.click(buttons.corner_button(debug.layout_type))
|
debug.click(btns.menu())
|
||||||
|
|
||||||
|
|
||||||
def check_pin_backoff_time(attempts: int, start: float) -> None:
|
def check_pin_backoff_time(attempts: int, start: float) -> None:
|
||||||
|
@ -41,9 +41,10 @@ def show_details_input_flow(client: Client):
|
|||||||
# 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 is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(client.layout_type)
|
||||||
# Delizia - "Show all" button from context menu
|
# Delizia - "Show all" button from context menu
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
client.debug.click(buttons.vertical_menu(client.layout_type)[0])
|
client.debug.click(btns.vertical_menu_items()[0])
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
# reset ui flow to continue "automatically"
|
# reset ui flow to continue "automatically"
|
||||||
|
@ -187,17 +187,18 @@ def test_change_invalid_current(client: Client):
|
|||||||
def test_pin_menu_cancel_setup(client: Client):
|
def test_pin_menu_cancel_setup(client: Client):
|
||||||
def cancel_pin_setup_input_flow():
|
def cancel_pin_setup_input_flow():
|
||||||
yield
|
yield
|
||||||
|
btns = buttons.ScreenButtons(client.layout_type)
|
||||||
# enter context menu
|
# enter context menu
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
client.debug.synchronize_at("VerticalMenu")
|
client.debug.synchronize_at("VerticalMenu")
|
||||||
# click "Cancel PIN setup"
|
# click "Cancel PIN setup"
|
||||||
client.debug.click(buttons.vertical_menu(client.layout_type)[0])
|
client.debug.click(btns.vertical_menu_items()[0])
|
||||||
client.debug.synchronize_at("Paragraphs")
|
client.debug.synchronize_at("Paragraphs")
|
||||||
# swipe through info screen
|
# swipe through info screen
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
client.debug.synchronize_at("PromptScreen")
|
client.debug.synchronize_at("PromptScreen")
|
||||||
# tap to confirm
|
# tap to confirm
|
||||||
client.debug.click(buttons.tap_to_confirm(client.layout_type))
|
client.debug.click(btns.tap_to_confirm())
|
||||||
|
|
||||||
with client, pytest.raises(Cancelled):
|
with client, pytest.raises(Cancelled):
|
||||||
client.set_input_flow(cancel_pin_setup_input_flow)
|
client.set_input_flow(cancel_pin_setup_input_flow)
|
||||||
|
@ -316,12 +316,13 @@ class InputFlowSignVerifyMessageLong(InputFlowBase):
|
|||||||
layouts: list[LayoutContent] = []
|
layouts: list[LayoutContent] = []
|
||||||
|
|
||||||
br = yield # confirm address
|
br = yield # confirm address
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
self.debug.read_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
self.debug.read_layout()
|
self.debug.read_layout()
|
||||||
@ -351,8 +352,9 @@ class InputFlowSignMessageInfo(InputFlowBase):
|
|||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
# signing address/message info
|
# signing address/message info
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
|
self.debug.click(btns.menu())
|
||||||
# signing address "x"
|
# signing address "x"
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
self.debug.synchronize_at("IconDialog")
|
self.debug.synchronize_at("IconDialog")
|
||||||
@ -363,10 +365,11 @@ class InputFlowSignMessageInfo(InputFlowBase):
|
|||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
# show address/message info
|
# show address/message info
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.menu())
|
||||||
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
# address mismatch? yes!
|
# address mismatch? yes!
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield
|
yield
|
||||||
@ -378,14 +381,15 @@ class InputFlowShowAddressQRCode(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
# synchronize; TODO get rid of this once we have single-global-layout
|
# synchronize; TODO get rid of this once we have single-global-layout
|
||||||
self.debug.synchronize_at("SimplePage")
|
self.debug.synchronize_at("SimplePage")
|
||||||
|
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.swipe_right()
|
self.debug.swipe_right()
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -413,26 +417,27 @@ class InputFlowShowAddressQRCode(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
# synchronize; TODO get rid of this once we have single-global-layout
|
# synchronize; TODO get rid of this once we have single-global-layout
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
# address details
|
# address details
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[2])
|
self.debug.click(btns.vertical_menu_items()[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
|
|
||||||
layout = self.debug.read_layout()
|
layout = self.debug.read_layout()
|
||||||
while "PromptScreen" not in layout.all_components():
|
while "PromptScreen" not in layout.all_components():
|
||||||
@ -440,7 +445,7 @@ class InputFlowShowAddressQRCode(InputFlowBase):
|
|||||||
layout = self.debug.read_layout()
|
layout = self.debug.read_layout()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
# tap to confirm
|
# tap to confirm
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
|
|
||||||
|
|
||||||
class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
||||||
@ -449,12 +454,13 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
# synchronize; TODO get rid of this once we have single-global-layout
|
# synchronize; TODO get rid of this once we have single-global-layout
|
||||||
self.debug.synchronize_at("SimplePage")
|
self.debug.synchronize_at("SimplePage")
|
||||||
|
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
@ -475,25 +481,26 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
# synchronize; TODO get rid of this once we have single-global-layout
|
# synchronize; TODO get rid of this once we have single-global-layout
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
# address details
|
# address details
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[2])
|
self.debug.click(btns.vertical_menu_items()[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
|
|
||||||
|
|
||||||
class InputFlowShowMultisigXPUBs(InputFlowBase):
|
class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||||
@ -513,6 +520,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
yield # multisig address warning
|
yield # multisig address warning
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # show address
|
yield # show address
|
||||||
@ -521,7 +529,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
assert "(MULTISIG)" in layout.title()
|
assert "(MULTISIG)" in layout.title()
|
||||||
assert layout.text_content().replace(" ", "") == self.address
|
assert layout.text_content().replace(" ", "") == self.address
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
assert "Qr" in self.all_components()
|
assert "Qr" in self.all_components()
|
||||||
|
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
@ -538,7 +546,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
content = layout.text_content().replace(" ", "")
|
content = layout.text_content().replace(" ", "")
|
||||||
assert self.xpubs[xpub_num] in content
|
assert self.xpubs[xpub_num] in content
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# show address
|
# show address
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
# address mismatch
|
# address mismatch
|
||||||
@ -590,26 +598,27 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
yield # multisig address warning
|
yield # multisig address warning
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
|
|
||||||
yield # show address
|
yield # show address
|
||||||
layout = self.debug.read_layout()
|
layout = self.debug.read_layout()
|
||||||
assert TR.address__title_receive_address in layout.title()
|
assert TR.address__title_receive_address in layout.title()
|
||||||
assert layout.text_content().replace(" ", "") == self.address
|
assert layout.text_content().replace(" ", "") == self.address
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
assert "Qr" in self.all_components()
|
assert "Qr" in self.all_components()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
layout = self.debug.synchronize_at("AddressDetails")
|
layout = self.debug.synchronize_at("AddressDetails")
|
||||||
# address details
|
# address details
|
||||||
assert "Multisig 2 of 3" in layout.screen_content()
|
assert "Multisig 2 of 3" in layout.screen_content()
|
||||||
@ -620,17 +629,17 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[2])
|
self.debug.click(btns.vertical_menu_items()[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
layout = self.debug.synchronize_at("Paragraphs")
|
layout = self.debug.synchronize_at("Paragraphs")
|
||||||
# address
|
# address
|
||||||
while "PromptScreen" not in layout.all_components():
|
while "PromptScreen" not in layout.all_components():
|
||||||
@ -647,6 +656,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.passphrase = passphrase
|
self.passphrase = passphrase
|
||||||
|
|
||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
if self.passphrase:
|
if self.passphrase:
|
||||||
yield
|
yield
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -659,14 +669,14 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
br = yield
|
br = yield
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# synchronize; TODO get rid of this once we have single-global-layout
|
# synchronize; TODO get rid of this once we have single-global-layout
|
||||||
self.debug.synchronize_at("SimplePage")
|
self.debug.synchronize_at("SimplePage")
|
||||||
|
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.swipe_right()
|
self.debug.swipe_right()
|
||||||
self.debug.swipe_left()
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
@ -701,6 +711,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
if self.passphrase:
|
if self.passphrase:
|
||||||
yield
|
yield
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -716,32 +727,32 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
|
|
||||||
assert layout.title() in (TR.address__public_key, "XPUB")
|
assert layout.title() in (TR.address__public_key, "XPUB")
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
assert "Qr" in self.all_components()
|
assert "Qr" in self.all_components()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
# menu
|
# menu
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
layout = self.debug.synchronize_at("AddressDetails")
|
layout = self.debug.synchronize_at("AddressDetails")
|
||||||
# address details
|
# address details
|
||||||
assert TR.address_details__derivation_path in layout.screen_content()
|
assert TR.address_details__derivation_path in layout.screen_content()
|
||||||
|
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[2])
|
self.debug.click(btns.vertical_menu_items()[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
layout = self.debug.synchronize_at("Paragraphs")
|
layout = self.debug.synchronize_at("Paragraphs")
|
||||||
# address
|
# address
|
||||||
while "PromptScreen" not in layout.all_components():
|
while "PromptScreen" not in layout.all_components():
|
||||||
@ -854,6 +865,7 @@ class InputFlowSignTxHighFee(InputFlowBase):
|
|||||||
|
|
||||||
|
|
||||||
def sign_tx_go_to_info(client: Client) -> Generator[None, messages.ButtonRequest, str]:
|
def sign_tx_go_to_info(client: Client) -> Generator[None, messages.ButtonRequest, str]:
|
||||||
|
btns = buttons.ScreenButtons(client.layout_type)
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.read_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
@ -868,7 +880,7 @@ def sign_tx_go_to_info(client: Client) -> Generator[None, messages.ButtonRequest
|
|||||||
layout = client.debug.read_layout()
|
layout = client.debug.read_layout()
|
||||||
content = layout.text_content()
|
content = layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
@ -876,6 +888,7 @@ def sign_tx_go_to_info(client: Client) -> Generator[None, messages.ButtonRequest
|
|||||||
def sign_tx_go_to_info_t3t1(
|
def sign_tx_go_to_info_t3t1(
|
||||||
client: Client, multi_account: bool = False
|
client: Client, multi_account: bool = False
|
||||||
) -> Generator[None, messages.ButtonRequest, str]:
|
) -> Generator[None, messages.ButtonRequest, str]:
|
||||||
|
btns = buttons.ScreenButtons(client.layout_type)
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.read_layout()
|
client.debug.read_layout()
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
@ -890,22 +903,22 @@ def sign_tx_go_to_info_t3t1(
|
|||||||
|
|
||||||
yield # confirm transaction
|
yield # confirm transaction
|
||||||
client.debug.read_layout()
|
client.debug.read_layout()
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
client.debug.synchronize_at("VerticalMenu")
|
client.debug.synchronize_at("VerticalMenu")
|
||||||
client.debug.click(buttons.vertical_menu(client.layout_type)[0])
|
client.debug.click(btns.vertical_menu_items()[0])
|
||||||
|
|
||||||
layout = client.debug.read_layout()
|
layout = client.debug.read_layout()
|
||||||
content = layout.text_content()
|
content = layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
client.debug.synchronize_at("VerticalMenu")
|
client.debug.synchronize_at("VerticalMenu")
|
||||||
client.debug.click(buttons.vertical_menu(client.layout_type)[1])
|
client.debug.click(btns.vertical_menu_items()[1])
|
||||||
|
|
||||||
layout = client.debug.read_layout()
|
layout = client.debug.read_layout()
|
||||||
content += " " + layout.text_content()
|
content += " " + layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
client.debug.click(buttons.corner_button(client.layout_type))
|
client.debug.click(btns.menu())
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
@ -1018,11 +1031,12 @@ class InputFlowSignTxInformationCancel(InputFlowBase):
|
|||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
yield from sign_tx_go_to_info_t3t1(self.client)
|
yield from sign_tx_go_to_info_t3t1(self.client)
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[2])
|
self.debug.click(btns.vertical_menu_items()[2])
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
|
|
||||||
|
|
||||||
class InputFlowSignTxInformationReplacement(InputFlowBase):
|
class InputFlowSignTxInformationReplacement(InputFlowBase):
|
||||||
@ -1030,6 +1044,7 @@ class InputFlowSignTxInformationReplacement(InputFlowBase):
|
|||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
|
|
||||||
def input_flow_bolt(self) -> BRGeneratorType:
|
def input_flow_bolt(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
yield # confirm txid
|
yield # confirm txid
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # confirm address
|
yield # confirm address
|
||||||
@ -1043,8 +1058,8 @@ class InputFlowSignTxInformationReplacement(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # transaction summary, press info
|
yield # transaction summary, press info
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_caesar(self) -> BRGeneratorType:
|
def input_flow_caesar(self) -> BRGeneratorType:
|
||||||
@ -2326,17 +2341,18 @@ class InputFlowResetSkipBackup(InputFlowBase):
|
|||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
yield from self.BAK.confirm_new_wallet()
|
yield from self.BAK.confirm_new_wallet()
|
||||||
yield # Skip Backup
|
yield # Skip Backup
|
||||||
assert TR.backup__new_wallet_created in self.text_content()
|
assert TR.backup__new_wallet_created in self.text_content()
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
|
|
||||||
|
|
||||||
class InputFlowConfirmAllWarnings(InputFlowBase):
|
class InputFlowConfirmAllWarnings(InputFlowBase):
|
||||||
@ -2355,6 +2371,7 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
|||||||
return self.input_flow_bolt()
|
return self.input_flow_bolt()
|
||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
br = yield
|
br = yield
|
||||||
while True:
|
while True:
|
||||||
# wait for homescreen to go away
|
# wait for homescreen to go away
|
||||||
@ -2372,9 +2389,9 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
|||||||
TR.send__cancel_sign,
|
TR.send__cancel_sign,
|
||||||
)
|
)
|
||||||
if any(needle.lower() in text for needle in hi_prio):
|
if any(needle.lower() in text for needle in hi_prio):
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[1])
|
self.debug.click(btns.vertical_menu_items()[1])
|
||||||
elif "PromptScreen" in layout.all_components():
|
elif "PromptScreen" in layout.all_components():
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
elif "SwipeContent" in layout.all_components():
|
elif "SwipeContent" in layout.all_components():
|
||||||
@ -2398,7 +2415,8 @@ class InputFlowFidoConfirm(InputFlowBase):
|
|||||||
yield from self.input_flow_bolt()
|
yield from self.input_flow_bolt()
|
||||||
|
|
||||||
def input_flow_delizia(self) -> BRGeneratorType:
|
def input_flow_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
while True:
|
while True:
|
||||||
yield
|
yield
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
|
@ -143,13 +143,14 @@ class RecoveryFlow:
|
|||||||
else:
|
else:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
elif self.client.layout_type is LayoutType.Delizia:
|
elif self.client.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
assert TR.recovery__enter_each_word in self._text_content()
|
assert TR.recovery__enter_each_word in self._text_content()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
if confirm:
|
if confirm:
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
else:
|
else:
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
else:
|
else:
|
||||||
assert TR.recovery__enter_any_share in self._text_content()
|
assert TR.recovery__enter_any_share in self._text_content()
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -175,14 +176,15 @@ class RecoveryFlow:
|
|||||||
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.click(buttons.corner_button(self.client.layout_type))
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
assert (yield).name == "abort_recovery"
|
assert (yield).name == "abort_recovery"
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
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(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
else:
|
else:
|
||||||
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()
|
||||||
@ -337,16 +339,17 @@ class RecoveryFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def click_info_delizia(self) -> BRGeneratorType:
|
def click_info_delizia(self) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
# Moving through the menu into the show_shares screen
|
# Moving through the menu into the show_shares screen
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
br = yield
|
br = yield
|
||||||
assert br.name == "show_shares"
|
assert br.name == "show_shares"
|
||||||
assert br.code == B.Other
|
assert br.code == B.Other
|
||||||
# Getting back to the homepage
|
# Getting back to the homepage
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
|
|
||||||
|
|
||||||
class EthereumFlow:
|
class EthereumFlow:
|
||||||
@ -461,6 +464,7 @@ class EthereumFlow:
|
|||||||
def _confirm_tx_delizia(
|
def _confirm_tx_delizia(
|
||||||
self, cancel: bool, info: bool, go_back_from_summary: bool
|
self, cancel: bool, info: bool, go_back_from_summary: bool
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
assert (yield).name == "confirm_output"
|
assert (yield).name == "confirm_output"
|
||||||
title = self.debug.read_layout().title()
|
title = self.debug.read_layout().title()
|
||||||
assert TR.words__address in title
|
assert TR.words__address in title
|
||||||
@ -481,17 +485,17 @@ class EthereumFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
assert (yield).name == "confirm_ethereum_tx"
|
assert (yield).name == "confirm_ethereum_tx"
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
text = self.debug.read_layout().text_content()
|
text = self.debug.read_layout().text_content()
|
||||||
assert TR.ethereum__gas_limit in text
|
assert TR.ethereum__gas_limit in text
|
||||||
assert TR.ethereum__gas_price in text
|
assert TR.ethereum__gas_price in text
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.read_layout()
|
self.debug.read_layout()
|
||||||
self.debug.click(buttons.tap_to_confirm(self.client.layout_type))
|
self.debug.click(btns.tap_to_confirm())
|
||||||
assert (yield).name == "confirm_ethereum_tx"
|
assert (yield).name == "confirm_ethereum_tx"
|
||||||
|
|
||||||
def confirm_tx(
|
def confirm_tx(
|
||||||
@ -527,10 +531,11 @@ class EthereumFlow:
|
|||||||
TR.ethereum__staking_claim_intro,
|
TR.ethereum__staking_claim_intro,
|
||||||
)
|
)
|
||||||
if self.client.layout_type is LayoutType.Bolt:
|
if self.client.layout_type is LayoutType.Bolt:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(
|
self.debug.click(
|
||||||
buttons.corner_button(self.client.layout_type),
|
btns.menu(),
|
||||||
)
|
)
|
||||||
assert self.debug.read_layout().title() in (
|
assert self.debug.read_layout().title() in (
|
||||||
TR.ethereum__staking_stake_address,
|
TR.ethereum__staking_stake_address,
|
||||||
@ -552,17 +557,18 @@ class EthereumFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
elif self.client.layout_type is LayoutType.Delizia:
|
elif self.client.layout_type is LayoutType.Delizia:
|
||||||
|
btns = buttons.ScreenButtons(self.client.layout_type)
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
assert self.debug.read_layout().title() in (
|
assert self.debug.read_layout().title() in (
|
||||||
TR.ethereum__staking_stake_address,
|
TR.ethereum__staking_stake_address,
|
||||||
TR.ethereum__staking_claim_address,
|
TR.ethereum__staking_claim_address,
|
||||||
)
|
)
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
br = yield
|
br = yield
|
||||||
@ -571,13 +577,13 @@ class EthereumFlow:
|
|||||||
|
|
||||||
# confirm summary
|
# confirm summary
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.vertical_menu(self.client.layout_type)[0])
|
self.debug.click(btns.vertical_menu_items()[0])
|
||||||
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
assert TR.ethereum__gas_limit in self.debug.read_layout().text_content()
|
||||||
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
assert TR.ethereum__gas_price in self.debug.read_layout().text_content()
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.click(buttons.corner_button(self.client.layout_type))
|
self.debug.click(btns.menu())
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
# br = yield # FIXME: no BR on sign transaction
|
# br = yield # FIXME: no BR on sign transaction
|
||||||
|
|
||||||
|
@ -10,48 +10,45 @@ def _enter_word(
|
|||||||
debug: "DebugLink", word: str, is_slip39: bool = False
|
debug: "DebugLink", word: str, is_slip39: bool = False
|
||||||
) -> "LayoutContent":
|
) -> "LayoutContent":
|
||||||
typed_word = word[:4]
|
typed_word = word[:4]
|
||||||
for coords in buttons.type_word(typed_word, debug.layout_type, is_slip39=is_slip39):
|
actions = buttons.ButtonActions(debug.layout_type)
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
for coords in actions.type_word(typed_word, is_slip39=is_slip39):
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
debug.read_layout(wait=False)
|
debug.read_layout(wait=False)
|
||||||
|
|
||||||
debug.click(buttons.input(debug.layout_type))
|
debug.click(btns.mnemonic_confirm())
|
||||||
return debug.read_layout(wait=True)
|
return debug.read_layout(wait=True)
|
||||||
|
|
||||||
|
|
||||||
def confirm_recovery(debug: "DebugLink") -> None:
|
def confirm_recovery(debug: "DebugLink") -> None:
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
|
debug.click(btns.ok())
|
||||||
debug.read_layout(wait=True)
|
debug.read_layout(wait=True)
|
||||||
|
|
||||||
|
|
||||||
def select_number_of_words(
|
def select_number_of_words(
|
||||||
debug: "DebugLink", tag_version: tuple | None, num_of_words: int = 20
|
debug: "DebugLink", tag_version: tuple | None, num_of_words: int = 20
|
||||||
) -> None:
|
) -> None:
|
||||||
|
btns = buttons.ScreenButtons(debug.layout_type)
|
||||||
if "SelectWordCount" not in debug.read_layout().all_components():
|
if "SelectWordCount" not in debug.read_layout().all_components():
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(btns.ok())
|
||||||
debug.read_layout(wait=True)
|
debug.read_layout(wait=True)
|
||||||
if tag_version is None or tag_version > (2, 8, 8):
|
if tag_version is None or tag_version > (2, 8, 8):
|
||||||
# layout changed after adding the cancel button
|
# layout changed after adding the cancel button
|
||||||
coords_map = {
|
coords = btns.word_count_all_word(num_of_words)
|
||||||
12: buttons.grid34(0, 2, debug.layout_type),
|
|
||||||
18: buttons.grid34(1, 2, debug.layout_type),
|
|
||||||
20: buttons.grid34(2, 2, debug.layout_type),
|
|
||||||
24: buttons.grid34(1, 3, debug.layout_type),
|
|
||||||
33: buttons.grid34(2, 3, debug.layout_type),
|
|
||||||
}
|
|
||||||
coords = coords_map.get(num_of_words)
|
|
||||||
else:
|
else:
|
||||||
word_option_offset = 6
|
word_option_offset = 6
|
||||||
word_options = (12, 18, 20, 24, 33)
|
word_options = (12, 18, 20, 24, 33)
|
||||||
index = word_option_offset + word_options.index(
|
index = word_option_offset + word_options.index(
|
||||||
num_of_words
|
num_of_words
|
||||||
) # raises if num of words is invalid
|
) # raises if num of words is invalid
|
||||||
coords = buttons.grid34(index % 3, index // 3, debug.layout_type)
|
coords = btns.grid34(index % 3, index // 3)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
debug.read_layout(wait=True)
|
debug.read_layout(wait=True)
|
||||||
|
|
||||||
|
|
||||||
def enter_share(debug: "DebugLink", share: str) -> "LayoutContent":
|
def enter_share(debug: "DebugLink", share: str) -> "LayoutContent":
|
||||||
debug.click(buttons.ok(debug.layout_type))
|
debug.click(buttons.ScreenButtons(debug.layout_type).ok())
|
||||||
for word in share.split(" "):
|
for word in share.split(" "):
|
||||||
_enter_word(debug, word, is_slip39=True)
|
_enter_word(debug, word, is_slip39=True)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user