diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 741883517cf..635f3229c63 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -128,6 +128,7 @@ static void _librust_qstrs(void) { MP_QSTR_button; MP_QSTR_button_event; MP_QSTR_button_request; + MP_QSTR_button_style_confirm; MP_QSTR_buttons__abort; MP_QSTR_buttons__access; MP_QSTR_buttons__again; diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index 63c6db46c35..d9ba5cf77fa 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -1161,6 +1161,8 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map let block = move |_args: &[Obj], kwargs: &Map| { let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?; + let button_style_confirm: bool = + kwargs.get_or(Qstr::MP_QSTR_button_style_confirm, false)?; let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?; let mut paragraphs = ParagraphVecLong::new(); @@ -1177,7 +1179,11 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map title, ButtonPage::new(paragraphs.into_paragraphs(), theme::BG) .with_cancel_confirm(None, Some(button)) - .with_confirm_style(theme::button_default()) + .with_confirm_style(if button_style_confirm { + theme::button_confirm() + } else { + theme::button_default() + }) .with_back_button(), ))?; Ok(obj.into()) @@ -1988,6 +1994,7 @@ pub static mp_module_trezorui2: Module = obj_module! { /// *, /// title: str, /// button: str, + /// button_style_confirm: bool = False, /// items: Iterable[tuple[int, str | bytes]], /// ) -> LayoutObj[UiResult]: /// """Confirm long content with the possibility to go back from any page. diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 6dff117cf86..deda1a847fe 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -1463,6 +1463,7 @@ def confirm_more( *, title: str, button: str, + button_style_confirm: bool = False, items: Iterable[tuple[int, str | bytes]], ) -> LayoutObj[UiResult]: """Confirm long content with the possibility to go back from any page. diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index f6132a30a3a..3557312640f 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -885,7 +885,8 @@ async def _confirm_ask_pagination( paginated = RustLayout( trezorui2.confirm_more( title=title, - button=TR.buttons__close, + button=TR.buttons__confirm, + button_style_confirm=True, items=[(ui.MONO, data)], ) ) @@ -894,6 +895,8 @@ async def _confirm_ask_pagination( result = await interact(paginated, br_name, br_code) assert result in (CONFIRMED, CANCELLED) + if result is CONFIRMED: + return assert False diff --git a/tests/device_tests/ethereum/test_signtx.py b/tests/device_tests/ethereum/test_signtx.py index b12e7146cf9..54e565c2d1b 100644 --- a/tests/device_tests/ethereum/test_signtx.py +++ b/tests/device_tests/ethereum/test_signtx.py @@ -455,10 +455,11 @@ def _sign_tx_call(): client.set_input_flow(flow(client)) _sign_tx_call() - with client, pytest.raises(exceptions.Cancelled): - client.watch_layout() - client.set_input_flow(flow(client, cancel=True)) - _sign_tx_call() + if flow is not input_flow_data_scroll_down: + with client, pytest.raises(exceptions.Cancelled): + client.watch_layout() + client.set_input_flow(flow(client, cancel=True)) + _sign_tx_call() @pytest.mark.models("core") diff --git a/tests/input_flows.py b/tests/input_flows.py index b178331bae2..f351cb008cd 100644 --- a/tests/input_flows.py +++ b/tests/input_flows.py @@ -1216,13 +1216,22 @@ def __init__(self, client: Client, cancel: bool = False): self.cancel = cancel def input_flow_common(self) -> BRGeneratorType: + # this flow will not test for the cancel case, + # because once we enter the "view all data", + # the only way to cancel is by going back to the 1st page view + # but that case would be covered by InputFlowEthereumSignTxDataGoBack + assert not self.cancel + yield from self.ETH.confirm_data(info=True) yield from self.ETH.paginate_data() - if self.cancel: - yield from self.ETH.confirm_data(cancel=True) + + self.debug.wait_layout() + if self.debug.layout_type is LayoutType.TR: + self.debug.press_right() else: - yield from self.ETH.confirm_data() - yield from self.ETH.confirm_tx() + self.debug.click(buttons.OK) + + yield from self.ETH.confirm_tx() class InputFlowEthereumSignTxDataGoBack(InputFlowBase): diff --git a/tests/input_flows_helpers.py b/tests/input_flows_helpers.py index 6e04afb123d..46ee3493dc6 100644 --- a/tests/input_flows_helpers.py +++ b/tests/input_flows_helpers.py @@ -355,11 +355,15 @@ def paginate_data(self) -> BRGeneratorType: br = yield TR.assert_equals(self.debug.wait_layout().title(), "ethereum__title_input_data") assert br.pages is not None - for i in range(br.pages): - self.debug.wait_layout() - if i < br.pages - 1: - self.debug.swipe_up() - self.debug.press_yes() + if self.client.layout_type is LayoutType.TR: + for i in range(br.pages): + if i < br.pages - 1: + self.debug.press_right() + else: + 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: br = yield @@ -419,7 +423,7 @@ def confirm_tx( yield elif self.client.layout_type is LayoutType.TR: - TR.assert_equals(self.debug.wait_layout().title(), "words__recipient") + TR.assert_equals(self.debug.wait_layout().title(), "ethereum__interaction_contract") if cancel: self.debug.press_left() else: diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 34192ff7989..22f29b9a772 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -4891,7 +4891,7 @@ "T2T1_en_ethereum-test_signtx.py::test_signtx[True-nodata_2_bigvalue]": "75bbdb98339cba95f71645c8823ab7e4665b16fb76792a1dd333b6f5a204eabf", "T2T1_en_ethereum-test_signtx.py::test_signtx[True-wanchain]": "58dc789e90de2aefbbe3d6f56502eec9819799d24a5f81d6c6d4f06fcb79448d", "T2T1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_go_back]": "01b411d8ab81e6ab36eb2112b87e760f6b33ea34f3a00e80d15bc7ed02f5225a", -"T2T1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_scroll_down]": "8d598decbb9ce68ec0ef3d4ea78f6cabe469059eacf97602af98faa6aad257a4", +"T2T1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_scroll_down]": "cba875c1ff9d6964a4221ad4fa98aef676936a89bdc1b8bcab5b119a07b92efd", "T2T1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_skip]": "d6b1065283ca75c3e71797ad9ffa18911fc4def79198b6a050320103d4561bcd", "T2T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-Ledger Live legacy path]": "74c111cc08d0d298c31b3649412d8e036d788bc5f6f9eb7c12dcd39b988e7331", "T2T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_1]": "41478bd9d88609cbca5c7404e25435812644005b69cd9ed21ed0a2759459d5c9", @@ -13662,9 +13662,9 @@ "T3B1_en_ethereum-test_signtx.py::test_signtx[True-nodata_1]": "542b5da607b0b9de781c2d2b44ebf531024ea9a6d69ab88bb600915952251aaa", "T3B1_en_ethereum-test_signtx.py::test_signtx[True-nodata_2_bigvalue]": "7205121561dc02edc919030228c9ee2351efcf2e272575cc1d032f23b9747d5f", "T3B1_en_ethereum-test_signtx.py::test_signtx[True-wanchain]": "d0cc4a6be5dab8a57e932b669e4bafa3f9911500f222bbec81b84066183eef6d", -"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_go_back]": "1825d4be360362111e38db28a788b2250b1a420037e87ad0c1a25d193a462f4e", -"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_scroll_down]": "bb93c331ddef290deec4079509bf93a6826162a01a46c2ef1dc07227239a3977", -"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_skip]": "eb6e718ab30bf5327ca9105e5621adc003660f3d97fefc269464addb683a381c", +"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_go_back]": "d976b87196121919c468e0c0d2c46d38bace5b61d8dff6151dbb5b504c14f94a", +"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_scroll_down]": "daf4c21604e74fca4e16a180ac4fa0352cd744cdf2c5294730bebda8d8564fc7", +"T3B1_en_ethereum-test_signtx.py::test_signtx_data_pagination[input_flow_data_skip]": "3e86320ff8946dbe4375c26bae07bd6f30bac5c03de8a5094a18b57f86088cfd", "T3B1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-Ledger Live legacy path]": "fc801083241509eb6e3bfef1bfd1adc5cd69fd56a24cec7e2ddc2b21aad01be5", "T3B1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_1]": "c316ff1f80892905022fca36f95e85a6c9091b60646ec5eef5932abfd3a90425", "T3B1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_2_bigdata]": "62cb201669693857050b80e8e03f5a7d160a401459286e25bb6f67f93191cbec",