Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.17.3] - 2026-07-06

### Fixed

- `eflyt_case.approve_case` now waits around the ASP.NET postbacks (removing a
`StaleElementReferenceException`) and can resume a half-approved case where the anmeldelse is
already approved and only the persons remain (removing an `ElementNotInteractableException`).

## [2.17.2] - 2026-06-29

### Fixed
Expand Down Expand Up @@ -294,6 +302,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial release

[2.17.3]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.17.3
[2.17.2]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.17.2
[2.17.1]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.17.1
[2.17.0]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.17.0
[2.16.2]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.16.2
Expand Down
53 changes: 36 additions & 17 deletions itk_dev_shared_components/eflyt/eflyt_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

WAIT_TIMEOUT = 10 # Seconds to wait for ASP.NET postbacks in approve_case.


@dataclass
Expand Down Expand Up @@ -131,33 +136,47 @@ def change_tab(browser: webdriver.Chrome, tab_index: int):


def approve_case(browser: webdriver.Chrome):
"""Approve a case.
If any person on the case is blocking approval, approve each person individually.
"""Approve a case, including cases where the anmeldelse is already approved and only the
persons remain. Uses waits around the ASP.NET postbacks to avoid stale/not-interactable
races. If any person on the case is blocking approval, approve each person individually.
"""
change_tab(browser, 0)

deadline_field = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_ncPersonTab_txtDeadline")
deadline_field.clear()
note_field = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_ncPersonTab_txtDeadlineNote")
note_field.clear()

browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnGodkend").click()
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnApproveYes").click()

approve_persons_button = browser.find_elements(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnGodkendAlle")
if any(approve_persons_button) and approve_persons_button[0].is_enabled():
approve_persons_button[0].click()
else:
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_ncPersonTab_txtDeadline").clear()
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_ncPersonTab_txtDeadlineNote").clear()

# 1. Approve the anmeldelse only if that step is available (skip if already approved).
godkend = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnGodkend")
if godkend.is_enabled():
godkend.click()
# 2. Confirm OK only if the confirmation dialog actually appears.
try:
WebDriverWait(browser, WAIT_TIMEOUT).until(
EC.element_to_be_clickable((By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnApproveYes"))
).click()
except TimeoutException:
pass

# 3. Approve the persons; clickability decides bulk vs per-person and waits out the
# postback (no is_enabled() on a stale element).
try:
WebDriverWait(browser, WAIT_TIMEOUT).until(
EC.element_to_be_clickable((By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnGodkendAlle"))
).click()
except TimeoutException:
# Approve each person individually
person_count = len(browser.find_elements(By.XPATH, '//table[@id="ctl00_ContentPlaceHolder2_GridViewMovingPersons"]//tr')) - 1

for i in range(person_count):
browser.find_element(By.XPATH, f'//table[@id="ctl00_ContentPlaceHolder2_GridViewMovingPersons"]//tr[{i+2}]//td[2]').click()

browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnGodkend").click()
approve_button = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnApproveYes")
if approve_button.is_displayed():
approve_button.click()
try:
WebDriverWait(browser, WAIT_TIMEOUT).until(
EC.element_to_be_clickable((By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_stcPersonTab1_btnApproveYes"))
).click()
except TimeoutException:
pass

# Go back to the case
browser.find_element(By.XPATH, '//table[@id="ctl00_ContentPlaceHolder2_GridViewMovingPersons"]//tr[1]//td[2]').click()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "itk_dev_shared_components"
version = "2.17.2"
version = "2.17.3"
authors = [
{ name="ITK Development", email="itk-rpa@mkb.aarhus.dk" },
]
Expand Down
Loading