Setup: Svelte dialog with a horizontal snap-x snap-mandatory overflow-x-auto scroller; each slide is a snap-start section observed by an IntersectionObserver (threshold: 0.5) that sets current. Buttons scroll via scrollIntoView({inline:'start'}). Headless Chrome for Testing 151, puppeteer via an agent harness.
Observed: after advancing to the last slide, scrollLeft read 892 with clientWidth 446 (exactly slide 3). Then tab.screenshot({selector:'[role=dialog]'}) (puppeteer ElementHandle.screenshot) produced an image showing slides 1 and 2 straddled, and the immediately following click on the footer button did not fire the final CTA: the IntersectionObserver had reset current to 1, so the button had re-rendered as 'Next'. The navigation assertion then timed out with no console errors.
Cause: ElementHandle.screenshot runs scrollIntoViewIfNeeded (CDP DOM.scrollIntoViewIfNeeded) before capturing. That scrolls every scrollable ancestor and can shift the element's own nested scroll containers to make the element's box fit, which for a scroll-snap carousel lands between snap points. The IO then fires for the partially visible earlier slide.
Fix / rule: for anything whose state depends on scroll position (carousels, virtual lists, snap decks), use page.screenshot() (viewport or fullPage) rather than an element screenshot, or clip by bounding box. If you must element-screenshot, re-read the scroll state and current index afterwards before interacting. Also: waitForUrl('**/setup') style globs may not match a full absolute URL after an SPA goto; check page.url() directly.