feat(playwright-core): add remove cookies api

Change removeCookies signature
This commit is contained in:
PaulTriandafilov 2024-03-01 14:20:47 +02:00
parent 8d7e4a4f0e
commit c03e307252
10 changed files with 261 additions and 43 deletions

View file

@ -1011,19 +1011,25 @@ Creates a new page in the browser context.
Returns all open pages in the context. Returns all open pages in the context.
## async method: BrowserContext.removeCookies ## async method: BrowserContext.removeCookies
* since: v1.42 * since: v1.43
Removes cookies from context. Removes cookies from context.
**Usage** **Usage**
```js ```js
await browserContext.removeCookies([cookieName1, cookieName2]); await browserContext.removeCookies({ name: 'session-id' });
await browserContext.removeCookies({ domain: 'my-origin.com' });
await browserContext.removeCookies({ path: '/api/v1' });
await browserContext.removeCookies({ name: 'session-id', domain: 'my-origin.com' });
``` ```
### param: BrowserContext.removeCookies.cookieNames ### param: BrowserContext.removeCookies.cookies
* since: v1.42 * since: v1.43
- `cookieNames` <[string]|[Array]<[string]>> - list of cookie names to remove from context - `cookies` <[Object]>
- `name` ?<[string]>
- `domain` ?<[string]>
- `path` ?<[string]>
## property: BrowserContext.request ## property: BrowserContext.request
* since: v1.16 * since: v1.16

View file

