@@ -5,6 +5,7 @@ import type { OidcTestUser } from "../types";
55
66type LoginExpectation = "allow" | "deny" ;
77type BrowserArtifactKind = "success" | "failure" ;
8+ type PasswordWaitResult = { state : "password" ; selector : string } | { state : "target" } ;
89
910type LoginOptions = {
1011 outputDir : string ;
@@ -84,27 +85,33 @@ const CONSENT_SUBMIT_SELECTORS = ["Allow", "Authorize", "Approve", "Accept", "Co
8485 `input[type="button"][value="${ label } "]`
8586] ) ;
8687
87- async function waitForPasswordInputAfterUsernameSubmit ( page : Page , usernameSelector : string , userEmail : string , targetHost : string ) : Promise < string > {
88+ async function waitForPasswordInputAfterUsernameSubmit ( page : Page , usernameSelector : string , userEmail : string , targetHost : string ) : Promise < PasswordWaitResult > {
8889 const deadline = Date . now ( ) + BROWSER_WAIT_TIMEOUT_MS ;
8990 let lastResubmit = 0 ;
9091 let lastBody = "" ;
9192
9293 while ( Date . now ( ) < deadline ) {
93- if ( isPasswordLoginStep ( page . url ( ) ) ) {
94+ const currentUrl = page . url ( ) ;
95+ if ( isTargetApplicationPage ( currentUrl , targetHost ) ) {
96+ return { state : "target" } ;
97+ }
98+
99+ if ( isPasswordLoginStep ( currentUrl ) ) {
94100 const selector = await visiblePasswordInputSelector ( page , 5000 ) ;
95101 if ( selector ) {
96- return selector ;
102+ return { state : "password" , selector } ;
97103 }
98104 }
99105
100- for ( const selector of PASSWORD_INPUT_SELECTORS ) {
101- const locator = page . locator ( selector ) . first ( ) ;
102- if ( await locatorVisible ( locator ) ) {
103- return selector ;
106+ if ( isIdentityLoginInputPage ( currentUrl , targetHost ) ) {
107+ for ( const selector of PASSWORD_INPUT_SELECTORS ) {
108+ const locator = page . locator ( selector ) . first ( ) ;
109+ if ( await locatorVisible ( locator ) ) {
110+ return { state : "password" , selector } ;
111+ }
104112 }
105113 }
106114
107- const currentUrl = page . url ( ) ;
108115 lastBody = ( await maybeWithTimeout ( page . locator ( "body" ) . innerText ( { timeout : 1000 } ) . catch ( ( ) => "" ) , 2000 ) ) ?? "" ;
109116 const normalizedBody = lastBody . toLowerCase ( ) ;
110117 if (
@@ -221,6 +228,7 @@ async function resubmitUsernameIfStillOnUsernameStep(page: Page, userEmail: stri
221228
222229export const __browserTestHooks = {
223230 resubmitUsernameIfStillOnUsernameStep,
231+ submitIdentityForm,
224232 waitForPasswordInputAfterUsernameSubmit
225233} ;
226234
@@ -270,8 +278,13 @@ async function clickFirstVisible(page: Page, selectors: string[]): Promise<boole
270278 ( await locatorVisible ( locator ) ) &&
271279 ! ( await locatorDisabled ( locator ) )
272280 ) {
273- await locator . click ( { noWaitAfter : true , timeout : BROWSER_CLICK_TIMEOUT_MS } ) ;
274- return true ;
281+ const clicked = await maybeWithTimeout (
282+ locator . click ( { noWaitAfter : true , timeout : BROWSER_CLICK_TIMEOUT_MS } ) . then ( ( ) => true ) . catch ( ( ) => false ) ,
283+ BROWSER_CLICK_TIMEOUT_MS + 1000
284+ ) ;
285+ if ( clicked ) {
286+ return true ;
287+ }
275288 }
276289 }
277290 return false ;
@@ -649,7 +662,7 @@ async function submitIdentityForm(page: Page, inputSelector: string, buttonSelec
649662 }
650663
651664 if ( await waitForEnabledWithin ( page , buttonSelectors , 1000 ) ) {
652- await submitForm ( page , buttonSelectors ) ;
665+ await clickFirstVisible ( page , buttonSelectors ) . catch ( ( ) => false ) ;
653666 await page . waitForTimeout ( 750 ) ;
654667 if ( await identitySubmissionAdvanced ( page , beforeUrl , inputSelector ) ) {
655668 return ;
@@ -1187,11 +1200,17 @@ async function loginThroughZitadelWithContext(
11871200 await submitIdentityForm ( page , emailSelector , USERNAME_SUBMIT_SELECTORS ) ;
11881201
11891202 stage = "waiting for password input after username submit" ;
1190- const passwordSelector = await waitForPasswordInputAfterUsernameSubmit ( page , emailSelector , user . email , targetHost ) ;
1203+ const passwordWait = await waitForPasswordInputAfterUsernameSubmit ( page , emailSelector , user . email , targetHost ) ;
1204+ if ( passwordWait . state === "target" ) {
1205+ stage = `waiting for ${ expected } return to target host` ;
1206+ await waitForReturnToTargetHost ( page , targetHost , user . email , expected ) ;
1207+ stage = "capturing success page" ;
1208+ return await finishBrowserLogin ( page , screenshotPath , options ) ;
1209+ }
11911210 stage = "entering password" ;
1192- await typeInto ( page , passwordSelector , user . password ) ;
1211+ await typeInto ( page , passwordWait . selector , user . password ) ;
11931212 stage = "submitting password" ;
1194- await submitIdentityForm ( page , passwordSelector , PASSWORD_SUBMIT_SELECTORS ) ;
1213+ await submitIdentityForm ( page , passwordWait . selector , PASSWORD_SUBMIT_SELECTORS ) ;
11951214
11961215 stage = `waiting for ${ expected } return to target host` ;
11971216 await waitForReturnToTargetHost ( page , targetHost , user . email , expected ) ;
0 commit comments