[Feature]: Support Partitioned cookies (CHIPS) in `storageState`
🚀 Feature Request
I'm trying to implement the new Partitioned flag for our backend's cookies (see https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies).
With this I'm hoping to support Safari and upcoming cookie-blocking chrome versions in the use case where our frontend runs on another domain than our backend (e.g. during e2e testing on preview builds).
My auth setup looks like this:
await request.post(`${apiUrl}/latest/auth/login`, {
data: {
username: email,
password,
},
})
await request.storageState({ path: authFile })
But when the cookies come back with a Partitioned flag on them, this isn't represented in the authFile, so when I use this storageState in my tests I have two problems:
- Browsers that only send Partitioned cookies in cross-site requests won't send this auth cookie if the apiUrl is on a different domain than the frontend.
- When I try to log out in a test, the (empty, expired) cookie that comes back is
Partitioned, but the auth cookie from thestorageStateis notPartitioned, so the browser thinks those cookies are not the same and keeps the auth cookie from thestorageStateinstead of dropping it. I can solve this by removing both unpartitioned and partitioned cookies in my logout endpoint though.
Example
- Hit a login endpoint which uses
Partitionedcookies to return an authentication token. - use
request.storageState({ path: authFile })to persist the storage state, taking thePartitionedflag into account - use the
storageStatetest option to load the storage state, taking thePartitionedflag into account. The browser's cookie storage will now be the same as if I had done the authentication in each test withoutstorageState.
Motivation
Without this, it's impossible to use storageState to accurately represent the actual browser behaviour when Partitioned cookies are in play.
Here is an example web-site for testing the CHIPS cookie behavior: https://cookie-server.azurewebsites.net/
Here is the behavior I see on macOS 15.5 with the above web page:
| Browser | Cookie Behavior (Origin 1 → Origin 2 → Origin 1) | Cookie Behavior (Origin 2 → Origin 1) |
|---|---|---|
| Chrome 137 | frame-non-partitioned, frame-partitioned, top-level-non-partitioned | frame-non-partitioned, frame-partitioned, top-level-non-partitioned |
| Firefox 139 | frame-non-partitioned, frame-partitioned | frame-non-partitioned, frame-partitioned |
| Safari 18.5 | frame-non-partitioned, frame-partitioned, top-level-non-partitioned, top-level-partitioned | no cookies sent to the server |
On further investigation, it turns out that the partitioned cookies did work in Safari 18.4 but were disable in 18.5, see this commit: https://commits.webkit.org/295121@main. This is not mentioned in 18.5 release notes. The setting from the screenshot below was there in 18.4 and is gone in 18.5:
The functionality works in Chromium. You can test the server behavior with that. We will get back to it once WebKit settles on the CHIPS behavior, so far it has been reverted and going back and forth.