feat(context): introduce BrowserContext close event (#918)
This commit is contained in:
parent
5fee93ae96
commit
72b9cf010e
16
docs/api.md
16
docs/api.md
|
|
@ -159,7 +159,7 @@ See [ChromiumBrowser], [FirefoxBrowser] and [WebKitBrowser] for browser-specific
|
|||
#### event: 'disconnected'
|
||||
Emitted when Browser gets disconnected from the browser application. This might happen because of one of the following:
|
||||
- Browser application is closed or crashed.
|
||||
- The [`browser.disconnect`](#browserdisconnect) method was called.
|
||||
- The [`browser.close`](#browserclose) method was called.
|
||||
|
||||
#### browser.close()
|
||||
- returns: <[Promise]>
|
||||
|
|
@ -263,6 +263,7 @@ await context.close();
|
|||
```
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'close'](#event-close)
|
||||
- [browserContext.clearCookies()](#browsercontextclearcookies)
|
||||
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
||||
- [browserContext.close()](#browsercontextclose)
|
||||
|
|
@ -274,6 +275,13 @@ await context.close();
|
|||
- [browserContext.setPermissions(origin, permissions[])](#browsercontextsetpermissionsorigin-permissions)
|
||||
<!-- GEN:stop -->
|
||||
|
||||
#### event: 'close'
|
||||
|
||||
Emitted when Browser context gets closed. This might happen because of one of the following:
|
||||
- Browser context is closed.
|
||||
- Browser application is closed or crashed.
|
||||
- The [`browser.close`](#browserclose) method was called.
|
||||
|
||||
#### browserContext.clearCookies()
|
||||
- returns: <[Promise]>
|
||||
|
||||
|
|
@ -426,7 +434,7 @@ page.removeListener('request', logRequest);
|
|||
```
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'close'](#event-close)
|
||||
- [event: 'close'](#event-close-1)
|
||||
- [event: 'console'](#event-console)
|
||||
- [event: 'dialog'](#event-dialog)
|
||||
- [event: 'domcontentloaded'](#event-domcontentloaded)
|
||||
|
|
@ -3168,7 +3176,7 @@ const { selectors, firefox } = require('playwright'); // Or 'chromium' or 'webk
|
|||
The [WebSocket] class represents websocket connections in the page.
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'close'](#event-close-1)
|
||||
- [event: 'close'](#event-close-2)
|
||||
- [event: 'error'](#event-error)
|
||||
- [event: 'messageReceived'](#event-messagereceived)
|
||||
- [event: 'messageSent'](#event-messagesent)
|
||||
|
|
@ -3423,7 +3431,7 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then
|
|||
### class: BrowserServer
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'close'](#event-close-2)
|
||||
- [event: 'close'](#event-close-3)
|
||||
- [browserServer.close()](#browserserverclose)
|
||||
- [browserServer.kill()](#browserserverkill)
|
||||
- [browserServer.process()](#browserserverprocess)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ export interface Browser extends platform.EventEmitterType {
|
|||
newPage(options?: BrowserContextOptions): Promise<Page>;
|
||||
isConnected(): boolean;
|
||||
close(): Promise<void>;
|
||||
_defaultContext: BrowserContext | undefined;
|
||||
}
|
||||
|
||||
export type ConnectOptions = {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ import { Page } from './page';
|
|||
import * as network from './network';
|
||||
import * as types from './types';
|
||||
import { helper } from './helper';
|
||||
import * as platform from './platform';
|
||||
import { Events } from './events';
|
||||
|
||||
export interface BrowserContextDelegate {
|
||||
pages(): Promise<Page[]>;
|
||||
|
|
@ -47,12 +49,13 @@ export type BrowserContextOptions = {
|
|||
permissions?: { [key: string]: string[] };
|
||||
};
|
||||
|
||||
export class BrowserContext {
|
||||
export class BrowserContext extends platform.EventEmitter {
|
||||
private readonly _delegate: BrowserContextDelegate;
|
||||
readonly _options: BrowserContextOptions;
|
||||
private _closed = false;
|
||||
|
||||
constructor(delegate: BrowserContextDelegate, options: BrowserContextOptions) {
|
||||
super();
|
||||
this._delegate = delegate;
|
||||
this._options = { ...options };
|
||||
if (!this._options.viewport && this._options.viewport !== null)
|
||||
|
|
@ -114,12 +117,18 @@ export class BrowserContext {
|
|||
return;
|
||||
await this._delegate.close();
|
||||
this._closed = true;
|
||||
this.emit(Events.BrowserContext.Close);
|
||||
}
|
||||
|
||||
static validateOptions(options: BrowserContextOptions) {
|
||||
if (options.geolocation)
|
||||
verifyGeolocation(options.geolocation);
|
||||
}
|
||||
|
||||
_browserClosed() {
|
||||
this._closed = true;
|
||||
this.emit(Events.BrowserContext.Close);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyGeolocation(geolocation: types.Geolocation): types.Geolocation {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
|||
this._client = connection.rootSession;
|
||||
|
||||
this._defaultContext = this._createBrowserContext(null, {});
|
||||
this._connection.on(ConnectionEvents.Disconnected, () => this.emit(CommonEvents.Browser.Disconnected));
|
||||
this._connection.on(ConnectionEvents.Disconnected, () => {
|
||||
for (const context of this.contexts())
|
||||
context._browserClosed();
|
||||
this.emit(CommonEvents.Browser.Disconnected);
|
||||
});
|
||||
this._client.on('Target.targetCreated', this._targetCreated.bind(this));
|
||||
this._client.on('Target.targetDestroyed', this._targetDestroyed.bind(this));
|
||||
this._client.on('Target.targetInfoChanged', this._targetInfoChanged.bind(this));
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ export const Events = {
|
|||
Disconnected: 'disconnected'
|
||||
},
|
||||
|
||||
BrowserContext: {
|
||||
Close: 'close'
|
||||
},
|
||||
|
||||
BrowserServer: {
|
||||
Close: 'close',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -50,8 +50,11 @@ export class FFBrowser extends platform.EventEmitter implements Browser {
|
|||
|
||||
this._defaultContext = this._createBrowserContext(null, {});
|
||||
this._contexts = new Map();
|
||||
this._connection.on(ConnectionEvents.Disconnected, () => this.emit(Events.Browser.Disconnected));
|
||||
|
||||
this._connection.on(ConnectionEvents.Disconnected, () => {
|
||||
for (const context of this.contexts())
|
||||
context._browserClosed();
|
||||
this.emit(Events.Browser.Disconnected);
|
||||
});
|
||||
this._eventListeners = [
|
||||
helper.addEventListener(this._connection, 'Target.targetCreated', this._onTargetCreated.bind(this)),
|
||||
helper.addEventListener(this._connection, 'Target.targetDestroyed', this._onTargetDestroyed.bind(this)),
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ export class WebKit implements BrowserType {
|
|||
handleSIGINT = true,
|
||||
handleSIGTERM = true,
|
||||
handleSIGHUP = true,
|
||||
timeout = 30000
|
||||
} = options;
|
||||
|
||||
let temporaryUserDataDir: string | null = null;
|
||||
|
|
@ -136,7 +135,6 @@ export class WebKit implements BrowserType {
|
|||
},
|
||||
});
|
||||
|
||||
const timeoutError = new TimeoutError(`Timed out after ${timeout} ms while trying to connect to WebKit!`);
|
||||
transport = new PipeTransport(launchedProcess.stdio[3] as NodeJS.WritableStream, launchedProcess.stdio[4] as NodeJS.ReadableStream);
|
||||
browserServer = new BrowserServer(launchedProcess, gracefullyClose, launchType === 'server' ? await wrapTransportWithWebSocket(transport, port || 0) : null);
|
||||
return { browserServer, transport };
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
|
|||
}
|
||||
|
||||
_onDisconnect() {
|
||||
for (const context of this.contexts())
|
||||
context._browserClosed();
|
||||
for (const pageProxy of this._pageProxies.values())
|
||||
pageProxy.dispose();
|
||||
this._pageProxies.clear();
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
|||
await page.goto(server.EMPTY_PAGE);
|
||||
const target = await targetPromise;
|
||||
expect(await target.page()).toBe(page);
|
||||
await page.close();
|
||||
await page.context().close();
|
||||
});
|
||||
it('should fire target events', async function({browser, newContext, server}) {
|
||||
const context = await newContext();
|
||||
|
|
|
|||
|
|
@ -172,6 +172,19 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
|||
expect(error.message).toContain('has been closed');
|
||||
await browserServer.close();
|
||||
});
|
||||
it('should emit close events on pages and contexts', async({server}) => {
|
||||
const browserServer = await playwright.launchServer({...defaultBrowserOptions });
|
||||
const remote = await playwright.connect({ wsEndpoint: browserServer.wsEndpoint() });
|
||||
const context = await remote.newContext();
|
||||
const page = await context.newPage();
|
||||
let contextClosed = false;
|
||||
let pageClosed = false;
|
||||
context.on('close', e => contextClosed = true);
|
||||
page.on('close', e => pageClosed = true);
|
||||
await browserServer.close();
|
||||
expect(contextClosed).toBeTruthy();
|
||||
expect(pageClosed).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Browser.close', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue