Skip to content

Commit ce4d968

Browse files
Navigation scenario with spinner
1 parent c7a5b3b commit ce4d968

2 files changed

Lines changed: 39 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.43.0] - 2026-03-02
9+
10+
### Added
11+
12+
- Added scenario navigation for review finishing with spinner
13+
814
## [1.42.1] - 2026-02-05
915

1016
### Fixed

src/ragger/navigator/navigation_scenario.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ class NavigationScenarioData:
1818
validation: Sequence[InstructionType]
1919
dismiss_warning: Sequence[InstructionType]
2020
pattern: str = ""
21+
post_validation_spinner: Optional[str] = None
2122

2223
def __init__(self,
2324
device: Device,
2425
backend: BackendInterface,
2526
use_case: UseCase,
2627
approve: bool,
28+
post_validation_spinner: Optional[str] = None,
2729
nb_warnings: int = 1):
30+
2831
if device.is_nano:
2932
self.navigation = NavInsID.RIGHT_CLICK
3033
self.validation = [NavInsID.BOTH_CLICK]
@@ -82,12 +85,16 @@ def __init__(self,
8285
else:
8386
raise NotImplementedError("Unknown use case")
8487

85-
# Dismiss the result modal in all cases
86-
self.validation += [NavInsID.USE_CASE_STATUS_DISMISS]
88+
# We assume no spinner == modal
89+
if post_validation_spinner is None:
90+
self.validation += [NavInsID.USE_CASE_STATUS_DISMISS]
8791

8892
else:
8993
raise NotImplementedError("Unknown device")
9094

95+
# For both Nano AND e-ink : remember if we have a final spinner to check for
96+
self.post_validation_spinner = post_validation_spinner
97+
9198

9299
class NavigateWithScenario:
93100

@@ -108,17 +115,28 @@ def _navigate_with_scenario(self,
108115
if custom_screen_text is not None:
109116
scenario.pattern = custom_screen_text
110117

118+
# Assert post validation modal (give True) only if no spinner
119+
screen_change_after_last_instruction = scenario.post_validation_spinner is None
120+
111121
if do_comparison:
112122
self.navigator.navigate_until_text_and_compare(
113123
navigate_instruction=scenario.navigation,
114124
validation_instructions=scenario.validation,
115125
text=scenario.pattern,
116126
path=path if path else self.screenshot_path,
117-
test_case_name=test_name if test_name else self.test_name)
127+
test_case_name=test_name if test_name else self.test_name,
128+
screen_change_after_last_instruction=screen_change_after_last_instruction)
118129
else:
119130
self.navigator.navigate_until_text(navigate_instruction=scenario.navigation,
120131
validation_instructions=scenario.validation,
121-
text=scenario.pattern)
132+
text=scenario.pattern,
133+
screen_change_after_last_instruction=screen_change_after_last_instruction)
134+
135+
if scenario.post_validation_spinner is not None:
136+
# If the navigation ended with a spinner, we did not assert the post validation screen in navigate_until_text
137+
# because we do not want to assert the spinner screen to avoid race issues
138+
# We perform a manual text_on_screen check instead
139+
self.backend.wait_for_text_on_screen(scenario.post_validation_spinner)
122140

123141
def _navigate_warning(self,
124142
scenario: NavigationScenarioData,
@@ -151,10 +169,19 @@ def review_approve_with_warning(self,
151169
warning_path: str = "warning",
152170
nb_warnings: int = 1):
153171
scenario = NavigationScenarioData(self.device, self.backend, UseCase.TX_REVIEW, True,
154-
nb_warnings)
172+
nb_warnings=nb_warnings)
155173
self._navigate_warning(scenario, test_name, do_comparison, warning_path)
156174
self._navigate_with_scenario(scenario, path, test_name, custom_screen_text, do_comparison)
157175

176+
def review_approve_with_spinner(self,
177+
spinner_text: str,
178+
path: Optional[Path] = None,
179+
test_name: Optional[str] = None,
180+
custom_screen_text: Optional[str] = None,
181+
do_comparison: bool = True):
182+
scenario = NavigationScenarioData(self.device, self.backend, UseCase.TX_REVIEW, True, post_validation_spinner=spinner_text)
183+
self._navigate_with_scenario(scenario, path, test_name, custom_screen_text, do_comparison)
184+
158185
def review_reject(self,
159186
path: Optional[Path] = None,
160187
test_name: Optional[str] = None,
@@ -171,7 +198,7 @@ def review_reject_with_warning(self,
171198
warning_path: str = "warning",
172199
nb_warnings: int = 1):
173200
scenario = NavigationScenarioData(self.device, self.backend, UseCase.TX_REVIEW, False,
174-
nb_warnings)
201+
nb_warnings=nb_warnings)
175202
self._navigate_warning(scenario, test_name, do_comparison, warning_path)
176203
self._navigate_with_scenario(scenario, path, test_name, custom_screen_text, do_comparison)
177204

0 commit comments

Comments
 (0)