This commit is contained in:
@@ -188,6 +188,12 @@ async def interactions_service(
|
|||||||
|
|
||||||
async def interactions_operation(page):
|
async def interactions_operation(page):
|
||||||
try:
|
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]:
|
async def resolve_viewport_point(px: int, py: int) -> tuple[float, float]:
|
||||||
"""
|
"""
|
||||||
Playwright's `document.elementFromPoint(x, y)` uses viewport coordinates.
|
Playwright's `document.elementFromPoint(x, y)` uses viewport coordinates.
|
||||||
@@ -251,8 +257,15 @@ async def interactions_service(
|
|||||||
vp_width = getattr(viewport, "width", None)
|
vp_width = getattr(viewport, "width", None)
|
||||||
vp_height = getattr(viewport, "height", None)
|
vp_height = getattr(viewport, "height", None)
|
||||||
|
|
||||||
|
requested_viewport_width = vp_width
|
||||||
if vp_width and vp_height:
|
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:
|
except Exception as e:
|
||||||
print(f"Error setting viewport: {e}")
|
print(f"Error setting viewport: {e}")
|
||||||
|
|
||||||
@@ -405,7 +418,30 @@ async def interactions_service(
|
|||||||
if return_type == "html":
|
if return_type == "html":
|
||||||
return await page.content()
|
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")
|
return await page.screenshot(full_page=False, type="png")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user