diff --git a/packages/playwright-core/src/server/fetch.ts b/packages/playwright-core/src/server/fetch.ts index 0f83928bc5..c1e15aefa2 100644 --- a/packages/playwright-core/src/server/fetch.ts +++ b/packages/playwright-core/src/server/fetch.ts @@ -517,7 +517,21 @@ function toHeadersArray(rawHeaders: string[]): types.HeadersArray { const redirectStatus = [301, 302, 303, 307, 308]; function parseCookie(header: string): types.NetworkCookie | null { - const pairs = header.split(';').filter(s => s.trim().length > 0).map(p => p.split('=').map(s => s.trim())); + const pairs = header.split(';').filter(s => s.trim().length > 0).map(p => { + let key = ''; + let value = ''; + const separatorPos = p.indexOf('='); + if (separatorPos === -1) { + // If only a key is specified, the value is left undefined. + key = p.trim(); + } else { + // Otherwise we assume that the key is the element before the first `=` + key = p.slice(0, separatorPos).trim(); + // And the value is the rest of the string. + value = p.slice(separatorPos + 1).trim(); + } + return [key, value]; + }); if (!pairs.length) return null; const [name, value] = pairs[0]; diff --git a/tests/global-fetch-cookie.spec.ts b/tests/global-fetch-cookie.spec.ts index 01178f20f5..fa3e09097f 100644 --- a/tests/global-fetch-cookie.spec.ts +++ b/tests/global-fetch-cookie.spec.ts @@ -166,6 +166,33 @@ it('should remove expired cookies', async ({ request, server }) => { expect(serverRequest.headers.cookie).toBe('a=v'); }); +it('should store cookie from Set-Cookie header even if it contains equal signs', async ({ request, server }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/11612' }); + + server.setRoute('/setcookie.html', (req, res) => { + res.setHeader('Set-Cookie', ['f=value == value=; secure; httpOnly; path=/some=value']); + res.end(); + }); + + await request.get(`http://a.b.one.com:${server.PORT}/setcookie.html`); + const state = await request.storageState(); + expect(state).toEqual({ + 'cookies': [ + { + domain: 'a.b.one.com', + expires: -1, + name: 'f', + path: '/some=value', + sameSite: 'Lax', + httpOnly: true, + secure: true, + value: 'value == value=', + } + ], + 'origins': [] + }); +}); + it('should export cookies to storage state', async ({ request, server }) => { const expires = new Date('12/31/2100 PST'); server.setRoute('/setcookie.html', (req, res) => {