This commit is contained in:
@@ -188,6 +188,12 @@ async def interactions_service(
|
||||
|
||||
async def interactions_operation(page):
|
||||
try:
|
||||
# When the API caller sets viewport.height = -1, treat that as "capture full webpage".
|
||||
# We implement this by resizing the viewport to the document's scroll height just
|
||||
# before the final screenshot. (This keeps existing coordinate-click behavior intact.)
|
||||
full_page_via_viewport = False
|
||||
requested_viewport_width = None
|
||||
|
||||
async def resolve_viewport_point(px: int, py: int) -> tuple[float, float]:
|
||||
"""
|
||||
Playwright's `document.elementFromPoint(x, y)` uses viewport coordinates.
|
||||
@@ -251,8 +257,15 @@ async def interactions_service(
|
||||
vp_width = getattr(viewport, "width", None)
|
||||
vp_height = getattr(viewport, "height", None)
|
||||
|
||||
requested_viewport_width = vp_width
|
||||
if vp_width and vp_height:
|
||||
await page.set_viewport_size({"width": vp_width, "height": vp_height})
|
||||
if int(vp_height) == -1:
|
||||
# Defer height calculation until after navigation/interactions.
|
||||
full_page_via_viewport = True
|
||||
vp_size = page.viewport_size or {"width": 1280, "height": 720}
|
||||
await page.set_viewport_size({"width": int(vp_width), "height": int(vp_size.get("height", 720))})
|
||||
else:
|
||||
await page.set_viewport_size({"width": int(vp_width), "height": int(vp_height)})
|
||||
except Exception as e:
|
||||
print(f"Error setting viewport: {e}")
|
||||
|
||||
@@ -405,7 +418,30 @@ async def interactions_service(
|
||||
if return_type == "html":
|
||||
return await page.content()
|
||||
|
||||
# For coordinate-based workflows, return the viewport screenshot so pixel coords align.
|
||||
if full_page_via_viewport:
|
||||
try:
|
||||
# Chromium has practical limits on viewport height; cap to avoid errors.
|
||||
max_vp_h = 16384
|
||||
|
||||
# Ensure we capture from the top of the document.
|
||||
await page.evaluate("() => window.scrollTo({ left: 0, top: 0, behavior: 'auto' })")
|
||||
await page.wait_for_timeout(250)
|
||||
|
||||
full_h = await page.evaluate(
|
||||
"() => Math.max(document.body?.scrollHeight || 0, document.documentElement?.scrollHeight || 0)"
|
||||
)
|
||||
target_h = int(min(max(full_h, 1), max_vp_h))
|
||||
|
||||
cur_vp = page.viewport_size or {"width": 1280, "height": 720}
|
||||
target_w = int(requested_viewport_width or cur_vp.get("width", 1280))
|
||||
|
||||
await page.set_viewport_size({"width": target_w, "height": target_h})
|
||||
await page.wait_for_timeout(500)
|
||||
except Exception as e:
|
||||
print(f"Error resizing viewport for full-page capture: {e}")
|
||||
|
||||
# For coordinate-based workflows, default is viewport screenshot so pixel coords align.
|
||||
# If full_page_via_viewport is enabled, the viewport has been expanded to the full document height.
|
||||
return await page.screenshot(full_page=False, type="png")
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user