Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/upgrading/upgrading_v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,17 @@ The `transformRequestFunction` callback receives a `RequestOptions` object and c
- A new `RequestOptions` plain object
- `'unchanged'` to keep the original options as-is
- A falsy value or `'skip'` to exclude the request from the queue

## Puppeteer cookies are now read and written at the browser-context level

The `PuppeteerController._getCookies` / `_setCookies` methods (used internally by the session pool to sync cookies between a `Session` and a Puppeteer page) now call `page.browserContext().cookies()` / `setCookie()` instead of the deprecated `page.cookies()` / `page.setCookie()`. The page-level API was removed in newer Puppeteer releases.

This aligns the Puppeteer controller with the Playwright controller, which has always worked at the context level.

**What changes in practice**
- Cookie reads return every cookie stored in the page's browser context, not just cookies matching the page's current URL. If your `Session` relied on the URL-scoped filtering (for example, to avoid pulling cookies that belong to other tabs in the same context), you'll now see the full set.
- Cookie writes are applied to the whole browser context. When you launch pages with shared contexts, cookies written via `Session.setCookiesFromResponse` or similar will be visible to every other page in that context.

If you rely on Crawlee's default configuration (one browser context per session, which is the `useIncognitoPages` / `newContextPerSession` behavior used by `PuppeteerCrawler`), you should not notice any difference — each session already owns its own context.

**Cookie `url` field** — the old `page.setCookie()` auto-filled a missing `url` on each cookie with the page's current URL. The new `browserContext().setCookie()` does not; Chromium rejects cookies that carry neither `url` nor `domain`. Crawlee's internal `_setCookies` keeps the old behavior by back-filling `page.url()` for any cookie that has neither field set, but if you call `browserContext().setCookie()` directly (outside of Crawlee) you need to provide one of them yourself.
10 changes: 8 additions & 2 deletions packages/browser-pool/src/puppeteer/puppeteer-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,16 @@ export class PuppeteerController extends BrowserController<
}

protected async _getCookies(page: PuppeteerTypes.Page): Promise<Cookie[]> {
return page.cookies();
return page.browserContext().cookies();
}

protected async _setCookies(page: PuppeteerTypes.Page, cookies: Cookie[]): Promise<void> {
return page.setCookie(...cookies);
// BrowserContext.setCookie requires `url` or `domain`; the page-level API used to back-fill
// the page's current URL for us. Replicate that so callers who pass neither don't get rejected.
const pageUrl = page.url();
const normalized = cookies.map((cookie) =>
cookie.url || cookie.domain ? cookie : { ...cookie, url: pageUrl },
);
return page.browserContext().setCookie(...(normalized as PuppeteerTypes.CookieData[]));
}
}
Loading