fix: support cookies with empty value (#9376)
This commit is contained in:
parent
0713cb3d39
commit
9164fc71ef
|
|
@ -327,7 +327,7 @@ export abstract class BrowserContext extends SdkObject {
|
|||
|
||||
async storageState(): Promise<types.StorageState> {
|
||||
const result: types.StorageState = {
|
||||
cookies: (await this.cookies()).filter(c => c.value !== ''),
|
||||
cookies: await this.cookies(),
|
||||
origins: []
|
||||
};
|
||||
if (this._origins.size) {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): t
|
|||
const parsedURLs = urls.map(s => new URL(s));
|
||||
// Chromiums's cookies are missing sameSite when it is 'None'
|
||||
return cookies.filter(c => {
|
||||
// Firefox and WebKit can return cookies with empty values.
|
||||
if (!c.value)
|
||||
return false;
|
||||
if (!parsedURLs.length)
|
||||
return true;
|
||||
for (const parsedURL of parsedURLs) {
|
||||
|
|
@ -50,7 +47,6 @@ export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): t
|
|||
export function rewriteCookies(cookies: types.SetNetworkCookieParam[]): types.SetNetworkCookieParam[] {
|
||||
return cookies.map(c => {
|
||||
assert(c.name, 'Cookie should have a name');
|
||||
assert(c.value, 'Cookie should have a value');
|
||||
assert(c.url || (c.domain && c.path), 'Cookie should have a url or a domain/path pair');
|
||||
assert(!(c.url && c.domain), 'Cookie should have either url or domain');
|
||||
assert(!(c.url && c.path), 'Cookie should have either url or path');
|
||||
|
|
|
|||
|
|
@ -45,6 +45,24 @@ it('should work with expires=-1', async ({ context, page }) => {
|
|||
expect(await page.evaluate(() => document.cookie)).toEqual('username=John Doe');
|
||||
});
|
||||
|
||||
it('should add cookies with empty value', async ({ context, page, server }) => {
|
||||
await context.addCookies([{
|
||||
name: 'marker',
|
||||
value: '',
|
||||
domain: 'www.example.com',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
sameSite: 'Lax',
|
||||
}]);
|
||||
await page.route('**/*', route => {
|
||||
route.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||
});
|
||||
await page.goto('https://www.example.com');
|
||||
expect(await page.evaluate(() => document.cookie)).toEqual('marker=');
|
||||
});
|
||||
|
||||
it('should roundtrip cookie', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
|
|
|
|||
|
|
@ -202,14 +202,19 @@ it('should work with subdomain cookie', async ({ context, browserName, isWindows
|
|||
}]);
|
||||
});
|
||||
|
||||
it('should not return cookies with empty value', async ({ context, page, server }) => {
|
||||
it('should return cookies with empty value', async ({ context, page, server }) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=;Path=/');
|
||||
res.end();
|
||||
});
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const cookies = await context.cookies();
|
||||
expect(cookies.length).toBe(0);
|
||||
expect(cookies).toEqual([
|
||||
expect.objectContaining({
|
||||
name: 'name',
|
||||
value: ''
|
||||
})
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return secure cookies based on HTTP(S) protocol', async ({ context, browserName, isWindows }) => {
|
||||
|
|
|
|||
|
|
@ -229,6 +229,23 @@ it('should add cookies from Set-Cookie header', async ({ context, page, server }
|
|||
expect((await page.evaluate(() => document.cookie)).split(';').map(s => s.trim()).sort()).toEqual(['foo=bar', 'session=value']);
|
||||
});
|
||||
|
||||
it('should support cookie with empty value', async ({ context, page, server }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', ['first=']);
|
||||
res.end();
|
||||
});
|
||||
await context.request.get(server.PREFIX + '/setcookie.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(await page.evaluate(() => document.cookie)).toBe('first=');
|
||||
const cookies = await context.cookies();
|
||||
expect(cookies.map(c => ({ name: c.name, value: c.value }))).toEqual([
|
||||
{
|
||||
name: 'first',
|
||||
value: ''
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not lose body while handling Set-Cookie header', async ({ context, server }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
|
||||
|
|
|
|||
|
|
@ -103,3 +103,41 @@ it('should round-trip through the file', async ({ contextFactory }, testInfo) =>
|
|||
expect(cookie).toEqual('username=John Doe');
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it('should capture cookies', async ({ server, context, page, contextFactory }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', ['a=b', 'empty=']);
|
||||
res.end();
|
||||
});
|
||||
|
||||
await page.goto(server.PREFIX + '/setcookie.html');
|
||||
expect(await page.evaluate(() => {
|
||||
const cookies = document.cookie.split(';');
|
||||
return cookies.map(cookie => cookie.trim()).sort();
|
||||
})).toEqual([
|
||||
'a=b',
|
||||
'empty=',
|
||||
]);
|
||||
|
||||
const storageState = await context.storageState();
|
||||
expect(new Set(storageState.cookies)).toEqual(new Set([
|
||||
expect.objectContaining({
|
||||
name: 'a',
|
||||
value: 'b'
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: 'empty',
|
||||
value: ''
|
||||
})
|
||||
]));
|
||||
const context2 = await contextFactory({ storageState });
|
||||
const page2 = await context2.newPage();
|
||||
await page2.goto(server.EMPTY_PAGE);
|
||||
expect(await page2.evaluate(() => {
|
||||
const cookies = document.cookie.split(';');
|
||||
return cookies.map(cookie => cookie.trim()).sort();
|
||||
})).toEqual([
|
||||
'a=b',
|
||||
'empty=',
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue