fix: add support for "Default" SameSite cookie property (#14637)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: OrKoN <[email protected]>
Co-authored-by: Nikolay Vitkov <[email protected]>
This commit is contained in:
Alex Rudenko
2026-02-02 10:32:11 +01:00
committed by GitHub
co-authored by google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> OrKoN Nikolay Vitkov
parent fa45e350bc
commit b144f573a3
7 changed files with 134 additions and 9 deletions
+1 -1
View File
@@ -9,5 +9,5 @@ Represents the cookie's 'SameSite' status: https://tools.ietf.org/html/draft-wes
### Signature
```typescript
export type CookieSameSite = 'Strict' | 'Lax' | 'None';
export type CookieSameSite = 'Strict' | 'Lax' | 'None' | 'Default';
```
+20 -6
View File
@@ -1160,17 +1160,31 @@ export function cdpSpecificCookiePropertiesFromPuppeteerToBidi(
function convertCookiesSameSiteBiDiToCdp(
sameSite: Bidi.Network.SameSite | undefined,
): CookieSameSite {
return sameSite === 'strict' ? 'Strict' : sameSite === 'lax' ? 'Lax' : 'None';
switch (sameSite) {
case 'strict':
return 'Strict';
case 'lax':
return 'Lax';
case 'none':
return 'None';
default:
return 'Default';
}
}
export function convertCookiesSameSiteCdpToBiDi(
sameSite: CookieSameSite | undefined,
): Bidi.Network.SameSite {
return sameSite === 'Strict'
? Bidi.Network.SameSite.Strict
: sameSite === 'Lax'
? Bidi.Network.SameSite.Lax
: Bidi.Network.SameSite.None;
switch (sameSite) {
case 'Strict':
return Bidi.Network.SameSite.Strict;
case 'Lax':
return Bidi.Network.SameSite.Lax;
case 'None':
return Bidi.Network.SameSite.None;
default:
return Bidi.Network.SameSite.Default;
}
}
export function convertCookiesExpiryCdpToBiDi(
@@ -21,7 +21,10 @@ import {assert} from '../util/assert.js';
import type {CdpBrowser} from './Browser.js';
import type {Connection} from './Connection.js';
import {convertCookiesPartitionKeyFromPuppeteerToCdp} from './Page.js';
import {
convertCookiesPartitionKeyFromPuppeteerToCdp,
convertSameSiteFromPuppeteerToCdp,
} from './Page.js';
import type {CdpTarget} from './Target.js';
/**
@@ -162,6 +165,7 @@ export class CdpBrowserContext extends BrowserContext {
partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp(
cookie.partitionKey,
),
sameSite: convertSameSiteFromPuppeteerToCdp(cookie.sameSite),
};
}),
});
+18
View File
@@ -41,6 +41,7 @@ import type {
DeleteCookiesRequest,
CookieParam,
CookiePartitionKey,
CookieSameSite,
} from '../common/Cookie.js';
import {TargetCloseError} from '../common/Errors.js';
import {EventEmitter} from '../common/EventEmitter.js';
@@ -100,6 +101,22 @@ function convertConsoleMessageLevel(method: string): ConsoleMessageType {
}
}
/**
* @internal
*/
export function convertSameSiteFromPuppeteerToCdp(
sameSite: CookieSameSite | undefined,
): Protocol.Network.CookieSameSite | undefined {
switch (sameSite) {
case 'Strict':
case 'Lax':
case 'None':
return sameSite;
default:
return undefined;
}
}
/**
* @internal
*/
@@ -717,6 +734,7 @@ export class CdpPage extends Page {
partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp(
cookieParam.partitionKey,
),
sameSite: convertSameSiteFromPuppeteerToCdp(cookieParam.sameSite),
};
}),
});
+1 -1
View File
@@ -10,7 +10,7 @@
*
* @public
*/
export type CookieSameSite = 'Strict' | 'Lax' | 'None';
export type CookieSameSite = 'Strict' | 'Lax' | 'None' | 'Default';
/**
* Represents the cookie's 'Priority' status:
+44
View File
@@ -78,6 +78,26 @@ describe('BrowserContext cookies', () => {
: undefined,
);
});
it('should properly report "Default" sameSite cookie', async () => {
const {context, server, page} = state;
await page.goto(server.EMPTY_PAGE);
const name = 'defaultSameSite';
await context.setCookie({
name,
value: 'b',
domain: 'localhost',
sameSite: 'Default',
});
const cookies = await context.cookies();
const cookie = cookies.find(c => {
return c.name === name;
});
expect(cookie).toBeDefined();
// Different browsers have different sameSite values for the "Default" sameSite.
expect(['Default', 'Lax', undefined]).toContain(cookie!.sameSite);
await context.deleteMatchingCookies({name, domain: 'localhost'});
});
});
describe('BrowserContext.setCookie', function () {
it('should set with undefined partition key', async () => {
@@ -183,6 +203,30 @@ describe('BrowserContext cookies', () => {
}),
).toEqual('cookie2=2');
});
it('should be able to delete "Default" sameSite cookie', async () => {
const {page, context, server} = state;
await page.goto(server.EMPTY_PAGE);
const name = 'deleteDefaultSameSite';
await context.setCookie({
name,
value: 'b',
domain: 'localhost',
sameSite: 'Default',
});
const cookies = await context.cookies();
const cookie = cookies.find(c => {
return c.name === name;
});
expect(cookie).toBeDefined();
await context.deleteMatchingCookies({name, domain: 'localhost'});
const cookiesAfter = await context.cookies();
expect(
cookiesAfter.find(c => {
return c.name === name;
}),
).toBeUndefined();
});
});
describe('BrowserContext.deleteMatchingCookies', () => {
+45
View File
@@ -77,6 +77,51 @@ describe('Cookie specs', () => {
expect(cookies).toHaveLength(1);
expect(cookies[0]!.sameSite).toBe('Lax');
});
it('should properly report "Default" sameSite cookie', async () => {
const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
name: 'a',
value: 'b',
sameSite: 'Default',
});
const cookies = await page.cookies();
expect(cookies).toHaveLength(1);
expect(cookies[0]!.name).toBe('a');
// Different browsers have different sameSite values for the "Default" sameSite.
expect(['Default', 'Lax', undefined]).toContain(cookies[0]!.sameSite);
});
it('should be able to delete "Default" sameSite cookie', async () => {
const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
name: 'a',
value: 'b',
sameSite: 'Default',
});
const cookies = await page.cookies();
expect(
cookies.find(c => {
return c.name === 'a';
}),
).toBeDefined();
await page.deleteCookie(...cookies);
expect(await page.cookies()).toHaveLength(0);
});
it('should report "Default" sameSite cookie when not specified', async () => {
const {page, server, defaultBrowserOptions, isFirefox} =
await getTestState();
server.setRoute('/empty.html', (_req, res) => {
res.setHeader('Set-Cookie', 'a=b');
res.end();
});
await page.goto(server.EMPTY_PAGE);
const cookies = await page.cookies();
expect(cookies).toHaveLength(1);
if (defaultBrowserOptions.protocol === 'webDriverBiDi' && isFirefox) {
expect(cookies[0]!.sameSite).toBe('Default');
}
});
it('should get multiple cookies', async () => {
const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE);