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.
|
||||
- `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Puppeteer to use.
|
||||
- `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]>>
|
||||
|
||||
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`.
|
||||
- `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`)
|
||||
- `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.
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type TargetFilterCallback = (
|
||||
target: Protocol.Target.TargetInfo
|
||||
) => Promise<boolean> | boolean;
|
||||
|
||||
const WEB_PERMISSION_TO_PROTOCOL_PERMISSION = new Map<
|
||||
Permission,
|
||||
Protocol.Browser.PermissionType
|
||||
@ -189,7 +196,8 @@ export class Browser extends EventEmitter {
|
||||
ignoreHTTPSErrors: boolean,
|
||||
defaultViewport?: Viewport | null,
|
||||
process?: ChildProcess,
|
||||
closeCallback?: BrowserCloseCallback
|
||||
closeCallback?: BrowserCloseCallback,
|
||||
targetFilterCallback?: TargetFilterCallback
|
||||
): Promise<Browser> {
|
||||
const browser = new Browser(
|
||||
connection,
|
||||
@ -197,7 +205,8 @@ export class Browser extends EventEmitter {
|
||||
ignoreHTTPSErrors,
|
||||
defaultViewport,
|
||||
process,
|
||||
closeCallback
|
||||
closeCallback,
|
||||
targetFilterCallback
|
||||
);
|
||||
await connection.send('Target.setDiscoverTargets', { discover: true });
|
||||
return browser;
|
||||
@ -207,6 +216,7 @@ export class Browser extends EventEmitter {
|
||||
private _process?: ChildProcess;
|
||||
private _connection: Connection;
|
||||
private _closeCallback: BrowserCloseCallback;
|
||||
private _targetFilterCallback: TargetFilterCallback;
|
||||
private _defaultContext: BrowserContext;
|
||||
private _contexts: Map<string, BrowserContext>;
|
||||
/**
|
||||
@ -224,7 +234,8 @@ export class Browser extends EventEmitter {
|
||||
ignoreHTTPSErrors: boolean,
|
||||
defaultViewport?: Viewport | null,
|
||||
process?: ChildProcess,
|
||||
closeCallback?: BrowserCloseCallback
|
||||
closeCallback?: BrowserCloseCallback,
|
||||
targetFilterCallback?: TargetFilterCallback
|
||||
) {
|
||||
super();
|
||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||
@ -232,6 +243,7 @@ export class Browser extends EventEmitter {
|
||||
this._process = process;
|
||||
this._connection = connection;
|
||||
this._closeCallback = closeCallback || function (): void {};
|
||||
this._targetFilterCallback = targetFilterCallback || ((): boolean => true);
|
||||
|
||||
this._defaultContext = new BrowserContext(this._connection, this, null);
|
||||
this._contexts = new Map();
|
||||
@ -330,6 +342,11 @@ export class Browser extends EventEmitter {
|
||||
? this._contexts.get(browserContextId)
|
||||
: this._defaultContext;
|
||||
|
||||
const shouldAttachToTarget = await this._targetFilterCallback(targetInfo);
|
||||
if (!shouldAttachToTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = new Target(
|
||||
targetInfo,
|
||||
context,
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ConnectionTransport } from './ConnectionTransport.js';
|
||||
import { Browser } from './Browser.js';
|
||||
import { Browser, TargetFilterCallback } from './Browser.js';
|
||||
import { assert } from './assert.js';
|
||||
import { debugError } from '../common/helper.js';
|
||||
import { Connection } from './Connection.js';
|
||||
@ -43,6 +43,10 @@ export interface BrowserConnectOptions {
|
||||
* aid debugging.
|
||||
*/
|
||||
slowMo?: number;
|
||||
/**
|
||||
* Callback to decide if Puppeteer should connect to a given target or not.
|
||||
*/
|
||||
targetFilter?: TargetFilterCallback;
|
||||
}
|
||||
|
||||
const getWebSocketTransportClass = async () => {
|
||||
@ -71,6 +75,7 @@ export const connectToBrowser = async (
|
||||
defaultViewport = { width: 800, height: 600 },
|
||||
transport,
|
||||
slowMo = 0,
|
||||
targetFilter,
|
||||
} = options;
|
||||
|
||||
assert(
|
||||
@ -106,7 +111,8 @@ export const connectToBrowser = async (
|
||||
ignoreHTTPSErrors,
|
||||
defaultViewport,
|
||||
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 sinon from 'sinon';
|
||||
import { promisify } from 'util';
|
||||
import Protocol from 'devtools-protocol';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
@ -538,6 +539,35 @@ describe('Launcher specs', function () {
|
||||
await page.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(
|
||||
'should be able to reconnect to a disconnected browser',
|
||||
async () => {
|
||||
|
Loading…
Reference in New Issue
Block a user