@ -269,11 +269,8 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
await this._channel.clearCookies(); await this._channel.clearCookies();
} }
async removeCookies(cookieNames: string | string[]): Promise<void> { async removeCookies(cookies: network.RemoveNetworkCookieParam): Promise<void> {
if (typeof cookieNames === 'string') await this._channel.removeCookies({ cookies });
cookieNames = [cookieNames];
await this._channel.removeCookies({ cookieNames: cookieNames as string[] });
} }
async grantPermissions(permissions: string[], options?: { origin?: string }): Promise<void> { async grantPermissions(permissions: string[], options?: { origin?: string }): Promise<void> {

View file

@ -58,6 +58,12 @@ export type SetNetworkCookieParam = {
sameSite?: 'Strict' | 'Lax' | 'None' sameSite?: 'Strict' | 'Lax' | 'None'
}; };
export type RemoveNetworkCookieParam = {
name?: string,
domain?: string,
path?: string,
};
type SerializedFallbackOverrides = { type SerializedFallbackOverrides = {
url?: string; url?: string;
method?: string; method?: string;

View file

@ -829,7 +829,11 @@ scheme.BrowserContextAddInitScriptResult = tOptional(tObject({}));
scheme.BrowserContextClearCookiesParams = tOptional(tObject({})); scheme.BrowserContextClearCookiesParams = tOptional(tObject({}));
scheme.BrowserContextClearCookiesResult = tOptional(tObject({})); scheme.BrowserContextClearCookiesResult = tOptional(tObject({}));
scheme.BrowserContextRemoveCookiesParams = tObject({ scheme.BrowserContextRemoveCookiesParams = tObject({
cookieNames: tArray(tString), cookies: tObject({
name: tOptional(tString),
domain: tOptional(tString),
path: tOptional(tString),
}),
}); });
scheme.BrowserContextRemoveCookiesResult = tOptional(tObject({})); scheme.BrowserContextRemoveCookiesResult = tOptional(tObject({}));
scheme.BrowserContextClearPermissionsParams = tOptional(tObject({})); scheme.BrowserContextClearPermissionsParams = tOptional(tObject({}));

View file

@ -276,13 +276,19 @@ export abstract class BrowserContext extends SdkObject {
return await this.doGetCookies(urls as string[]); return await this.doGetCookies(urls as string[]);
} }
async removeCookies(cookieNames: string | string[]): Promise<void> { async removeCookies(cookies: {name?: string, domain?: string, path?: string}): Promise<void> {
const setCookies = await this.cookies(); const setCookies = await this.cookies();
const newCookiesSet = setCookies.filter(c => !cookieNames.includes(c.name)); if (!cookies.name && !cookies.domain && !cookies.path) return;
const filteredCookies = setCookies.filter(cookie => {
return !((!cookies.name || cookies.name === cookie.name) &&
(!cookies.domain || cookies.domain === cookie.domain) &&
(!cookies.path || cookies.path === cookie.path));
});
await this.clearCookies(); await this.clearCookies();
await this.addCookies(newCookiesSet); await this.addCookies(filteredCookies);
} }
setHTTPCredentials(httpCredentials?: types.Credentials): Promise<void> { setHTTPCredentials(httpCredentials?: types.Credentials): Promise<void> {

View file

@ -225,7 +225,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
} }
async removeCookies(params: channels.BrowserContextRemoveCookiesParams): Promise<void> { async removeCookies(params: channels.BrowserContextRemoveCookiesParams): Promise<void> {
await this._context.removeCookies(params.cookieNames); await this._context.removeCookies(params.cookies);
} }
async grantPermissions(params: channels.BrowserContextGrantPermissionsParams): Promise<void> { async grantPermissions(params: channels.BrowserContextGrantPermissionsParams): Promise<void> {

View file

@ -8444,12 +8444,21 @@ export interface BrowserContext {
* **Usage** * **Usage**
* *
* ```js * ```js
* await browserContext.removeCookies([cookieName1, cookieName2]); * await browserContext.removeCookies({ name: 'session-id' });
* await browserContext.removeCookies({ domain: 'my-origin.com' });
* await browserContext.removeCookies({ path: '/api/v1' });
* await browserContext.removeCookies({ name: 'session-id', domain: 'my-origin.com' });
* ``` * ```
* *
* @param cookieNames * @param cookies
*/ */
removeCookies(cookieNames: string|ReadonlyArray<string>): Promise<void>; removeCookies(cookies: {
name?: string;
domain?: string;
path?: string;
}): Promise<void>;
/** /**
* Routing provides the capability to modify network requests that are made by any page in the browser context. Once * Routing provides the capability to modify network requests that are made by any page in the browser context. Once

View file

@ -1525,7 +1525,11 @@ export type BrowserContextClearCookiesParams = {};
export type BrowserContextClearCookiesOptions = {}; export type BrowserContextClearCookiesOptions = {};
export type BrowserContextClearCookiesResult = void; export type BrowserContextClearCookiesResult = void;
export type BrowserContextRemoveCookiesParams = { export type BrowserContextRemoveCookiesParams = {
cookieNames: string[], cookies: {
name?: string,
domain?: string,
path?: string,
},
}; };
export type BrowserContextRemoveCookiesOptions = { export type BrowserContextRemoveCookiesOptions = {

View file

@ -1034,9 +1034,12 @@ BrowserContext:
removeCookies: removeCookies:
parameters: parameters:
cookieNames: cookies:
type: array type: object
items: string properties:
name: string?
domain: string?
path: string?
clearPermissions: clearPermissions:

View file

@ -17,31 +17,214 @@
import { contextTest as it, expect } from '../config/browserTest'; import { contextTest as it, expect } from '../config/browserTest';
it('should remove cookies', async ({ context, page, server }) => { it('should remove cookies by name', async ({ context, page, server }) => {
await page.goto(server.EMPTY_PAGE);
await context.addCookies([{ await context.addCookies([{
url: server.EMPTY_PAGE,
name: 'cookie1', name: 'cookie1',
value: '1' value: '1',
domain: 'www.example.com',
path: '/',
}, },
{ {
url: server.EMPTY_PAGE,
name: 'cookie2', name: 'cookie2',
value: '2' value: '2',
}, domain: 'www.example.com',
{ path: '/',
url: server.EMPTY_PAGE, }
name: 'cookie3', ]);
value: '3' await page.goto('https://www.example.com');
}]); expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2; cookie3=3'); await context.removeCookies({ name: 'cookie1' });
await context.removeCookies(['cookie1', 'cookie2']); expect(await page.evaluate('document.cookie')).toBe('cookie2=2');
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
await page.reload();
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
await context.removeCookies('cookie3');
expect(await page.evaluate('document.cookie')).toBe('');
await page.reload();
expect(await page.evaluate('document.cookie')).toBe('');
}); });
it('should remove cookies by domain', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/',
},
{
name: 'cookie2',
value: '2',
domain: 'www.example.org',
path: '/',
}
]);
await page.goto('https://www.example.com');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
await page.goto('https://www.example.org');
expect(await page.evaluate('document.cookie')).toBe('cookie2=2');
await context.removeCookies({ domain: 'www.example.org' });
expect(await page.evaluate('document.cookie')).toBe('');
await page.goto('https://www.example.com');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
});
it('should remove cookies by path', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/api/v1',
},
{
name: 'cookie2',
value: '2',
domain: 'www.example.com',
path: '/api/v2',
},
{
name: 'cookie3',
value: '3',
domain: 'www.example.com',
path: '/',
}
]);
await page.goto('https://www.example.com/api/v1');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie3=3');
await context.removeCookies({ path: '/api/v1' });
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
await page.goto('https://www.example.com/api/v2');
expect(await page.evaluate('document.cookie')).toBe('cookie2=2; cookie3=3');
await page.goto('https://www.example.com/');
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
});
it('should remove cookies by name and domain', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/',
},
{
name: 'cookie1',
value: '1',
domain: 'www.example.org',
path: '/',
}
]);
await page.goto('https://www.example.com');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
await context.removeCookies({ name: 'cookie1', domain: 'www.example.com' });
expect(await page.evaluate('document.cookie')).toBe('');
await page.goto('https://www.example.org');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
});
it('should remove cookies by name and path', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/api/v1',
},
{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/api/v2',
},
{
name: 'cookie3',
value: '3',
domain: 'www.example.com',
path: '/',
}
]);
await page.goto('https://www.example.com/api/v1');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie3=3');
await context.removeCookies({ name: 'cookie1', path: '/api/v1' });
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
await page.goto('https://www.example.com/api/v2');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie3=3');
await page.goto('https://www.example.com/');
expect(await page.evaluate('document.cookie')).toBe('cookie3=3');
});
it('should remove cookies by domain and path', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/api/v1',
},
{
name: 'cookie2',
value: '2',
domain: 'www.example.com',
path: '/api/v2',
},
{
name: 'cookie3',
value: '3',
domain: 'www.example.org',
path: '/api/v1',
},
{
name: 'cookie4',
value: '4',
domain: 'www.example.org',
path: '/api/v2',
}
]);
await page.goto('https://www.example.com/api/v1');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
await context.removeCookies({ domain: 'www.example.com', path: '/api/v1' });
expect(await page.evaluate('document.cookie')).toBe('');
await page.goto('https://www.example.com/api/v2');
expect(await page.evaluate('document.cookie')).toBe('cookie2=2');
await page.goto('https://www.example.org/api/v2');
expect(await page.evaluate('document.cookie')).toBe('cookie4=4');
});
it('should remove cookies by name, domain and path', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/api/v1',
},
{
name: 'cookie2',
value: '2',
domain: 'www.example.com',
path: '/api/v2',
},
{
name: 'cookie1',
value: '1',
domain: 'www.example.org',
path: '/api/v1',
},
]);
await page.goto('https://www.example.com/api/v1');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
await context.removeCookies({ name: 'cookie1', domain: 'www.example.com', path: '/api/v1' });
expect(await page.evaluate('document.cookie')).toBe('');
await page.goto('https://www.example.com/api/v2');
expect(await page.evaluate('document.cookie')).toBe('cookie2=2');
await page.goto('https://www.example.org/api/v1');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
});
it('should not remove cookies when empty object passed', async ({ context, page, server }) => {
await context.addCookies([{
name: 'cookie1',
value: '1',
domain: 'www.example.com',
path: '/',
},
{
name: 'cookie2',
value: '2',
domain: 'www.example.com',
path: '/',
},
]);
await page.goto('https://www.example.com/');
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2');
await context.removeCookies({ });
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2');
});