|
| 1 | +""" |
| 2 | +Windows Test Helpers for Unity Passport Authentication |
| 3 | +
|
| 4 | +CRITICAL WORKAROUND IMPLEMENTED: |
| 5 | +This module implements browser process isolation workarounds for Unity Passport authentication. |
| 6 | +
|
| 7 | +PROBLEM: |
| 8 | +Unity's Application.OpenURL() opens authentication URLs in separate browser processes that |
| 9 | +automated testing tools (Selenium) cannot control. This breaks authentication flows in CI. |
| 10 | +
|
| 11 | +SOLUTION: |
| 12 | +1. Launch browser with remote debugging enabled (port 9222) |
| 13 | +2. Monitor Unity logs to capture auth/logout URLs that Unity wants to open |
| 14 | +3. Navigate controlled browser to captured URLs instead of relying on Unity's browser |
| 15 | +4. Complete authentication/logout in controlled browser |
| 16 | +5. Unity receives callbacks properly due to protocol association setup |
| 17 | +
|
| 18 | +This approach enables reliable automated testing of Passport authentication flows. |
| 19 | +""" |
| 20 | + |
1 | 21 | import os
|
2 | 22 | import re
|
3 | 23 | import subprocess
|
@@ -374,32 +394,21 @@ def login():
|
374 | 394 |
|
375 | 395 | # Try to find and click the submit button (arrow button)
|
376 | 396 | submit_selectors = [
|
377 |
| - 'button[type="submit"]', # Standard submit button |
378 |
| - 'button[data-testid*="submit"]', # Submit button with testid |
379 |
| - 'button:has(svg)', # Button containing SVG (arrow) |
380 |
| - '.submit-button', # Submit button class |
381 |
| - 'button[aria-label*="submit"]', # Submit button with aria-label |
382 |
| - 'button[aria-label*="continue"]', # Continue button |
383 |
| - 'form button', # Any button in form |
384 |
| - 'button' # Any button as last resort |
| 397 | + 'button[type="submit"]', # Primary - always works |
| 398 | + 'button[data-testid*="submit"]', # Fallback with testid |
| 399 | + 'form button' # Last resort - any form button |
385 | 400 | ]
|
386 | 401 |
|
387 | 402 | button_clicked = False
|
388 | 403 | for selector in submit_selectors:
|
389 | 404 | try:
|
390 |
| - print(f"Looking for submit button with selector: {selector}") |
391 | 405 | submit_button = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector)))
|
392 |
| - print(f"Found button with selector: {selector}") |
393 |
| - print(f"Button text: '{submit_button.text}'") |
394 |
| - print(f"Button HTML: {submit_button.get_attribute('outerHTML')[:200]}...") |
395 |
| - |
396 |
| - # Click the button |
397 | 406 | submit_button.click()
|
398 | 407 | print(f"Successfully clicked submit button with selector: {selector}")
|
399 | 408 | button_clicked = True
|
400 | 409 | break
|
401 | 410 | except Exception as e:
|
402 |
| - print(f"Selector {selector} failed: {e}") |
| 411 | + print(f"Submit button selector {selector} failed: {e}") |
403 | 412 | continue
|
404 | 413 |
|
405 | 414 | if not button_clicked:
|
@@ -449,20 +458,14 @@ def login():
|
449 | 458 |
|
450 | 459 | # Try multiple selectors for OTP input field
|
451 | 460 | otp_selectors = [
|
452 |
| - 'input[data-testid="passwordless_passcode__TextInput--0__input"]', # Original |
453 |
| - 'input[placeholder*="verification"]', # By placeholder text |
454 |
| - 'input[type="text"][maxlength="6"]', # By input type and length |
455 |
| - 'input[autocomplete="one-time-code"]', # By autocomplete attribute |
456 |
| - '.otp-input input', # By class |
457 |
| - 'input[data-testid*="passcode"]', # Partial testid match |
458 |
| - 'input[name*="otp"]', # By name attribute |
459 |
| - 'input[id*="otp"]' # By id attribute |
| 461 | + 'input[data-testid="passwordless_passcode__TextInput--0__input"]', # Primary - always works |
| 462 | + 'input[data-testid*="passcode"]', # Fallback - partial testid match |
| 463 | + 'input[type="text"][maxlength="6"]' # Last resort - by input characteristics |
460 | 464 | ]
|
461 | 465 |
|
462 | 466 | otp_field = None
|
463 | 467 | for selector in otp_selectors:
|
464 | 468 | try:
|
465 |
| - print(f"Trying OTP selector: {selector}") |
466 | 469 | otp_field = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, selector)))
|
467 | 470 | print(f"Found OTP field with selector: {selector}")
|
468 | 471 | break
|
|
0 commit comments