feat: United SCO claim worker rewrite + eligibility/patient-table fixes

- Rewrote UnitedDH claim worker to navigate via eligibility page → Selected Patient → Submit Claim button flow
- Updated helpers_uniteddh_claim.py step names to match new 9-step workflow
- Changed payer selection in both eligibility and claim workers to type + Enter
- Updated patient table column header from 'DOB / Gender' to 'DOB'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-05-30 14:46:51 -04:00
parent cda00f5f8a
commit 70f36fc13c
4 changed files with 541 additions and 434 deletions

View File

@@ -524,7 +524,7 @@ class AutomationUnitedSCOEligibilityCheck:
# Step 1.2: Select Payer - UnitedHealthcare Massachusetts
print("[UnitedSCO step1] Selecting Payer...")
# First dismiss any blocking dialogs (e.g. Chrome password save)
try:
self.driver.execute_script("""
@@ -534,12 +534,10 @@ class AutomationUnitedSCOEligibilityCheck:
""")
except Exception:
pass
payer_selected = False
# Strategy 1: Click the ng-select, type to search, and select the option
try:
# Find the Payer ng-select by multiple selectors
payer_selectors = [
"//label[contains(text(),'Payer')]/following-sibling::ng-select",
"//label[contains(text(),'Payer')]/..//ng-select",
@@ -554,101 +552,27 @@ class AutomationUnitedSCOEligibilityCheck:
break
except Exception:
continue
if payer_ng_select:
# Scroll to it and click to open
self.driver.execute_script("arguments[0].scrollIntoView({block:'center'});", payer_ng_select)
time.sleep(0.5)
payer_ng_select.click()
time.sleep(1)
# Type into the search input inside ng-select to filter options
try:
search_input = payer_ng_select.find_element(By.XPATH, ".//input[contains(@type,'text') or contains(@role,'combobox')]")
search_input.clear()
search_input.send_keys("UnitedHealthcare Massachusetts")
print("[UnitedSCO step1] Typed payer search text")
time.sleep(2)
except Exception:
# If no search input, try sending keys directly to ng-select
try:
ActionChains(self.driver).send_keys("UnitedHealthcare Mass").perform()
print("[UnitedSCO step1] Typed payer search via ActionChains")
time.sleep(2)
except Exception:
pass
# Find and click the matching option
payer_options = self.driver.find_elements(By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option')]"
)
for opt in payer_options:
opt_text = opt.text.strip()
if "UnitedHealthcare Massachusetts" in opt_text:
opt.click()
print(f"[UnitedSCO step1] Selected Payer: {opt_text}")
payer_selected = True
break
if not payer_selected and payer_options:
# Select first visible option if it contains "United"
for opt in payer_options:
opt_text = opt.text.strip()
if "United" in opt_text and opt.is_displayed():
opt.click()
print(f"[UnitedSCO step1] Selected first matching Payer: {opt_text}")
payer_selected = True
break
# Close dropdown
ActionChains(self.driver).send_keys(Keys.ESCAPE).perform()
search_input = payer_ng_select.find_element(By.XPATH,
".//input[contains(@type,'text') or contains(@role,'combobox')]")
search_input.clear()
search_input.send_keys("UnitedHealthcare Massachusetts")
print("[UnitedSCO step1] Typed payer search text")
time.sleep(2)
search_input.send_keys(Keys.ENTER)
print("[UnitedSCO step1] Pressed Enter to select Payer")
time.sleep(0.5)
payer_selected = True
else:
print("[UnitedSCO step1] Could not find Payer ng-select element")
except Exception as e:
print(f"[UnitedSCO step1] Payer selection strategy 1 error: {e}")
try:
ActionChains(self.driver).send_keys(Keys.ESCAPE).perform()
except Exception:
pass
# Strategy 2: JavaScript direct selection if strategy 1 failed
if not payer_selected:
try:
# Try clicking via JavaScript
clicked = self.driver.execute_script("""
// Find ng-select near the Payer label
var labels = document.querySelectorAll('label');
for (var i = 0; i < labels.length; i++) {
if (labels[i].textContent.includes('Payer')) {
var parent = labels[i].parentElement;
var ngSelect = parent.querySelector('ng-select') || labels[i].nextElementSibling;
if (ngSelect) {
ngSelect.click();
return true;
}
}
}
return false;
""")
if clicked:
time.sleep(1)
ActionChains(self.driver).send_keys("UnitedHealthcare Mass").perform()
time.sleep(2)
payer_options = self.driver.find_elements(By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option')]"
)
for opt in payer_options:
if "UnitedHealthcare" in opt.text and "Massachusetts" in opt.text:
opt.click()
print(f"[UnitedSCO step1] Selected Payer via JS: {opt.text.strip()}")
payer_selected = True
break
ActionChains(self.driver).send_keys(Keys.ESCAPE).perform()
except Exception as e:
print(f"[UnitedSCO step1] Payer selection strategy 2 error: {e}")
print(f"[UnitedSCO step1] Payer selection error: {e}")
if not payer_selected:
print("[UnitedSCO step1] WARNING: Could not select Payer - form may fail")
@@ -699,6 +623,10 @@ class AutomationUnitedSCOEligibilityCheck:
print("[UnitedSCO step1] Select Insurance modal closed")
except TimeoutException:
print("[UnitedSCO step1] Modal staleness timeout — continuing anyway")
# Wait for the Provider & Location page to begin rendering after modal closes
WebDriverWait(self.driver, 5).until(
EC.presence_of_element_located((By.XPATH, "//label[@for='treatmentLocation'] | //label[@for='paymentGroupId']"))
)
except TimeoutException:
print("[UnitedSCO step1] Select Insurance popup not found — proceeding")
@@ -721,17 +649,15 @@ class AutomationUnitedSCOEligibilityCheck:
"//label[@for='treatmentLocation']/..//ng-select"
))
)
self.driver.execute_script("arguments[0].scrollIntoView({block:'end'});", location_ng)
arrow = location_ng.find_element(By.XPATH, ".//span[contains(@class,'ng-arrow-wrapper')]")
ActionChains(self.driver).move_to_element(arrow).click().perform()
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//ng-dropdown-panel"))
)
first_option = self.driver.find_element(By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option') and not(contains(@class,'disabled'))]"
# Center in viewport so panel opens downward instead of upward
self.driver.execute_script("arguments[0].scrollIntoView({block:'center'});", location_ng)
arrow = location_ng.find_element(By.CSS_SELECTOR, ".ng-arrow-wrapper")
arrow.click()
first_option = WebDriverWait(self.driver, 5).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, ".ng-dropdown-panel .ng-option"))
)
option_text = first_option.text.strip()
ActionChains(self.driver).send_keys(Keys.ARROW_DOWN).send_keys(Keys.ENTER).perform()
first_option.click()
print(f"[UnitedSCO step1] Selected Treatment Location: {option_text}")
location_selected = True
except Exception as e:
@@ -750,17 +676,15 @@ class AutomationUnitedSCOEligibilityCheck:
"//label[@for='paymentGroupId']/..//ng-select"
))
)
self.driver.execute_script("arguments[0].scrollIntoView({block:'end'});", billing_ng)
arrow = billing_ng.find_element(By.XPATH, ".//span[contains(@class,'ng-arrow-wrapper')]")
ActionChains(self.driver).move_to_element(arrow).click().perform()
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//ng-dropdown-panel"))
)
first_option = self.driver.find_element(By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option') and not(contains(@class,'disabled'))]"
# Center in viewport so panel opens downward instead of upward
self.driver.execute_script("arguments[0].scrollIntoView({block:'center'});", billing_ng)
arrow = billing_ng.find_element(By.CSS_SELECTOR, ".ng-arrow-wrapper")
arrow.click()
first_option = WebDriverWait(self.driver, 5).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, ".ng-dropdown-panel .ng-option"))
)
option_text = first_option.text.strip()
ActionChains(self.driver).send_keys(Keys.ARROW_DOWN).send_keys(Keys.ENTER).perform()
first_option.click()
print(f"[UnitedSCO step1] Selected Billing Entity: {option_text}")
billing_selected = True
except Exception as e: