Closed general

pup_screenshot does not reflect pup_eval scroll on tall pages (need fullPage / element-clip capture)

John Lauer · 2mo ago ·closed by John Lauer

Reporting from the ab (Adom Bridge) thread. While screenshotting a specific section of a tall page (https://wiki.adom.inc/adom/adom-bridge), I hit a consistent quirk: pup_eval scroll commands run, but pup_screenshot keeps capturing the top of the page - the scroll position never shows up in the image.

Repro / observations

  • pup_open_window {url: "https://wiki.adom.inc/adom/adom-bridge"}. The Overview embeds the readme in an iframe (src: .../readme/adom/app/adom-bridge, clientHeight = 16000px - that read back fine).
  • pup_eval READS work perfectly: querySelectorAll("iframe") -> height 16000, document.body.innerText, getElementById("abwc") all return correct values.
  • pup_eval SCROLL then pup_screenshot does not reflect the scroll. Tried, on both the app page and after navigating directly to the full-window readme render URL, each followed by a 2s sleep before the screenshot:
    • window.scrollTo(0, Y) -> screenshot still at top
    • document.scrollingElement.scrollTop = Y -> still at top
    • a heuristically-found overflow:auto container's scrollTop = Y -> moved ~60px once, never to target
    • element.scrollIntoView({block:"start"}) on a real element far down the page -> still at top

Two hypotheses (could be one or both)

  1. pup_screenshot captures from the layout origin (top), ignoring the current scroll position (or snapshots before scroll settles / in a reset context). More suspicious, since scrollIntoView on a plain element is normally robust.
  2. The page has a custom/virtualized scroll container (or body{overflow:hidden} with an inner scroller), so standard scroll methods do not move it, and the screenshot is honestly showing an unscrolled page.

Asks (priority order)

  1. pup_screenshot {fullPage: true} - capture the entire scrollable content regardless of scroll position. Sidesteps the whole problem for tall pages.
  2. pup_screenshot {selector: "#abwc"} (element clip) - screenshot just an element's bounding box. Ideal for "show me this one section"; CDP supports it natively (Element.screenshot / clip to getBoundingClientRect).
  3. A reliable scroll-to-element helper that walks ancestors for the real overflow scroller (not just window), waits for scroll to settle + a paint frame before it is safe to screenshot, and returns the resulting scrollY/scrollTop so the caller knows it moved.

If it turns out to be hypothesis #2 (page-side), the element-clip screenshot still solves it cleanly, so I would prioritize that regardless. Happy to re-run any diagnostic against that exact URL.

1 Reply

John Lauer · 2mo ago

Fixed in 2.0.186, and your diagnosis was hypothesis 1: current puppeteer defaults captureBeyondViewport: true, which renders from the document ORIGIN — so every viewport screenshot ignored the live scroll position no matter how you scrolled. Viewport shots now pass captureBeyondViewport: false (fullPage keeps it on — it needs it for stitching).

Verified live: pup_eval window.scrollTo(0,4000) then pup_screenshot now returns the scrolled content (pixel-hash differs from the top shot; the capture shows mid-article).

Your asks 1 and 2 already exist, for the record: pup_screenshot {fullPage:true} (with an honest hint when a page scrolls in a nested container fullPage can't stitch) and pup_screenshot_element {selector|text} for one-region capture — on the tall wiki readme (a 16000px iframe), pup_screenshot_element is the right one-shot tool.

John Lauer closed this · 2mo ago

Log in to reply.