3636sys .path .insert (0 , str (Path (__file__ ).resolve ().parent .parent / 'src' ))
3737from fetch_otp import EMAIL , fetch_code
3838
39+ # Unity authentication success markers we can reliably detect from Player.log.
40+ _UNITY_AUTH_SUCCESS_MARKERS = [
41+ "AuthenticatedScene" ,
42+ "COMPLETE_LOGIN_PKCE" ,
43+ "LoginPKCESuccess" ,
44+ "HandleLoginPkceSuccess" ,
45+ "authentication successful" ,
46+ "logged in successfully" ,
47+ "Passport token received" ,
48+ ]
49+
50+
51+ def wait_for_authentication_success_in_unity_logs (timeout_seconds : int = 60 ) -> bool :
52+ """
53+ Best-effort wait for Unity to process the deep-link callback.
54+
55+ This is needed in CI because the browser may auto-handle the external protocol
56+ without showing any permission dialog (especially if protocol association is set),
57+ so Selenium won't have any button to click, but Unity will still authenticate.
58+ """
59+ import os
60+
61+ product_name = os .getenv ("UNITY_APP_NAME" , get_product_name ())
62+ log_path = os .path .join ("C:\\ Users\\ WindowsBuildsdkServi\\ AppData\\ LocalLow\\ Immutable" , product_name , "Player.log" )
63+
64+ print (f"Waiting up to { timeout_seconds } s for Unity auth success in Player.log..." )
65+ print (f"Monitoring Unity log: { log_path } " )
66+
67+ for _ in range (max (1 , int (timeout_seconds ))):
68+ try :
69+ with open (log_path , 'r' , encoding = 'utf-8' , errors = 'ignore' ) as f :
70+ content = f .read ()
71+ if any (marker in content for marker in _UNITY_AUTH_SUCCESS_MARKERS ):
72+ print ("Authentication success detected in Unity logs!" )
73+ return True
74+ except Exception :
75+ # Log may not exist yet or be temporarily locked; retry.
76+ pass
77+ time .sleep (1 )
78+
79+ print ("No authentication success detected in Unity logs within timeout." )
80+ return False
81+
3982# Add chrome.exe to environment variable
4083# Download chrome driver and add to environment variable
4184
@@ -538,6 +581,8 @@ def login():
538581 time .sleep (3 )
539582
540583 try :
584+ current_url_lower = (driver .current_url or "" ).lower ()
585+
541586 # Check what's actually on the page
542587 buttons = driver .find_elements (By .TAG_NAME , "button" )
543588 print (f"Found { len (buttons )} buttons on page:" )
@@ -548,16 +593,29 @@ def login():
548593 print (f" Button { i } : '{ text } '" )
549594 except :
550595 pass
551-
552- # Wait for the deep link dialog to appear and click the button
553- # Use more specific selector to avoid clicking "Restore" button
596+
597+ # In CI, if protocol association is already configured, Chrome/Brave may auto-handle
598+ # the external protocol WITHOUT showing any permission dialog. In that case there
599+ # may be 0 buttons on /checking, and waiting for a dialog will just time out.
600+ if "auth.immutable.com/checking" in current_url_lower and len (buttons ) == 0 :
601+ print ("No deep link permission dialog present on /checking (0 buttons)." )
602+ print ("Assuming protocol is already permitted; waiting for Unity to process callback via Player.log..." )
603+ wait_for_authentication_success_in_unity_logs (timeout_seconds = 75 )
604+ return
605+
606+ # Otherwise, try to click the deep link dialog if it appears.
607+ # Use more specific selector to avoid clicking "Restore" button.
554608 product_name = os .getenv ("UNITY_APP_NAME" , get_product_name ())
555- deep_link_button = wait .until (EC .element_to_be_clickable ((By .XPATH , f"//button[text()='Open { product_name } .cmd']" )))
609+ dialog_wait = WebDriverWait (driver , 8 )
610+ deep_link_button = dialog_wait .until (
611+ EC .element_to_be_clickable ((By .XPATH , f"//button[text()='Open { product_name } .cmd']" ))
612+ )
556613 deep_link_button .click ()
557614 print ("Clicked deep link permission dialog - Unity should receive redirect" )
558615 except Exception as e :
559616 print (f"Deep link dialog not found or failed to click: { e } " )
560- print ("This may cause the test to timeout waiting for scene change" )
617+ print ("Assuming dialog was suppressed/auto-handled; waiting for Unity to process callback via Player.log..." )
618+ wait_for_authentication_success_in_unity_logs (timeout_seconds = 75 )
561619
562620 # Keep browser alive for Unity deep link redirect
563621 # driver.quit()
0 commit comments