mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 12:28:09 +00:00
tests: use read_layout everywhere
This commit is contained in:
parent
e3a478044d
commit
82290c2e5c
@ -45,39 +45,36 @@ def get_char_category(char: str) -> PassphraseCategory:
|
|||||||
return PassphraseCategory.SPECIAL
|
return PassphraseCategory.SPECIAL
|
||||||
|
|
||||||
|
|
||||||
def go_next(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
|
def go_next(debug: "DebugLink") -> LayoutContent:
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
return debug.click(buttons.OK, wait=wait) # type: ignore
|
return debug.click(buttons.OK) # type: ignore
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
return debug.press_right(wait=wait) # type: ignore
|
return debug.press_right() # type: ignore
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
return debug.swipe_up(wait=wait)
|
return debug.swipe_up()
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown model")
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def tap_to_confirm(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
|
def tap_to_confirm(debug: "DebugLink") -> LayoutContent:
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
return debug.read_layout() # type: ignore
|
return debug.read_layout() # type: ignore
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
return debug.read_layout() # type: ignore
|
return debug.read_layout() # type: ignore
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
return debug.click(buttons.TAP_TO_CONFIRM, wait=wait)
|
return debug.click(buttons.TAP_TO_CONFIRM, )
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown model")
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def go_back(
|
def go_back(debug: "DebugLink", r_middle: bool = False) -> LayoutContent:
|
||||||
debug: "DebugLink", wait: bool = False, r_middle: bool = False
|
|
||||||
) -> LayoutContent | None:
|
|
||||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
return debug.click(buttons.CANCEL, wait=wait) # type: ignore
|
return debug.click(buttons.CANCEL) # type: ignore
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
|
|
||||||
if r_middle:
|
if r_middle:
|
||||||
return debug.press_middle(wait=wait) # type: ignore
|
return debug.press_middle()
|
||||||
else:
|
else:
|
||||||
return debug.press_left(wait=wait) # type: ignore
|
return debug.press_left()
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown model")
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
@ -118,19 +115,16 @@ def navigate_to_action_and_press(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Press or hold
|
# Press or hold
|
||||||
if hold_ms:
|
debug.press_middle(hold_ms=hold_ms)
|
||||||
debug.press_middle_htc(1000)
|
|
||||||
else:
|
|
||||||
debug.press_middle(wait=True)
|
|
||||||
|
|
||||||
|
|
||||||
def unlock_gesture(debug: "DebugLink", wait: bool = False) -> LayoutContent | None:
|
def unlock_gesture(debug: "DebugLink") -> LayoutContent:
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
return debug.click(buttons.OK, wait=wait) # type: ignore
|
return debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
return debug.press_right(wait=wait) # type: ignore
|
return debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
return debug.click(buttons.TAP_TO_CONFIRM, wait=wait) # type: ignore
|
return debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown model")
|
raise RuntimeError("Unknown model")
|
||||||
|
|
||||||
@ -156,7 +150,7 @@ def _move_one_closer(
|
|||||||
current_action: str,
|
current_action: str,
|
||||||
all_actions: list[str],
|
all_actions: list[str],
|
||||||
is_carousel: bool,
|
is_carousel: bool,
|
||||||
) -> "LayoutContent":
|
) -> LayoutContent:
|
||||||
"""Pressing either left or right regarding to the current situation"""
|
"""Pressing either left or right regarding to the current situation"""
|
||||||
index_diff = _get_action_index(wanted_action, all_actions) - _get_action_index(
|
index_diff = _get_action_index(wanted_action, all_actions) - _get_action_index(
|
||||||
current_action, all_actions
|
current_action, all_actions
|
||||||
@ -164,17 +158,17 @@ def _move_one_closer(
|
|||||||
if not is_carousel:
|
if not is_carousel:
|
||||||
# Simply move according to the index in a closed list
|
# Simply move according to the index in a closed list
|
||||||
if index_diff > 0:
|
if index_diff > 0:
|
||||||
return debug.press_right(wait=True)
|
return debug.press_right()
|
||||||
else:
|
else:
|
||||||
return debug.press_left(wait=True)
|
return debug.press_left()
|
||||||
else:
|
else:
|
||||||
# Carousel can move in a circle - over the edges
|
# Carousel can move in a circle - over the edges
|
||||||
# Always move the shortest way
|
# Always move the shortest way
|
||||||
action_half = len(all_actions) // 2
|
action_half = len(all_actions) // 2
|
||||||
if index_diff > action_half or -action_half < index_diff < 0:
|
if index_diff > action_half or -action_half < index_diff < 0:
|
||||||
return debug.press_left(wait=True)
|
return debug.press_left()
|
||||||
else:
|
else:
|
||||||
return debug.press_right(wait=True)
|
return debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
def get_possible_btn_texts(path: str) -> str:
|
def get_possible_btn_texts(path: str) -> str:
|
||||||
|
@ -24,8 +24,8 @@ def enter_word(
|
|||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
if debug.layout_type is LayoutType.Mercury and not is_slip39 and len(word) > 4:
|
if debug.layout_type is LayoutType.Mercury and not is_slip39 and len(word) > 4:
|
||||||
# T3T1 (mercury) BIP39 keyboard allows to "confirm" only if the word is fully written, you need to click the word to auto-complete
|
# T3T1 (mercury) BIP39 keyboard allows to "confirm" only if the word is fully written, you need to click the word to auto-complete
|
||||||
debug.click(buttons.CONFIRM_WORD, wait=True)
|
debug.click(buttons.CONFIRM_WORD)
|
||||||
return debug.click(buttons.CONFIRM_WORD, wait=True)
|
return debug.click(buttons.CONFIRM_WORD)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
letter_index = 0
|
letter_index = 0
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
@ -34,35 +34,34 @@ def enter_word(
|
|||||||
while layout.find_values_by_key("letter_choices"):
|
while layout.find_values_by_key("letter_choices"):
|
||||||
letter = word[letter_index]
|
letter = word[letter_index]
|
||||||
while not layout.get_middle_choice() == letter:
|
while not layout.get_middle_choice() == letter:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
|
|
||||||
layout = debug.press_middle(wait=True)
|
layout = debug.press_middle()
|
||||||
letter_index += 1
|
letter_index += 1
|
||||||
|
|
||||||
# Word choices
|
# Word choices
|
||||||
while not layout.get_middle_choice() == word:
|
while not layout.get_middle_choice() == word:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
|
|
||||||
return debug.press_middle(wait=True)
|
return debug.press_middle()
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown model")
|
raise ValueError("Unknown model")
|
||||||
|
|
||||||
|
|
||||||
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
|
def confirm_recovery(debug: "DebugLink", title: str = "recovery__title") -> None:
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), title)
|
TR.assert_equals(layout.title(), title)
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
def select_number_of_words(
|
def select_number_of_words(
|
||||||
debug: "DebugLink",
|
debug: "DebugLink",
|
||||||
num_of_words: int = 20,
|
num_of_words: int = 20,
|
||||||
wait: bool = True,
|
|
||||||
unlock_repeated_backup=False,
|
unlock_repeated_backup=False,
|
||||||
) -> None:
|
) -> None:
|
||||||
def select_tt() -> "LayoutContent":
|
def select_tt() -> "LayoutContent":
|
||||||
@ -80,15 +79,15 @@ def select_number_of_words(
|
|||||||
coords = coords_map.get(num_of_words)
|
coords = coords_map.get(num_of_words)
|
||||||
if coords is None:
|
if coords is None:
|
||||||
raise ValueError("Invalid num_of_words")
|
raise ValueError("Invalid num_of_words")
|
||||||
return debug.click(coords, wait=True)
|
return debug.click(coords)
|
||||||
|
|
||||||
def select_tr() -> "LayoutContent":
|
def select_tr() -> "LayoutContent":
|
||||||
# navigate to the number and confirm it
|
# navigate to the number and confirm it
|
||||||
word_options = (20, 33) if unlock_repeated_backup else (12, 18, 20, 24, 33)
|
word_options = (20, 33) if unlock_repeated_backup else (12, 18, 20, 24, 33)
|
||||||
index = word_options.index(num_of_words)
|
index = word_options.index(num_of_words)
|
||||||
for _ in range(index):
|
for _ in range(index):
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
return debug.press_middle(wait=True)
|
return debug.press_middle()
|
||||||
|
|
||||||
def select_mercury() -> "LayoutContent":
|
def select_mercury() -> "LayoutContent":
|
||||||
# click the button from ValuePad
|
# click the button from ValuePad
|
||||||
@ -105,16 +104,14 @@ def select_number_of_words(
|
|||||||
coords = coords_map.get(num_of_words)
|
coords = coords_map.get(num_of_words)
|
||||||
if coords is None:
|
if coords is None:
|
||||||
raise ValueError("Invalid num_of_words")
|
raise ValueError("Invalid num_of_words")
|
||||||
return debug.click(coords, wait=True)
|
return debug.click(coords)
|
||||||
|
|
||||||
if wait:
|
|
||||||
debug.wait_layout()
|
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
TR.assert_equals(debug.read_layout().text_content(), "recovery__num_of_words")
|
TR.assert_equals(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||||
layout = select_tt()
|
layout = select_tt()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
TR.assert_equals(layout.title(), "word_count__title")
|
TR.assert_equals(layout.title(), "word_count__title")
|
||||||
layout = select_tr()
|
layout = select_tr()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
@ -159,14 +156,14 @@ def enter_share(
|
|||||||
) -> "LayoutContent":
|
) -> "LayoutContent":
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
TR.assert_in(debug.read_layout().title(), before_title)
|
TR.assert_in(debug.read_layout().title(), before_title)
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
for _ in range(layout.page_count()):
|
for _ in range(layout.page_count()):
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
else:
|
else:
|
||||||
TR.assert_in(debug.read_layout().title(), before_title)
|
TR.assert_in(debug.read_layout().title(), before_title)
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
|
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
@ -241,24 +238,24 @@ def enter_seed_previous_correct(
|
|||||||
if go_back:
|
if go_back:
|
||||||
go_back = False
|
go_back = False
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.swipe_right(wait=True)
|
debug.swipe_right()
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
debug.click(buttons.RECOVERY_DELETE, wait=True)
|
debug.click(buttons.RECOVERY_DELETE)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
|
|
||||||
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
layout = debug.press_middle(wait=True)
|
layout = debug.press_middle()
|
||||||
|
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
while layout.get_middle_choice() not in DELETE_BTN_TEXTS:
|
||||||
layout = debug.press_left(wait=True)
|
layout = debug.press_left()
|
||||||
layout = debug.press_middle(wait=True)
|
layout = debug.press_middle()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.click(buttons.RECOVERY_DELETE, wait=True) # Top-left
|
debug.click(buttons.RECOVERY_DELETE) # Top-left
|
||||||
for _ in range(len(bad_word)):
|
for _ in range(len(bad_word)):
|
||||||
debug.click(buttons.RECOVERY_DELETE, wait=True)
|
debug.click(buttons.RECOVERY_DELETE)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if i in bad_indexes:
|
if i in bad_indexes:
|
||||||
@ -286,18 +283,18 @@ def prepare_enter_seed(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
layout = debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
layout = debug.press_right()
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
|
|
||||||
def finalize(debug: "DebugLink") -> None:
|
def finalize(debug: "DebugLink") -> None:
|
||||||
layout = go_next(debug, wait=True)
|
layout = go_next(debug)
|
||||||
assert layout is not None
|
assert layout is not None
|
||||||
assert layout.main_component() == "Homescreen"
|
assert layout.main_component() == "Homescreen"
|
||||||
|
@ -15,103 +15,103 @@ if TYPE_CHECKING:
|
|||||||
def confirm_new_wallet(debug: "DebugLink") -> None:
|
def confirm_new_wallet(debug: "DebugLink") -> None:
|
||||||
TR.assert_equals(debug.read_layout().title(), "reset__title_create_wallet")
|
TR.assert_equals(debug.read_layout().title(), "reset__title_create_wallet")
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
debug.swipe_up(wait=True) # Wallet created
|
debug.swipe_up() # Wallet created
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
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.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
page_count = debug.read_layout().page_count()
|
page_count = debug.read_layout().page_count()
|
||||||
if page_count > 1:
|
if page_count > 1:
|
||||||
for _ in range(page_count - 1):
|
for _ in range(page_count - 1):
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
if middle_r:
|
if middle_r:
|
||||||
debug.press_middle(wait=True)
|
debug.press_middle()
|
||||||
else:
|
else:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
def cancel_backup(
|
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.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.CANCEL, wait=True)
|
debug.click(buttons.CANCEL)
|
||||||
debug.click(buttons.CANCEL, wait=True)
|
debug.click(buttons.CANCEL)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.click(buttons.CORNER_BUTTON, wait=True)
|
debug.click(buttons.CORNER_BUTTON)
|
||||||
debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
debug.click(buttons.VERTICAL_MENU[0])
|
||||||
if confirm:
|
if confirm:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
debug.click(buttons.TAP_TO_CONFIRM)
|
debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
|
|
||||||
|
|
||||||
def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> None:
|
def set_selection(debug: "DebugLink", button: tuple[int, int], diff: int) -> None:
|
||||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
assert "NumberInputDialog" in debug.read_layout().all_components()
|
assert "NumberInputDialog" in debug.read_layout().all_components()
|
||||||
for _ in range(diff):
|
for _ in range(diff):
|
||||||
debug.click(button, wait=True)
|
debug.click(button)
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
else:
|
else:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
if layout.title() in TR.translate(
|
if layout.title() in TR.translate(
|
||||||
"reset__title_number_of_shares"
|
"reset__title_number_of_shares"
|
||||||
) + TR.translate("words__title_threshold"):
|
) + TR.translate("words__title_threshold"):
|
||||||
# Special info screens
|
# Special info screens
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
assert "NumberInput" in layout.all_components()
|
assert "NumberInput" in layout.all_components()
|
||||||
if button == buttons.reset_minus(debug.model.internal_name):
|
if button == buttons.reset_minus(debug.model.internal_name):
|
||||||
for _ in range(diff):
|
for _ in range(diff):
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
else:
|
else:
|
||||||
for _ in range(diff):
|
for _ in range(diff):
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
debug.press_middle(wait=True)
|
debug.press_middle()
|
||||||
|
|
||||||
|
|
||||||
def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
||||||
words: list[str] = []
|
words: list[str] = []
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
# Swiping through all the pages and loading the words
|
# Swiping through all the pages and loading the words
|
||||||
layout = debug.read_layout()
|
layout = debug.read_layout()
|
||||||
for _ in range(layout.page_count() - 1):
|
for _ in range(layout.page_count() - 1):
|
||||||
words.extend(layout.seed_words())
|
words.extend(layout.seed_words())
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
assert layout is not None
|
assert layout is not None
|
||||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
words.extend(layout.seed_words())
|
words.extend(layout.seed_words())
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Mercury:
|
if debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
# There is hold-to-confirm button
|
# There is hold-to-confirm button
|
||||||
if do_htc:
|
if do_htc:
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click_hold(buttons.OK, hold_ms=1500)
|
debug.click(buttons.OK, hold_ms=1500)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1500)
|
debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1500)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right_htc(1200)
|
debug.press_right(hold_ms=1200)
|
||||||
else:
|
else:
|
||||||
# It would take a very long time to test 16-of-16 with doing 1500 ms HTC after
|
# It would take a very long time to test 16-of-16 with doing 1500 ms HTC after
|
||||||
# each word set
|
# each word set
|
||||||
@ -122,15 +122,15 @@ def read_words(debug: "DebugLink", do_htc: bool = True) -> list[str]:
|
|||||||
|
|
||||||
def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
||||||
if debug.layout_type is LayoutType.Mercury:
|
if debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
TR.assert_template(layout.text_content(), "reset__select_word_x_of_y_template")
|
TR.assert_template(layout.text_content(), "reset__select_word_x_of_y_template")
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
# "Select word 3 of 20"
|
# "Select word 3 of 20"
|
||||||
# ^
|
# ^
|
||||||
word_pos_match = re.search(r"\d+", debug.wait_layout().text_content())
|
word_pos_match = re.search(r"\d+", debug.read_layout().text_content())
|
||||||
assert word_pos_match is not None
|
assert word_pos_match is not None
|
||||||
word_pos = int(word_pos_match.group(0))
|
word_pos = int(word_pos_match.group(0))
|
||||||
# Unifying both the buttons and words to lowercase
|
# Unifying both the buttons and words to lowercase
|
||||||
@ -139,13 +139,13 @@ 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)
|
||||||
layout = debug.click(buttons.RESET_WORD_CHECK[button_pos], wait=True)
|
layout = debug.click(buttons.RESET_WORD_CHECK[button_pos])
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
TR.assert_template(layout.subtitle(), "reset__select_word_x_of_y_template")
|
TR.assert_template(layout.subtitle(), "reset__select_word_x_of_y_template")
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
# "Select word 3 of 20"
|
# "Select word 3 of 20"
|
||||||
# ^
|
# ^
|
||||||
word_pos_match = re.search(r"\d+", debug.wait_layout().subtitle())
|
word_pos_match = re.search(r"\d+", debug.read_layout().subtitle())
|
||||||
assert word_pos_match is not None
|
assert word_pos_match is not None
|
||||||
word_pos = int(word_pos_match.group(0))
|
word_pos = int(word_pos_match.group(0))
|
||||||
# Unifying both the buttons and words to lowercase
|
# Unifying both the buttons and words to lowercase
|
||||||
@ -154,10 +154,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)
|
||||||
layout = debug.click(buttons.VERTICAL_MENU[button_pos], wait=True)
|
layout = debug.click(buttons.VERTICAL_MENU[button_pos])
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
TR.assert_in(layout.text_content(), "reset__select_correct_word")
|
TR.assert_in(layout.text_content(), "reset__select_correct_word")
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
# "SELECT 2ND WORD"
|
# "SELECT 2ND WORD"
|
||||||
# ^
|
# ^
|
||||||
@ -168,9 +168,9 @@ def confirm_words(debug: "DebugLink", words: list[str]) -> None:
|
|||||||
wanted_word = words[word_pos - 1].lower()
|
wanted_word = words[word_pos - 1].lower()
|
||||||
|
|
||||||
while not layout.get_middle_choice() == wanted_word:
|
while not layout.get_middle_choice() == wanted_word:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
|
|
||||||
layout = debug.press_middle(wait=True)
|
layout = debug.press_middle()
|
||||||
|
|
||||||
|
|
||||||
def validate_mnemonics(mnemonics: list[str], expected_ems: bytes) -> None:
|
def validate_mnemonics(mnemonics: list[str], expected_ems: bytes) -> None:
|
||||||
|
@ -61,18 +61,18 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int)
|
|||||||
|
|
||||||
device_handler.run(device.apply_settings, auto_lock_delay_ms=delay_ms) # type: ignore
|
device_handler.run(device.apply_settings, auto_lock_delay_ms=delay_ms) # type: ignore
|
||||||
|
|
||||||
assert "PinKeyboard" in debug.wait_layout().all_components()
|
assert "PinKeyboard" in debug.read_layout().all_components()
|
||||||
|
|
||||||
debug.input("1234")
|
debug.input("1234")
|
||||||
|
|
||||||
TR.assert_template(
|
TR.assert_template(
|
||||||
debug.wait_layout().text_content(),
|
debug.read_layout().text_content(),
|
||||||
"auto_lock__change_template",
|
"auto_lock__change_template",
|
||||||
)
|
)
|
||||||
|
|
||||||
layout = go_next(debug, wait=True)
|
layout = go_next(debug)
|
||||||
if debug.layout_type is LayoutType.Mercury:
|
if debug.layout_type is LayoutType.Mercury:
|
||||||
layout = tap_to_confirm(debug, wait=True)
|
layout = tap_to_confirm(debug)
|
||||||
assert layout.main_component() == "Homescreen"
|
assert layout.main_component() == "Homescreen"
|
||||||
assert device_handler.result() == "Settings applied"
|
assert device_handler.result() == "Settings applied"
|
||||||
|
|
||||||
@ -102,22 +102,22 @@ def test_autolock_interrupts_signing(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
assert (
|
assert (
|
||||||
"1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1"
|
"1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1"
|
||||||
in debug.wait_layout().text_content().replace(" ", "")
|
in debug.read_layout().text_content().replace(" ", "")
|
||||||
)
|
)
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
|
|
||||||
@ -154,23 +154,23 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
|||||||
|
|
||||||
assert (
|
assert (
|
||||||
"1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1"
|
"1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1"
|
||||||
in debug.wait_layout().text_content().replace(" ", "")
|
in debug.read_layout().text_content().replace(" ", "")
|
||||||
)
|
)
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
TR.assert_in(layout.text_content(), "send__total_amount")
|
TR.assert_in(layout.text_content(), "send__total_amount")
|
||||||
assert "0.0039 BTC" in layout.text_content()
|
assert "0.0039 BTC" in layout.text_content()
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
|||||||
# get address
|
# get address
|
||||||
device_handler.run(common.get_test_address) # type: ignore
|
device_handler.run(common.get_test_address) # type: ignore
|
||||||
|
|
||||||
assert "PassphraseKeyboard" in debug.wait_layout().all_components()
|
assert "PassphraseKeyboard" in debug.read_layout().all_components()
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
# Going into the selected character category
|
# Going into the selected character category
|
||||||
@ -228,11 +228,11 @@ def test_autolock_passphrase_keyboard(device_handler: "BackgroundDeviceHandler")
|
|||||||
|
|
||||||
# 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.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
debug.click(buttons.CORNER_BUTTON, wait=True)
|
debug.click(buttons.CORNER_BUTTON)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
debug.input("j" * 8, wait=True)
|
debug.input("j" * 8)
|
||||||
|
|
||||||
# address corresponding to "jjjjjjjj" passphrase
|
# address corresponding to "jjjjjjjj" passphrase
|
||||||
assert device_handler.result() == "mnF4yRWJXmzRB6EuBzuVigqeqTqirQupxJ"
|
assert device_handler.result() == "mnF4yRWJXmzRB6EuBzuVigqeqTqirQupxJ"
|
||||||
@ -246,7 +246,7 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
|||||||
# get address
|
# get address
|
||||||
device_handler.run(common.get_test_address) # type: ignore
|
device_handler.run(common.get_test_address) # type: ignore
|
||||||
|
|
||||||
assert "PassphraseKeyboard" in debug.wait_layout().all_components()
|
assert "PassphraseKeyboard" in debug.read_layout().all_components()
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
# Going into the selected character category
|
# Going into the selected character category
|
||||||
@ -263,17 +263,17 @@ def test_autolock_interrupts_passphrase(device_handler: "BackgroundDeviceHandler
|
|||||||
|
|
||||||
# wait for autolock to kick in
|
# wait for autolock to kick in
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
assert debug.wait_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
|
|
||||||
def unlock_dry_run(debug: "DebugLink") -> "LayoutContent":
|
def unlock_dry_run(debug: "DebugLink") -> "LayoutContent":
|
||||||
TR.assert_in(debug.wait_layout().text_content(), "recovery__check_dry_run")
|
TR.assert_in(debug.read_layout().text_content(), "recovery__check_dry_run")
|
||||||
layout = go_next(debug, wait=True)
|
layout = go_next(debug)
|
||||||
assert "PinKeyboard" in layout.all_components()
|
assert "PinKeyboard" in layout.all_components()
|
||||||
|
|
||||||
layout = debug.input(PIN4, wait=True)
|
layout = debug.input(PIN4)
|
||||||
assert layout is not None
|
assert layout is not None
|
||||||
return layout
|
return layout
|
||||||
|
|
||||||
@ -286,28 +286,28 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
|
|||||||
device_handler.run(device.recover, dry_run=True) # type: ignore
|
device_handler.run(device.recover, dry_run=True) # type: ignore
|
||||||
|
|
||||||
layout = unlock_dry_run(debug)
|
layout = unlock_dry_run(debug)
|
||||||
TR.assert_in(debug.wait_layout().text_content(), "recovery__num_of_words")
|
TR.assert_in(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
# wait for autolock to trigger
|
# wait for autolock to trigger
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
assert debug.wait_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
# unlock
|
# unlock
|
||||||
# lockscreen triggered automatically
|
# lockscreen triggered automatically
|
||||||
debug.wait_layout(wait_for_external_change=True)
|
# debug.wait_layout()
|
||||||
layout = unlock_gesture(debug, wait=True)
|
layout = unlock_gesture(debug)
|
||||||
|
|
||||||
assert "PinKeyboard" in layout.all_components()
|
assert "PinKeyboard" in layout.all_components()
|
||||||
layout = debug.input(PIN4, wait=True)
|
layout = debug.input(PIN4)
|
||||||
assert layout is not None
|
assert layout is not None
|
||||||
|
|
||||||
# we are back at homescreen
|
# we are back at homescreen
|
||||||
TR.assert_in(debug.wait_layout().text_content(), "recovery__num_of_words")
|
TR.assert_in(debug.read_layout().text_content(), "recovery__num_of_words")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin=PIN4)
|
@pytest.mark.setup_client(pin=PIN4)
|
||||||
@ -323,15 +323,15 @@ def test_dryrun_locks_at_word_entry(device_handler: "BackgroundDeviceHandler"):
|
|||||||
recovery.select_number_of_words(debug, 20)
|
recovery.select_number_of_words(debug, 20)
|
||||||
|
|
||||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
layout = go_next(debug, wait=True)
|
layout = go_next(debug)
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
# make sure keyboard locks
|
# make sure keyboard locks
|
||||||
time.sleep(10.1)
|
time.sleep(10.1)
|
||||||
assert debug.wait_layout().main_component() == "Lockscreen"
|
assert debug.read_layout().main_component() == "Lockscreen"
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -349,39 +349,44 @@ 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.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
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", is_slip39=True):
|
for coords in buttons.type_word("ocea", is_slip39=True):
|
||||||
time.sleep(9)
|
time.sleep(9)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
layout = debug.click(buttons.CONFIRM_WORD, wait=True)
|
layout = debug.click(buttons.CONFIRM_WORD)
|
||||||
# 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.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
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", is_slip39=True):
|
for coords in buttons.type_word("ocea", is_slip39=True):
|
||||||
time.sleep(9)
|
time.sleep(9)
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
layout = debug.click(buttons.CONFIRM_WORD, wait=True)
|
layout = debug.click(buttons.CONFIRM_WORD)
|
||||||
# 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.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
layout = debug.press_right(wait=True)
|
layout = debug.press_right()
|
||||||
assert "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
# pressing middle button three times
|
# pressing middle button three times
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
time.sleep(9)
|
time.sleep(9)
|
||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
layout = debug.wait_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 "MnemonicKeyboard" in layout.all_components()
|
assert "MnemonicKeyboard" in layout.all_components()
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported layout type: {debug.layout_type}")
|
||||||
|
|
||||||
with pytest.raises(exceptions.Cancelled):
|
with pytest.raises(exceptions.Cancelled):
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -406,7 +411,7 @@ def test_autolock_does_not_interrupt_preauthorized(
|
|||||||
coin_name="Testnet",
|
coin_name="Testnet",
|
||||||
script_type=messages.InputScriptType.SPENDTAPROOT,
|
script_type=messages.InputScriptType.SPENDTAPROOT,
|
||||||
)
|
)
|
||||||
debug.press_yes(wait=True)
|
debug.press_yes()
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
|
@ -50,19 +50,19 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
|||||||
models.T3T1: 3500,
|
models.T3T1: 3500,
|
||||||
}[debug.model]
|
}[debug.model]
|
||||||
|
|
||||||
def hold(duration: int, wait: bool = True) -> None:
|
def hold(duration: int) -> None:
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
debug.press_right_htc(hold_ms=duration)
|
debug.press_right(hold_ms=duration)
|
||||||
else:
|
else:
|
||||||
debug.input(x=13, y=37, hold_ms=duration, wait=wait)
|
debug.click((13, 37), hold_ms=duration)
|
||||||
|
|
||||||
assert device_handler.features().unlocked is False
|
assert device_handler.features().unlocked is False
|
||||||
|
|
||||||
# unlock with message
|
# unlock with message
|
||||||
device_handler.run(common.get_test_address)
|
device_handler.run(common.get_test_address)
|
||||||
|
|
||||||
assert "PinKeyboard" in debug.wait_layout().all_components()
|
assert "PinKeyboard" in debug.read_layout().all_components()
|
||||||
debug.input("1234", wait=True)
|
debug.input("1234")
|
||||||
assert device_handler.result()
|
assert device_handler.result()
|
||||||
|
|
||||||
assert device_handler.features().unlocked is True
|
assert device_handler.features().unlocked is True
|
||||||
@ -80,12 +80,11 @@ def test_hold_to_lock(device_handler: "BackgroundDeviceHandler"):
|
|||||||
# unlock by touching
|
# unlock by touching
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
# Doing a short HTC to simulate a click
|
# Doing a short HTC to simulate a click
|
||||||
debug.press_right_htc(hold_ms=100)
|
layout = debug.press_right(hold_ms=100)
|
||||||
layout = debug.wait_layout()
|
|
||||||
else:
|
else:
|
||||||
layout = debug.click(buttons.INFO, wait=True)
|
layout = debug.click(buttons.INFO)
|
||||||
assert "PinKeyboard" in layout.all_components()
|
assert "PinKeyboard" in layout.all_components()
|
||||||
debug.input("1234", wait=True)
|
debug.input("1234")
|
||||||
|
|
||||||
assert device_handler.features().unlocked is True
|
assert device_handler.features().unlocked is True
|
||||||
|
|
||||||
|
@ -98,7 +98,8 @@ def prepare_passphrase_dialogue(
|
|||||||
) -> Generator["DebugLink", None, None]:
|
) -> Generator["DebugLink", None, None]:
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(get_test_address) # type: ignore
|
device_handler.run(get_test_address) # type: ignore
|
||||||
assert debug.wait_layout().main_component() == "PassphraseKeyboard"
|
# TODO
|
||||||
|
assert debug.read_layout().main_component() == "PassphraseKeyboard"
|
||||||
|
|
||||||
# Resetting the category as it could have been changed by previous tests
|
# Resetting the category as it could have been changed by previous tests
|
||||||
global MERCURY_CATEGORY
|
global MERCURY_CATEGORY
|
||||||
@ -124,10 +125,10 @@ def go_to_category(debug: "DebugLink", category: PassphraseCategory) -> None:
|
|||||||
target_index = MERCURY_CATEGORIES.index(category)
|
target_index = MERCURY_CATEGORIES.index(category)
|
||||||
if target_index > current_index:
|
if target_index > current_index:
|
||||||
for _ in range(target_index - current_index):
|
for _ in range(target_index - current_index):
|
||||||
debug.swipe_left(wait=True)
|
debug.swipe_left()
|
||||||
else:
|
else:
|
||||||
for _ in range(current_index - target_index):
|
for _ in range(current_index - target_index):
|
||||||
debug.swipe_right(wait=True)
|
debug.swipe_right()
|
||||||
MERCURY_CATEGORY = category # type: ignore
|
MERCURY_CATEGORY = category # type: ignore
|
||||||
# Category changed, reset coordinates
|
# Category changed, reset coordinates
|
||||||
MERCURY_COORDS_PREV = (0, 0) # type: ignore
|
MERCURY_COORDS_PREV = (0, 0) # type: ignore
|
||||||
@ -152,7 +153,7 @@ def press_char(debug: "DebugLink", char: str) -> None:
|
|||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
MERCURY_COORDS_PREV = coords # type: ignore
|
MERCURY_COORDS_PREV = coords # type: ignore
|
||||||
for _ in range(amount):
|
for _ in range(amount):
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> None:
|
def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> None:
|
||||||
@ -170,7 +171,7 @@ def enter_passphrase(debug: "DebugLink") -> None:
|
|||||||
"""Enter a passphrase"""
|
"""Enter a passphrase"""
|
||||||
is_empty: bool = len(debug.read_layout().passphrase()) == 0
|
is_empty: bool = len(debug.read_layout().passphrase()) == 0
|
||||||
coords = buttons.CORNER_BUTTON # top-right corner
|
coords = buttons.CORNER_BUTTON # top-right corner
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
if is_empty:
|
if is_empty:
|
||||||
debug.click(buttons.MERCURY_YES)
|
debug.click(buttons.MERCURY_YES)
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ def enter_passphrase(debug: "DebugLink") -> None:
|
|||||||
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)
|
coords = buttons.pin_passphrase_grid(9)
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
VECTORS = ( # passphrase, address
|
VECTORS = ( # passphrase, address
|
||||||
@ -215,7 +216,7 @@ def test_passphrase_delete(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
for _ in range(4):
|
for _ in range(4):
|
||||||
delete_char(debug)
|
delete_char(debug)
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
@ -245,7 +246,7 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
|||||||
PassphraseCategory.SPECIAL,
|
PassphraseCategory.SPECIAL,
|
||||||
):
|
):
|
||||||
go_to_category(debug, category)
|
go_to_category(debug, category)
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
coords = buttons.pin_passphrase_grid(11)
|
coords = buttons.pin_passphrase_grid(11)
|
||||||
|
@ -102,7 +102,7 @@ def prepare_passphrase_dialogue(
|
|||||||
) -> Generator["DebugLink", None, None]:
|
) -> Generator["DebugLink", None, None]:
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(get_test_address) # type: ignore
|
device_handler.run(get_test_address) # type: ignore
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
assert "PassphraseKeyboard" in layout.all_components()
|
assert "PassphraseKeyboard" in layout.all_components()
|
||||||
assert layout.passphrase() == ""
|
assert layout.passphrase() == ""
|
||||||
assert _current_category(debug) == PassphraseCategory.MENU
|
assert _current_category(debug) == PassphraseCategory.MENU
|
||||||
|
@ -70,7 +70,7 @@ def prepare_passphrase_dialogue(
|
|||||||
) -> Generator["DebugLink", None, None]:
|
) -> Generator["DebugLink", None, None]:
|
||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(get_test_address) # type: ignore
|
device_handler.run(get_test_address) # type: ignore
|
||||||
assert debug.wait_layout().main_component() == "PassphraseKeyboard"
|
assert debug.read_layout().main_component() == "PassphraseKeyboard"
|
||||||
|
|
||||||
# Resetting the category as it could have been changed by previous tests
|
# Resetting the category as it could have been changed by previous tests
|
||||||
global TT_CATEGORY
|
global TT_CATEGORY
|
||||||
@ -96,10 +96,10 @@ def go_to_category(debug: "DebugLink", category: PassphraseCategory) -> None:
|
|||||||
target_index = TT_CATEGORIES.index(category)
|
target_index = TT_CATEGORIES.index(category)
|
||||||
if target_index > current_index:
|
if target_index > current_index:
|
||||||
for _ in range(target_index - current_index):
|
for _ in range(target_index - current_index):
|
||||||
debug.swipe_left(wait=True)
|
debug.swipe_left()
|
||||||
else:
|
else:
|
||||||
for _ in range(current_index - target_index):
|
for _ in range(current_index - target_index):
|
||||||
debug.swipe_right(wait=True)
|
debug.swipe_right()
|
||||||
TT_CATEGORY = category # type: ignore
|
TT_CATEGORY = category # type: ignore
|
||||||
# Category changed, reset coordinates
|
# Category changed, reset coordinates
|
||||||
TT_COORDS_PREV = (0, 0) # type: ignore
|
TT_COORDS_PREV = (0, 0) # type: ignore
|
||||||
@ -125,7 +125,7 @@ def press_char(debug: "DebugLink", char: str) -> None:
|
|||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
TT_COORDS_PREV = coords # type: ignore
|
TT_COORDS_PREV = coords # type: ignore
|
||||||
for _ in range(amount):
|
for _ in range(amount):
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> None:
|
def input_passphrase(debug: "DebugLink", passphrase: str, check: bool = True) -> None:
|
||||||
@ -142,13 +142,13 @@ 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)
|
coords = buttons.pin_passphrase_grid(11)
|
||||||
debug.click(coords, wait=True)
|
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)
|
coords = buttons.pin_passphrase_grid(9)
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
VECTORS = ( # passphrase, address
|
VECTORS = ( # passphrase, address
|
||||||
@ -185,7 +185,6 @@ def test_passphrase_delete(device_handler: "BackgroundDeviceHandler"):
|
|||||||
|
|
||||||
for _ in range(4):
|
for _ in range(4):
|
||||||
delete_char(debug)
|
delete_char(debug)
|
||||||
debug.wait_layout()
|
|
||||||
|
|
||||||
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
input_passphrase(debug, CommonPass.SHORT[8 - 4 :])
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
@ -215,7 +214,6 @@ def test_passphrase_loop_all_characters(device_handler: "BackgroundDeviceHandler
|
|||||||
PassphraseCategory.SPECIAL,
|
PassphraseCategory.SPECIAL,
|
||||||
):
|
):
|
||||||
go_to_category(debug, category)
|
go_to_category(debug, category)
|
||||||
debug.wait_layout()
|
|
||||||
|
|
||||||
enter_passphrase(debug)
|
enter_passphrase(debug)
|
||||||
coords = buttons.pin_passphrase_grid(11)
|
coords = buttons.pin_passphrase_grid(11)
|
||||||
|
@ -104,43 +104,41 @@ def prepare(
|
|||||||
# Set new PIN
|
# Set new PIN
|
||||||
device_handler.run(device.change_pin) # type: ignore
|
device_handler.run(device.change_pin) # type: ignore
|
||||||
TR.assert_in_multiple(
|
TR.assert_in_multiple(
|
||||||
debug.wait_layout().text_content(), ["pin__turn_on", "pin__info"]
|
debug.read_layout().text_content(), ["pin__turn_on", "pin__info"]
|
||||||
)
|
)
|
||||||
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
elif situation == Situation.PIN_CHANGE:
|
elif situation == Situation.PIN_CHANGE:
|
||||||
# Change PIN
|
# Change PIN
|
||||||
device_handler.run(device.change_pin) # type: ignore
|
device_handler.run(device.change_pin) # type: ignore
|
||||||
_input_see_confirm(debug, old_pin)
|
_input_see_confirm(debug, old_pin)
|
||||||
TR.assert_in(debug.wait_layout().text_content(), "pin__change")
|
TR.assert_in(debug.read_layout().text_content(), "pin__change")
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
_input_see_confirm(debug, old_pin)
|
_input_see_confirm(debug, old_pin)
|
||||||
elif situation == Situation.WIPE_CODE_SETUP:
|
elif situation == Situation.WIPE_CODE_SETUP:
|
||||||
# Set wipe code
|
# Set wipe code
|
||||||
device_handler.run(device.change_wipe_code) # type: ignore
|
device_handler.run(device.change_wipe_code) # type: ignore
|
||||||
if old_pin:
|
if old_pin:
|
||||||
_input_see_confirm(debug, old_pin)
|
_input_see_confirm(debug, old_pin)
|
||||||
TR.assert_in(debug.wait_layout().text_content(), "wipe_code__turn_on")
|
TR.assert_in(debug.read_layout().text_content(), "wipe_code__turn_on")
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
if old_pin:
|
if old_pin:
|
||||||
debug.wait_layout()
|
|
||||||
_input_see_confirm(debug, old_pin)
|
_input_see_confirm(debug, old_pin)
|
||||||
|
|
||||||
debug.wait_layout()
|
|
||||||
_assert_pin_entry(debug)
|
_assert_pin_entry(debug)
|
||||||
yield debug
|
yield debug
|
||||||
|
|
||||||
if debug.layout_type is LayoutType.Mercury and tap:
|
if debug.layout_type is LayoutType.Mercury and tap:
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
debug.click(buttons.TAP_TO_CONFIRM)
|
debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
else:
|
else:
|
||||||
go_next(debug)
|
go_next(debug)
|
||||||
@ -162,7 +160,7 @@ def _input_pin(debug: "DebugLink", pin: str, check: bool = False) -> None:
|
|||||||
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)
|
coords = buttons.pin_passphrase_index(digit_index)
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
for digit in pin:
|
for digit in pin:
|
||||||
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, digit, TR_PIN_ACTIONS)
|
||||||
@ -175,7 +173,7 @@ 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.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
debug.click(buttons.TOP_ROW, wait=True)
|
debug.click(buttons.TOP_ROW)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
navigate_to_action_and_press(debug, SHOW, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, SHOW, TR_PIN_ACTIONS)
|
||||||
|
|
||||||
@ -187,7 +185,7 @@ 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.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
debug.click(buttons.pin_passphrase_grid(9), wait=True)
|
debug.click(buttons.pin_passphrase_grid(9))
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, DELETE, TR_PIN_ACTIONS)
|
||||||
|
|
||||||
@ -199,7 +197,7 @@ 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.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
debug.click_hold(buttons.pin_passphrase_grid(9), hold_ms=1500)
|
debug.click(buttons.pin_passphrase_grid(9), hold_ms=1500)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
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)
|
||||||
|
|
||||||
@ -218,7 +216,7 @@ 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.TT, LayoutType.Mercury):
|
if debug.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
debug.click(buttons.pin_passphrase_grid(11), wait=True)
|
debug.click(buttons.pin_passphrase_grid(11))
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
|
navigate_to_action_and_press(debug, ENTER, TR_PIN_ACTIONS)
|
||||||
|
|
||||||
@ -234,7 +232,7 @@ def _enter_two_times(debug: "DebugLink", pin1: str, pin2: str) -> None:
|
|||||||
|
|
||||||
if debug.layout_type is LayoutType.TR:
|
if debug.layout_type is LayoutType.TR:
|
||||||
# Please re-enter
|
# Please re-enter
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
|
|
||||||
_input_see_confirm(debug, pin2)
|
_input_see_confirm(debug, pin2)
|
||||||
|
|
||||||
@ -329,7 +327,7 @@ def test_pin_setup_mismatch(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug.press_middle()
|
debug.press_middle()
|
||||||
debug.press_no()
|
debug.press_no()
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
_cancel_pin(debug)
|
_cancel_pin(debug)
|
||||||
|
|
||||||
|
|
||||||
@ -361,7 +359,7 @@ def test_wipe_code_same_as_pin(device_handler: "BackgroundDeviceHandler"):
|
|||||||
with prepare(device_handler, Situation.WIPE_CODE_SETUP, old_pin="1") as debug:
|
with prepare(device_handler, Situation.WIPE_CODE_SETUP, old_pin="1") as debug:
|
||||||
_input_see_confirm(debug, "1")
|
_input_see_confirm(debug, "1")
|
||||||
# Try again
|
# Try again
|
||||||
go_next(debug, wait=True)
|
go_next(debug)
|
||||||
_enter_two_times(debug, "2", "2")
|
_enter_two_times(debug, "2", "2")
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ def test_repeated_backup(
|
|||||||
|
|
||||||
# ... so let's try to do a 2-of-3 backup
|
# ... so let's try to do a 2-of-3 backup
|
||||||
|
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
|
|
||||||
# confirm backup intro
|
# confirm backup intro
|
||||||
reset.confirm_read(debug)
|
reset.confirm_read(debug)
|
||||||
|
@ -38,19 +38,19 @@ def test_tutorial_ignore_menu(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||||
layout = debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||||
layout = debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -59,25 +59,25 @@ def test_tutorial_menu_open_close(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||||
layout = debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||||
layout = debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -86,22 +86,22 @@ def test_tutorial_menu_exit(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||||
layout = debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||||
layout = debug.click(buttons.VERTICAL_MENU[2], wait=True)
|
layout = debug.click(buttons.VERTICAL_MENU[2])
|
||||||
TR.assert_in(layout.footer(), "instructions__hold_to_exit_tutorial")
|
TR.assert_in(layout.footer(), "instructions__hold_to_exit_tutorial")
|
||||||
layout = debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -110,29 +110,29 @@ def test_tutorial_menu_repeat(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||||
layout = debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||||
layout = debug.click(buttons.VERTICAL_MENU[1], wait=True)
|
layout = debug.click(buttons.VERTICAL_MENU[1])
|
||||||
|
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||||
layout = debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
|
||||||
@ -141,32 +141,32 @@ def test_tutorial_menu_funfact(device_handler: "BackgroundDeviceHandler"):
|
|||||||
debug = device_handler.debuglink()
|
debug = device_handler.debuglink()
|
||||||
device_handler.run(device.show_device_tutorial)
|
device_handler.run(device.show_device_tutorial)
|
||||||
|
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
TR.assert_equals(layout.title(), "tutorial__welcome_safe5")
|
||||||
layout = debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
layout = debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
TR.assert_equals(layout.title(), "tutorial__title_lets_begin")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
TR.assert_equals(layout.title(), "tutorial__title_easy_navigation")
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||||
layout = debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
layout = debug.click(buttons.VERTICAL_MENU[0])
|
||||||
text_content = [
|
text_content = [
|
||||||
s.replace("\n", " ") for s in TR.translate("tutorial__first_wallet")
|
s.replace("\n", " ") for s in TR.translate("tutorial__first_wallet")
|
||||||
]
|
]
|
||||||
assert layout.text_content() in text_content
|
assert layout.text_content() in text_content
|
||||||
|
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
TR.assert_in(layout.text_content(), "tutorial__did_you_know")
|
||||||
layout = debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = debug.click(buttons.CORNER_BUTTON)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
TR.assert_equals(layout.title(), "tutorial__title_handy_menu")
|
||||||
|
|
||||||
layout = debug.swipe_up(wait=True)
|
layout = debug.swipe_up()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
TR.assert_equals(layout.title(), "tutorial__title_hold")
|
||||||
layout = debug.click_hold(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
layout = debug.click(buttons.TAP_TO_CONFIRM, hold_ms=1000)
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
TR.assert_equals(layout.title(), "tutorial__title_well_done")
|
||||||
debug.swipe_up(wait=True)
|
debug.swipe_up()
|
||||||
|
|
||||||
device_handler.result()
|
device_handler.result()
|
||||||
|
@ -51,12 +51,12 @@ def prepare_tutorial_and_cancel_after_it(
|
|||||||
|
|
||||||
|
|
||||||
def go_through_tutorial_tr(debug: "DebugLink") -> None:
|
def go_through_tutorial_tr(debug: "DebugLink") -> None:
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
debug.press_right_htc(hold_ms=1000)
|
debug.press_right(hold_ms=1000)
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
layout = debug.press_middle(wait=True)
|
layout = debug.press_middle()
|
||||||
TR.assert_equals(layout.title(), "tutorial__title_tutorial_complete")
|
TR.assert_equals(layout.title(), "tutorial__title_tutorial_complete")
|
||||||
|
|
||||||
|
|
||||||
@ -66,14 +66,14 @@ def test_tutorial_finish(device_handler: "BackgroundDeviceHandler"):
|
|||||||
go_through_tutorial_tr(debug)
|
go_through_tutorial_tr(debug)
|
||||||
|
|
||||||
# FINISH
|
# FINISH
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
def test_tutorial_skip(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_skip(device_handler: "BackgroundDeviceHandler"):
|
||||||
with prepare_tutorial_and_cancel_after_it(device_handler, cancelled=True) as debug:
|
with prepare_tutorial_and_cancel_after_it(device_handler, cancelled=True) as debug:
|
||||||
# SKIP
|
# SKIP
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
|
||||||
|
|
||||||
def test_tutorial_again_and_skip(device_handler: "BackgroundDeviceHandler"):
|
def test_tutorial_again_and_skip(device_handler: "BackgroundDeviceHandler"):
|
||||||
@ -82,8 +82,8 @@ def test_tutorial_again_and_skip(device_handler: "BackgroundDeviceHandler"):
|
|||||||
go_through_tutorial_tr(debug)
|
go_through_tutorial_tr(debug)
|
||||||
|
|
||||||
# AGAIN
|
# AGAIN
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
|
|
||||||
# SKIP
|
# SKIP
|
||||||
debug.press_left(wait=True)
|
debug.press_left()
|
||||||
debug.press_right(wait=True)
|
debug.press_right()
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
# You should have received a copy of the License along with this library.
|
# You should have received a copy of the License along with this library.
|
||||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
@ -226,10 +228,8 @@ def read_mnemonic_from_screen_tt(
|
|||||||
br = yield
|
br = yield
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
|
|
||||||
debug.wait_layout()
|
|
||||||
|
|
||||||
for i in range(br.pages):
|
for i in range(br.pages):
|
||||||
words = debug.wait_layout().seed_words()
|
words = debug.read_layout().seed_words()
|
||||||
mnemonic.extend(words)
|
mnemonic.extend(words)
|
||||||
# Not swiping on the last page
|
# Not swiping on the last page
|
||||||
if i < br.pages - 1:
|
if i < br.pages - 1:
|
||||||
@ -248,7 +248,7 @@ def read_mnemonic_from_screen_tr(
|
|||||||
br = yield
|
br = yield
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
words = layout.seed_words()
|
words = layout.seed_words()
|
||||||
mnemonic.extend(words)
|
mnemonic.extend(words)
|
||||||
debug.press_right()
|
debug.press_right()
|
||||||
@ -266,15 +266,15 @@ def read_mnemonic_from_screen_mercury(
|
|||||||
br = yield
|
br = yield
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
|
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
for _ in range(br.pages - 2):
|
for _ in range(br.pages - 2):
|
||||||
words = debug.wait_layout().seed_words()
|
words = debug.read_layout().seed_words()
|
||||||
mnemonic.extend(words)
|
mnemonic.extend(words)
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
return mnemonic
|
return mnemonic
|
||||||
@ -292,13 +292,13 @@ def check_share(
|
|||||||
if debug.layout_type is LayoutType.TT:
|
if debug.layout_type is LayoutType.TT:
|
||||||
# T2T1 has position as the first number in the text
|
# T2T1 has position as the first number in the text
|
||||||
word_pos_match = re.search(
|
word_pos_match = re.search(
|
||||||
re_num_of_word, debug.wait_layout().text_content()
|
re_num_of_word, debug.read_layout().text_content()
|
||||||
)
|
)
|
||||||
elif debug.layout_type is LayoutType.TR:
|
elif debug.layout_type is LayoutType.TR:
|
||||||
# other models have the instruction in the title/subtitle
|
# other models have the instruction in the title/subtitle
|
||||||
word_pos_match = re.search(re_num_of_word, debug.wait_layout().title())
|
word_pos_match = re.search(re_num_of_word, debug.read_layout().title())
|
||||||
elif debug.layout_type is LayoutType.Mercury:
|
elif debug.layout_type is LayoutType.Mercury:
|
||||||
word_pos_match = re.search(re_num_of_word, debug.wait_layout().subtitle())
|
word_pos_match = re.search(re_num_of_word, debug.read_layout().subtitle())
|
||||||
else:
|
else:
|
||||||
word_pos_match = None
|
word_pos_match = None
|
||||||
|
|
||||||
@ -318,16 +318,16 @@ def check_share(
|
|||||||
def click_info_button_tt(debug: "DebugLink"):
|
def click_info_button_tt(debug: "DebugLink"):
|
||||||
"""Click Shamir backup info button and return back."""
|
"""Click Shamir backup info button and return back."""
|
||||||
debug.press_info()
|
debug.press_info()
|
||||||
yield # Info screen with text
|
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
def click_info_button_mercury(debug: "DebugLink"):
|
def click_info_button_mercury(debug: "DebugLink"):
|
||||||
"""Click Shamir backup info button and return back."""
|
"""Click Shamir backup info button and return back."""
|
||||||
debug.click(buttons.CORNER_BUTTON, wait=True)
|
debug.click(buttons.CORNER_BUTTON)
|
||||||
debug.synchronize_at("VerticalMenu")
|
debug.synchronize_at("VerticalMenu")
|
||||||
debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
debug.click(buttons.VERTICAL_MENU[0])
|
||||||
debug.click(buttons.CORNER_BUTTON, wait=True)
|
debug.click(buttons.CORNER_BUTTON)
|
||||||
debug.click(buttons.CORNER_BUTTON)
|
debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
|
|
||||||
@ -356,12 +356,12 @@ def compact_size(n: int) -> bytes:
|
|||||||
|
|
||||||
|
|
||||||
def get_text_possible_pagination(debug: "DebugLink", br: messages.ButtonRequest) -> str:
|
def get_text_possible_pagination(debug: "DebugLink", br: messages.ButtonRequest) -> str:
|
||||||
text = debug.wait_layout().text_content()
|
text = debug.read_layout().text_content()
|
||||||
if br.pages is not None:
|
if br.pages is not None:
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
text += " "
|
text += " "
|
||||||
text += debug.wait_layout().text_content()
|
text += debug.read_layout().text_content()
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,11 @@ if t.TYPE_CHECKING:
|
|||||||
HERE = Path(__file__).resolve().parent
|
HERE = Path(__file__).resolve().parent
|
||||||
CORE = HERE.parent / "core"
|
CORE = HERE.parent / "core"
|
||||||
|
|
||||||
|
# So that we see details of failed asserts from this module
|
||||||
|
pytest.register_assert_rewrite("tests.common")
|
||||||
|
pytest.register_assert_rewrite("tests.input_flows")
|
||||||
|
pytest.register_assert_rewrite("tests.input_flows_helpers")
|
||||||
|
|
||||||
|
|
||||||
def _emulator_wrapper_main_args() -> list[str]:
|
def _emulator_wrapper_main_args() -> list[str]:
|
||||||
"""Look at TREZOR_PROFILING env variable, so that we can generate coverage reports."""
|
"""Look at TREZOR_PROFILING env variable, so that we can generate coverage reports."""
|
||||||
|
@ -33,7 +33,7 @@ pytestmark = [
|
|||||||
|
|
||||||
def show_details_input_flow(client: Client):
|
def show_details_input_flow(client: Client):
|
||||||
yield
|
yield
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
if client.layout_type is LayoutType.TT:
|
if client.layout_type is LayoutType.TT:
|
||||||
SHOW_ALL_BUTTON_POSITION = (143, 167)
|
SHOW_ALL_BUTTON_POSITION = (143, 167)
|
||||||
client.debug.click(SHOW_ALL_BUTTON_POSITION)
|
client.debug.click(SHOW_ALL_BUTTON_POSITION)
|
||||||
|
@ -64,17 +64,23 @@ def test_busy_state(client: Client):
|
|||||||
|
|
||||||
@pytest.mark.flaky(max_runs=5)
|
@pytest.mark.flaky(max_runs=5)
|
||||||
def test_busy_expiry(client: Client):
|
def test_busy_expiry(client: Client):
|
||||||
|
WAIT_TIME_MS = 1500
|
||||||
|
TOLERANCE = 1000
|
||||||
|
|
||||||
_assert_busy(client, False)
|
_assert_busy(client, False)
|
||||||
|
# Start a timer
|
||||||
|
start = time.monotonic()
|
||||||
# Show the busy dialog.
|
# Show the busy dialog.
|
||||||
device.set_busy(client, expiry_ms=1500)
|
device.set_busy(client, expiry_ms=WAIT_TIME_MS)
|
||||||
_assert_busy(client, True)
|
_assert_busy(client, True)
|
||||||
|
|
||||||
# Hasn't expired yet.
|
# Wait until the layout changes
|
||||||
time.sleep(0.1)
|
client.debug.wait_layout()
|
||||||
_assert_busy(client, True)
|
end = time.monotonic()
|
||||||
|
|
||||||
# Wait for it to expire. Add some tolerance to account for CI/hardware slowness.
|
# Check that the busy dialog was shown for at least WAIT_TIME_MS.
|
||||||
time.sleep(4.0)
|
duration = (end - start) * 1000
|
||||||
|
assert WAIT_TIME_MS <= duration <= WAIT_TIME_MS + TOLERANCE
|
||||||
|
|
||||||
# Check that the device is no longer busy.
|
# Check that the device is no longer busy.
|
||||||
# Also needs to come back to Homescreen (for UI tests).
|
# Also needs to come back to Homescreen (for UI tests).
|
||||||
|
@ -69,7 +69,7 @@ def client(client: Client) -> Iterator[Client]:
|
|||||||
def _check_ping_screen_texts(client: Client, title: str, right_button: str) -> None:
|
def _check_ping_screen_texts(client: Client, title: str, right_button: str) -> None:
|
||||||
def ping_input_flow(client: Client, title: str, right_button: str):
|
def ping_input_flow(client: Client, title: str, right_button: str):
|
||||||
yield
|
yield
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
assert layout.title().upper() == title.upper()
|
assert layout.title().upper() == title.upper()
|
||||||
assert layout.button_contents()[-1].upper() == right_button.upper()
|
assert layout.button_contents()[-1].upper() == right_button.upper()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
@ -161,7 +161,8 @@ def test_repeated_backup_cancel(client: Client):
|
|||||||
)
|
)
|
||||||
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
||||||
|
|
||||||
client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
|
TR.assert_in(layout.text_content(), "recovery__unlock_repeated_backup")
|
||||||
|
|
||||||
# send a Cancel message
|
# send a Cancel message
|
||||||
|
|
||||||
@ -216,7 +217,8 @@ def test_repeated_backup_send_disallowed_message(client: Client):
|
|||||||
)
|
)
|
||||||
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
assert client.features.recovery_status == messages.RecoveryStatus.Backup
|
||||||
|
|
||||||
client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
|
TR.assert_in(layout.text_content(), "recovery__unlock_repeated_backup")
|
||||||
|
|
||||||
# send a GetAddress message
|
# send a GetAddress message
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ def test_sd_no_format(client: Client):
|
|||||||
@pytest.mark.sd_card
|
@pytest.mark.sd_card
|
||||||
@pytest.mark.setup_client(pin="1234")
|
@pytest.mark.setup_client(pin="1234")
|
||||||
def test_sd_protect_unlock(client: Client):
|
def test_sd_protect_unlock(client: Client):
|
||||||
layout = client.debug.wait_layout
|
layout = client.debug.read_layout
|
||||||
|
|
||||||
def input_flow_enable_sd_protect():
|
def input_flow_enable_sd_protect():
|
||||||
yield # Enter PIN to unlock device
|
yield # Enter PIN to unlock device
|
||||||
|
@ -397,7 +397,7 @@ def test_hide_passphrase_from_host(client: Client):
|
|||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
yield
|
yield
|
||||||
content = client.debug.wait_layout().text_content().lower()
|
content = client.debug.read_layout().text_content().lower()
|
||||||
assert any(
|
assert any(
|
||||||
(s[:50].lower() in content)
|
(s[:50].lower() in content)
|
||||||
for s in TR.translate("passphrase__from_host_not_shown")
|
for s in TR.translate("passphrase__from_host_not_shown")
|
||||||
@ -436,17 +436,17 @@ def test_hide_passphrase_from_host(client: Client):
|
|||||||
def input_flow():
|
def input_flow():
|
||||||
yield
|
yield
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
client.debug.wait_layout().text_content(),
|
client.debug.read_layout().text_content(),
|
||||||
"passphrase__next_screen_will_show_passphrase",
|
"passphrase__next_screen_will_show_passphrase",
|
||||||
)
|
)
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
yield
|
yield
|
||||||
TR.assert_equals(
|
TR.assert_equals(
|
||||||
client.debug.wait_layout().title(),
|
client.debug.read_layout().title(),
|
||||||
"passphrase__title_confirm",
|
"passphrase__title_confirm",
|
||||||
)
|
)
|
||||||
assert passphrase in client.debug.wait_layout().text_content()
|
assert passphrase in client.debug.read_layout().text_content()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
client.watch_layout()
|
client.watch_layout()
|
||||||
|
@ -73,16 +73,16 @@ class InputFlowBase:
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def text_content(self) -> str:
|
def text_content(self) -> str:
|
||||||
return self.debug.wait_layout().text_content()
|
return self.debug.read_layout().text_content()
|
||||||
|
|
||||||
def main_component(self) -> str:
|
def main_component(self) -> str:
|
||||||
return self.debug.wait_layout().main_component()
|
return self.debug.read_layout().main_component()
|
||||||
|
|
||||||
def all_components(self) -> list[str]:
|
def all_components(self) -> list[str]:
|
||||||
return self.debug.wait_layout().all_components()
|
return self.debug.read_layout().all_components()
|
||||||
|
|
||||||
def title(self) -> str:
|
def title(self) -> str:
|
||||||
return self.debug.wait_layout().title()
|
return self.debug.read_layout().title()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowSetupDevicePINWIpeCode(InputFlowBase):
|
class InputFlowSetupDevicePINWIpeCode(InputFlowBase):
|
||||||
@ -213,13 +213,13 @@ class InputFlowSignMessagePagination(InputFlowBase):
|
|||||||
layouts: list[LayoutContent] = []
|
layouts: list[LayoutContent] = []
|
||||||
|
|
||||||
br = yield # confirm address
|
br = yield # confirm address
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
for i in range(br.pages):
|
for i in range(br.pages):
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
layouts.append(layout)
|
layouts.append(layout)
|
||||||
|
|
||||||
if i < br.pages - 1:
|
if i < br.pages - 1:
|
||||||
@ -257,13 +257,13 @@ class InputFlowSignMessagePagination(InputFlowBase):
|
|||||||
layouts: list[LayoutContent] = []
|
layouts: list[LayoutContent] = []
|
||||||
|
|
||||||
br = yield # confirm address
|
br = yield # confirm address
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
# assert br.pages is not None
|
# assert br.pages is not None
|
||||||
for i in range(br.pages or 1):
|
for i in range(br.pages or 1):
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
layouts.append(layout)
|
layouts.append(layout)
|
||||||
|
|
||||||
if br.pages and i < br.pages - 1:
|
if br.pages and i < br.pages - 1:
|
||||||
@ -281,9 +281,9 @@ class InputFlowSignMessageInfo(InputFlowBase):
|
|||||||
def input_flow_tt(self) -> BRGeneratorType:
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
# show address/message info
|
# show address/message info
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.synchronize_at("IconDialog")
|
self.debug.synchronize_at("IconDialog")
|
||||||
# address mismatch?
|
# address mismatch?
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -292,15 +292,15 @@ class InputFlowSignMessageInfo(InputFlowBase):
|
|||||||
yield
|
yield
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
yield
|
yield
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes(wait=True)
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
# show address/message info
|
# show address/message info
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.synchronize_at("IconDialog")
|
self.debug.synchronize_at("IconDialog")
|
||||||
# address mismatch?
|
# address mismatch?
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -309,8 +309,8 @@ class InputFlowSignMessageInfo(InputFlowBase):
|
|||||||
yield
|
yield
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
yield
|
yield
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes(wait=True)
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowShowAddressQRCode(InputFlowBase):
|
class InputFlowShowAddressQRCode(InputFlowBase):
|
||||||
@ -319,16 +319,16 @@ class InputFlowShowAddressQRCode(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_tt(self) -> BRGeneratorType:
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# 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(wait=True)
|
self.debug.swipe_left()
|
||||||
self.debug.swipe_right(wait=True)
|
self.debug.swipe_right()
|
||||||
self.debug.swipe_left(wait=True)
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_tr(self) -> BRGeneratorType:
|
def input_flow_tr(self) -> BRGeneratorType:
|
||||||
@ -354,29 +354,29 @@ class InputFlowShowAddressQRCode(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# 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[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
# address details
|
# address details
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[2], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
layout = self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
layout = self.debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
while "PromptScreen" not in layout.all_components():
|
while "PromptScreen" not in layout.all_components():
|
||||||
layout = self.debug.swipe_up(wait=True)
|
layout = self.debug.swipe_up()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
# tap to confirm
|
# tap to confirm
|
||||||
self.debug.click(buttons.TAP_TO_CONFIRM)
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
@ -388,13 +388,13 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_tt(self) -> BRGeneratorType:
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# 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(wait=True)
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_tr(self) -> BRGeneratorType:
|
def input_flow_tr(self) -> BRGeneratorType:
|
||||||
@ -406,7 +406,7 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
|||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
# Cancel
|
# Cancel
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
# Confirm address mismatch
|
# Confirm address mismatch
|
||||||
# Clicking right twice, as some languages can have two pages
|
# Clicking right twice, as some languages can have two pages
|
||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
@ -414,25 +414,25 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# 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[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
self.debug.synchronize_at("Qr")
|
self.debug.synchronize_at("Qr")
|
||||||
# qr code
|
# qr code
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
# address details
|
# address details
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[2], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up(wait=True)
|
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, wait=True)
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
|
|
||||||
|
|
||||||
class InputFlowShowMultisigXPUBs(InputFlowBase):
|
class InputFlowShowMultisigXPUBs(InputFlowBase):
|
||||||
@ -447,7 +447,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # show address
|
yield # show address
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||||
assert "(MULTISIG)" in layout.title()
|
assert "(MULTISIG)" in layout.title()
|
||||||
assert layout.text_content().replace(" ", "") == self.address
|
assert layout.text_content().replace(" ", "") == self.address
|
||||||
@ -455,24 +455,26 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
self.debug.click(buttons.CORNER_BUTTON)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
assert "Qr" in self.all_components()
|
assert "Qr" in self.all_components()
|
||||||
|
|
||||||
layout = self.debug.swipe_left(wait=True)
|
layout = self.debug.swipe_left()
|
||||||
# address details
|
# address details
|
||||||
assert "Multisig 2 of 3" in layout.screen_content()
|
assert "Multisig 2 of 3" in layout.screen_content()
|
||||||
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
||||||
|
|
||||||
# Three xpub pages with the same testing logic
|
# Three xpub pages with the same testing logic
|
||||||
for xpub_num in range(3):
|
for xpub_num in range(3):
|
||||||
expected_title = f"MULTISIG XPUB #{xpub_num + 1}"
|
expected_title = f"MULTISIG XPUB #{xpub_num + 1}\n" + (
|
||||||
layout = self.debug.swipe_left(wait=True)
|
"(YOURS)" if self.index == xpub_num else "(COSIGNER)"
|
||||||
assert expected_title in layout.title()
|
)
|
||||||
|
layout = self.debug.swipe_left()
|
||||||
|
assert expected_title == layout.title()
|
||||||
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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# show address
|
# show address
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
# address mismatch
|
# address mismatch
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
# show address
|
# show address
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
@ -481,7 +483,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
|
|
||||||
yield # show address
|
yield # show address
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||||
assert "(MULTISIG)" in layout.title()
|
assert "(MULTISIG)" in layout.title()
|
||||||
assert layout.text_content().replace(" ", "") == self.address
|
assert layout.text_content().replace(" ", "") == self.address
|
||||||
@ -489,22 +491,24 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
assert "Qr" in self.all_components()
|
assert "Qr" in self.all_components()
|
||||||
|
|
||||||
layout = self.debug.press_right(wait=True)
|
layout = self.debug.press_right()
|
||||||
# address details
|
# address details
|
||||||
# TODO: locate it more precisely
|
# TODO: locate it more precisely
|
||||||
assert "Multisig 2 of 3" in layout.json_str
|
assert "Multisig 2 of 3" in layout.json_str
|
||||||
|
|
||||||
# Three xpub pages with the same testing logic
|
# Three xpub pages with the same testing logic
|
||||||
for xpub_num in range(3):
|
for xpub_num in range(3):
|
||||||
expected_title = f"MULTISIG XPUB #{xpub_num + 1}"
|
expected_title = f"MULTISIG XPUB #{xpub_num + 1} " + (
|
||||||
layout = self.debug.press_right(wait=True)
|
"(YOURS)" if self.index == xpub_num else "(COSIGNER)"
|
||||||
|
)
|
||||||
|
layout = self.debug.press_right()
|
||||||
assert expected_title in layout.title()
|
assert expected_title in layout.title()
|
||||||
xpub_part_1 = layout.text_content().replace(" ", "")
|
xpub_part_1 = layout.text_content().replace(" ", "")
|
||||||
# Press "SHOW MORE"
|
# Press "SHOW MORE"
|
||||||
layout = self.debug.press_middle(wait=True)
|
layout = self.debug.press_middle()
|
||||||
xpub_part_2 = layout.text_content().replace(" ", "")
|
xpub_part_2 = layout.text_content().replace(" ", "")
|
||||||
# Go back
|
# Go back
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
assert self.xpubs[xpub_num] == xpub_part_1 + xpub_part_2
|
assert self.xpubs[xpub_num] == xpub_part_1 + xpub_part_2
|
||||||
|
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
@ -518,26 +522,26 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield # multisig address warning
|
yield # multisig address warning
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1])
|
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
|
|
||||||
yield # show address
|
yield # show address
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
TR.assert_in(layout.title(), "address__title_receive_address")
|
TR.assert_in(layout.title(), "address__title_receive_address")
|
||||||
assert layout.text_content().replace(" ", "") == self.address
|
assert layout.text_content().replace(" ", "") == self.address
|
||||||
|
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[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()
|
||||||
@ -545,24 +549,24 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
|
|||||||
|
|
||||||
# three xpub pages with the same testing logic
|
# three xpub pages with the same testing logic
|
||||||
for _xpub_num in range(3):
|
for _xpub_num in range(3):
|
||||||
layout = self.debug.swipe_left(wait=True)
|
layout = self.debug.swipe_left()
|
||||||
layout = self.debug.swipe_left(wait=True)
|
layout = self.debug.swipe_left()
|
||||||
|
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[2], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
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():
|
||||||
layout = self.debug.swipe_up(wait=True)
|
layout = self.debug.swipe_up()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
# tap to confirm
|
# tap to confirm
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -581,23 +585,23 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
br = yield
|
br = yield
|
||||||
|
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# 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(wait=True)
|
self.debug.swipe_left()
|
||||||
self.debug.swipe_right(wait=True)
|
self.debug.swipe_right()
|
||||||
self.debug.swipe_left(wait=True)
|
self.debug.swipe_left()
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_tr(self) -> BRGeneratorType:
|
def input_flow_tr(self) -> BRGeneratorType:
|
||||||
@ -608,19 +612,19 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
br = yield
|
br = yield
|
||||||
|
|
||||||
# Go into details
|
# Go into details
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
# Go through details and back
|
# Go through details and back
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
@ -635,44 +639,44 @@ class InputFlowShowXpubQRCode(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
br = yield
|
br = yield
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
if "coinjoin" in layout.title().lower() or br.code == B.UnknownDerivationPath:
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
br = yield
|
br = yield
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
|
|
||||||
assert layout.title() in TR.translate("address__public_key") + ["XPUB"]
|
assert layout.title() in TR.translate("address__public_key") + ["XPUB"]
|
||||||
|
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
# menu
|
# menu
|
||||||
assert "VerticalMenu" in self.all_components()
|
assert "VerticalMenu" in self.all_components()
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
layout = self.debug.synchronize_at("AddressDetails")
|
layout = self.debug.synchronize_at("AddressDetails")
|
||||||
# address details
|
# address details
|
||||||
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
TR.assert_in(layout.screen_content(), "address_details__derivation_path")
|
||||||
|
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.VERTICAL_MENU[2], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[2])
|
||||||
# cancel
|
# cancel
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
# really cancel
|
# really cancel
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
layout = self.debug.synchronize_at("VerticalMenu")
|
layout = self.debug.synchronize_at("VerticalMenu")
|
||||||
# menu
|
# menu
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
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():
|
||||||
layout = self.debug.swipe_up(wait=True)
|
layout = self.debug.swipe_up()
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
# tap to confirm
|
# tap to confirm
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -685,21 +689,21 @@ class InputFlowPaymentRequestDetails(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_tt(self) -> BRGeneratorType:
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
yield # request to see details
|
yield # request to see details
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_info()
|
self.debug.press_info()
|
||||||
|
|
||||||
yield # confirm first output
|
yield # confirm first output
|
||||||
assert self.outputs[0].address[:16] in self.text_content() # type: ignore
|
assert self.outputs[0].address[:16] in self.text_content() # type: ignore
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # confirm first output
|
yield # confirm first output
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm second output
|
yield # confirm second output
|
||||||
assert self.outputs[1].address[:16] in self.text_content() # type: ignore
|
assert self.outputs[1].address[:16] in self.text_content() # type: ignore
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # confirm second output
|
yield # confirm second output
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm transaction
|
yield # confirm transaction
|
||||||
@ -709,21 +713,21 @@ class InputFlowPaymentRequestDetails(InputFlowBase):
|
|||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield # request to see details
|
yield # request to see details
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.press_info()
|
self.debug.press_info()
|
||||||
|
|
||||||
yield # confirm first output
|
yield # confirm first output
|
||||||
assert self.outputs[0].address[:16] in self.text_content() # type: ignore
|
assert self.outputs[0].address[:16] in self.text_content() # type: ignore
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # confirm first output
|
yield # confirm first output
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
|
|
||||||
yield # confirm second output
|
yield # confirm second output
|
||||||
assert self.outputs[1].address[:16] in self.text_content() # type: ignore
|
assert self.outputs[1].address[:16] in self.text_content() # type: ignore
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # confirm second output
|
yield # confirm second output
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
|
|
||||||
yield # confirm transaction
|
yield # confirm transaction
|
||||||
@ -779,85 +783,85 @@ class InputFlowSignTxHighFee(InputFlowBase):
|
|||||||
self.finished = True
|
self.finished = True
|
||||||
|
|
||||||
|
|
||||||
def sign_tx_go_to_info(client: Client) -> Generator[None, None, str]:
|
def sign_tx_go_to_info(client: Client) -> Generator[None, messages.ButtonRequest, str]:
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm transaction
|
yield # confirm transaction
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_info()
|
client.debug.press_info()
|
||||||
|
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
content = layout.text_content()
|
content = layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.CORNER_BUTTON, wait=True)
|
client.debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
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, None, str]:
|
) -> Generator[None, messages.ButtonRequest, str]:
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
|
|
||||||
if multi_account:
|
if multi_account:
|
||||||
yield
|
yield
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
|
|
||||||
yield # confirm transaction
|
yield # confirm transaction
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.click(buttons.CORNER_BUTTON)
|
client.debug.click(buttons.CORNER_BUTTON)
|
||||||
client.debug.synchronize_at("VerticalMenu")
|
client.debug.synchronize_at("VerticalMenu")
|
||||||
client.debug.click(buttons.VERTICAL_MENU[0])
|
client.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
|
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
content = layout.text_content()
|
content = layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.CORNER_BUTTON)
|
client.debug.click(buttons.CORNER_BUTTON)
|
||||||
client.debug.synchronize_at("VerticalMenu")
|
client.debug.synchronize_at("VerticalMenu")
|
||||||
client.debug.click(buttons.VERTICAL_MENU[1])
|
client.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
|
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
content += " " + layout.text_content()
|
content += " " + layout.text_content()
|
||||||
|
|
||||||
client.debug.click(buttons.CORNER_BUTTON)
|
client.debug.click(buttons.CORNER_BUTTON)
|
||||||
client.debug.click(buttons.CORNER_BUTTON, wait=True)
|
client.debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def sign_tx_go_to_info_tr(
|
def sign_tx_go_to_info_tr(
|
||||||
client: Client,
|
client: Client,
|
||||||
) -> Generator[None, None, str]:
|
) -> Generator[None, messages.ButtonRequest, str]:
|
||||||
yield # confirm address
|
yield # confirm address
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_yes() # CONTINUE
|
client.debug.press_yes() # CONTINUE
|
||||||
yield # confirm amount
|
yield # confirm amount
|
||||||
client.debug.wait_layout()
|
client.debug.read_layout()
|
||||||
client.debug.press_yes() # CONFIRM
|
client.debug.press_yes() # CONFIRM
|
||||||
|
|
||||||
screen_texts: list[str] = []
|
screen_texts: list[str] = []
|
||||||
|
|
||||||
yield # confirm total
|
yield # confirm total
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.read_layout()
|
||||||
if "multiple accounts" in layout.text_content().lower():
|
if "multiple accounts" in layout.text_content().lower():
|
||||||
client.debug.press_middle()
|
client.debug.press_middle()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
layout = client.debug.press_right(wait=True)
|
layout = client.debug.press_right()
|
||||||
screen_texts.append(layout.text_content())
|
screen_texts.append(layout.text_content())
|
||||||
|
|
||||||
layout = client.debug.press_right(wait=True)
|
layout = client.debug.press_right()
|
||||||
screen_texts.append(layout.text_content())
|
screen_texts.append(layout.text_content())
|
||||||
|
|
||||||
client.debug.press_left()
|
client.debug.press_left()
|
||||||
@ -959,15 +963,16 @@ class InputFlowSignTxInformationReplacement(InputFlowBase):
|
|||||||
yield # confirm address
|
yield # confirm address
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
# go back to address
|
# go back to address
|
||||||
|
yield
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
# confirm address
|
# confirm address
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # confirm amount
|
# confirm amount
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # transaction summary, press info
|
yield # transaction summary, press info
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_tr(self) -> BRGeneratorType:
|
def input_flow_tr(self) -> BRGeneratorType:
|
||||||
@ -997,8 +1002,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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
|
||||||
@ -1008,10 +1013,10 @@ def lock_time_input_flow_tt(
|
|||||||
double_confirm: bool = False,
|
double_confirm: bool = False,
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
br = yield # confirm locktime
|
br = yield # confirm locktime
|
||||||
@ -1030,10 +1035,10 @@ def lock_time_input_flow_tr(
|
|||||||
layout_assert_func: Callable[[DebugLink, messages.ButtonRequest], None],
|
layout_assert_func: Callable[[DebugLink, messages.ButtonRequest], None],
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
yield # confirm address
|
yield # confirm address
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
yield # confirm amount
|
yield # confirm amount
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
br = yield # confirm locktime
|
br = yield # confirm locktime
|
||||||
@ -1050,10 +1055,10 @@ def lock_time_input_flow_t3t1(
|
|||||||
double_confirm: bool = False,
|
double_confirm: bool = False,
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
yield # confirm output
|
yield # confirm output
|
||||||
debug.wait_layout()
|
debug.read_layout()
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
|
|
||||||
br = yield # confirm locktime
|
br = yield # confirm locktime
|
||||||
@ -1134,7 +1139,7 @@ class InputFlowEIP712ShowMore(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm domain
|
yield # confirm domain
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self._confirm_show_more()
|
self._confirm_show_more()
|
||||||
|
|
||||||
# confirm domain properties
|
# confirm domain properties
|
||||||
@ -1143,11 +1148,11 @@ class InputFlowEIP712ShowMore(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm message
|
yield # confirm message
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self._confirm_show_more()
|
self._confirm_show_more()
|
||||||
|
|
||||||
yield # confirm message.from
|
yield # confirm message.from
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self._confirm_show_more()
|
self._confirm_show_more()
|
||||||
|
|
||||||
# confirm message.from properties
|
# confirm message.from properties
|
||||||
@ -1156,7 +1161,7 @@ class InputFlowEIP712ShowMore(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # confirm message.to
|
yield # confirm message.to
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self._confirm_show_more()
|
self._confirm_show_more()
|
||||||
|
|
||||||
# confirm message.to properties
|
# confirm message.to properties
|
||||||
@ -1225,7 +1230,6 @@ class InputFlowEthereumSignTxDataScrollDown(InputFlowBase):
|
|||||||
yield from self.ETH.confirm_data(info=True)
|
yield from self.ETH.confirm_data(info=True)
|
||||||
yield from self.ETH.paginate_data()
|
yield from self.ETH.paginate_data()
|
||||||
|
|
||||||
self.debug.wait_layout()
|
|
||||||
if self.debug.layout_type is LayoutType.TR:
|
if self.debug.layout_type is LayoutType.TR:
|
||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
else:
|
else:
|
||||||
@ -1432,21 +1436,16 @@ class InputFlowSlip39BasicBackup(InputFlowBase):
|
|||||||
self.repeated = repeated
|
self.repeated = repeated
|
||||||
|
|
||||||
def input_flow_tt(self) -> BRGeneratorType:
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
if self.repeated:
|
yield # 1. Checklist
|
||||||
# intro confirmation screen
|
|
||||||
yield
|
|
||||||
self.debug.press_yes()
|
|
||||||
|
|
||||||
yield # 1. Backup intro
|
|
||||||
self.debug.press_yes()
|
|
||||||
yield # 2. Checklist
|
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
yield # 2. Number of shares (5)
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
yield from click_info_button_tt(self.debug)
|
yield from click_info_button_tt(self.debug)
|
||||||
yield # 3. Number of shares (5)
|
yield # 3. Number of shares (5)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # 4. Checklist
|
yield # 4. Checklist
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
yield # 4. Threshold (3)
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
yield from click_info_button_tt(self.debug)
|
yield from click_info_button_tt(self.debug)
|
||||||
yield # 5. Threshold (3)
|
yield # 5. Threshold (3)
|
||||||
@ -1502,20 +1501,18 @@ class InputFlowSlip39BasicBackup(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield # 1. Backup intro
|
yield # 1. Backup intro
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 2. Checklist
|
yield # 2. Checklist
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # 3. Number of shares (5)
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 4. Checklist
|
yield # 4. Checklist
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # 5. Threshold (3)
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 6. Checklist
|
yield # 6. Checklist
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
@ -1709,12 +1706,14 @@ class InputFlowSlip39AdvancedBackup(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # 2. Checklist
|
yield # 2. Checklist
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
yield # 2. Set and confirm group count
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
yield from click_info_button_tt(self.debug)
|
yield from click_info_button_tt(self.debug)
|
||||||
yield # 3. Set and confirm group count
|
yield # 3. Set and confirm group count
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # 4. Checklist
|
yield # 4. Checklist
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
yield # 4. Set and confirm group threshold
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
yield from click_info_button_tt(self.debug)
|
yield from click_info_button_tt(self.debug)
|
||||||
yield # 5. Set and confirm group threshold
|
yield # 5. Set and confirm group threshold
|
||||||
@ -1722,13 +1721,13 @@ class InputFlowSlip39AdvancedBackup(InputFlowBase):
|
|||||||
yield # 6. Checklist
|
yield # 6. Checklist
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
for _ in range(5): # for each of 5 groups
|
for _ in range(5): # for each of 5 groups
|
||||||
if self.click_info:
|
|
||||||
yield from click_info_button_tt(self.debug)
|
|
||||||
yield # Set & Confirm number of shares
|
yield # Set & Confirm number of shares
|
||||||
self.debug.press_yes()
|
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
yield from click_info_button_tt(self.debug)
|
yield from click_info_button_tt(self.debug)
|
||||||
|
self.debug.press_yes()
|
||||||
yield # Set & confirm share threshold value
|
yield # Set & confirm share threshold value
|
||||||
|
if self.click_info:
|
||||||
|
yield from click_info_button_tt(self.debug)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # Confirm show seeds
|
yield # Confirm show seeds
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -1773,33 +1772,32 @@ class InputFlowSlip39AdvancedBackup(InputFlowBase):
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
yield # 1. Backup intro
|
assert (yield).name == "backup_intro"
|
||||||
self.debug.wait_layout()
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 2. Checklist
|
assert (yield).name == "slip39_checklist"
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
|
assert (yield).name == "slip39_groups"
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # 3. Set and confirm group count
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 4. Checklist
|
assert (yield).name == "slip39_checklist"
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
|
assert (yield).name == "slip39_group_threshold"
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # 5. Set and confirm group threshold
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield # 6. Checklist
|
assert (yield).name == "slip39_checklist"
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
for _i in range(5): # for each of 5 groups
|
for _i in range(5): # for each of 5 groups
|
||||||
|
assert (yield).name == "slip39_shares"
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # Set & Confirm number of shares
|
self.debug.swipe_up()
|
||||||
self.debug.swipe_up(wait=True)
|
assert (yield).name == "slip39_threshold"
|
||||||
if self.click_info:
|
if self.click_info:
|
||||||
click_info_button_mercury(self.debug)
|
click_info_button_mercury(self.debug)
|
||||||
yield # Set & confirm share threshold value
|
self.debug.swipe_up()
|
||||||
self.debug.swipe_up(wait=_i != 4)
|
assert (yield).name == "backup_warning"
|
||||||
yield # Confirm show seeds
|
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
# Mnemonic phrases - show & confirm shares for all groups
|
# Mnemonic phrases - show & confirm shares for all groups
|
||||||
@ -2276,7 +2274,7 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
|||||||
br = yield
|
br = yield
|
||||||
while True:
|
while True:
|
||||||
# wait for homescreen to go away
|
# wait for homescreen to go away
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.client.ui._default_input_flow(br)
|
self.client.ui._default_input_flow(br)
|
||||||
br = yield
|
br = yield
|
||||||
|
|
||||||
@ -2288,11 +2286,11 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
|||||||
while True:
|
while True:
|
||||||
# wait for homescreen to go away
|
# wait for homescreen to go away
|
||||||
# probably won't be needed after https://github.com/trezor/trezor-firmware/pull/3686
|
# probably won't be needed after https://github.com/trezor/trezor-firmware/pull/3686
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
# Paginating (going as further as possible) and pressing Yes
|
# Paginating (going as further as possible) and pressing Yes
|
||||||
if br.pages is not None:
|
if br.pages is not None:
|
||||||
for _ in range(br.pages - 1):
|
for _ in range(br.pages - 1):
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
layout = self.debug.read_layout()
|
layout = self.debug.read_layout()
|
||||||
text = layout.text_content().lower()
|
text = layout.text_content().lower()
|
||||||
# hi priority warning
|
# hi priority warning
|
||||||
@ -2307,7 +2305,7 @@ class InputFlowConfirmAllWarnings(InputFlowBase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[1])
|
self.debug.click(buttons.VERTICAL_MENU[1])
|
||||||
elif "PromptScreen" in layout.all_components():
|
elif "PromptScreen" in layout.all_components():
|
||||||
@ -2335,5 +2333,5 @@ class InputFlowFidoConfirm(InputFlowBase):
|
|||||||
def input_flow_t3t1(self) -> BRGeneratorType:
|
def input_flow_t3t1(self) -> BRGeneratorType:
|
||||||
while True:
|
while True:
|
||||||
yield
|
yield
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
self.debug.click(buttons.TAP_TO_CONFIRM, wait=True)
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
|
@ -4,6 +4,7 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client
|
|||||||
|
|
||||||
from . import buttons
|
from . import buttons
|
||||||
from . import translations as TR
|
from . import translations as TR
|
||||||
|
from .click_tests.common import go_next
|
||||||
from .common import BRGeneratorType, get_text_possible_pagination
|
from .common import BRGeneratorType, get_text_possible_pagination
|
||||||
|
|
||||||
B = messages.ButtonRequestType
|
B = messages.ButtonRequestType
|
||||||
@ -18,16 +19,16 @@ class PinFlow:
|
|||||||
self, pin: str, second_different_pin: str | None = None
|
self, pin: str, second_different_pin: str | None = None
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
yield # Enter PIN
|
yield # Enter PIN
|
||||||
assert "PinKeyboard" in self.debug.wait_layout().all_components()
|
assert "PinKeyboard" in self.debug.read_layout().all_components()
|
||||||
self.debug.input(pin)
|
self.debug.input(pin)
|
||||||
if self.client.layout_type is LayoutType.TR:
|
if self.client.layout_type is LayoutType.TR:
|
||||||
yield # Reenter PIN
|
yield # Reenter PIN
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "pin__reenter_to_confirm"
|
self.debug.read_layout().text_content(), "pin__reenter_to_confirm"
|
||||||
)
|
)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield # Enter PIN again
|
yield # Enter PIN again
|
||||||
assert "PinKeyboard" in self.debug.wait_layout().all_components()
|
assert "PinKeyboard" in self.debug.read_layout().all_components()
|
||||||
if second_different_pin is not None:
|
if second_different_pin is not None:
|
||||||
self.debug.input(second_different_pin)
|
self.debug.input(second_different_pin)
|
||||||
else:
|
else:
|
||||||
@ -41,7 +42,7 @@ class BackupFlow:
|
|||||||
|
|
||||||
def confirm_new_wallet(self) -> BRGeneratorType:
|
def confirm_new_wallet(self) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
TR.assert_in(self.debug.wait_layout().text_content(), "reset__by_continuing")
|
TR.assert_in(self.debug.read_layout().text_content(), "reset__by_continuing")
|
||||||
if self.client.layout_type is LayoutType.TR:
|
if self.client.layout_type is LayoutType.TR:
|
||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
@ -53,7 +54,7 @@ class RecoveryFlow:
|
|||||||
self.debug = self.client.debug
|
self.debug = self.client.debug
|
||||||
|
|
||||||
def _text_content(self) -> str:
|
def _text_content(self) -> str:
|
||||||
layout = self.debug.wait_layout()
|
layout = self.debug.read_layout()
|
||||||
return layout.title() + " " + layout.text_content()
|
return layout.title() + " " + layout.text_content()
|
||||||
|
|
||||||
def confirm_recovery(self) -> BRGeneratorType:
|
def confirm_recovery(self) -> BRGeneratorType:
|
||||||
@ -98,13 +99,13 @@ class RecoveryFlow:
|
|||||||
else:
|
else:
|
||||||
TR.assert_in(self._text_content(), "recovery__enter_backup")
|
TR.assert_in(self._text_content(), "recovery__enter_backup")
|
||||||
is_dry_run = any(
|
is_dry_run = any(
|
||||||
title in self.debug.wait_layout().title().lower()
|
title in self.debug.read_layout().title().lower()
|
||||||
for title in TR.translate("recovery__title_dry_run", lower=True)
|
for title in TR.translate("recovery__title_dry_run", lower=True)
|
||||||
)
|
)
|
||||||
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
||||||
# Normal recovery has extra info (not dry run)
|
# Normal recovery has extra info (not dry run)
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def enter_any_share(self) -> BRGeneratorType:
|
def enter_any_share(self) -> BRGeneratorType:
|
||||||
@ -114,13 +115,13 @@ class RecoveryFlow:
|
|||||||
["recovery__enter_any_share", "recovery__enter_each_word"],
|
["recovery__enter_any_share", "recovery__enter_each_word"],
|
||||||
)
|
)
|
||||||
is_dry_run = any(
|
is_dry_run = any(
|
||||||
title in self.debug.wait_layout().title().lower()
|
title in self.debug.read_layout().title().lower()
|
||||||
for title in TR.translate("recovery__title_dry_run", lower=True)
|
for title in TR.translate("recovery__title_dry_run", lower=True)
|
||||||
)
|
)
|
||||||
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
if self.client.layout_type is LayoutType.TR and not is_dry_run:
|
||||||
# Normal recovery has extra info (not dry run)
|
# Normal recovery has extra info (not dry run)
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
def abort_recovery(self, confirm: bool) -> BRGeneratorType:
|
||||||
@ -137,12 +138,12 @@ class RecoveryFlow:
|
|||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
elif self.client.layout_type is LayoutType.Mercury:
|
elif self.client.layout_type is LayoutType.Mercury:
|
||||||
TR.assert_in(self._text_content(), "recovery__enter_each_word")
|
TR.assert_in(self._text_content(), "recovery__enter_each_word")
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
if confirm:
|
if confirm:
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
else:
|
else:
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
else:
|
else:
|
||||||
TR.assert_in(self._text_content(), "recovery__enter_any_share")
|
TR.assert_in(self._text_content(), "recovery__enter_any_share")
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -168,10 +169,10 @@ class RecoveryFlow:
|
|||||||
TR.assert_template(
|
TR.assert_template(
|
||||||
self._text_content(), "recovery__x_of_y_entered_template"
|
self._text_content(), "recovery__x_of_y_entered_template"
|
||||||
)
|
)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
assert (yield).name == "abort_recovery"
|
assert (yield).name == "abort_recovery"
|
||||||
self.debug.synchronize_at("PromptScreen")
|
self.debug.synchronize_at("PromptScreen")
|
||||||
self.debug.click(buttons.TAP_TO_CONFIRM)
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
@ -188,7 +189,7 @@ class RecoveryFlow:
|
|||||||
br = yield
|
br = yield
|
||||||
assert br.code == B.MnemonicWordCount
|
assert br.code == B.MnemonicWordCount
|
||||||
if self.client.layout_type is LayoutType.TR:
|
if self.client.layout_type is LayoutType.TR:
|
||||||
TR.assert_in(self.debug.wait_layout().title(), "word_count__title")
|
TR.assert_in(self.debug.read_layout().title(), "word_count__title")
|
||||||
else:
|
else:
|
||||||
TR.assert_in(self._text_content(), "recovery__num_of_words")
|
TR.assert_in(self._text_content(), "recovery__num_of_words")
|
||||||
self.debug.input(str(num_words))
|
self.debug.input(str(num_words))
|
||||||
@ -284,7 +285,7 @@ class RecoveryFlow:
|
|||||||
def input_mnemonic(self, mnemonic: list[str]) -> BRGeneratorType:
|
def input_mnemonic(self, mnemonic: list[str]) -> BRGeneratorType:
|
||||||
br = yield
|
br = yield
|
||||||
assert br.code == B.MnemonicInput
|
assert br.code == B.MnemonicInput
|
||||||
assert "MnemonicKeyboard" in self.debug.wait_layout().all_components()
|
assert "MnemonicKeyboard" in self.debug.read_layout().all_components()
|
||||||
for _, word in enumerate(mnemonic):
|
for _, word in enumerate(mnemonic):
|
||||||
self.debug.input(word)
|
self.debug.input(word)
|
||||||
|
|
||||||
@ -312,8 +313,8 @@ class RecoveryFlow:
|
|||||||
self,
|
self,
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
# Moving through the INFO button
|
# Moving through the INFO button
|
||||||
self.debug.press_info()
|
|
||||||
yield
|
yield
|
||||||
|
self.debug.press_info()
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
@ -323,15 +324,15 @@ class RecoveryFlow:
|
|||||||
assert br.name == "recovery"
|
assert br.name == "recovery"
|
||||||
assert br.code == B.RecoveryHomepage
|
assert br.code == B.RecoveryHomepage
|
||||||
# Moving through the menu into the show_shares screen
|
# Moving through the menu into the show_shares screen
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[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, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
|
|
||||||
class EthereumFlow:
|
class EthereumFlow:
|
||||||
@ -343,7 +344,7 @@ class EthereumFlow:
|
|||||||
|
|
||||||
def confirm_data(self, info: bool = False, cancel: bool = False) -> BRGeneratorType:
|
def confirm_data(self, info: bool = False, cancel: bool = False) -> BRGeneratorType:
|
||||||
yield
|
yield
|
||||||
TR.assert_equals(self.debug.wait_layout().title(), "ethereum__title_input_data")
|
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_info()
|
self.debug.press_info()
|
||||||
elif cancel:
|
elif cancel:
|
||||||
@ -353,21 +354,17 @@ class EthereumFlow:
|
|||||||
|
|
||||||
def paginate_data(self) -> BRGeneratorType:
|
def paginate_data(self) -> BRGeneratorType:
|
||||||
br = yield
|
br = yield
|
||||||
TR.assert_equals(self.debug.wait_layout().title(), "ethereum__title_input_data")
|
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
if self.client.layout_type is LayoutType.TR:
|
|
||||||
for i in range(br.pages):
|
for i in range(br.pages):
|
||||||
|
self.debug.read_layout()
|
||||||
if i < br.pages - 1:
|
if i < br.pages - 1:
|
||||||
self.debug.press_right()
|
go_next(self.debug)
|
||||||
else:
|
self.debug.press_yes()
|
||||||
for i in range(br.pages):
|
|
||||||
self.debug.wait_layout()
|
|
||||||
if i < br.pages - 1:
|
|
||||||
self.debug.click(buttons.OK)
|
|
||||||
|
|
||||||
def paginate_data_go_back(self) -> BRGeneratorType:
|
def paginate_data_go_back(self) -> BRGeneratorType:
|
||||||
br = yield
|
br = yield
|
||||||
TR.assert_equals(self.debug.wait_layout().title(), "ethereum__title_input_data")
|
TR.assert_equals(self.debug.read_layout().title(), "ethereum__title_input_data")
|
||||||
assert br.pages is not None
|
assert br.pages is not None
|
||||||
assert br.pages > 2
|
assert br.pages > 2
|
||||||
if self.client.layout_type is LayoutType.TR:
|
if self.client.layout_type is LayoutType.TR:
|
||||||
@ -377,8 +374,8 @@ class EthereumFlow:
|
|||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
elif self.client.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
elif self.client.layout_type in (LayoutType.TT, LayoutType.Mercury):
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
self.debug.swipe_up(wait=True)
|
self.debug.swipe_up()
|
||||||
self.debug.click(self.GO_BACK)
|
self.debug.click(self.GO_BACK)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unknown layout: {self.client.layout_type}")
|
raise ValueError(f"Unknown layout: {self.client.layout_type}")
|
||||||
@ -393,17 +390,17 @@ class EthereumFlow:
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
if self.client.layout_type is LayoutType.TT:
|
if self.client.layout_type is LayoutType.TT:
|
||||||
TR.assert_equals(self.debug.wait_layout().title(), "words__address")
|
TR.assert_equals(self.debug.read_layout().title(), "words__address")
|
||||||
if cancel:
|
if cancel:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
else:
|
else:
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
TR.assert_equals(
|
TR.assert_equals(
|
||||||
self.debug.wait_layout().title(), "words__title_summary"
|
self.debug.read_layout().title(), "words__title_summary"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "send__maximum_fee"
|
self.debug.read_layout().text_content(), "send__maximum_fee"
|
||||||
)
|
)
|
||||||
if go_back_from_summary:
|
if go_back_from_summary:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -411,20 +408,20 @@ class EthereumFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_info(wait=True)
|
self.debug.press_info()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
|
|
||||||
yield
|
yield
|
||||||
elif self.client.layout_type is LayoutType.TR:
|
elif self.client.layout_type is LayoutType.TR:
|
||||||
TR.assert_in_multiple(
|
TR.assert_in_multiple(
|
||||||
self.debug.wait_layout().title(),
|
self.debug.read_layout().title(),
|
||||||
["ethereum__interaction_contract", "words__recipient"],
|
["ethereum__interaction_contract", "words__recipient"],
|
||||||
)
|
)
|
||||||
if cancel:
|
if cancel:
|
||||||
@ -433,7 +430,7 @@ class EthereumFlow:
|
|||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
yield
|
yield
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "send__maximum_fee"
|
self.debug.read_layout().text_content(), "send__maximum_fee"
|
||||||
)
|
)
|
||||||
if go_back_from_summary:
|
if go_back_from_summary:
|
||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
@ -441,25 +438,25 @@ class EthereumFlow:
|
|||||||
self.debug.press_right()
|
self.debug.press_right()
|
||||||
yield
|
yield
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
|
|
||||||
yield
|
yield
|
||||||
elif self.client.layout_type is LayoutType.Mercury:
|
elif self.client.layout_type is LayoutType.Mercury:
|
||||||
TR.assert_equals(
|
TR.assert_equals(
|
||||||
self.debug.wait_layout().title().split("\n")[0], "words__address"
|
self.debug.read_layout().title().split("\n")[0], "words__address"
|
||||||
)
|
)
|
||||||
TR.assert_equals(
|
TR.assert_equals(
|
||||||
self.debug.wait_layout().title().split("\n")[1], "words__recipient"
|
self.debug.read_layout().title().split("\n")[1], "words__recipient"
|
||||||
)
|
)
|
||||||
if cancel:
|
if cancel:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -467,10 +464,10 @@ class EthereumFlow:
|
|||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
yield
|
yield
|
||||||
TR.assert_equals(
|
TR.assert_equals(
|
||||||
self.debug.wait_layout().title(), "words__title_summary"
|
self.debug.read_layout().title(), "words__title_summary"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "send__maximum_fee"
|
self.debug.read_layout().text_content(), "send__maximum_fee"
|
||||||
)
|
)
|
||||||
if go_back_from_summary:
|
if go_back_from_summary:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
@ -478,19 +475,19 @@ class EthereumFlow:
|
|||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
self.debug.wait_layout()
|
self.debug.read_layout()
|
||||||
self.debug.click(buttons.TAP_TO_CONFIRM)
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
yield
|
yield
|
||||||
else:
|
else:
|
||||||
@ -504,7 +501,7 @@ class EthereumFlow:
|
|||||||
assert br.code == B.SignTx
|
assert br.code == B.SignTx
|
||||||
assert br.name == "confirm_ethereum_staking_tx"
|
assert br.name == "confirm_ethereum_staking_tx"
|
||||||
TR.assert_equals_multiple(
|
TR.assert_equals_multiple(
|
||||||
self.debug.wait_layout().title(),
|
self.debug.read_layout().title(),
|
||||||
[
|
[
|
||||||
"ethereum__staking_stake",
|
"ethereum__staking_stake",
|
||||||
"ethereum__staking_unstake",
|
"ethereum__staking_unstake",
|
||||||
@ -512,7 +509,7 @@ class EthereumFlow:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
TR.assert_equals_multiple(
|
TR.assert_equals_multiple(
|
||||||
self.debug.wait_layout().text_content(),
|
self.debug.read_layout().text_content(),
|
||||||
[
|
[
|
||||||
"ethereum__staking_stake_intro",
|
"ethereum__staking_stake_intro",
|
||||||
"ethereum__staking_unstake_intro",
|
"ethereum__staking_unstake_intro",
|
||||||
@ -522,28 +519,28 @@ class EthereumFlow:
|
|||||||
if self.client.layout_type is LayoutType.TT:
|
if self.client.layout_type is LayoutType.TT:
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON, )
|
||||||
TR.assert_equals_multiple(
|
TR.assert_equals_multiple(
|
||||||
self.debug.wait_layout().title(),
|
self.debug.read_layout().title(),
|
||||||
[
|
[
|
||||||
"ethereum__staking_stake_address",
|
"ethereum__staking_stake_address",
|
||||||
"ethereum__staking_claim_address",
|
"ethereum__staking_claim_address",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
# confirm summary
|
# confirm summary
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_info(wait=True)
|
self.debug.press_info()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no()
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
@ -552,18 +549,18 @@ class EthereumFlow:
|
|||||||
elif self.client.layout_type is LayoutType.Mercury:
|
elif self.client.layout_type is LayoutType.Mercury:
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
TR.assert_equals_multiple(
|
TR.assert_equals_multiple(
|
||||||
self.debug.wait_layout().title(),
|
self.debug.read_layout().title(),
|
||||||
[
|
[
|
||||||
"ethereum__staking_stake_address",
|
"ethereum__staking_stake_address",
|
||||||
"ethereum__staking_claim_address",
|
"ethereum__staking_claim_address",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
|
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
br = yield
|
br = yield
|
||||||
@ -572,17 +569,17 @@ class EthereumFlow:
|
|||||||
|
|
||||||
# confirm summary
|
# confirm summary
|
||||||
if info:
|
if info:
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.synchronize_at("VerticalMenu")
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
self.debug.click(buttons.VERTICAL_MENU[0])
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
self.debug.click(buttons.CORNER_BUTTON)
|
||||||
self.debug.swipe_up()
|
self.debug.swipe_up()
|
||||||
# br = yield # FIXME: no BR on sign transaction
|
# br = yield # FIXME: no BR on sign transaction
|
||||||
|
|
||||||
@ -591,30 +588,30 @@ class EthereumFlow:
|
|||||||
elif self.client.layout_type is LayoutType.TR:
|
elif self.client.layout_type is LayoutType.TR:
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
TR.assert_equals_multiple(
|
TR.assert_equals_multiple(
|
||||||
self.debug.wait_layout().title().rstrip(":"),
|
self.debug.read_layout().title(),
|
||||||
[
|
[
|
||||||
"ethereum__staking_stake_address",
|
"ethereum__staking_stake_address",
|
||||||
"ethereum__staking_claim_address",
|
"ethereum__staking_claim_address",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
# confirm summary
|
# confirm summary
|
||||||
if info:
|
if info:
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
self.debug.read_layout().text_content(), "ethereum__gas_limit"
|
||||||
)
|
)
|
||||||
self.debug.press_right(wait=True)
|
self.debug.press_right()
|
||||||
TR.assert_in(
|
TR.assert_in(
|
||||||
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
self.debug.read_layout().text_content(), "ethereum__gas_price"
|
||||||
)
|
)
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_left(wait=True)
|
self.debug.press_left()
|
||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -48,9 +48,9 @@ def test_abort(core_emulator: Emulator):
|
|||||||
|
|
||||||
device_handler.run(device.recover, pin_protection=False)
|
device_handler.run(device.recover, pin_protection=False)
|
||||||
|
|
||||||
assert debug.wait_layout().title().lower() == "recover wallet"
|
assert debug.read_layout().title().lower() == "recover wallet"
|
||||||
|
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
assert "number of words" in layout.text_content()
|
assert "number of words" in layout.text_content()
|
||||||
|
|
||||||
debug = _restart(device_handler, core_emulator)
|
debug = _restart(device_handler, core_emulator)
|
||||||
@ -61,14 +61,14 @@ def test_abort(core_emulator: Emulator):
|
|||||||
# no waiting for layout because layout doesn't change
|
# no waiting for layout because layout doesn't change
|
||||||
assert "number of words" in debug.read_layout().text_content()
|
assert "number of words" in debug.read_layout().text_content()
|
||||||
# clicking at 24 in word choice (the same coords as CANCEL)
|
# clicking at 24 in word choice (the same coords as CANCEL)
|
||||||
layout = debug.click(buttons.CANCEL, wait=True)
|
layout = debug.click(buttons.CANCEL)
|
||||||
|
|
||||||
# Cancelling the backup
|
# Cancelling the backup
|
||||||
assert "Enter your backup" in debug.read_layout().text_content()
|
assert "Enter your backup" in debug.read_layout().text_content()
|
||||||
layout = debug.click(buttons.CANCEL, wait=True)
|
layout = debug.click(buttons.CANCEL)
|
||||||
|
|
||||||
assert layout.title().lower() in ("abort recovery", "cancel recovery")
|
assert layout.title().lower() in ("abort recovery", "cancel recovery")
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
|
|
||||||
assert layout.main_component() == "Homescreen"
|
assert layout.main_component() == "Homescreen"
|
||||||
features = device_handler.features()
|
features = device_handler.features()
|
||||||
@ -95,7 +95,7 @@ def test_recovery_single_reset(core_emulator: Emulator):
|
|||||||
assert features.recovery_status == RecoveryStatus.Recovery
|
assert features.recovery_status == RecoveryStatus.Recovery
|
||||||
|
|
||||||
# we need to enter the number of words again, that's a feature
|
# we need to enter the number of words again, that's a feature
|
||||||
recovery.select_number_of_words(debug, wait=False)
|
recovery.select_number_of_words(debug)
|
||||||
recovery.enter_shares(debug, MNEMONIC_SLIP39_BASIC_20_3of6)
|
recovery.enter_shares(debug, MNEMONIC_SLIP39_BASIC_20_3of6)
|
||||||
recovery.finalize(debug)
|
recovery.finalize(debug)
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ def test_recovery_on_old_wallet(core_emulator: Emulator):
|
|||||||
assert features.recovery_status == RecoveryStatus.Recovery
|
assert features.recovery_status == RecoveryStatus.Recovery
|
||||||
|
|
||||||
# enter number of words
|
# enter number of words
|
||||||
recovery.select_number_of_words(debug, wait=False)
|
recovery.select_number_of_words(debug)
|
||||||
|
|
||||||
first_share = MNEMONIC_SLIP39_BASIC_20_3of6[0]
|
first_share = MNEMONIC_SLIP39_BASIC_20_3of6[0]
|
||||||
words = first_share.split(" ")
|
words = first_share.split(" ")
|
||||||
@ -140,11 +140,11 @@ def test_recovery_on_old_wallet(core_emulator: Emulator):
|
|||||||
# start entering first share
|
# start entering first share
|
||||||
assert "Enter each word of your wallet backup" in debug.read_layout().text_content()
|
assert "Enter each word of your wallet backup" in debug.read_layout().text_content()
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
assert debug.wait_layout().main_component() == "MnemonicKeyboard"
|
assert debug.read_layout().main_component() == "MnemonicKeyboard"
|
||||||
|
|
||||||
# enter first word
|
# enter first word
|
||||||
debug.input(words[0])
|
debug.input(words[0])
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
|
|
||||||
# while keyboard is open, hit the device with Initialize/GetFeatures
|
# while keyboard is open, hit the device with Initialize/GetFeatures
|
||||||
device_handler.client.init_device()
|
device_handler.client.init_device()
|
||||||
@ -154,7 +154,7 @@ def test_recovery_on_old_wallet(core_emulator: Emulator):
|
|||||||
for word in words[1:]:
|
for word in words[1:]:
|
||||||
assert layout.main_component() == "MnemonicKeyboard"
|
assert layout.main_component() == "MnemonicKeyboard"
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
layout = debug.wait_layout()
|
layout = debug.read_layout()
|
||||||
|
|
||||||
# check that we entered the first share successfully
|
# check that we entered the first share successfully
|
||||||
assert "2 more shares needed" in layout.text_content()
|
assert "2 more shares needed" in layout.text_content()
|
||||||
@ -208,7 +208,7 @@ def test_recovery_multiple_resets(core_emulator: Emulator):
|
|||||||
assert features.recovery_status == RecoveryStatus.Recovery
|
assert features.recovery_status == RecoveryStatus.Recovery
|
||||||
|
|
||||||
# enter the number of words again, that's a feature!
|
# enter the number of words again, that's a feature!
|
||||||
recovery.select_number_of_words(debug, wait=False)
|
recovery.select_number_of_words(debug)
|
||||||
|
|
||||||
# enter shares and restart after each one
|
# enter shares and restart after each one
|
||||||
enter_shares_with_restarts(debug)
|
enter_shares_with_restarts(debug)
|
||||||
|
@ -13,19 +13,15 @@ def _enter_word(
|
|||||||
for coords in buttons.type_word(typed_word, is_slip39=is_slip39):
|
for coords in buttons.type_word(typed_word, is_slip39=is_slip39):
|
||||||
debug.click(coords)
|
debug.click(coords)
|
||||||
|
|
||||||
return debug.click(buttons.CONFIRM_WORD, wait=True)
|
return debug.click(buttons.CONFIRM_WORD)
|
||||||
|
|
||||||
|
|
||||||
def confirm_recovery(debug: "DebugLink") -> None:
|
def confirm_recovery(debug: "DebugLink") -> None:
|
||||||
debug.click(buttons.OK, wait=True)
|
debug.click(buttons.OK)
|
||||||
|
|
||||||
|
|
||||||
def select_number_of_words(
|
def select_number_of_words(debug: "DebugLink", num_of_words: int = 20) -> None:
|
||||||
debug: "DebugLink", num_of_words: int = 20, wait: bool = True
|
debug.click(buttons.OK)
|
||||||
) -> None:
|
|
||||||
if wait:
|
|
||||||
debug.wait_layout()
|
|
||||||
debug.click(buttons.OK, wait=True)
|
|
||||||
|
|
||||||
# click the number
|
# click the number
|
||||||
word_option_offset = 6
|
word_option_offset = 6
|
||||||
@ -34,13 +30,13 @@ def select_number_of_words(
|
|||||||
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)
|
coords = buttons.grid34(index % 3, index // 3)
|
||||||
debug.click(coords, wait=True)
|
debug.click(coords)
|
||||||
|
|
||||||
|
|
||||||
def enter_share(
|
def enter_share(
|
||||||
debug: "DebugLink", share: str, is_first: bool = True
|
debug: "DebugLink", share: str, is_first: bool = True
|
||||||
) -> "LayoutContent":
|
) -> "LayoutContent":
|
||||||
layout = debug.click(buttons.OK, wait=True)
|
layout = debug.click(buttons.OK)
|
||||||
for word in share.split(" "):
|
for word in share.split(" "):
|
||||||
layout = _enter_word(debug, word, is_slip39=True)
|
layout = _enter_word(debug, word, is_slip39=True)
|
||||||
return layout
|
return layout
|
||||||
|
Loading…
Reference in New Issue
Block a user