feat(tests,eckhart): traverse TextScreen menus
What changed, and why it matters
This commit is a test-infrastructure and UI-layout change for the upcoming Trezor Safe 5 (Eckhart layout). It lets automated UI tests detect whether a text screen has an external menu, and it swaps a red cancel menu item for a dedicated themed cancel button. There is no security-relevant behavior change visible in the diff.
No security action required. Treat as normal feature/test code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch adds a #[cfg(feature = "ui_debug")] external_menu flag to TextScreen, exposes it via a builder method, and reports it in the UI debug trace as has_menu. It also wires the external_menu parameter already passed into UI Eckhart::confirm_homescreen_action so the debug flag is set. Separately, it replaces Button::new_menu_item(text, theme::menu_item_title_red()) with Button::new_cancel_menu_item(text) in a vertical menu. Both changes are cosmetic/test-facing and gated by debug/test features.
Changed components
core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rscore/embed/rust/src/ui/layout_eckhart/ui_firmware.rsInspect captured patch +18 / −2
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs
index dbac7316..42872eff 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs
@@ -46,6 +46,8 @@ pub struct TextScreen<T> {
show_action_bar: bool,
show_page_counter: bool,
+ #[cfg(feature = "ui_debug")]
+ external_menu: bool,
#[cfg(feature = "ui_debug")]
has_flow_menu: bool,
// TODO: swipe handling
@@ -76,6 +78,8 @@ where
show_action_bar: false,
show_page_counter: false,
#[cfg(feature = "ui_debug")]
+ external_menu: false,
+ #[cfg(feature = "ui_debug")]
has_flow_menu: false,
}
}
@@ -112,6 +116,16 @@ where
self
}
+ #[cfg(feature = "ui_debug")]
+ pub fn with_external_menu(mut self, external_menu: bool) -> Self {
+ self.external_menu = external_menu;
+ self
+ }
+ #[cfg(not(feature = "ui_debug"))]
+ pub fn with_external_menu(self, _external_menu: bool) -> Self {
+ self
+ }
+
// TODO: currently used to traverse old style (aka non-"external" menus)
// which are implemented as part of swipe flows.
// Once we have eventually replaced all these with new style "external menu",
@@ -389,6 +403,7 @@ where
t.int("page_limit", page_limit as i64);
}
t.int("page_count", self.content.pager().total() as i64);
+ t.bool("has_menu", self.external_menu);
t.bool("has_flow_menu", self.has_flow_menu);
}
}
diff --git a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs
index a2eec488..861121a6 100644
--- a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs
@@ -516,7 +516,8 @@ impl FirmwareUI for UIEckhart {
let mut screen = TextScreen::new(paragraphs)
.with_header(header)
.with_subtitle(subtitle.unwrap_or(TString::empty()))
- .with_action_bar(action_bar);
+ .with_action_bar(action_bar)
+ .with_external_menu(external_menu);
if page_counter {
screen = screen.with_hint(Hint::new_page_counter())
} else if let Some(warning_footer) = warning_footer {
@@ -997,7 +998,7 @@ impl FirmwareUI for UIEckhart {
menu.item(Button::new_menu_item(*text, theme::menu_item_title()));
}
if let Some(text) = cancel {
- menu.item(Button::new_menu_item(text, theme::menu_item_title_red()));
+ menu.item(Button::new_cancel_menu_item(text));
}
let screen = VerticalMenuScreen::new(menu)
.with_header(Header::new(TString::empty()).with_close_button())
Why this scored 13/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.