@@ -79,6 +79,70 @@ def wait_for_authentication_success_in_unity_logs(timeout_seconds: int = 60) ->
7979 print ("No authentication success detected in Unity logs within timeout." )
8080 return False
8181
82+
83+ def try_click_protocol_permission_dialog (timeout_seconds : int = 15 ) -> bool :
84+ """
85+ Try to click the browser-level external protocol permission prompt.
86+
87+ Important: this dialog is NOT part of the web page DOM, so Selenium cannot click it.
88+ We use Windows UIAutomation to locate and invoke an "Open/Allow/Yes" button.
89+ """
90+ product_name = os .getenv ("UNITY_APP_NAME" , get_product_name ())
91+ print ("Attempting to click external protocol permission dialog via UIAutomation..." )
92+
93+ ps_script = f'''
94+ $deadline = (Get-Date).AddSeconds({ int (timeout_seconds )} )
95+ Add-Type -AssemblyName UIAutomationClient
96+
97+ function Find-And-Click($titlePart) {{
98+ $procs = Get-Process -ErrorAction SilentlyContinue | Where-Object {{ $_.MainWindowHandle -ne 0 -and $_.MainWindowTitle -like "*$titlePart*" }}
99+ foreach ($p in $procs) {{
100+ try {{
101+ $el = [Windows.Automation.AutomationElement]::FromHandle($p.MainWindowHandle)
102+ if ($null -eq $el) {{ continue }}
103+ $buttons = $el.FindAll([Windows.Automation.TreeScope]::Descendants,
104+ [Windows.Automation.Condition]::new([Windows.Automation.AutomationElement]::ControlTypeProperty, [Windows.Automation.ControlType]::Button))
105+
106+ foreach ($b in $buttons) {{
107+ $name = $b.Current.Name
108+ if ($name -like "*Open*" -or $name -like "*Allow*" -or $name -like "*Yes*" -or $name -like "*{ product_name } *") {{
109+ $b.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke()
110+ Write-Host "Clicked protocol dialog button: $name"
111+ return $true
112+ }}
113+ }}
114+ }} catch {{}}
115+ }}
116+ return $false
117+ }}
118+
119+ while ((Get-Date) -lt $deadline) {{
120+ if (Find-And-Click "auth.immutable.com") {{ exit 0 }}
121+ if (Find-And-Click "Immutable Passport") {{ exit 0 }}
122+ if (Find-And-Click "Open") {{ exit 0 }}
123+ Start-Sleep -Milliseconds 500
124+ }}
125+ Write-Host "No protocol dialog found"
126+ exit 1
127+ '''
128+
129+ try :
130+ result = subprocess .run (
131+ ["powershell" , "-Command" , ps_script ],
132+ capture_output = True ,
133+ text = True ,
134+ timeout = max (5 , int (timeout_seconds ) + 5 ),
135+ )
136+ if "Clicked protocol dialog button" in (result .stdout or "" ):
137+ print (result .stdout .strip ())
138+ print ("Successfully clicked protocol dialog via UIAutomation." )
139+ return True
140+ print ((result .stdout or "" ).strip () or "UIAutomation did not find/click any dialog button." )
141+ return False
142+ except Exception as e :
143+ print (f"UIAutomation dialog click failed: { e } " )
144+ return False
145+
82146# Add chrome.exe to environment variable
83147# Download chrome driver and add to environment variable
84148
@@ -594,13 +658,23 @@ def login():
594658 except :
595659 pass
596660
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 )
661+ # The "open external protocol" prompt is typically browser UI (not DOM),
662+ # so 0 buttons on /checking is expected. Try:
663+ # - wait briefly for Unity success (maybe protocol already fired)
664+ # - click the browser-level prompt via UIAutomation
665+ # - wait again for Unity success
666+ if "auth.immutable.com/checking" in current_url_lower :
667+ if wait_for_authentication_success_in_unity_logs (timeout_seconds = 10 ):
668+ return
669+
670+ clicked = try_click_protocol_permission_dialog (timeout_seconds = 20 )
671+ if clicked :
672+ # Give Unity a moment to receive and process the callback
673+ wait_for_authentication_success_in_unity_logs (timeout_seconds = 75 )
674+ return
675+
676+ print ("No protocol dialog clicked; Unity may never receive the callback." )
677+ wait_for_authentication_success_in_unity_logs (timeout_seconds = 30 )
604678 return
605679
606680 # Otherwise, try to click the deep link dialog if it appears.
0 commit comments