From 8cbdba092d35b65db6c384db2f5d59cf6d45f7d5 Mon Sep 17 00:00:00 2001 From: Gitead Date: Tue, 15 Sep 2026 23:23:48 -0400 Subject: [PATCH] fix: handle no-history single-match case in United Ucard claim search Only two paths now: click the radio in the last history row when a table is shown, or click the Member Details link directly when no history/radio appears at all (single unambiguous match, as seen for patient Nassim). Removes the first-row retry fallback. Co-Authored-By: Claude Sonnet 5 --- .../selenium_UnitedUcard_claimSubmitWorker.py | 129 +++++++++--------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/apps/SeleniumService/selenium_UnitedUcard_claimSubmitWorker.py b/apps/SeleniumService/selenium_UnitedUcard_claimSubmitWorker.py index 3f39c939..2105e1f8 100644 --- a/apps/SeleniumService/selenium_UnitedUcard_claimSubmitWorker.py +++ b/apps/SeleniumService/selenium_UnitedUcard_claimSubmitWorker.py @@ -431,79 +431,55 @@ class AutomationUnitedUcardClaimSubmit: def _select_search_result(self): """ - When the Subscriber ID + DOB search matches multiple coverage records - ("Duplicate records have been found"), select the LAST row in the - results table (the default/most-recent coverage record) and click - SELECT. If the "Member Details" name link doesn't show up afterward - (the last row turned out to be an inactive coverage record — seen - for some providers' patients, e.g. provider "JOHN"), fall back to - selecting the FIRST row instead and click SELECT again. + After the Subscriber ID + DOB search, the site does one of two things: - Confirmed against the live site (2026-09-13): a results table with - columns Name / Group / Coverage End Date / Address, a radio button - in the first cell of each row, and CANCEL / SELECT pill buttons - below the table. + 1. Multiple coverage records exist ("Duplicate records have been + found") — a results table appears with a radio button in each + row (Name / Group / Coverage End Date / Address columns) and + CANCEL / SELECT pill buttons below it. Select the LAST row (the + default/most-recent coverage record) and click SELECT. + 2. A single unambiguous match — no insurance history table and no + radio at all; the page goes straight to a "Member Details" + table with the patient's name as a link (confirmed live for + patient Nassim, 2026-09-15). + + Either path ends by clicking the "Member Details" name link, which + replaces the table with a confirmation card and enables the bottom + "Next" button. """ try: result_rows = WebDriverWait(self.driver, 15).until( - lambda d: d.find_elements(By.CSS_SELECTOR, "table tbody tr") or None + lambda d: [r for r in d.find_elements(By.CSS_SELECTOR, "table tbody tr") + if r.find_elements(By.CSS_SELECTOR, "input[type='radio']")] or None ) except TimeoutException: - # A single unambiguous match may skip the results table entirely - # and advance straight to Claim Information. - try: - WebDriverWait(self.driver, 5).until( - EC.presence_of_element_located((By.XPATH, "//*[contains(text(),'Claim Information')]")) - ) - print("[UnitedUcard Claim] Single match — already advanced to Claim Information") - return True - except TimeoutException: - return "ERROR: No search results table found after Search" + result_rows = None - if not result_rows: - return "ERROR: No matching patient records found" + if result_rows: + result = self._select_last_row_and_click_select(len(result_rows)) + if result is not True: + return result # propagate a hard ERROR (radio/select button not found) + else: + print("[UnitedUcard Claim] No insurance history/radio shown — single unambiguous match") - total_rows = len(result_rows) - result = self._select_row_and_wait_for_member_link(-1, "last", total_rows, member_link_timeout=8) + result = self._click_member_link_or_advance() if result is True: return self._click_next("Patient Information step") - - if result != "NO_MEMBER_LINK": - return result # propagate a hard ERROR (radio/select button not found) - - if total_rows < 2: - return "ERROR: Member Details link not found after selecting last row" - - print("[UnitedUcard Claim] Last row showed no active member — retrying with first row") - try: - WebDriverWait(self.driver, 10).until( - lambda d: d.find_elements(By.CSS_SELECTOR, "table tbody tr") or None - ) - except TimeoutException: - return "ERROR: Results table no longer available to retry with first row" - - result = self._select_row_and_wait_for_member_link(0, "first", total_rows, member_link_timeout=15) - if result is True: - return self._click_next("Patient Information step") - if result == "NO_MEMBER_LINK": - return "ERROR: Member Details link not found after selecting either the last or first row" return result - def _select_row_and_wait_for_member_link(self, row_index, row_label, total_rows, member_link_timeout): + def _select_last_row_and_click_select(self, total_rows): """ - Clicks the radio button in the row at `row_index` (re-located fresh, - since a prior failed SELECT may have altered the DOM), clicks SELECT, - then waits up to `member_link_timeout` seconds for the "Member - Details" name link to appear. + Clicks the radio button in the LAST row of the insurance history + table, then clicks SELECT. - Returns True (link found & clicked), "NO_MEMBER_LINK" (link never - appeared — likely an inactive record), or an "ERROR: ..." string for - a hard failure (radio/select button not found). + Returns True, or an "ERROR: ..." string for a hard failure. """ try: - row = self.driver.find_elements(By.CSS_SELECTOR, "table tbody tr")[row_index] + rows = [r for r in self.driver.find_elements(By.CSS_SELECTOR, "table tbody tr") + if r.find_elements(By.CSS_SELECTOR, "input[type='radio']")] + row = rows[-1] except IndexError: - return f"ERROR: Could not re-locate {row_label} search result row" + return "ERROR: Could not re-locate last search result row" try: radio = row.find_element(By.CSS_SELECTOR, "input[type='radio']") @@ -511,7 +487,7 @@ class AutomationUnitedUcardClaimSubmit: try: radio = row.find_element(By.XPATH, ".//*[@role='radio' or contains(@class,'radio')]") except Exception as e: - return f"ERROR: Could not find radio button in {row_label} search result row: {e}" + return f"ERROR: Could not find radio button in last search result row: {e}" self.driver.execute_script("arguments[0].scrollIntoView({block:'center'});", radio) time.sleep(0.3) @@ -519,7 +495,7 @@ class AutomationUnitedUcardClaimSubmit: radio.click() except Exception: self.driver.execute_script("arguments[0].click();", radio) - print(f"[UnitedUcard Claim] Selected {row_label} matching patient record ({total_rows} found)") + print(f"[UnitedUcard Claim] Selected last matching patient record ({total_rows} found)") # Confirmed against the live site (2026-09-13): #