@@ -140,6 +140,30 @@ describe("browser assertion helpers", () => {
140140 )
141141 ) . toBe ( true ) ;
142142
143+ expect (
144+ isRetryableBlankNavigationError (
145+ new Error (
146+ [
147+ "none of the password selectors were visible after username submit: input[type=\"password\"]" ,
148+ "current URL: https://issuer.example.test/ui/v2/login/password?requestId=oidc_123" ,
149+ "body:\n<empty>"
150+ ] . join ( "\n" )
151+ )
152+ )
153+ ) . toBe ( true ) ;
154+
155+ expect (
156+ isRetryableBlankNavigationError (
157+ new Error (
158+ [
159+ "none of the password selectors were visible after username submit: input[type=\"password\"]" ,
160+ "current URL: https://issuer.example.test/ui/v2/login/password?requestId=oidc_123" ,
161+ "body:\nPassword\nEnter your password."
162+ ] . join ( "\n" )
163+ )
164+ )
165+ ) . toBe ( false ) ;
166+
143167 expect (
144168 isRetryableBlankNavigationError (
145169 new Error (
@@ -250,7 +274,7 @@ describe("browser assertion helpers", () => {
250274 return this ;
251275 } ,
252276 isVisible : async ( ) => selector === '[data-testid="password-text-input"]' && passwordVisible ,
253- innerText : async ( ) => ""
277+ innerText : async ( ) => passwordVisible ? "Password\nEnter your password." : ""
254278 } ) ;
255279 const page = {
256280 url : ( ) => currentUrl ,
@@ -280,6 +304,47 @@ describe("browser assertion helpers", () => {
280304 expect ( evaluatedAt ) . toEqual ( [ "http://issuer.example.test/ui/v2/login/loginname?requestId=oidc_123" ] ) ;
281305 } ) ;
282306
307+ test ( "reloads a blank ZITADEL password document before waiting for password selectors" , async ( ) => {
308+ let currentUrl = "https://issuer.example.test/ui/v2/login/password?requestId=oidc_123" ;
309+ let body = "" ;
310+ let reloads = 0 ;
311+ let passwordVisible = false ;
312+ let waitedForPasswordSelector = false ;
313+ const page = {
314+ url : ( ) => currentUrl ,
315+ locator : ( selector : string ) => ( {
316+ first ( ) {
317+ return this ;
318+ } ,
319+ isVisible : async ( ) => {
320+ if ( selector === '[data-testid="password-text-input"]' ) {
321+ waitedForPasswordSelector = true ;
322+ return passwordVisible ;
323+ }
324+ return false ;
325+ } ,
326+ innerText : async ( ) => body
327+ } ) ,
328+ reload : async ( ) => {
329+ reloads += 1 ;
330+ body = "Password\nEnter your password." ;
331+ passwordVisible = true ;
332+ } ,
333+ waitForTimeout : async ( ) => undefined
334+ } as unknown as Page ;
335+
336+ const result = await __browserTestHooks . waitForPasswordInputAfterUsernameSubmit (
337+ page ,
338+ '[data-testid="username-text-input"]' ,
339+ "agent@example.test" ,
340+ "app.example.test"
341+ ) ;
342+
343+ expect ( result ) . toEqual ( { state : "password" , selector : '[data-testid="password-text-input"]' } ) ;
344+ expect ( reloads ) . toBe ( 1 ) ;
345+ expect ( waitedForPasswordSelector ) . toBe ( true ) ;
346+ } ) ;
347+
283348 test ( "does not treat the target app password field as a ZITADEL password step" , async ( ) => {
284349 const page = {
285350 url : ( ) => "https://app.example.test/" ,
0 commit comments