fix: CCA login — proper portal detection, robust field entry, input diagnostics

This commit is contained in:
Gitead
2026-04-18 09:15:13 -04:00
parent 4505d5db85
commit c8cb649e25

View File

@@ -77,6 +77,28 @@ class AutomationCCAEligibilityCheck:
except Exception:
return False
def _set_input_value(self, field, value: str):
"""Set input value in a way that triggers React/Vue/Angular framework state updates."""
try:
self.driver.execute_script(
"""
var el = arguments[0];
var val = arguments[1];
var nativeSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype, 'value').set;
nativeSetter.call(el, val);
el.dispatchEvent(new Event('input', {bubbles: true}));
el.dispatchEvent(new Event('change', {bubbles: true}));
""",
field, value
)
except Exception:
# Fallback to regular send_keys if JS fails
field.click()
field.send_keys(Keys.CONTROL + "a")
field.send_keys(Keys.DELETE)
field.send_keys(value)
def login(self, url):
"""
Login to ScionDental portal for CCA.
@@ -124,59 +146,96 @@ class AutomationCCAEligibilityCheck:
# Session expired — navigate to login URL
print("[CCA login] Session not valid, navigating to login page...")
self.driver.get(url)
time.sleep(2)
# Wait up to 15s for ANY input to appear, then snapshot the page
try:
WebDriverWait(self.driver, 15).until(
EC.presence_of_element_located((By.XPATH, "//input"))
)
except TimeoutException:
pass
time.sleep(1)
current_url = self.driver.current_url
print(f"[CCA login] After login nav URL: {current_url}")
# Enter username
# Dump all inputs so we can see what's on the page
try:
all_inputs = self.driver.find_elements(By.XPATH, "//input")
print(f"[CCA login] Found {len(all_inputs)} input(s) on page:")
for inp in all_inputs:
try:
print(f" input: type={inp.get_attribute('type')!r} "
f"id={inp.get_attribute('id')!r} "
f"name={inp.get_attribute('name')!r} "
f"visible={inp.is_displayed()}")
except Exception:
pass
except Exception as e:
print(f"[CCA login] Could not enumerate inputs: {e}")
# Enter username — click first to ensure focus, then type
print("[CCA login] Looking for username field...")
username_entered = False
username_field = None
for sel in [
(By.ID, "Username"),
(By.NAME, "Username"),
(By.XPATH, "//input[@type='text']"),
(By.XPATH, "//input[@type='email']"),
]:
try:
field = WebDriverWait(self.driver, 6).until(
EC.presence_of_element_located(sel))
if field.is_displayed():
field.clear()
field.send_keys(self.cca_username)
username_entered = True
print(f"[CCA login] Username entered via {sel}")
break
EC.element_to_be_clickable(sel))
username_field = field
print(f"[CCA login] Found username field via {sel}")
break
except Exception:
continue
if not username_entered:
if not username_field:
if self._page_has_logged_in_content():
return "ALREADY_LOGGED_IN"
return "ERROR: Could not find username field"
username_field.click()
username_field.send_keys(Keys.CONTROL + "a")
username_field.send_keys(Keys.DELETE)
username_field.send_keys(self.cca_username)
time.sleep(0.3)
actual_val = username_field.get_attribute("value")
print(f"[CCA login] Username field value after entry: {actual_val!r}")
time.sleep(0.5)
# Enter password
print("[CCA login] Looking for password field...")
pw_entered = False
pw_field = None
for sel in [
(By.ID, "Password"),
(By.NAME, "Password"),
(By.XPATH, "//input[@type='password']"),
]:
try:
field = self.driver.find_element(*sel)
if field.is_displayed():
field.clear()
field.send_keys(self.cca_password)
pw_entered = True
print(f"[CCA login] Password entered via {sel}")
break
field = WebDriverWait(self.driver, 6).until(
EC.element_to_be_clickable(sel))
pw_field = field
print(f"[CCA login] Found password field via {sel}")
break
except Exception:
continue
if not pw_entered:
if not pw_field:
return "ERROR: Password field not found"
# Click login button
pw_field.click()
pw_field.send_keys(Keys.CONTROL + "a")
pw_field.send_keys(Keys.DELETE)
pw_field.send_keys(self.cca_password)
time.sleep(0.3)
print(f"[CCA login] Password field value length after entry: {len(pw_field.get_attribute('value') or '')}")
# Submit — try button click, fall back to Enter key
submitted = False
for sel in [
(By.XPATH, "//button[@type='submit']"),
(By.XPATH, "//input[@type='submit']"),
@@ -187,45 +246,43 @@ class AutomationCCAEligibilityCheck:
btn = self.driver.find_element(*sel)
if btn.is_displayed():
btn.click()
submitted = True
print(f"[CCA login] Clicked login button via {sel}")
break
except Exception:
continue
if not submitted:
print("[CCA login] No submit button found — pressing Enter on password field")
pw_field.send_keys(Keys.RETURN)
if self.cca_username:
browser_manager.save_credentials_hash(self.cca_username)
# Wait for page to load after login
# Wait for actual portal content — NOT just URL (login page URL also contains "Landing")
try:
WebDriverWait(self.driver, 15).until(
lambda d: "Landing" in d.current_url
or "Dental" in d.current_url
or "Home" in d.current_url
WebDriverWait(self.driver, 20).until(
lambda d: any(x in d.find_element(By.TAG_NAME, "body").text
for x in ["Verify Patient Eligibility", "Patient Management",
"Submit a Claim", "Claim Inquiry"])
)
print("[CCA login] Redirected to portal page")
current_url = self.driver.current_url
print(f"[CCA login] Portal content detected — login successful. URL: {current_url}")
return "SUCCESS"
except TimeoutException:
time.sleep(3)
pass
current_url = self.driver.current_url
print(f"[CCA login] After login submit URL: {current_url}")
# Check for login errors
# Login did not succeed — dump page text for diagnosis
try:
body_text = self.driver.find_element(By.TAG_NAME, "body").text
print(f"[CCA login] Page text after submit (first 600): {body_text[:600]}")
if "invalid" in body_text.lower() and ("password" in body_text.lower() or "username" in body_text.lower()):
return "ERROR: Invalid username or password"
except Exception:
pass
if self._page_has_logged_in_content():
print("[CCA login] Login successful")
return "SUCCESS"
if "Landing" in current_url or "Home" in current_url or "Dental" in current_url:
return "SUCCESS"
# Check for errors
try:
errors = self.driver.find_elements(By.XPATH,
"//*[contains(@class,'error') or contains(@class,'alert-danger') or contains(@class,'validation-summary')]")
for err in errors:
@@ -234,8 +291,7 @@ class AutomationCCAEligibilityCheck:
except Exception:
pass
print("[CCA login] Login completed (assuming success)")
return "SUCCESS"
return "ERROR: Login did not succeed — portal content not found after submit"
except Exception as e:
print(f"[CCA login] Exception: {e}")