Navigation and waiting
When the capture happens, and how to move it later.
A capture is only as good as the moment it is taken. Four controls decide that moment.
Navigation state
wait_until picks how far the navigation must get:
load— the load event. Default, and right for most pages.domcontentloaded— the DOM is parsed, subresources may still be in flight. Fastest.networkidle0— zero requests in flight for 500 ms.networkidle2— at most two requests in flight for 500 ms.
The two idle levels are the Puppeteer vocabulary and they are implemented here by counting requests in flight, because Playwright's single networkidle is a third behaviour and matches neither.
Prefer networkidle2 over networkidle0 on real sites: analytics beacons, chat widgets and long-polling connections keep one or two requests open forever, and networkidle0 will simply wait until the timeout.
Timeouts
timeout is the budget for the whole capture and navigation_timeout for navigation alone. Both are in seconds. timeout defaults to 60 with a maximum of 90; navigation_timeout defaults to 30 with a maximum of 30, and cannot exceed timeout.
Waiting for something specific
wait_for_selector waits for a CSS selector. wait_for_selector_algorithm controls how many nodes satisfy it, not how the selector is read:
at_least_one— the first match becomes visible. Default.at_least_by_count— every match the page is still rendering, by waiting until the match count stops changing. This is the one for a list filled by XHR.
If the selector never appears, the capture continues. Set error_on_selector_not_found=true to fail with selector_not_found instead.
A fixed pause
delay waits a number of seconds after the navigation state, before anything else runs. Reach for it last: it is the control that makes every capture slower whether the page needed it or not.
Order
The order of actions is public and stable: navigate → wait condition → delay → wait_for_selector → styles → hide → scripts → hover → click → scroll into view → full-page scroll → settle → capture.