fix: CCA login — proper portal detection, robust field entry, input diagnostics
This commit is contained in:
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user