fix: UnitedSCO status always inactive and missing patient name

This commit is contained in:
Gitead
2026-04-18 09:25:02 -04:00
parent c8cb649e25
commit 5d1275d628

View File

@@ -158,6 +158,21 @@ class AutomationUnitedSCOEligibilityCheck:
if "b2clogin.com" in current_url or "login" in current_url.lower(): if "b2clogin.com" in current_url or "login" in current_url.lower():
print("[UnitedSCO login] On B2C login page - filling credentials") print("[UnitedSCO login] On B2C login page - filling credentials")
# Check if we're already on the phone verification ("Text Me") page
# This happens if the browser session was left on this page
try:
send_code_btn = self.driver.find_element(By.XPATH,
"//button[@id='sendCode'] | //input[@id='sendCode'] | "
"//button[contains(text(),'Text Me') or contains(text(),'Send Code')]"
)
if send_code_btn.is_displayed():
print("[UnitedSCO login] Already on phone verification page - clicking 'Text Me'")
self.driver.execute_script("arguments[0].click();", send_code_btn)
time.sleep(3)
return "OTP_REQUIRED"
except Exception:
pass
try: try:
# Find email field by id="signInName" (Azure B2C specific) # Find email field by id="signInName" (Azure B2C specific)
email_field = WebDriverWait(self.driver, 10).until( email_field = WebDriverWait(self.driver, 10).until(
@@ -231,7 +246,49 @@ class AutomationUnitedSCOEligibilityCheck:
# Click Continue # Click Continue
continue_btn.click() continue_btn.click()
print("[UnitedSCO login] Clicked 'Continue' on MFA selection page") print("[UnitedSCO login] Clicked 'Continue' on MFA selection page")
time.sleep(5) # Wait for OTP to be sent time.sleep(3) # Wait for phone verification page to load
# Click "Text Me" button on the phone verification page
# Azure B2C uses id="sendCode" for this button
try:
text_me_btn = WebDriverWait(self.driver, 8).until(
EC.element_to_be_clickable((By.XPATH,
"//button[@id='sendCode'] | "
"//input[@id='sendCode'] | "
"//button[contains(text(),'Text Me') or contains(text(),'Send Code') or contains(text(),'Send me')] | "
"//input[@value='Text Me' or @value='Send Code' or @value='Send me']"
))
)
self.driver.execute_script("arguments[0].scrollIntoView({block:'center'});", text_me_btn)
time.sleep(0.5)
text_me_btn.click()
print("[UnitedSCO login] Clicked 'Text Me' / 'Send Code' button")
time.sleep(3) # Wait for SMS to be sent
except TimeoutException:
print("[UnitedSCO login] No 'Text Me' button found - trying JS fallback")
try:
clicked = self.driver.execute_script("""
var btn = document.getElementById('sendCode');
if (btn) { btn.click(); return 'sendCode clicked'; }
var all = document.querySelectorAll('button, input[type="button"], input[type="submit"]');
for (var i = 0; i < all.length; i++) {
var t = (all[i].textContent || all[i].value || '').toLowerCase();
if (t.includes('text me') || t.includes('send code') || t.includes('send me')) {
all[i].click();
return 'clicked: ' + t;
}
}
return null;
""")
if clicked:
print(f"[UnitedSCO login] JS 'Text Me' click result: {clicked}")
time.sleep(3)
else:
print("[UnitedSCO login] WARNING: Could not find 'Text Me' button via JS either")
except Exception as js_err:
print(f"[UnitedSCO login] JS click error: {js_err}")
except Exception as e:
print(f"[UnitedSCO login] Error clicking 'Text Me': {e}")
except Exception: except Exception:
pass # No MFA selection page - proceed normally pass # No MFA selection page - proceed normally
@@ -784,26 +841,45 @@ class AutomationUnitedSCOEligibilityCheck:
patientName = f"{self.firstName} {self.lastName}".strip() patientName = f"{self.firstName} {self.lastName}".strip()
foundMemberId = self.memberId # Use provided memberId as default foundMemberId = self.memberId # Use provided memberId as default
# Extract eligibility status # Extract eligibility status — try multiple text patterns
try: try:
status_elem = WebDriverWait(self.driver, 10).until( status_elem = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, EC.presence_of_element_located((By.XPATH,
"//*[contains(text(),'Member Eligible') or contains(text(),'member eligible')]" "//*[contains(text(),'Member Eligible') or contains(text(),'member eligible') or "
"contains(text(),'Eligible') or contains(text(),'eligible') or "
"contains(text(),'Ineligible') or contains(text(),'ineligible') or "
"contains(text(),'Not Eligible') or contains(text(),'not eligible')]"
)) ))
) )
status_text = status_elem.text.strip().lower() status_text = status_elem.text.strip().lower()
print(f"[UnitedSCO step2] Found status: {status_text}") print(f"[UnitedSCO step2] Found status element text: {status_text}")
if "eligible" in status_text: if "ineligible" in status_text or "not eligible" in status_text:
eligibilityText = "active"
elif "ineligible" in status_text or "not eligible" in status_text:
eligibilityText = "inactive" eligibilityText = "inactive"
elif "eligible" in status_text:
eligibilityText = "active"
except TimeoutException: except TimeoutException:
print("[UnitedSCO step2] Eligibility status badge not found") print("[UnitedSCO step2] Eligibility status element not found via text — trying page text scan")
except Exception as e: except Exception as e:
print(f"[UnitedSCO step2] Error extracting status: {e}") print(f"[UnitedSCO step2] Error extracting status: {e}")
# Fallback: scan page text for eligibility keywords
if eligibilityText == "unknown":
try:
body_text = self.driver.find_element(By.TAG_NAME, "body").text.lower()
if "member eligible" in body_text or "member is eligible" in body_text:
eligibilityText = "active"
print("[UnitedSCO step2] Status from page text: active (member eligible)")
elif "not eligible" in body_text or "ineligible" in body_text or "member ineligible" in body_text:
eligibilityText = "inactive"
print("[UnitedSCO step2] Status from page text: inactive")
elif "eligible" in body_text:
eligibilityText = "active"
print("[UnitedSCO step2] Status from page text: active (eligible found)")
except Exception as e:
print(f"[UnitedSCO step2] Page text status scan error: {e}")
print(f"[UnitedSCO step2] Eligibility status: {eligibilityText}") print(f"[UnitedSCO step2] Eligibility status: {eligibilityText}")
# Extract patient name from the page # Extract patient name from the page
@@ -842,6 +918,10 @@ class AutomationUnitedSCOEligibilityCheck:
"//div[contains(@class,'patient')]//h3 | //div[contains(@class,'patient')]//h4", "//div[contains(@class,'patient')]//h3 | //div[contains(@class,'patient')]//h4",
"//*[contains(@class,'eligibility__banner')]//h3 | //*[contains(@class,'eligibility__banner')]//h4", "//*[contains(@class,'eligibility__banner')]//h3 | //*[contains(@class,'eligibility__banner')]//h4",
"//*[contains(@class,'banner__patient')]", "//*[contains(@class,'banner__patient')]",
# Heading elements near "Selected Patient" label
"//*[contains(text(),'Selected Patient')]/following-sibling::*[self::h1 or self::h2 or self::h3 or self::h4 or self::strong or self::p][1]",
"//*[contains(text(),'Selected Patient')]/..//*[self::h1 or self::h2 or self::h3 or self::h4 or self::strong][1]",
"//*[contains(text(),'Selected Patient')]/parent::*/following-sibling::*[1]//*[self::h3 or self::h4 or self::p or self::span][1]",
] ]
for sel in name_selectors: for sel in name_selectors:
try: try:
@@ -863,13 +943,16 @@ class AutomationUnitedSCOEligibilityCheck:
# IMPORTANT: Use [^\n] to avoid matching across newlines (e.g. picking up "Member Eligible") # IMPORTANT: Use [^\n] to avoid matching across newlines (e.g. picking up "Member Eligible")
if not name_extracted: if not name_extracted:
name_patterns = [ name_patterns = [
# Name on the line right after "Selected Patient" # Name on the line right after "Selected Patient" (on same or next line)
r'Selected Patient\s*\n\s*([A-Z][A-Za-z\-\']+(?: [A-Z][A-Za-z\-\']+)+)', r'Selected Patient[:\s]*\n\s*([A-Z][A-Za-z\-\']+(?: [A-Z][A-Za-z\-\']+)+)',
r'Selected Patient[:\s]+([A-Z][A-Za-z\-\']+(?: [A-Z][A-Za-z\-\']+)+)',
r'Patient Name\s*[\n:]\s*([A-Z][A-Za-z\-\']+(?: [A-Z][A-Za-z\-\']+)+)', r'Patient Name\s*[\n:]\s*([A-Z][A-Za-z\-\']+(?: [A-Z][A-Za-z\-\']+)+)',
# "LASTNAME, FIRSTNAME" format # "LASTNAME, FIRSTNAME" format
r'Selected Patient\s*\n\s*([A-Z][A-Za-z\-\']+,\s*[A-Z][A-Za-z\-\']+)', r'Selected Patient\s*\n\s*([A-Z][A-Za-z\-\']+,\s*[A-Z][A-Za-z\-\']+)',
# Name on the line right before "Member Eligible" or "Member ID" # Name on the line right before "Member Eligible", "Eligible", "Member ID", or "Date Of Birth"
r'\n([A-Z][A-Za-z\-\']+(?: [A-Z]\.?)? [A-Z][A-Za-z\-\']+)\n(?:Member|Date Of Birth|DOB)', r'\n([A-Z][A-Za-z\-\']+(?: [A-Z]\.?)? [A-Z][A-Za-z\-\']+)\n(?:Member|Eligible|Date Of Birth|DOB)',
# Name before DOB in any case
r'([A-Z][A-Za-z\-\']+(?:\s+[A-Z][A-Za-z\-\']+)+)\n\d{2}/\d{2}/\d{4}',
] ]
for pattern in name_patterns: for pattern in name_patterns:
try: try: