tests: add click-based recovery test

pull/632/head
matejcik 5 years ago
parent 3664a5f06f
commit 370b2c4c49

@ -83,16 +83,24 @@ class DebugLink:
obj = self._call(proto.DebugLinkGetState())
return obj.passphrase_protection
def input(self, word=None, button=None, swipe=None):
def input(self, word=None, button=None, swipe=None, x=None, y=None, wait=False):
if not self.allow_interactions:
return
args = sum(a is not None for a in (word, button, swipe))
args = sum(a is not None for a in (word, button, swipe, x))
if args != 1:
raise ValueError("Invalid input - must use one of word, button, swipe")
decision = proto.DebugLinkDecision(yes_no=button, swipe=swipe, input=word)
self._call(decision, nowait=True)
decision = proto.DebugLinkDecision(
yes_no=button, swipe=swipe, input=word, x=x, y=y, wait=wait
)
ret = self._call(decision, nowait=not wait)
if ret is not None:
return ret.lines
def click(self, click, wait=False):
x, y = click
return self.input(x=x, y=y, wait=wait)
def press_yes(self):
self.input(button=True)

@ -0,0 +1,44 @@
DISPLAY_WIDTH = 240
DISPLAY_HEIGHT = 240
def grid(dim, grid_cells, cell):
step = dim // grid_cells
ofs = step // 2
return cell * step + ofs
LEFT = grid(DISPLAY_WIDTH, 3, 0)
MID = grid(DISPLAY_WIDTH, 3, 1)
RIGHT = grid(DISPLAY_WIDTH, 3, 2)
TOP = grid(DISPLAY_HEIGHT, 4, 0)
BOTTOM = grid(DISPLAY_HEIGHT, 4, 3)
OK = (RIGHT, BOTTOM)
CANCEL = (LEFT, BOTTOM)
INFO = (MID, BOTTOM)
CONFIRM_WORD = (MID, TOP)
MINUS = (LEFT, grid(DISPLAY_HEIGHT, 5, 2))
PLUS = (RIGHT, grid(DISPLAY_HEIGHT, 5, 2))
BUTTON_LETTERS = ("ab", "cd", "ef", "ghij", "klm", "nopq", "rs", "tuv", "wxyz")
def grid35(x, y):
return grid(DISPLAY_WIDTH, 3, x), grid(DISPLAY_HEIGHT, 5, y)
def grid34(x, y):
return grid(DISPLAY_WIDTH, 3, x), grid(DISPLAY_HEIGHT, 5, y)
def type_word(word):
for l in word:
idx = next(i for i, letters in enumerate(BUTTON_LETTERS) if l in letters)
grid_x = idx % 3
grid_y = idx // 3 + 1 # first line is empty
yield grid34(grid_x, grid_y)

@ -0,0 +1,67 @@
import pytest
from trezorlib import device, messages
from .. import buttons
from ..common import MNEMONIC_SLIP39_BASIC_20_3of6
def enter_word(debug, word):
word = word[:4]
for coords in buttons.type_word(word):
debug.click(coords)
return " ".join(debug.click(buttons.CONFIRM_WORD, wait=True))
def click_ok(debug):
return " ".join(debug.click(buttons.OK, wait=True))
@pytest.mark.skip_t1
@pytest.mark.setup_client(uninitialized=True)
def test_recovery(client):
with client:
client.set_expected_responses(
[
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
messages.Success(),
messages.Features(),
]
)
device.recover(client, pin_protection=False)
assert client.features.initialized is False
assert client.features.recovery_mode is True
# select number of words
state = client.debug.state()
text = " ".join(state.layout_lines)
assert "Select number of words" in text
text = click_ok(client.debug)
assert text == "WordSelector"
# click "20" at 2, 2
coords = buttons.grid34(2, 2)
lines = client.debug.click(coords, wait=True)
text = " ".join(lines)
expected_text = "Enter any share (20 words)"
remaining = len(MNEMONIC_SLIP39_BASIC_20_3of6)
for share in MNEMONIC_SLIP39_BASIC_20_3of6:
assert expected_text in text
text = click_ok(client.debug)
assert text == "Slip39Keyboard"
for word in share.split(" "):
text = enter_word(client.debug, word)
remaining -= 1
expected_text = "RecoveryHomescreen {} more".format(remaining)
assert "You have successfully recovered your wallet" in text
text = click_ok(client.debug)
assert text == "Homescreen"
client.init_device()
assert client.features.initialized is True
assert client.features.recovery_mode is False
Loading…
Cancel
Save