mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: add option to filter targets (#7192)
* feat: add option to filter targets Co-authored-by: Mathias Bynens <mathias@qiwi.be>
This commit is contained in:
parent
a293b96952
commit
ec3fc2e035
@ -516,6 +516,7 @@ Clears all registered handlers.
|
|||||||
- `slowMo` <[number]> Slows down Puppeteer operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
- `slowMo` <[number]> Slows down Puppeteer operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
||||||
- `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Puppeteer to use.
|
- `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Puppeteer to use.
|
||||||
- `product` <[string]> Possible values are: `chrome`, `firefox`. Defaults to `chrome`.
|
- `product` <[string]> Possible values are: `chrome`, `firefox`. Defaults to `chrome`.
|
||||||
|
- `targetFilter` <?[function]\([Protocol.Target.TargetInfo]\):[Promise]<[boolean]>|[boolean]> Use this function to decide if Puppeteer should connect to the given target. If a `targetFilter` is provided, Puppeteer only connects to targets for which `targetFilter` returns `true`. By default, Puppeteer connects to all available targets.
|
||||||
- returns: <[Promise]<[Browser]>>
|
- returns: <[Promise]<[Browser]>>
|
||||||
|
|
||||||
This methods attaches Puppeteer to an existing browser instance.
|
This methods attaches Puppeteer to an existing browser instance.
|
||||||
@ -623,6 +624,7 @@ try {
|
|||||||
- `devtools` <[boolean]> Whether to auto-open a DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
|
- `devtools` <[boolean]> Whether to auto-open a DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
|
||||||
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
||||||
- `extraPrefsFirefox` <[Object]> Additional [preferences](https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Preference_reference) that can be passed to Firefox (see `PUPPETEER_PRODUCT`)
|
- `extraPrefsFirefox` <[Object]> Additional [preferences](https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Preference_reference) that can be passed to Firefox (see `PUPPETEER_PRODUCT`)
|
||||||
|
- `targetFilter` <?[function]\([Protocol.Target.TargetInfo]\):[Promise]<[boolean]>|[boolean]> Use this function to decide if Puppeteer should connect to the given target. If a `targetFilter` is provided, Puppeteer only connects to targets for which `targetFilter` returns `true`. By default, Puppeteer connects to all available targets.
|
||||||
- returns: <[Promise]<[Browser]>> Promise which resolves to browser instance.
|
- returns: <[Promise]<[Browser]>> Promise which resolves to browser instance.
|
||||||
|
|
||||||
You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments:
|
You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments:
|
||||||
|
@ -29,6 +29,13 @@ import { Viewport } from './PuppeteerViewport.js';
|
|||||||
*/
|
*/
|
||||||
export type BrowserCloseCallback = () => Promise<void> | void;
|
export type BrowserCloseCallback = () => Promise<void> | void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type TargetFilterCallback = (
|
||||||
|
target: Protocol.Target.TargetInfo
|
||||||
|
) => Promise<boolean> | boolean;
|
||||||
|
|
||||||
const WEB_PERMISSION_TO_PROTOCOL_PERMISSION = new Map<
|
const WEB_PERMISSION_TO_PROTOCOL_PERMISSION = new Map<
|
||||||
Permission,
|
Permission,
|
||||||
Protocol.Browser.PermissionType
|
Protocol.Browser.PermissionType
|
||||||
@ -189,7 +196,8 @@ export class Browser extends EventEmitter {
|
|||||||
ignoreHTTPSErrors: boolean,
|
ignoreHTTPSErrors: boolean,
|
||||||
defaultViewport?: Viewport | null,
|
defaultViewport?: Viewport | null,
|
||||||
process?: ChildProcess,
|
process?: ChildProcess,
|
||||||
closeCallback?: BrowserCloseCallback
|
closeCallback?: BrowserCloseCallback,
|
||||||
|
targetFilterCallback?: TargetFilterCallback
|
||||||
): Promise<Browser> {
|
): Promise<Browser> {
|
||||||
const browser = new Browser(
|
const browser = new Browser(
|
||||||
connection,
|
connection,
|
||||||
@ -197,7 +205,8 @@ export class Browser extends EventEmitter {
|
|||||||
ignoreHTTPSErrors,
|
ignoreHTTPSErrors,
|
||||||
defaultViewport,
|
defaultViewport,
|
||||||
process,
|
process,
|
||||||
closeCallback
|
closeCallback,
|
||||||
|
targetFilterCallback
|
||||||
);
|
);
|
||||||
await connection.send('Target.setDiscoverTargets', { discover: true });
|
await connection.send('Target.setDiscoverTargets', { discover: true });
|
||||||
return browser;
|
return browser;
|
||||||
@ -207,6 +216,7 @@ export class Browser extends EventEmitter {
|
|||||||
private _process?: ChildProcess;
|
private _process?: ChildProcess;
|
||||||
private _connection: Connection;
|
private _connection: Connection;
|
||||||
private _closeCallback: BrowserCloseCallback;
|
private _closeCallback: BrowserCloseCallback;
|
||||||
|
private _targetFilterCallback: TargetFilterCallback;
|
||||||
private _defaultContext: BrowserContext;
|
private _defaultContext: BrowserContext;
|
||||||
private _contexts: Map<string, BrowserContext>;
|
private _contexts: Map<string, BrowserContext>;
|
||||||
/**
|
/**
|
||||||
@ -224,7 +234,8 @@ export class Browser extends EventEmitter {
|
|||||||
ignoreHTTPSErrors: boolean,
|
ignoreHTTPSErrors: boolean,
|
||||||
defaultViewport?: Viewport | null,
|
defaultViewport?: Viewport | null,
|
||||||
process?: ChildProcess,
|
process?: ChildProcess,
|
||||||
closeCallback?: BrowserCloseCallback
|
closeCallback?: BrowserCloseCallback,
|
||||||
|
targetFilterCallback?: TargetFilterCallback
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||||
@ -232,6 +243,7 @@ export class Browser extends EventEmitter {
|
|||||||
this._process = process;
|
this._process = process;
|
||||||
this._connection = connection;
|
this._connection = connection;
|
||||||
this._closeCallback = closeCallback || function (): void {};
|
this._closeCallback = closeCallback || function (): void {};
|
||||||
|
this._targetFilterCallback = targetFilterCallback || ((): boolean => true);
|
||||||
|
|
||||||
this._defaultContext = new BrowserContext(this._connection, this, null);
|
this._defaultContext = new BrowserContext(this._connection, this, null);
|
||||||
this._contexts = new Map();
|
this._contexts = new Map();
|
||||||
@ -330,6 +342,11 @@ export class Browser extends EventEmitter {
|
|||||||
? this._contexts.get(browserContextId)
|
? this._contexts.get(browserContextId)
|
||||||
: this._defaultContext;
|
: this._defaultContext;
|
||||||
|
|
||||||
|
const shouldAttachToTarget = await this._targetFilterCallback(targetInfo);
|
||||||
|
if (!shouldAttachToTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const target = new Target(
|
const target = new Target(
|
||||||
targetInfo,
|
targetInfo,
|
||||||
context,
|
context,
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ConnectionTransport } from './ConnectionTransport.js';
|
import { ConnectionTransport } from './ConnectionTransport.js';
|
||||||
import { Browser } from './Browser.js';
|
import { Browser, TargetFilterCallback } from './Browser.js';
|
||||||
import { assert } from './assert.js';
|
import { assert } from './assert.js';
|
||||||
import { debugError } from '../common/helper.js';
|
import { debugError } from '../common/helper.js';
|
||||||
import { Connection } from './Connection.js';
|
import { Connection } from './Connection.js';
|
||||||
@ -43,6 +43,10 @@ export interface BrowserConnectOptions {
|
|||||||
* aid debugging.
|
* aid debugging.
|
||||||
*/
|
*/
|
||||||
slowMo?: number;
|
slowMo?: number;
|
||||||
|
/**
|
||||||
|
* Callback to decide if Puppeteer should connect to a given target or not.
|
||||||
|
*/
|
||||||
|
targetFilter?: TargetFilterCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getWebSocketTransportClass = async () => {
|
const getWebSocketTransportClass = async () => {
|
||||||
@ -71,6 +75,7 @@ export const connectToBrowser = async (
|
|||||||
defaultViewport = { width: 800, height: 600 },
|
defaultViewport = { width: 800, height: 600 },
|
||||||
transport,
|
transport,
|
||||||
slowMo = 0,
|
slowMo = 0,
|
||||||
|
targetFilter,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@ -106,7 +111,8 @@ export const connectToBrowser = async (
|
|||||||
ignoreHTTPSErrors,
|
ignoreHTTPSErrors,
|
||||||
defaultViewport,
|
defaultViewport,
|
||||||
null,
|
null,
|
||||||
() => connection.send('Browser.close').catch(debugError)
|
() => connection.send('Browser.close').catch(debugError),
|
||||||
|
targetFilter
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import os from 'os';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
import Protocol from 'devtools-protocol';
|
||||||
import {
|
import {
|
||||||
getTestState,
|
getTestState,
|
||||||
itFailsFirefox,
|
itFailsFirefox,
|
||||||
@ -538,6 +539,35 @@ describe('Launcher specs', function () {
|
|||||||
await page.close();
|
await page.close();
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
it('should support targetFilter option', async () => {
|
||||||
|
const { server, puppeteer, defaultBrowserOptions } = getTestState();
|
||||||
|
|
||||||
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
|
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
||||||
|
|
||||||
|
const page1 = await originalBrowser.newPage();
|
||||||
|
await page1.goto(server.EMPTY_PAGE);
|
||||||
|
|
||||||
|
const page2 = await originalBrowser.newPage();
|
||||||
|
await page2.goto(server.EMPTY_PAGE + '?should-be-ignored');
|
||||||
|
|
||||||
|
const browser = await puppeteer.connect({
|
||||||
|
browserWSEndpoint,
|
||||||
|
targetFilter: (targetInfo: Protocol.Target.TargetInfo) =>
|
||||||
|
!targetInfo.url.includes('should-be-ignored'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const pages = await browser.pages();
|
||||||
|
|
||||||
|
await page2.close();
|
||||||
|
await page1.close();
|
||||||
|
await browser.close();
|
||||||
|
|
||||||
|
expect(pages.map((p: Page) => p.url()).sort()).toEqual([
|
||||||
|
'about:blank',
|
||||||
|
server.EMPTY_PAGE,
|
||||||
|
]);
|
||||||
|
});
|
||||||
itFailsFirefox(
|
itFailsFirefox(
|
||||||
'should be able to reconnect to a disconnected browser',
|
'should be able to reconnect to a disconnected browser',
|
||||||
async () => {
|
async () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user