1616"""
1717
1818import os
19+ import re
1920import signal
2021import subprocess
2122import sys
2829
2930
3031WALLET_NAME = "receive_requests"
32+ SECOND_WALLET_NAME = "receive_requests_alt"
33+
34+
35+ def wait_until (predicate , timeout = 20 , interval = 0.1 , description = "condition" ):
36+ deadline = time .time () + timeout
37+ last_error = None
38+ while time .time () < deadline :
39+ try :
40+ if predicate ():
41+ return
42+ except Exception as err : # noqa: BLE001 - test polling should tolerate transient state
43+ last_error = err
44+ time .sleep (interval )
45+ if last_error :
46+ raise AssertionError (f"Timed out waiting for { description } : { last_error } " )
47+ raise AssertionError (f"Timed out waiting for { description } " )
3148
3249
3350def _stop_gui (harness ):
@@ -69,15 +86,14 @@ def _relaunch_gui(harness):
6986 harness .driver = QmlDriver (harness .socket_path , timeout = GUI_STARTUP_TIMEOUT )
7087
7188
72- def _import_wallet (harness ):
73- harness .start_source_node ()
74- backup_path = os .path .join (harness .tmpdir , f"{ WALLET_NAME } .bak" )
75- rpc_call (harness .source_rpc_port , "createwallet" , {"wallet_name" : WALLET_NAME })
76- rpc_call (harness .source_rpc_port , "backupwallet" , [backup_path ], wallet = WALLET_NAME )
77- harness .stop_source_node ()
89+ def _create_wallet_backup (harness , wallet_name ):
90+ backup_path = os .path .join (harness .tmpdir , f"{ wallet_name } .bak" )
91+ rpc_call (harness .source_rpc_port , "createwallet" , {"wallet_name" : wallet_name })
92+ rpc_call (harness .source_rpc_port , "backupwallet" , [backup_path ], wallet = wallet_name )
93+ return backup_path
7894
79- harness . start_gui ()
80- gui = harness . driver
95+
96+ def _import_wallet_backup ( gui , backup_path , wallet_name ):
8197 gui .wait_for_property ("walletBadge" , "loading" , False , timeout_ms = 20000 )
8298 gui .click ("walletBadge" )
8399 try :
@@ -92,10 +108,50 @@ def _import_wallet(harness):
92108 gui .click ("importWalletChooseFileButton" )
93109 gui .wait_for_page ("importWalletSuccessPage" , timeout_ms = 30000 )
94110 gui .click ("importWalletSuccessOverviewButton" )
95- gui .wait_for_property ("walletBadge" , "text" , WALLET_NAME , timeout_ms = 20000 )
111+ gui .wait_for_property ("walletBadge" , "text" , wallet_name , timeout_ms = 20000 )
112+
113+
114+ def _import_wallet (harness ):
115+ harness .start_source_node ()
116+ backup_path = _create_wallet_backup (harness , WALLET_NAME )
117+ harness .stop_source_node ()
118+
119+ harness .start_gui ()
120+ gui = harness .driver
121+ _import_wallet_backup (gui , backup_path , WALLET_NAME )
122+ return gui
123+
124+
125+ def _import_wallets (harness ):
126+ harness .start_source_node ()
127+ primary_backup_path = _create_wallet_backup (harness , WALLET_NAME )
128+ secondary_backup_path = _create_wallet_backup (harness , SECOND_WALLET_NAME )
129+ harness .stop_source_node ()
130+
131+ harness .start_gui ()
132+ gui = harness .driver
133+ _import_wallet_backup (gui , primary_backup_path , WALLET_NAME )
134+ _import_wallet_backup (gui , secondary_backup_path , SECOND_WALLET_NAME )
135+ _select_wallet (gui , WALLET_NAME )
96136 return gui
97137
98138
139+ def _select_wallet (gui , wallet_name ):
140+ gui .wait_for_property ("walletBadge" , "loading" , False , timeout_ms = 20000 )
141+ if gui .get_property ("walletBadge" , "text" ) == wallet_name :
142+ return
143+
144+ gui .click ("walletBadge" )
145+ gui .wait_for_property ("walletSelectPopup" , "opened" , True , timeout_ms = 5000 )
146+
147+ wallet_object_name = "walletSelectItem_" + re .sub (r"[^A-Za-z0-9_]" , "_" , wallet_name )
148+ gui .wait_for_property (wallet_object_name , "visible" , True , timeout_ms = 10000 )
149+ gui .click (wallet_object_name )
150+ gui .wait_for_property ("walletBadge" , "text" , wallet_name , timeout_ms = 10000 )
151+ gui .wait_for_property ("walletSelectPopup" , "opened" , False , timeout_ms = 5000 )
152+ gui .settle (timeout_ms = 5000 )
153+
154+
99155def _open_receive (gui ):
100156 gui .click ("receiveTabButton" )
101157 gui .wait_for_page ("requestPaymentPage" , timeout_ms = 10000 )
@@ -192,7 +248,7 @@ def run_test():
192248 harness = WalletFlowHarness ("qml_receive_requests" , port_offset = 70 )
193249 try :
194250 print ("[qml_receive_requests] starting" )
195- gui = _import_wallet (harness )
251+ gui = _import_wallets (harness )
196252 _open_receive (gui )
197253
198254 # Create first request — verify QR is available from the generated-state button.
@@ -262,6 +318,17 @@ def run_test():
262318 gui .click ("paymentRequestDetailEdit" )
263319 gui .wait_for_page ("requestPaymentPage" , timeout_ms = 10000 )
264320 gui .wait_for_property ("requestPaymentTitle" , "text" , "Payment request #1" , timeout_ms = 10000 )
321+ gui .click ("activityTabButton" )
322+ gui .wait_for_page ("paymentRequestDetailPage" , timeout_ms = 10000 )
323+ gui .wait_for_property ("paymentRequestDetailBack" , "visible" , True , timeout_ms = 10000 )
324+ gui .click ("paymentRequestDetailBack" )
325+ gui .wait_for_property ("activityDetailsPaymentRequestsSection" , "visible" , True , timeout_ms = 10000 )
326+ gui .wait_for_property ("activityDetailsPaymentRequest_0" , "visible" , True , timeout_ms = 10000 )
327+ gui .click ("activityDetailsPaymentRequest_0" )
328+ gui .wait_for_page ("paymentRequestDetailPage" , timeout_ms = 10000 )
329+ _select_wallet (gui , SECOND_WALLET_NAME )
330+ gui .click ("activityTabButton" )
331+ gui .wait_for_property ("activitySearchToggle" , "visible" , True , timeout_ms = 10000 )
265332 print ("[qml_receive_requests] fulfilled transaction links to payment request detail" )
266333
267334 # Restart and verify persistence
0 commit comments