fix: CCA login — proper portal detection, robust field entry, input diagnostics
This commit is contained in:
@@ -77,6 +77,28 @@ class AutomationCCAEligibilityCheck:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return False
|
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):
|
def login(self, url):
|
||||||
"""
|
"""
|
||||||
Login to ScionDental portal for CCA.
|
Login to ScionDental portal for CCA.
|
||||||
@@ -124,59 +146,96 @@ class AutomationCCAEligibilityCheck:
|
|||||||
# Session expired — navigate to login URL
|
# Session expired — navigate to login URL
|
||||||
print("[CCA login] Session not valid, navigating to login page...")
|
print("[CCA login] Session not valid, navigating to login page...")
|
||||||
self.driver.get(url)
|
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
|
current_url = self.driver.current_url
|
||||||
print(f"[CCA login] After login nav URL: {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...")
|
print("[CCA login] Looking for username field...")
|
||||||
username_entered = False
|
username_field = None
|
||||||
for sel in [
|
for sel in [
|
||||||
(By.ID, "Username"),
|
(By.ID, "Username"),
|
||||||
(By.NAME, "Username"),
|
(By.NAME, "Username"),
|
||||||
(By.XPATH, "//input[@type='text']"),
|
(By.XPATH, "//input[@type='text']"),
|
||||||
|
(By.XPATH, "//input[@type='email']"),
|
||||||
]:
|
]:
|
||||||
try:
|
try:
|
||||||
field = WebDriverWait(self.driver, 6).until(
|
field = WebDriverWait(self.driver, 6).until(
|
||||||
EC.presence_of_element_located(sel))
|
EC.element_to_be_clickable(sel))
|
||||||
if field.is_displayed():
|
username_field = field
|
||||||
field.clear()
|
print(f"[CCA login] Found username field via {sel}")
|
||||||
field.send_keys(self.cca_username)
|
break
|
||||||
username_entered = True
|
|
||||||
print(f"[CCA login] Username entered via {sel}")
|
|
||||||
break
|
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not username_entered:
|
if not username_field:
|
||||||
if self._page_has_logged_in_content():
|
if self._page_has_logged_in_content():
|
||||||
return "ALREADY_LOGGED_IN"
|
return "ALREADY_LOGGED_IN"
|
||||||
return "ERROR: Could not find username field"
|
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
|
# Enter password
|
||||||
print("[CCA login] Looking for password field...")
|
print("[CCA login] Looking for password field...")
|
||||||
pw_entered = False
|
pw_field = None
|
||||||
for sel in [
|
for sel in [
|
||||||
(By.ID, "Password"),
|
(By.ID, "Password"),
|
||||||
(By.NAME, "Password"),
|
(By.NAME, "Password"),
|
||||||
(By.XPATH, "//input[@type='password']"),
|
(By.XPATH, "//input[@type='password']"),
|
||||||
]:
|
]:
|
||||||
try:
|
try:
|
||||||
field = self.driver.find_element(*sel)
|
field = WebDriverWait(self.driver, 6).until(
|
||||||
if field.is_displayed():
|
EC.element_to_be_clickable(sel))
|
||||||
field.clear()
|
pw_field = field
|
||||||
field.send_keys(self.cca_password)
|
print(f"[CCA login] Found password field via {sel}")
|
||||||
pw_entered = True
|
break
|
||||||
print(f"[CCA login] Password entered via {sel}")
|
|
||||||
break
|
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not pw_entered:
|
if not pw_field:
|
||||||
return "ERROR: Password field not found"
|
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 [
|
for sel in [
|
||||||
(By.XPATH, "//button[@type='submit']"),
|
(By.XPATH, "//button[@type='submit']"),
|
||||||
(By.XPATH, "//input[@type='submit']"),
|
(By.XPATH, "//input[@type='submit']"),
|
||||||
@@ -187,45 +246,43 @@ class AutomationCCAEligibilityCheck:
|
|||||||
btn = self.driver.find_element(*sel)
|
btn = self.driver.find_element(*sel)
|
||||||
if btn.is_displayed():
|
if btn.is_displayed():
|
||||||
btn.click()
|
btn.click()
|
||||||
|
submitted = True
|
||||||
print(f"[CCA login] Clicked login button via {sel}")
|
print(f"[CCA login] Clicked login button via {sel}")
|
||||||
break
|
break
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
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:
|
if self.cca_username:
|
||||||
browser_manager.save_credentials_hash(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:
|
try:
|
||||||
WebDriverWait(self.driver, 15).until(
|
WebDriverWait(self.driver, 20).until(
|
||||||
lambda d: "Landing" in d.current_url
|
lambda d: any(x in d.find_element(By.TAG_NAME, "body").text
|
||||||
or "Dental" in d.current_url
|
for x in ["Verify Patient Eligibility", "Patient Management",
|
||||||
or "Home" in d.current_url
|
"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:
|
except TimeoutException:
|
||||||
time.sleep(3)
|
pass
|
||||||
|
|
||||||
current_url = self.driver.current_url
|
current_url = self.driver.current_url
|
||||||
print(f"[CCA login] After login submit URL: {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:
|
try:
|
||||||
body_text = self.driver.find_element(By.TAG_NAME, "body").text
|
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()):
|
if "invalid" in body_text.lower() and ("password" in body_text.lower() or "username" in body_text.lower()):
|
||||||
return "ERROR: Invalid username or password"
|
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,
|
errors = self.driver.find_elements(By.XPATH,
|
||||||
"//*[contains(@class,'error') or contains(@class,'alert-danger') or contains(@class,'validation-summary')]")
|
"//*[contains(@class,'error') or contains(@class,'alert-danger') or contains(@class,'validation-summary')]")
|
||||||
for err in errors:
|
for err in errors:
|
||||||
@@ -234,8 +291,7 @@ class AutomationCCAEligibilityCheck:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print("[CCA login] Login completed (assuming success)")
|
return "ERROR: Login did not succeed — portal content not found after submit"
|
||||||
return "SUCCESS"
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[CCA login] Exception: {e}")
|
print(f"[CCA login] Exception: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user