1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-08-04 04:48:48 +00:00

WIP - some feedback from product

This commit is contained in:
grdddj 2023-01-08 17:48:53 +01:00
parent cf538e5789
commit aa4c3551d4
29 changed files with 213 additions and 125 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 134 B

View File

@ -10,11 +10,23 @@ pub fn shuffle<T>(slice: &mut [T]) {
}
}
/// Returns a random number in the range [min, max].
pub fn uniform_between(min: u32, max: u32) -> u32 {
assert!(max > min);
uniform(max - min + 1) + min
}
/// Returns a random number in the range [min, max] except one `except` number.
pub fn uniform_between_except(min: u32, max: u32, except: u32) -> u32 {
// Generate uniform_between as long as it is not except
loop {
let rand = uniform_between(min, max);
if rand != except {
return rand;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -27,4 +39,11 @@ mod tests {
assert!((256..=512).contains(&uniform_between(256, 512)));
}
}
#[test]
fn uniform_between_except_test() {
for _ in 0..10 {
assert!(uniform_between_except(10, 12, 11) != 11);
}
}
}

View File

@ -545,6 +545,15 @@ impl ButtonLayout {
)
}
/// Left text and right arrow.
pub fn text_none_arrow(text: StrBuffer) -> Self {
Self::new(
Some(ButtonDetails::text(text)),
None,
Some(ButtonDetails::right_arrow_icon()),
)
}
/// Only right text.
pub fn none_none_text(text: StrBuffer) -> Self {
Self::new(None, None, Some(ButtonDetails::text(text)))

View File

@ -36,13 +36,10 @@ where
}
/// Aligning the title to the center, instead of the left.
/// Also disabling scrollbar in the positive case, as they are not
/// compatible.
pub fn with_title_center(mut self, title_centered: bool) -> Self {
self.title_centered = title_centered;
if title_centered {
/// Also disabling scrollbar, as they are not compatible.
pub fn with_title_centered(mut self) -> Self {
self.title_centered = true;
self.account_for_scrollbar = false;
}
self
}

View File

@ -44,6 +44,17 @@ impl ChoiceItem {
self
}
/// Getting the offset of the icon to center it vertically.
/// Depending on its size and used font.
fn icon_vertical_offset(&self) -> Offset {
if let Some(icon) = self.icon {
let height_diff = self.font.text_height() - icon.height();
Offset::y(-height_diff / 2)
} else {
Offset::zero()
}
}
/// Getting the text width in pixels.
pub fn text_width(&self) -> i16 {
self.font.text_width(&self.text)
@ -88,7 +99,11 @@ impl ChoiceItem {
/// Showing only the icon, if available, otherwise the text.
pub fn render_left(&self, area: Rect) {
if let Some(icon) = self.icon {
icon.draw_bottom_right(area.bottom_right(), theme::FG, theme::BG);
icon.draw_bottom_right(
area.bottom_right() + self.icon_vertical_offset(),
theme::FG,
theme::BG,
);
} else {
display_right(area.bottom_right(), &self.text, self.font);
}
@ -98,7 +113,11 @@ impl ChoiceItem {
/// Showing only the icon, if available, otherwise the text.
pub fn render_right(&self, area: Rect) {
if let Some(icon) = self.icon {
icon.draw_bottom_left(area.bottom_left(), theme::FG, theme::BG);
icon.draw_bottom_left(
area.bottom_left() + self.icon_vertical_offset(),
theme::FG,
theme::BG,
);
} else {
display(area.bottom_left(), &self.text, self.font);
}
@ -135,7 +154,7 @@ impl Choice for ChoiceItem {
if let Some(icon) = self.icon {
let fg_color = if inverse { theme::BG } else { theme::FG };
let bg_color = if inverse { theme::FG } else { theme::BG };
icon.draw_bottom_left(baseline, fg_color, bg_color);
icon.draw_bottom_left(baseline + self.icon_vertical_offset(), fg_color, bg_color);
baseline = baseline + Offset::x(icon.width() + 2);
}
if inverse {

View File

@ -193,10 +193,12 @@ impl Component for PinEntry {
_ => {
if !self.is_full() {
self.append_new_digit(ctx, page_counter);
// Choosing any random digit to be shown next
let new_page_counter = random::uniform_between(
// Choosing random digit to be shown next, but different
// from the current choice.
let new_page_counter = random::uniform_between_except(
NUMBER_START_INDEX as u32,
(CHOICE_LENGTH - 1) as u32,
page_counter as u32,
);
self.choice_page
.set_page_counter(ctx, new_page_counter as u8);

View File

@ -75,6 +75,13 @@ impl<const N: usize> SimpleChoice<N> {
self
}
/// Show choices even when they do not fit entirely.
pub fn with_show_incomplete(mut self) -> Self {
self.choice_page = self.choice_page.with_incomplete(true);
self
}
/// Returning chosen page index instead of the string result.
pub fn with_return_index(mut self) -> Self {
self.return_index = true;
self

View File

@ -149,8 +149,6 @@ impl Loader {
// NOTE: need to calculate this in `i32`, it would overflow using `i16`
let invert_from = ((self.area.width() as i32 + 1) * done) / (display::LOADER_MAX as i32);
// TODO: the text should be moved one pixel to the top so it is centered in the
// loader
display::bar_with_text_and_fill(
self.area,
Some(&self.text_overlay),
@ -167,7 +165,8 @@ impl Component for Loader {
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
let baseline = bounds.bottom_center() + Offset::new(1, -1);
// Centering the text in the loader rectangle.
let baseline = bounds.bottom_center() + Offset::new(1, -2);
self.text_overlay.place(baseline);
self.area
}

View File

@ -414,7 +414,7 @@ extern "C" fn new_show_receive_address(n_args: usize, args: *const Obj, kwargs:
.text_bold("ADDRESS MISMATCH?".into())
.newline()
.newline_half()
.text_mono("Please contact Trezor support on trezor.io/support".into())
.text_mono("Please contact Trezor support at trezor.io/support".into())
}
_ => unreachable!(),
}
@ -565,7 +565,7 @@ extern "C" fn tutorial(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj
tutorial_screen(
"HELLO".into(),
"Welcome to Trezor.\nPress right to continue.".into(),
ButtonLayout::cancel_none_arrow(),
ButtonLayout::text_none_arrow("SKIP".into()),
ButtonActions::last_none_next(),
)
},
@ -609,7 +609,7 @@ extern "C" fn tutorial(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj
Font::MONO,
)
.newline()
.text_mono("Tutorial finished.".into())
.text_mono("Tutorial complete.".into())
.newline()
.newline()
.alignment(Alignment::Center)
@ -655,10 +655,9 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut M
let max_count: u32 = kwargs.get(Qstr::MP_QSTR_max_count)?.try_into()?;
let count: u32 = kwargs.get(Qstr::MP_QSTR_count)?.try_into()?;
let obj = LayoutObj::new(Frame::new(
title,
NumberInput::new(min_count, max_count, count),
))?;
let obj = LayoutObj::new(
Frame::new(title, NumberInput::new(min_count, max_count, count)).with_title_centered(),
)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -736,10 +735,10 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
Frame::new(
title,
SimpleChoice::new(words, false)
.with_only_one_item()
.with_show_incomplete()
.with_return_index(),
)
.with_title_center(true),
.with_title_centered(),
)?;
Ok(obj.into())
};
@ -756,7 +755,9 @@ extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mu
.into_iter()
.collect();
let obj = LayoutObj::new(Frame::new(title, SimpleChoice::new(choices, false)))?;
let obj = LayoutObj::new(
Frame::new(title, SimpleChoice::new(choices, false)).with_title_centered(),
)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -767,7 +768,7 @@ extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Ma
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(prompt, WordlistEntry::new(WordlistType::Bip39)).with_title_center(true),
Frame::new(prompt, WordlistEntry::new(WordlistType::Bip39)).with_title_centered(),
)?;
Ok(obj.into())
};
@ -779,7 +780,7 @@ extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut M
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(prompt, WordlistEntry::new(WordlistType::Slip39)).with_title_center(true),
Frame::new(prompt, WordlistEntry::new(WordlistType::Slip39)).with_title_centered(),
)?;
Ok(obj.into())
};

View File

@ -48,7 +48,7 @@ pub const ICON_CANCEL: IconAndName = IconAndName::new(
"cancel",
); // 8*8
pub const ICON_DELETE: IconAndName =
IconAndName::new(include_res!("model_tr/res/delete.toif"), "delete"); // 12*8
IconAndName::new(include_res!("model_tr/res/delete.toif"), "delete"); // 10*7
pub const ICON_EYE: IconAndName =
IconAndName::new(include_res!("model_tr/res/eye_round.toif"), "eye"); // 12*7
pub const ICON_LOCK: IconAndName = IconAndName::new(include_res!("model_tr/res/lock.toif"), "lock"); // 10*10

View File

@ -9,6 +9,7 @@ from trezor.enums import (
)
from trezor.strings import format_amount
from trezor.ui import layouts
from trezor.ui.layouts import confirm_metadata, confirm_properties
from apps.common.paths import address_n_to_str
@ -21,9 +22,6 @@ from .helpers.utils import (
format_stake_pool_id,
)
confirm_metadata = layouts.confirm_metadata # global_import_cache
confirm_properties = layouts.confirm_properties # global_import_cache
if TYPE_CHECKING:
from typing import Literal

View File

@ -121,7 +121,7 @@ async def error_pin_invalid(ctx: Context) -> NoReturn:
await show_error_and_raise(
ctx,
"warning_wrong_pin",
"The PIN you entered is invalid.",
"PIN you have entered is not valid.",
"Wrong PIN", # header
exc=wire.PinInvalid,
)

View File

@ -28,7 +28,11 @@ async def change_pin(ctx: Context, msg: ChangePin) -> Success:
await _require_confirm_change_pin(ctx, msg)
# get old pin
curpin, salt = await request_pin_and_sd_salt(ctx, "Enter old PIN")
if msg.remove:
prompt = "Enter PIN"
else:
prompt = "Enter old PIN"
curpin, salt = await request_pin_and_sd_salt(ctx, prompt)
# if changing pin, pre-check the entered pin before getting new pin
if curpin and not msg.remove:

View File

@ -90,7 +90,7 @@ def _require_confirm_action(
title,
"enable wipe code?",
[
"Wipe code will\nbe used to delete this device.",
"Wipe code can be used to erase all data from this device.",
],
)

View File

@ -65,7 +65,9 @@ async def _continue_recovery_process(ctx: GenericContext) -> Success:
if is_first_step:
# If we are starting recovery, ask for word count first...
# _request_word_count
await layout.homescreen_dialog(ctx, "Select", "Select number of words")
await layout.homescreen_dialog(
ctx, "Select", "First select the number of words in your recovery seed"
)
# ask for the number of words
word_count = await layout.request_word_count(ctx, dry_run)
# ...and only then show the starting screen with word count.
@ -158,7 +160,7 @@ async def _finish_recovery(
storage_recovery.end_progress()
await show_success(
ctx, "success_recovery", "You have successfully recovered your wallet."
ctx, "success_recovery", "You have finished recovering your wallet."
)
return Success(message="Device recovered")
@ -196,7 +198,7 @@ async def _request_share_first_screen(ctx: GenericContext, word_count: int) -> N
)
else: # BIP-39
await layout.homescreen_dialog(
ctx, "Enter seed", "Enter recovery seed", f"({word_count} words)"
ctx, "Enter seed", "Now enter your recovery seed", f"({word_count} words)"
)

View File

@ -52,7 +52,7 @@ async def request_mnemonic(
ctx,
"request_word",
"WORD ENTERING",
description="You'll only have to select first 2-3 letters.",
description="You'll only have to select the first 2-3 letters.",
verb="CONTINUE",
verb_cancel=None,
br_code=ButtonRequestType.MnemonicInput,
@ -103,14 +103,7 @@ async def show_dry_run_result(
from trezor.ui.layouts import show_success
if result:
if is_slip39:
text = text_r(
"The entered recovery\nshares are valid and\nmatch what is currently\nin the device."
)
else:
text = text_r(
"The entered recovery\nseed is valid and\nmatches the one\nin the device."
)
text = "You have finished verifying your recovery seed"
await show_success(ctx, "success_dry_recovery", text, button="Continue")
else:
if is_slip39:

View File

@ -12,8 +12,6 @@ from trezor.ui.layouts.reset import ( # noqa: F401
slip39_show_checklist,
)
from .. import text_r
if TYPE_CHECKING:
from typing import Sequence
from trezor.wire import GenericContext
@ -170,8 +168,9 @@ async def show_backup_warning(ctx: GenericContext, slip39: bool = False) -> None
async def show_backup_success(ctx: GenericContext) -> None:
text = text_r("Use your backup\nwhen you need to\nrecover your wallet.")
await show_success(ctx, "success_backup", text, "Your backup is done.")
from trezor.ui.layouts.reset import show_success_backup
await show_success_backup(ctx)
# BIP39

View File

@ -24,11 +24,20 @@ async def cipher_key_value(ctx: Context, msg: CipherKeyValue) -> CipheredKeyValu
encrypt = msg.encrypt
decrypt = not msg.encrypt
if (encrypt and msg.ask_on_encrypt) or (decrypt and msg.ask_on_decrypt):
# Special case for Trezor Suite, which asks for setting up labels
if msg.key == "Enable labeling?":
title = "SUITE LABELING"
verb = "ENABLE"
else:
if encrypt:
title = "Encrypt value"
else:
title = "Decrypt value"
await confirm_action(ctx, "cipher_key_value", title, description=msg.key)
verb = "CONFIRM"
await confirm_action(
ctx, "cipher_key_value", title, description=msg.key, verb=verb
)
node = keychain.derive(msg.address_n)

View File

@ -510,6 +510,7 @@ async def confirm_action(
hold: bool = False,
hold_danger: bool = False,
reverse: bool = False,
uppercase_title: bool = True,
exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None:
@ -535,7 +536,7 @@ async def confirm_action(
ctx,
RustLayout(
trezorui2.confirm_action(
title=title.upper(),
title=title.upper() if uppercase_title else title,
action=action,
description=description,
verb=verb,
@ -566,15 +567,12 @@ async def confirm_reset_device(
if show_tutorial:
await tutorial(ctx)
to_show = "By continuing you agree to our terms and conditions.\nMore info at trezor.io/tos."
if not recovery:
to_show += "\nUse you backup to recover your wallet."
return await _placeholder_confirm(
ctx,
"recover_device" if recovery else "setup_device",
"WALLET RECOVERY" if recovery else "WALLET BACKUP",
description=to_show,
"WALLET RECOVERY" if recovery else "WALLET CREATION",
description="By continuing you agree to Trezor Company terms and conditions.\n\rMore info at trezor.io/tos",
verb="RECOVER WALLET" if recovery else "CREATE WALLET",
br_code=ButtonRequestType.ProtectCall
if recovery
else ButtonRequestType.ResetDevice,
@ -587,14 +585,14 @@ async def confirm_backup(ctx: GenericContext) -> bool:
ctx,
"backup_device",
"SUCCESS",
"New wallet created successfully!\nYou should back up your new wallet right now.",
description="New wallet has been created.\nIt should be backed up now!",
verb="BACK UP",
verb_cancel="SKIP",
br_code=ButtonRequestType.ResetDevice,
):
return True
confirmed = await get_bool(
return await get_bool(
ctx,
"backup_device",
"WARNING",
@ -604,7 +602,6 @@ async def confirm_backup(ctx: GenericContext) -> bool:
verb_cancel="SKIP",
br_code=ButtonRequestType.ResetDevice,
)
return confirmed
async def confirm_path_warning(
@ -771,10 +768,25 @@ def show_success(
subheader: str | None = None,
button: str = "Continue",
) -> Awaitable[None]:
title = "Success"
# In case only subheader is supplied, showing it
# in regular font, not bold.
if not content and subheader:
content = subheader
subheader = None
# Special case for Shamir backup - to show everything just on one page
# in regular font.
if "Continue with" in content:
content = f"{subheader}\n{content}"
subheader = None
title = ""
return _show_modal(
ctx,
br_type,
"Success",
title,
subheader,
content,
button_confirm=button,
@ -1192,7 +1204,7 @@ async def show_popup(
def request_passphrase_on_host() -> None:
draw_simple(
trezorui2.show_info(
title="",
title="HIDDEN WALLET",
description="Please type your passphrase on the connected host.",
)
)
@ -1226,7 +1238,9 @@ async def request_pin_on_device(
) -> str:
from trezor import wire
if attempts_remaining is None:
# Not showing the prompt in case user did not enter it badly yet
# (has full 16 attempts left)
if attempts_remaining is None or attempts_remaining == 16:
subprompt = ""
elif attempts_remaining == 1:
subprompt = "Last attempt"
@ -1260,7 +1274,7 @@ async def confirm_reenter_pin(
ctx,
br_type,
"CHECK PIN",
"Please re-enter to confirm.",
description="Please re-enter PIN to confirm.",
verb="BEGIN",
br_code=br_code,
)
@ -1294,7 +1308,7 @@ async def confirm_pin_action(
ctx,
br_type,
title,
f"{description} {action}",
description=f"{description} {action}",
br_code=br_code,
)
@ -1317,21 +1331,22 @@ async def confirm_set_new_pin(
br_code=br_code,
)
# TODO: this is a hack to put the next info on new screen in case of wipe code
# TODO: there should be a possibility to give a list of strings and each of them
# would be rendered on a new screen
if len(information) == 1:
information.append("\n")
if "wipe_code" in br_type:
title = "WIPE CODE INFO"
verb = "HODL TO BEGIN" # Easter egg from @Hannsek
else:
title = "PIN INFORMATION"
information.append(
"Position of individual numbers will change between entries for more security."
"Position of individual numbers will change between entries for enhanced security."
)
verb = "HOLD TO BEGIN"
return await confirm_action(
ctx,
br_type,
title="",
title=title,
description="\n".join(information),
verb="HOLD TO BEGIN",
verb=verb,
hold=True,
br_code=br_code,
)

View File

@ -79,7 +79,7 @@ async def continue_recovery(
if dry_run:
title = "SEED CHECK"
else:
title = "RECOVERY MODE"
title = "WALLET RECOVERY"
return await get_bool(
ctx,

View File

@ -47,18 +47,18 @@ async def show_share_words(
)
if share_index is None:
check_title = "CHECK SEED"
check_title = "CHECK BACKUP"
elif group_index is None:
check_title = f"CHECK SHARE #{share_index + 1}"
else:
check_title = f"CHECK G{group_index + 1} - SHARE {share_index + 1}"
check_title = f"GROUP {group_index + 1} - SHARE {share_index + 1}"
if await get_bool(
ctx,
"backup_words",
check_title,
None,
"Select correct words in correct positions.",
"Select correct word for each position.",
verb_cancel="SEE AGAIN",
verb="BEGIN",
br_code=ButtonRequestType.ResetDevice,
@ -84,7 +84,7 @@ async def select_word(
RustLayout(
trezorui2.select_word( # type: ignore [Argument missing for parameter "description"]
title=f"SELECT {format_ordinal(checked_index + 1).upper()} WORD",
words=(words[0].upper(), words[1].upper(), words[2].upper()),
words=(words[0].lower(), words[1].lower(), words[2].lower()),
)
)
)
@ -165,10 +165,11 @@ async def slip39_prompt_threshold(
await confirm_action(
ctx,
"slip39_prompt_threshold",
"Set threshold",
"Threshold",
description="= number of shares needed for recovery",
verb="BEGIN",
verb_cancel=None,
uppercase_title=False,
)
count = num_of_shares // 2 + 1
@ -199,9 +200,10 @@ async def slip39_prompt_number_of_shares(
ctx,
"slip39_shares",
"Number of shares",
description="= total number of unique word lists used for wallet backup.",
description="= total number of unique word lists used for wallet backup",
verb="BEGIN",
verb_cancel=None,
uppercase_title=False,
)
count = 5
@ -256,21 +258,26 @@ async def slip39_advanced_prompt_group_threshold(
async def show_warning_backup(ctx: GenericContext, slip39: bool) -> None:
if slip39:
description = (
"Never make a digital copy of your shares and never upload them online."
)
else:
description = (
"Never make a digital copy of your seed and never upload it online."
)
await confirm_action(
ctx,
"backup_warning",
"Caution",
description=description,
verb="I understand",
verb_cancel=None,
"SHAMIR BACKUP" if slip39 else "WALLET BACKUP",
description="You can use your backup to recover your wallet at any time.",
verb="HOLD TO BEGIN",
hold=True,
br_code=ButtonRequestType.ResetDevice,
)
async def show_success_backup(ctx: GenericContext) -> None:
from . import confirm_action
await confirm_action(
ctx,
"success_backup",
"BACKUP IS DONE",
description="Keep it safe!",
verb="CONTINUE",
verb_cancel=None,
br_code=ButtonRequestType.Success,
)

View File

@ -331,3 +331,10 @@ async def show_warning_backup(ctx: GenericContext, slip39: bool) -> None:
)
if result != CONFIRMED:
raise ActionCancelled
async def show_success_backup(ctx: GenericContext) -> None:
from . import show_success
text = "Use your backup when you need to recover your wallet."
await show_success(ctx, "success_backup", text, "Your backup is done.")

View File

@ -992,6 +992,7 @@ static secbool decrypt_dek(const uint8_t *kek, const uint8_t *keiv) {
static void ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) {
if (sectrue != is_not_wipe_code(pin, pin_len)) {
storage_wipe();
// TODO: need to account for smaller model R - smaller font and different copy
error_shutdown("You have entered the", "wipe code. All private",
"data has been erased.", NULL);
}

View File

@ -35,7 +35,7 @@ def select_number_of_words(
layout = debug.read_layout()
# select number of words
assert "Select number of words" in layout.get_content()
assert "select the number of words" in layout.get_content()
layout = debug.click(buttons.OK, wait=True)
if legacy_ui:
assert layout.text == "WordSelector"

View File

@ -131,7 +131,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
layout = debug.click(buttons.OK, wait=True)
assert layout.text == "< PinKeyboard >"
layout = debug.input(PIN4, wait=True)
assert "Select number of words " in layout.get_content()
assert "select the number of words " in layout.get_content()
# wait for autolock to trigger
time.sleep(10.1)
@ -146,7 +146,7 @@ def test_dryrun_locks_at_number_of_words(device_handler: "BackgroundDeviceHandle
layout = debug.input(PIN4, wait=True)
# we are back at homescreen
assert "Select number of words" in layout.get_content()
assert "select the number of words" in layout.get_content()
@pytest.mark.setup_client(pin=PIN4)

View File

@ -58,7 +58,7 @@ def do_recover_core(client: Client, mnemonic: List[str], **kwargs: Any):
client.debug.click(buttons.OK)
yield
assert "Select number of words" in layout().get_content()
assert "select the number of words" in layout().get_content()
client.debug.click(buttons.OK)
yield
@ -70,7 +70,7 @@ def do_recover_core(client: Client, mnemonic: List[str], **kwargs: Any):
client.debug.click(buttons.grid34(index % 3, index // 3))
yield
assert "Enter recovery seed" in layout().get_content()
assert "enter your recovery seed" in layout().get_content()
client.debug.click(buttons.OK)
yield
@ -97,7 +97,7 @@ def do_recover_r(client: Client, mnemonic: List[str], **kwargs: Any):
client.debug.press_right()
yield
assert "Select number of words" in layout().text
assert "select the number of words" in layout().text
client.debug.press_yes()
yield
@ -110,7 +110,7 @@ def do_recover_r(client: Client, mnemonic: List[str], **kwargs: Any):
client.debug.input(str(len(mnemonic)))
yield
assert "Enter recovery seed" in layout().text
assert "enter your recovery seed" in layout().text
client.debug.press_yes()
yield
@ -173,7 +173,7 @@ def test_invalid_seed_core(client: Client):
client.debug.click(buttons.OK)
yield
assert "Select number of words" in layout().get_content()
assert "select the number of words" in layout().get_content()
client.debug.click(buttons.OK)
yield
@ -182,7 +182,7 @@ def test_invalid_seed_core(client: Client):
client.debug.click(buttons.grid34(0, 2))
yield
assert "Enter recovery seed" in layout().get_content()
assert "enter your recovery seed" in layout().get_content()
client.debug.click(buttons.OK)
yield
@ -197,7 +197,7 @@ def test_invalid_seed_core(client: Client):
yield
# retry screen
assert "Select number of words" in layout().get_content()
assert "select the number of words" in layout().get_content()
client.debug.click(buttons.CANCEL)
yield
@ -210,7 +210,7 @@ def test_invalid_seed_core(client: Client):
client.debug.press_right()
yield
assert "Select number of words" in layout().text
assert "select the number of words" in layout().text
client.debug.press_yes()
yield
@ -220,7 +220,7 @@ def test_invalid_seed_core(client: Client):
client.debug.press_middle()
yield
assert "Enter recovery seed" in layout().text
assert "enter your recovery seed" in layout().text
client.debug.press_yes()
yield
@ -239,7 +239,7 @@ def test_invalid_seed_core(client: Client):
yield
# retry screen
assert "Select number of words" in layout().text
assert "select the number of words" in layout().text
client.debug.press_left()
yield

View File

@ -43,7 +43,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input("654")
yield
assert "Select number of words" in layout().get_content()
assert "select the number of words" in layout().get_content()
client.debug.press_yes()
yield
@ -51,7 +51,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input(str(len(mnemonic)))
yield
assert "Enter recovery seed" in layout().get_content()
assert "enter your recovery seed" in layout().get_content()
client.debug.press_yes()
yield
@ -75,7 +75,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input("654")
yield
assert "re-enter to confirm" in layout().text
assert "re-enter PIN to confirm" in layout().text
client.debug.press_right()
yield
@ -83,7 +83,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input("654")
yield
assert "Select number of words" in layout().text
assert "select the number of words" in layout().text
client.debug.press_yes()
yield
@ -92,7 +92,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input(str(len(mnemonic)))
yield
assert "Enter recovery seed" in layout().text
assert "enter your recovery seed" in layout().text
client.debug.press_yes()
yield
@ -105,7 +105,7 @@ def test_tt_pin_passphrase(client: Client):
client.debug.input(word)
yield
assert "You have successfully recovered your wallet." in layout().text
assert "You have finished recovering your wallet." in layout().text
client.debug.press_yes()
with client:
@ -141,7 +141,7 @@ def test_tt_nopin_nopassphrase(client: Client):
client.debug.press_yes()
yield
assert "Select number of words" in layout().get_content()
assert "select the number of words" in layout().get_content()
client.debug.press_yes()
yield
@ -149,7 +149,7 @@ def test_tt_nopin_nopassphrase(client: Client):
client.debug.input(str(len(mnemonic)))
yield
assert "Enter recovery seed" in layout().get_content()
assert "enter your recovery seed" in layout().get_content()
client.debug.press_yes()
yield
@ -169,7 +169,7 @@ def test_tt_nopin_nopassphrase(client: Client):
client.debug.press_yes()
yield
assert "Select number of words" in layout().text
assert "select the number of words" in layout().text
client.debug.press_yes()
yield
@ -178,7 +178,7 @@ def test_tt_nopin_nopassphrase(client: Client):
client.debug.input(str(len(mnemonic)))
yield
assert "Enter recovery seed" in layout().text
assert "enter your recovery seed" in layout().text
client.debug.press_yes()
yield
@ -191,7 +191,7 @@ def test_tt_nopin_nopassphrase(client: Client):
client.debug.input(word)
yield
assert "You have successfully recovered your wallet." in layout().text
assert "You have finished recovering your wallet." in layout().text
client.debug.press_yes()
with client:

View File

@ -53,7 +53,7 @@ def test_abort(emulator: Emulator):
assert layout.get_title() == "RECOVERY MODE"
layout = debug.click(buttons.OK, wait=True)
assert "Select number of words" in layout.text
assert "select the number of words" in layout.text
device_handler.restart(emulator)
debug = device_handler.debuglink()
@ -63,7 +63,7 @@ def test_abort(emulator: Emulator):
# no waiting for layout because layout doesn't change
layout = debug.read_layout()
assert "Select number of words" in layout.text
assert "select the number of words" in layout.text
layout = debug.click(buttons.CANCEL, wait=True)
assert layout.get_title() == "ABORT RECOVERY"