Skip to content

Commit 7fda51f

Browse files
fix(tests): improve logout URL detection on macOS
- macOS: improve standalone Player.log detection for logout URL capture (additional paths + fallback scan) and trigger returnTo via open - Windows: revert deeplink registry changes that caused immutablerunner prompt
1 parent dc755d5 commit 7fda51f

1 file changed

Lines changed: 80 additions & 27 deletions

File tree

sample/Tests/test/test_mac_helpers.py

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import os
44
import re
55
from pathlib import Path
6-
from selenium import webdriver
7-
from selenium.webdriver.chrome.options import Options
86

97
def get_app_name():
108
"""Get the app name from environment variable, falling back to default"""
@@ -30,20 +28,54 @@ def get_product_name():
3028
# If regex fails, return default
3129
return "SampleApp"
3230

31+
def get_company_name():
32+
"""Get the company name from ProjectSettings.asset (used for log paths on some macOS setups)."""
33+
project_settings_path = Path(__file__).resolve().parent.parent.parent / 'ProjectSettings' / 'ProjectSettings.asset'
34+
35+
if not project_settings_path.exists():
36+
print(f"Warning: ProjectSettings.asset not found at {project_settings_path}")
37+
return None
38+
39+
try:
40+
with open(project_settings_path, 'r') as f:
41+
content = f.read()
42+
match = re.search(r'companyName: (.+)', content)
43+
if match:
44+
return match.group(1).strip()
45+
except Exception as e:
46+
print(f"Warning: failed to read companyName from ProjectSettings.asset: {e}")
47+
return None
48+
3349
def get_logout_url_from_unity_logs():
3450
"""Monitor Unity logs to capture logout URLs."""
3551
import tempfile
52+
from pathlib import Path as _Path
3653

3754
product_name = os.getenv("UNITY_APP_NAME", get_product_name())
55+
company_name = get_company_name()
3856

3957
# Unity log file locations on macOS
4058
log_paths = [
4159
os.path.join(os.path.expanduser("~"), "Library", "Logs", "Unity", product_name, "Player.log"),
4260
os.path.join(os.path.expanduser("~"), "Library", "Logs", product_name, "Player.log"),
61+
# Common standalone player paths
62+
os.path.join(os.path.expanduser("~"), "Library", "Logs", "Unity", "Player.log"),
63+
os.path.join(os.path.expanduser("~"), "Library", "Logs", "Unity", product_name, "Player.log"),
64+
os.path.join(os.path.expanduser("~"), "Library", "Logs", "Unity", "Player.log"),
4365
os.path.join(tempfile.gettempdir(), "UnityPlayer.log"),
4466
"Player.log" # Current directory
4567
]
68+
69+
if company_name:
70+
log_paths.insert(
71+
0,
72+
os.path.join(os.path.expanduser("~"), "Library", "Logs", company_name, product_name, "Player.log"),
73+
)
4674

75+
# De-dup while preserving order
76+
seen = set()
77+
log_paths = [p for p in log_paths if not (p in seen or seen.add(p))]
78+
4779
for log_path in log_paths:
4880
if os.path.exists(log_path):
4981
print(f"Monitoring Unity log for logout URL: {log_path}")
@@ -62,27 +94,53 @@ def get_logout_url_from_unity_logs():
6294
except Exception as e:
6395
print(f"Error reading log file {log_path}: {e}")
6496
continue
97+
98+
# Fallback: scan ~/Library/Logs for any Player.log and try the most recently modified few.
99+
# This helps on standalone runners where Unity logs may be under Company/Product folders.
100+
try:
101+
logs_root = _Path(os.path.expanduser("~")) / "Library" / "Logs"
102+
if logs_root.exists():
103+
candidates = []
104+
for p in logs_root.rglob("Player.log"):
105+
try:
106+
candidates.append((p.stat().st_mtime, str(p)))
107+
except Exception:
108+
continue
109+
110+
# Newest first; try a small number to avoid slow scans.
111+
candidates.sort(reverse=True)
112+
for _, p in candidates[:10]:
113+
if p in seen:
114+
continue
115+
print(f"Monitoring Unity log for logout URL (fallback): {p}")
116+
try:
117+
with open(p, 'r', encoding='utf-8', errors='ignore') as f:
118+
content = f.read()
119+
matches = re.findall(r'(?:\[Immutable\] PASSPORT_AUTH_URL: |PASSPORT_AUTH_URL: |LaunchAuthURL : )(https?://[^\s]+)', content)
120+
if matches:
121+
for url in reversed(matches):
122+
if 'logout' in url or 'im-logged-out' in url:
123+
print(f"Found logout URL: {url}")
124+
return url
125+
except Exception as e:
126+
print(f"Error reading log file {p}: {e}")
127+
continue
128+
except Exception as e:
129+
print(f"Warning: fallback Player.log scan failed: {e}")
65130

66131
print("No logout URL found in Unity logs")
67132
return None
68133

69134
def logout_with_controlled_browser():
70-
"""Handle logout using the controlled browser instance instead of letting Unity open its own browser."""
135+
"""Handle logout without relying on Selenium/ChromeDriver.
136+
137+
The Unity sample app already opens the logout URL in the system browser when LogoutBtn is tapped.
138+
Here we monitor Unity logs to capture that logout URL, extract its `returnTo` deep-link, and
139+
trigger it via `open` so Unity receives the callback deterministically.
140+
"""
71141
print("Starting controlled logout process...")
72-
73-
# Set up Chrome WebDriver options to connect to the existing browser instance
74-
chrome_options = Options()
75-
chrome_options.add_experimental_option("debuggerAddress", "localhost:9222")
76-
77-
# Brave binary location on macOS
78-
brave_path = "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
79-
chrome_options.binary_location = brave_path
80-
142+
81143
try:
82-
# Connect to the existing browser instance
83-
driver = webdriver.Chrome(options=chrome_options)
84-
print("Connected to existing browser for logout")
85-
86144
# Monitor Unity logs for logout URL
87145
print("Monitoring Unity logs for logout URL...")
88146
logout_url = None
@@ -93,17 +151,8 @@ def logout_with_controlled_browser():
93151
time.sleep(1)
94152

95153
if logout_url:
96-
print(f"Navigating controlled browser to logout URL: {logout_url}")
97-
driver.get(logout_url)
98-
99-
# Wait for logout page to load
100-
time.sleep(3)
101-
print("Logout completed in controlled browser")
102-
103-
# Check final page
104-
current_url = driver.current_url
105-
print(f"Final logout URL: {current_url}")
106-
154+
print(f"Captured logout URL from Unity logs: {logout_url}")
155+
107156
# Extract the deep-link from the redirect
108157
# Look for immutablerunner://logout in the response or extract from returnTo parameter
109158
if 'returnTo=' in logout_url:
@@ -118,6 +167,10 @@ def logout_with_controlled_browser():
118167
print(f"Triggering deep-link manually: {return_to}")
119168
subprocess.run(['open', return_to], check=False)
120169
time.sleep(2)
170+
else:
171+
print("Warning: returnTo parameter present but could not be parsed.")
172+
else:
173+
print("Warning: logout URL did not include returnTo; cannot trigger deep-link callback.")
121174

122175
else:
123176
print("Could not find logout URL in Unity logs - logout may complete without browser interaction")

0 commit comments

Comments
 (0)