feat(context): remove the notion of incognito context (#299)
This commit is contained in:
parent
da051a72a8
commit
0e3328218d
|
|
@ -44,7 +44,6 @@
|
||||||
* [browserContext.clearCookies()](#browsercontextclearcookies)
|
* [browserContext.clearCookies()](#browsercontextclearcookies)
|
||||||
* [browserContext.close()](#browsercontextclose)
|
* [browserContext.close()](#browsercontextclose)
|
||||||
* [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
* [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
||||||
* [browserContext.isIncognito()](#browsercontextisincognito)
|
|
||||||
* [browserContext.newPage()](#browsercontextnewpage)
|
* [browserContext.newPage()](#browsercontextnewpage)
|
||||||
* [browserContext.overrides](#browsercontextoverrides)
|
* [browserContext.overrides](#browsercontextoverrides)
|
||||||
* [browserContext.pages()](#browsercontextpages)
|
* [browserContext.pages()](#browsercontextpages)
|
||||||
|
|
@ -736,12 +735,6 @@ will be closed.
|
||||||
If no URLs are specified, this method returns all cookies.
|
If no URLs are specified, this method returns all cookies.
|
||||||
If URLs are specified, only cookies that affect those URLs are returned.
|
If URLs are specified, only cookies that affect those URLs are returned.
|
||||||
|
|
||||||
#### browserContext.isIncognito()
|
|
||||||
- returns: <[boolean]>
|
|
||||||
|
|
||||||
Returns whether BrowserContext is incognito.
|
|
||||||
The default browser context is the only non-incognito browser context.
|
|
||||||
|
|
||||||
> **NOTE** the default browser context cannot be closed.
|
> **NOTE** the default browser context cannot be closed.
|
||||||
|
|
||||||
#### browserContext.newPage()
|
#### browserContext.newPage()
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from './helper';
|
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import * as input from './input';
|
import * as input from './input';
|
||||||
import * as network from './network';
|
import * as network from './network';
|
||||||
import * as types from './types';
|
import * as types from './types';
|
||||||
|
|
||||||
export interface BrowserDelegate {
|
export interface BrowserContextDelegate {
|
||||||
contextPages(): Promise<Page[]>;
|
pages(): Promise<Page[]>;
|
||||||
createPageInContext(): Promise<Page>;
|
newPage(): Promise<Page>;
|
||||||
closeContext(): Promise<void>;
|
close(): Promise<void>;
|
||||||
getContextCookies(): Promise<network.NetworkCookie[]>;
|
cookies(): Promise<network.NetworkCookie[]>;
|
||||||
clearContextCookies(): Promise<void>;
|
clearCookies(): Promise<void>;
|
||||||
setContextCookies(cookies: network.SetNetworkCookieParam[]): Promise<void>;
|
setCookies(cookies: network.SetNetworkCookieParam[]): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BrowserContextOptions = {
|
export type BrowserContextOptions = {
|
||||||
|
|
@ -42,34 +41,28 @@ export type BrowserContextOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class BrowserContext {
|
export class BrowserContext {
|
||||||
private readonly _delegate: BrowserDelegate;
|
private readonly _delegate: BrowserContextDelegate;
|
||||||
private readonly _isIncognito: boolean;
|
|
||||||
readonly _options: BrowserContextOptions;
|
readonly _options: BrowserContextOptions;
|
||||||
private _closed = false;
|
private _closed = false;
|
||||||
|
|
||||||
constructor(delegate: BrowserDelegate, isIncognito: boolean, options: BrowserContextOptions) {
|
constructor(delegate: BrowserContextDelegate, options: BrowserContextOptions) {
|
||||||
this._delegate = delegate;
|
this._delegate = delegate;
|
||||||
this._isIncognito = isIncognito;
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
if (!options.viewport && options.viewport !== null)
|
if (!options.viewport && options.viewport !== null)
|
||||||
options.viewport = { width: 800, height: 600 };
|
options.viewport = { width: 800, height: 600 };
|
||||||
}
|
}
|
||||||
|
|
||||||
async pages(): Promise<Page[]> {
|
async pages(): Promise<Page[]> {
|
||||||
return this._delegate.contextPages();
|
return this._delegate.pages();
|
||||||
}
|
|
||||||
|
|
||||||
isIncognito(): boolean {
|
|
||||||
return this._isIncognito;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async newPage(): Promise<Page> {
|
async newPage(): Promise<Page> {
|
||||||
return this._delegate.createPageInContext();
|
return this._delegate.newPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createOwnerPage(): Promise<Page> {
|
async _createOwnerPage(): Promise<Page> {
|
||||||
try {
|
try {
|
||||||
const page = await this._delegate.createPageInContext();
|
const page = await this._delegate.newPage();
|
||||||
page._isContextOwner = true;
|
page._isContextOwner = true;
|
||||||
return page;
|
return page;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -79,22 +72,21 @@ export class BrowserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
async cookies(...urls: string[]): Promise<network.NetworkCookie[]> {
|
async cookies(...urls: string[]): Promise<network.NetworkCookie[]> {
|
||||||
return network.filterCookies(await this._delegate.getContextCookies(), urls);
|
return network.filterCookies(await this._delegate.cookies(), urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearCookies() {
|
async clearCookies() {
|
||||||
await this._delegate.clearContextCookies();
|
await this._delegate.clearCookies();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setCookies(cookies: network.SetNetworkCookieParam[]) {
|
async setCookies(cookies: network.SetNetworkCookieParam[]) {
|
||||||
await this._delegate.setContextCookies(network.rewriteCookies(cookies));
|
await this._delegate.setCookies(network.rewriteCookies(cookies));
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
if (this._closed)
|
if (this._closed)
|
||||||
return;
|
return;
|
||||||
assert(this._isIncognito, 'Non-incognito profiles cannot be closed!');
|
await this._delegate.close();
|
||||||
await this._delegate.closeContext();
|
|
||||||
this._closed = true;
|
this._closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,16 +73,15 @@ export class Browser extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBrowserContext(contextId: string | null, options: BrowserContextOptions): BrowserContext {
|
_createBrowserContext(contextId: string | null, options: BrowserContextOptions): BrowserContext {
|
||||||
const isIncognito = !!contextId;
|
|
||||||
let overrides: Overrides | null = null;
|
let overrides: Overrides | null = null;
|
||||||
const context = new BrowserContext({
|
const context = new BrowserContext({
|
||||||
contextPages: async (): Promise<Page[]> => {
|
pages: async (): Promise<Page[]> => {
|
||||||
const targets = this._allTargets().filter(target => target.browserContext() === context && target.type() === 'page');
|
const targets = this._allTargets().filter(target => target.browserContext() === context && target.type() === 'page');
|
||||||
const pages = await Promise.all(targets.map(target => target.page()));
|
const pages = await Promise.all(targets.map(target => target.page()));
|
||||||
return pages.filter(page => !!page);
|
return pages.filter(page => !!page);
|
||||||
},
|
},
|
||||||
|
|
||||||
createPageInContext: async (): Promise<Page> => {
|
newPage: async (): Promise<Page> => {
|
||||||
const { targetId } = await this._client.send('Target.createTarget', { url: 'about:blank', browserContextId: contextId || undefined });
|
const { targetId } = await this._client.send('Target.createTarget', { url: 'about:blank', browserContextId: contextId || undefined });
|
||||||
const target = this._targets.get(targetId);
|
const target = this._targets.get(targetId);
|
||||||
assert(await target._initializedPromise, 'Failed to create target for page');
|
assert(await target._initializedPromise, 'Failed to create target for page');
|
||||||
|
|
@ -109,12 +108,13 @@ export class Browser extends EventEmitter {
|
||||||
return page;
|
return page;
|
||||||
},
|
},
|
||||||
|
|
||||||
closeContext: async (): Promise<void> => {
|
close: async (): Promise<void> => {
|
||||||
|
assert(contextId, 'Non-incognito profiles cannot be closed!');
|
||||||
await this._client.send('Target.disposeBrowserContext', {browserContextId: contextId || undefined});
|
await this._client.send('Target.disposeBrowserContext', {browserContextId: contextId || undefined});
|
||||||
this._contexts.delete(contextId);
|
this._contexts.delete(contextId);
|
||||||
},
|
},
|
||||||
|
|
||||||
getContextCookies: async (): Promise<network.NetworkCookie[]> => {
|
cookies: async (): Promise<network.NetworkCookie[]> => {
|
||||||
const { cookies } = await this._client.send('Storage.getCookies', { browserContextId: contextId || undefined });
|
const { cookies } = await this._client.send('Storage.getCookies', { browserContextId: contextId || undefined });
|
||||||
return cookies.map(c => {
|
return cookies.map(c => {
|
||||||
const copy: any = { sameSite: 'None', ...c };
|
const copy: any = { sameSite: 'None', ...c };
|
||||||
|
|
@ -124,14 +124,14 @@ export class Browser extends EventEmitter {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
clearContextCookies: async (): Promise<void> => {
|
clearCookies: async (): Promise<void> => {
|
||||||
await this._client.send('Storage.clearCookies', { browserContextId: contextId || undefined });
|
await this._client.send('Storage.clearCookies', { browserContextId: contextId || undefined });
|
||||||
},
|
},
|
||||||
|
|
||||||
setContextCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
setCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
||||||
await this._client.send('Storage.setCookies', { cookies, browserContextId: contextId || undefined });
|
await this._client.send('Storage.setCookies', { cookies, browserContextId: contextId || undefined });
|
||||||
},
|
},
|
||||||
}, isIncognito, options);
|
}, options);
|
||||||
overrides = new Overrides(context);
|
overrides = new Overrides(context);
|
||||||
(context as any).permissions = new Permissions(this._client, contextId);
|
(context as any).permissions = new Permissions(this._client, contextId);
|
||||||
(context as any).overrides = overrides;
|
(context as any).overrides = overrides;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { helper, RegisteredListener } from '../helper';
|
import { helper, RegisteredListener, assert } from '../helper';
|
||||||
import { Connection, ConnectionEvents, JugglerSessionEvents } from './Connection';
|
import { Connection, ConnectionEvents, JugglerSessionEvents } from './Connection';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { Events as CommonEvents } from '../events';
|
import { Events as CommonEvents } from '../events';
|
||||||
|
|
@ -175,15 +175,14 @@ export class Browser extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBrowserContext(browserContextId: string | null, options: BrowserContextOptions): BrowserContext {
|
_createBrowserContext(browserContextId: string | null, options: BrowserContextOptions): BrowserContext {
|
||||||
const isIncognito = !!browserContextId;
|
|
||||||
const context = new BrowserContext({
|
const context = new BrowserContext({
|
||||||
contextPages: async (): Promise<Page[]> => {
|
pages: async (): Promise<Page[]> => {
|
||||||
const targets = this._allTargets().filter(target => target.browserContext() === context && target.type() === 'page');
|
const targets = this._allTargets().filter(target => target.browserContext() === context && target.type() === 'page');
|
||||||
const pages = await Promise.all(targets.map(target => target.page()));
|
const pages = await Promise.all(targets.map(target => target.page()));
|
||||||
return pages.filter(page => !!page);
|
return pages.filter(page => !!page);
|
||||||
},
|
},
|
||||||
|
|
||||||
createPageInContext: async (): Promise<Page> => {
|
newPage: async (): Promise<Page> => {
|
||||||
const {targetId} = await this._connection.send('Target.newPage', {
|
const {targetId} = await this._connection.send('Target.newPage', {
|
||||||
browserContextId: browserContextId || undefined
|
browserContextId: browserContextId || undefined
|
||||||
});
|
});
|
||||||
|
|
@ -205,12 +204,13 @@ export class Browser extends EventEmitter {
|
||||||
return page;
|
return page;
|
||||||
},
|
},
|
||||||
|
|
||||||
closeContext: async (): Promise<void> => {
|
close: async (): Promise<void> => {
|
||||||
|
assert(browserContextId, 'Non-incognito profiles cannot be closed!');
|
||||||
await this._connection.send('Target.removeBrowserContext', { browserContextId });
|
await this._connection.send('Target.removeBrowserContext', { browserContextId });
|
||||||
this._contexts.delete(browserContextId);
|
this._contexts.delete(browserContextId);
|
||||||
},
|
},
|
||||||
|
|
||||||
getContextCookies: async (): Promise<network.NetworkCookie[]> => {
|
cookies: async (): Promise<network.NetworkCookie[]> => {
|
||||||
const { cookies } = await this._connection.send('Browser.getCookies', { browserContextId: browserContextId || undefined });
|
const { cookies } = await this._connection.send('Browser.getCookies', { browserContextId: browserContextId || undefined });
|
||||||
return cookies.map(c => {
|
return cookies.map(c => {
|
||||||
const copy: any = { ... c };
|
const copy: any = { ... c };
|
||||||
|
|
@ -219,14 +219,14 @@ export class Browser extends EventEmitter {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
clearContextCookies: async (): Promise<void> => {
|
clearCookies: async (): Promise<void> => {
|
||||||
await this._connection.send('Browser.clearCookies', { browserContextId: browserContextId || undefined });
|
await this._connection.send('Browser.clearCookies', { browserContextId: browserContextId || undefined });
|
||||||
},
|
},
|
||||||
|
|
||||||
setContextCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
setCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
||||||
await this._connection.send('Browser.setCookies', { browserContextId: browserContextId || undefined, cookies });
|
await this._connection.send('Browser.setCookies', { browserContextId: browserContextId || undefined, cookies });
|
||||||
},
|
},
|
||||||
}, isIncognito, options);
|
}, options);
|
||||||
(context as any).permissions = new Permissions(this._connection, browserContextId);
|
(context as any).permissions = new Permissions(this._connection, browserContextId);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { helper, RegisteredListener, debugError } from '../helper';
|
import { helper, RegisteredListener, debugError, assert } from '../helper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import { Connection, ConnectionEvents, TargetSession } from './Connection';
|
import { Connection, ConnectionEvents, TargetSession } from './Connection';
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
|
|
@ -209,26 +209,26 @@ export class Browser extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBrowserContext(browserContextId: string | undefined, options: BrowserContextOptions): BrowserContext {
|
_createBrowserContext(browserContextId: string | undefined, options: BrowserContextOptions): BrowserContext {
|
||||||
const isIncognito = !!browserContextId;
|
|
||||||
const context = new BrowserContext({
|
const context = new BrowserContext({
|
||||||
contextPages: async (): Promise<Page[]> => {
|
pages: async (): Promise<Page[]> => {
|
||||||
const targets = this.targets().filter(target => target._browserContext === context && target._type === 'page');
|
const targets = this.targets().filter(target => target._browserContext === context && target._type === 'page');
|
||||||
const pages = await Promise.all(targets.map(target => target.page()));
|
const pages = await Promise.all(targets.map(target => target.page()));
|
||||||
return pages.filter(page => !!page);
|
return pages.filter(page => !!page);
|
||||||
},
|
},
|
||||||
|
|
||||||
createPageInContext: async (): Promise<Page> => {
|
newPage: async (): Promise<Page> => {
|
||||||
const { targetId } = await this._connection.send('Browser.createPage', { browserContextId });
|
const { targetId } = await this._connection.send('Browser.createPage', { browserContextId });
|
||||||
const target = this._targets.get(targetId);
|
const target = this._targets.get(targetId);
|
||||||
return await target.page();
|
return await target.page();
|
||||||
},
|
},
|
||||||
|
|
||||||
closeContext: async (): Promise<void> => {
|
close: async (): Promise<void> => {
|
||||||
|
assert(browserContextId, 'Non-incognito profiles cannot be closed!');
|
||||||
await this._connection.send('Browser.deleteContext', { browserContextId });
|
await this._connection.send('Browser.deleteContext', { browserContextId });
|
||||||
this._contexts.delete(browserContextId);
|
this._contexts.delete(browserContextId);
|
||||||
},
|
},
|
||||||
|
|
||||||
getContextCookies: async (): Promise<network.NetworkCookie[]> => {
|
cookies: async (): Promise<network.NetworkCookie[]> => {
|
||||||
const { cookies } = await this._connection.send('Browser.getAllCookies', { browserContextId });
|
const { cookies } = await this._connection.send('Browser.getAllCookies', { browserContextId });
|
||||||
return cookies.map((c: network.NetworkCookie) => ({
|
return cookies.map((c: network.NetworkCookie) => ({
|
||||||
...c,
|
...c,
|
||||||
|
|
@ -236,15 +236,15 @@ export class Browser extends EventEmitter {
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
clearContextCookies: async (): Promise<void> => {
|
clearCookies: async (): Promise<void> => {
|
||||||
await this._connection.send('Browser.deleteAllCookies', { browserContextId });
|
await this._connection.send('Browser.deleteAllCookies', { browserContextId });
|
||||||
},
|
},
|
||||||
|
|
||||||
setContextCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
setCookies: async (cookies: network.SetNetworkCookieParam[]): Promise<void> => {
|
||||||
const cc = cookies.map(c => ({ ...c, session: c.expires === -1 || c.expires === undefined })) as Protocol.Browser.SetCookieParam[];
|
const cc = cookies.map(c => ({ ...c, session: c.expires === -1 || c.expires === undefined })) as Protocol.Browser.SetCookieParam[];
|
||||||
await this._connection.send('Browser.setCookies', { cookies: cc, browserContextId });
|
await this._connection.send('Browser.setCookies', { cookies: cc, browserContextId });
|
||||||
},
|
},
|
||||||
}, isIncognito, options);
|
}, options);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ module.exports.addTests = function({testRunner, expect, playwright, WEBKIT}) {
|
||||||
it('should have default context', async function({browser, server}) {
|
it('should have default context', async function({browser, server}) {
|
||||||
expect(browser.browserContexts().length).toBe(1);
|
expect(browser.browserContexts().length).toBe(1);
|
||||||
const defaultContext = browser.browserContexts()[0];
|
const defaultContext = browser.browserContexts()[0];
|
||||||
expect(defaultContext.isIncognito()).toBe(false);
|
|
||||||
let error = null;
|
let error = null;
|
||||||
await defaultContext.close().catch(e => error = e);
|
await defaultContext.close().catch(e => error = e);
|
||||||
expect(browser.defaultContext()).toBe(defaultContext);
|
expect(browser.defaultContext()).toBe(defaultContext);
|
||||||
|
|
@ -35,7 +34,6 @@ module.exports.addTests = function({testRunner, expect, playwright, WEBKIT}) {
|
||||||
it('should create new incognito context', async function({browser, newContext}) {
|
it('should create new incognito context', async function({browser, newContext}) {
|
||||||
expect(browser.browserContexts().length).toBe(1);
|
expect(browser.browserContexts().length).toBe(1);
|
||||||
const context = await newContext();
|
const context = await newContext();
|
||||||
expect(context.isIncognito()).toBe(true);
|
|
||||||
expect(browser.browserContexts().length).toBe(2);
|
expect(browser.browserContexts().length).toBe(2);
|
||||||
expect(browser.browserContexts().indexOf(context) !== -1).toBe(true);
|
expect(browser.browserContexts().indexOf(context) !== -1).toBe(true);
|
||||||
await context.close();
|
await context.close();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue