@@ -36,6 +36,33 @@ def stop_altdriver(self):
3636 if self .__class__ .altdriver :
3737 self .__class__ .altdriver .stop ()
3838
39+ def wait_for_output (
40+ self ,
41+ output_obj ,
42+ predicate ,
43+ * ,
44+ timeout_seconds : float = 15.0 ,
45+ poll_seconds : float = 0.25 ,
46+ ) -> str :
47+ """
48+ Poll the `Output` UI element until `predicate(text)` is True.
49+
50+ UI actions often update `Output` asynchronously (especially in CI),
51+ so reading immediately after `.tap()` can be flaky.
52+ """
53+ deadline = time .time () + float (timeout_seconds )
54+ last_text = ""
55+ while time .time () < deadline :
56+ try :
57+ last_text = output_obj .get_text ()
58+ if predicate (last_text ):
59+ return last_text
60+ except Exception :
61+ # App/UI might be mid-transition; retry.
62+ pass
63+ time .sleep (float (poll_seconds ))
64+ return last_text
65+
3966 @pytest .mark .skip (reason = "Base test should not be executed directly" )
4067 def test_0_other_functions (self ):
4168 # Show set call timeout scene
@@ -59,31 +86,52 @@ def test_1_passport_functions(self):
5986 output = self .altdriver .find_object (By .NAME , "Output" )
6087
6188 # Get access token
89+ prev = output .get_text ()
6290 self .altdriver .find_object (By .NAME , "GetAccessTokenBtn" ).tap ()
63- text = output .get_text ()
64- self .assertTrue (len (text ) > 50 )
91+ text = self .wait_for_output (
92+ output ,
93+ lambda t : len (t ) > 50 and (t != prev or prev == "" ),
94+ timeout_seconds = 20 ,
95+ )
96+ self .assertTrue (len (text ) > 50 , f"Access token output too short. Actual output: '{ text } '" )
6597
6698 # Get ID token
99+ prev = output .get_text ()
67100 self .altdriver .find_object (By .NAME , "GetIdTokenBtn" ).tap ()
68- text = output .get_text ()
69- self .assertTrue (len (text ) > 50 )
101+ text = self .wait_for_output (
102+ output ,
103+ lambda t : len (t ) > 50 and (t != prev or prev == "" ),
104+ timeout_seconds = 20 ,
105+ )
106+ self .assertTrue (len (text ) > 50 , f"ID token output too short. Actual output: '{ text } '" )
70107
71108 # Get email
72109 self .altdriver .find_object (By .NAME , "GetEmail" ).tap ()
73- text = output .get_text ()
110+ text = self .wait_for_output (
111+ output ,
112+ lambda t : t == TestConfig .EMAIL ,
113+ timeout_seconds = 10 ,
114+ )
74115 print (f"GetEmail output: { text } " )
75116 self .assertEqual (TestConfig .EMAIL , text )
76117
77118 # Get Passport ID
78119 self .altdriver .find_object (By .NAME , "GetPassportId" ).tap ()
79- text = output .get_text ()
120+ text = self .wait_for_output (
121+ output ,
122+ lambda t : t == TestConfig .PASSPORT_ID ,
123+ timeout_seconds = 10 ,
124+ )
80125 print (f"GetPassportId output: { text } " )
81126 self .assertEqual (TestConfig .PASSPORT_ID , text )
82127
83128 # Get linked addresses
84129 self .altdriver .find_object (By .NAME , "GetLinkedAddresses" ).tap ()
85- time .sleep (1 )
86- text = output .get_text ()
130+ text = self .wait_for_output (
131+ output ,
132+ lambda t : t == "No linked addresses" ,
133+ timeout_seconds = 10 ,
134+ )
87135 print (f"GetLinkedAddresses output: { text } " )
88136 self .assertEqual ("No linked addresses" , text )
89137
0 commit comments