implement wait_for_xpath function to enhance XPath handling in interactions_service, ensuring proper validation and timeout management
Build and Push Docker Images / build-and-push (push) Successful in 22s

This commit is contained in:
2026-04-29 16:29:52 +02:00
parent be4719fe01
commit 9aa863f42d
+30 -4
View File
@@ -307,6 +307,27 @@ async def interactions_service(
if not action:
raise ValueError("Interaction must contain an action")
async def wait_for_xpath(xp: str, timeout_ms: int = 30000) -> None:
# Accept both raw XPath ("//div") and Playwright-style ("xpath=//div").
normalized = xp[len("xpath=") :] if xp.startswith("xpath=") else xp
await page.wait_for_function(
"""(xpath) => {
try {
return !!document.evaluate(
xpath,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue;
} catch (e) {
return false;
}
}""",
normalized,
timeout=timeout_ms,
)
# Prefer selector-based interactions when selectors are provided (CSS first, then XPath).
if selector or xpath_selector:
if action == "click":
@@ -322,7 +343,9 @@ async def interactions_service(
selector,
)
else:
await page.wait_for_selector(f"xpath={xpath_selector}", timeout=30000)
if not xpath_selector:
raise ValueError("xpath_selector must be a non-empty string")
await wait_for_xpath(xpath_selector, timeout_ms=30000)
await page.evaluate(
"""(xpath) => {
const el = document.evaluate(
@@ -335,7 +358,7 @@ async def interactions_service(
if (!el) throw new Error(`No element for xpath: ${xpath}`);
el.click();
}""",
xpath_selector,
xpath_selector[len("xpath=") :] if xpath_selector.startswith("xpath=") else xpath_selector,
)
elif action == "type":
@@ -358,7 +381,10 @@ async def interactions_service(
{"sel": selector, "value": text},
)
else:
await page.wait_for_selector(f"xpath={xpath_selector}", timeout=30000)
if not xpath_selector:
raise ValueError("xpath_selector must be a non-empty string")
await wait_for_xpath(xpath_selector, timeout_ms=30000)
normalized_xpath = xpath_selector[len("xpath=") :] if xpath_selector.startswith("xpath=") else xpath_selector
await page.evaluate(
"""({ xpath, value }) => {
const el = document.evaluate(
@@ -376,7 +402,7 @@ async def interactions_service(
el.dispatchEvent(new Event('change', { bubbles: true }));
}
}""",
{"xpath": xpath_selector, "value": text},
{"xpath": normalized_xpath, "value": text},
)
else: