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
Build and Push Docker Images / build-and-push (push) Successful in 22s
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user