mirror of
https://github.com/hanzoai/puppeteer.git
synced 2026-09-24 17:02:14 +00:00
feat: support channel in puppeteer.connect (#14466)
This commit is contained in:
@@ -115,6 +115,27 @@ Only works for `protocol="webDriverBiDi"` and [Puppeteer.connect()](./puppeteer.
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="channel">channel</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
`optional`
|
||||
|
||||
</td><td>
|
||||
|
||||
[ChromeReleaseChannel](./puppeteer.chromereleasechannel.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
**_(Experimental)_** If specified, puppeteer looks for an open WebSocket at the well-known default user data directory for the specified channel and attempts to connect to it using ws://localhost:$ActivePort/devtools/browser. Only works for Chrome and when run in Node.js.
|
||||
|
||||
This option is experimental when used with puppeteer.connect().
|
||||
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="defaultviewport">defaultViewport</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
sidebar_label: resolveDefaultUserDataDir
|
||||
---
|
||||
|
||||
# resolveDefaultUserDataDir() function
|
||||
|
||||
Returns the expected default user data dir for the given channel. It does not check if the dir actually exists.
|
||||
|
||||
### Signature
|
||||
|
||||
```typescript
|
||||
export declare function resolveDefaultUserDataDir(
|
||||
browser: Browser,
|
||||
platform: BrowserPlatform,
|
||||
channel: ChromeReleaseChannel,
|
||||
): string;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
<table><thead><tr><th>
|
||||
|
||||
Parameter
|
||||
|
||||
</th><th>
|
||||
|
||||
Type
|
||||
|
||||
</th><th>
|
||||
|
||||
Description
|
||||
|
||||
</th></tr></thead>
|
||||
<tbody><tr><td>
|
||||
|
||||
browser
|
||||
|
||||
</td><td>
|
||||
|
||||
[Browser](./browsers.browser.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
platform
|
||||
|
||||
</td><td>
|
||||
|
||||
[BrowserPlatform](./browsers.browserplatform.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
channel
|
||||
|
||||
</td><td>
|
||||
|
||||
[ChromeReleaseChannel](./browsers.chromereleasechannel.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
</tbody></table>
|
||||
|
||||
**Returns:**
|
||||
|
||||
string
|
||||
@@ -309,6 +309,15 @@ Launches a browser process according to [LaunchOptions](./browsers.launchoptions
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="resolvedefaultuserdatadir">[resolveDefaultUserDataDir(browser, platform, channel)](./browsers.resolvedefaultuserdatadir.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
Returns the expected default user data dir for the given channel. It does not check if the dir actually exists.
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="uninstall">[uninstall(options)](./browsers.uninstall.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
@@ -40,6 +40,7 @@ export {
|
||||
ChromeReleaseChannel,
|
||||
createProfile,
|
||||
getVersionComparator,
|
||||
resolveDefaultUserDataDir,
|
||||
} from './browser-data/browser-data.js';
|
||||
export {CLI} from './CLI.js';
|
||||
export {
|
||||
|
||||
@@ -27,6 +27,9 @@ export default {
|
||||
if (id.includes('node_modules')) {
|
||||
return true;
|
||||
}
|
||||
if (id.includes('@puppeteer/browsers')) {
|
||||
return true;
|
||||
}
|
||||
if (id.startsWith(path.join(cwd, `lib`, `esm`, `puppeteer`, `bidi`))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import type {Browser} from '../api/Browser.js';
|
||||
import {_connectToBiDiBrowser} from '../bidi/BrowserConnector.js';
|
||||
import {_connectToCdpBrowser} from '../cdp/BrowserConnector.js';
|
||||
import {isNode} from '../environment.js';
|
||||
import {environment, isNode} from '../environment.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {isErrorLike} from '../util/ErrorLike.js';
|
||||
|
||||
@@ -84,6 +84,50 @@ async function getConnectionTransport(
|
||||
connectionTransport: connectionTransport,
|
||||
endpointUrl: connectionURL,
|
||||
};
|
||||
} else if (options.channel && isNode) {
|
||||
const {detectBrowserPlatform, resolveDefaultUserDataDir, Browser} =
|
||||
await import('@puppeteer/browsers');
|
||||
const platform = detectBrowserPlatform();
|
||||
if (!platform) {
|
||||
throw new Error('Could not detect required browser platform');
|
||||
}
|
||||
const {convertPuppeteerChannelToBrowsersChannel} = await import(
|
||||
'../node/LaunchOptions.js'
|
||||
);
|
||||
const {join} = await import('node:path');
|
||||
const userDataDir = resolveDefaultUserDataDir(
|
||||
Browser.CHROME,
|
||||
platform,
|
||||
convertPuppeteerChannelToBrowsersChannel(options.channel),
|
||||
);
|
||||
const portPath = join(userDataDir, 'DevToolsActivePort');
|
||||
try {
|
||||
const portRawValue = await environment.value.fs.promises.readFile(
|
||||
portPath,
|
||||
'ascii',
|
||||
);
|
||||
const port = parseInt(portRawValue, 10);
|
||||
if (isNaN(port) || port <= 0 || port > 65535) {
|
||||
throw new Error(`Invalid port '${portRawValue}' found`);
|
||||
}
|
||||
const browserWSEndpoint = `ws://localhost:${port}`;
|
||||
const WebSocketClass = await getWebSocketTransportClass();
|
||||
const connectionTransport = await WebSocketClass.create(
|
||||
browserWSEndpoint,
|
||||
headers,
|
||||
);
|
||||
return {
|
||||
connectionTransport: connectionTransport,
|
||||
endpointUrl: browserWSEndpoint,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Could not find DevToolsActivePort for ${options.channel} at ${portPath}`,
|
||||
{
|
||||
cause: error,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
throw new Error('Invalid connection options');
|
||||
}
|
||||
|
||||
@@ -38,6 +38,15 @@ export interface SupportedWebDriverCapabilities {
|
||||
alwaysMatch?: SupportedWebDriverCapability;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ChromeReleaseChannel =
|
||||
| 'chrome'
|
||||
| 'chrome-beta'
|
||||
| 'chrome-canary'
|
||||
| 'chrome-dev';
|
||||
|
||||
/**
|
||||
* Generic browser options that can be passed when launching any browser or when
|
||||
* connecting to an existing browser instance.
|
||||
@@ -49,6 +58,17 @@ export interface ConnectOptions {
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
acceptInsecureCerts?: boolean;
|
||||
/**
|
||||
* If specified, puppeteer looks for an open WebSocket at the well-known
|
||||
* default user data directory for the specified channel and attempts to
|
||||
* connect to it using ws://localhost:$ActivePort/devtools/browser. Only works
|
||||
* for Chrome and when run in Node.js.
|
||||
*
|
||||
* This option is experimental when used with puppeteer.connect().
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
channel?: ChromeReleaseChannel;
|
||||
/**
|
||||
* Experimental setting to disable monitoring network events by default. When
|
||||
* set to `false`, parts of Puppeteer that depend on network events would not
|
||||
|
||||
@@ -11,7 +11,6 @@ import path from 'node:path';
|
||||
import {
|
||||
computeSystemExecutablePath,
|
||||
Browser as SupportedBrowsers,
|
||||
ChromeReleaseChannel as BrowsersChromeReleaseChannel,
|
||||
} from '@puppeteer/browsers';
|
||||
|
||||
import type {Browser} from '../api/Browser.js';
|
||||
@@ -19,7 +18,11 @@ import {debugError} from '../common/util.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
|
||||
import {BrowserLauncher, type ResolvedLaunchArgs} from './BrowserLauncher.js';
|
||||
import type {ChromeReleaseChannel, LaunchOptions} from './LaunchOptions.js';
|
||||
import {
|
||||
convertPuppeteerChannelToBrowsersChannel,
|
||||
type ChromeReleaseChannel,
|
||||
type LaunchOptions,
|
||||
} from './LaunchOptions.js';
|
||||
import type {PuppeteerNode} from './PuppeteerNode.js';
|
||||
import {rm} from './util/fs.js';
|
||||
|
||||
@@ -285,21 +288,6 @@ export class ChromeLauncher extends BrowserLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
function convertPuppeteerChannelToBrowsersChannel(
|
||||
channel: ChromeReleaseChannel,
|
||||
): BrowsersChromeReleaseChannel {
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
return BrowsersChromeReleaseChannel.STABLE;
|
||||
case 'chrome-dev':
|
||||
return BrowsersChromeReleaseChannel.DEV;
|
||||
case 'chrome-beta':
|
||||
return BrowsersChromeReleaseChannel.BETA;
|
||||
case 'chrome-canary':
|
||||
return BrowsersChromeReleaseChannel.CANARY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all features from the given command-line flag
|
||||
* (e.g. `--enable-features`, `--enable-features=`).
|
||||
|
||||
@@ -4,17 +4,33 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ConnectOptions} from '../common/ConnectOptions.js';
|
||||
import {ChromeReleaseChannel as BrowsersChromeReleaseChannel} from '@puppeteer/browsers';
|
||||
|
||||
import type {
|
||||
ChromeReleaseChannel,
|
||||
ConnectOptions,
|
||||
} from '../common/ConnectOptions.js';
|
||||
import type {SupportedBrowser} from '../common/SupportedBrowser.js';
|
||||
|
||||
export type {ChromeReleaseChannel};
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @internal
|
||||
*/
|
||||
export type ChromeReleaseChannel =
|
||||
| 'chrome'
|
||||
| 'chrome-beta'
|
||||
| 'chrome-canary'
|
||||
| 'chrome-dev';
|
||||
export function convertPuppeteerChannelToBrowsersChannel(
|
||||
channel: ChromeReleaseChannel,
|
||||
): BrowsersChromeReleaseChannel {
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
return BrowsersChromeReleaseChannel.STABLE;
|
||||
case 'chrome-dev':
|
||||
return BrowsersChromeReleaseChannel.DEV;
|
||||
case 'chrome-beta':
|
||||
return BrowsersChromeReleaseChannel.BETA;
|
||||
case 'chrome-canary':
|
||||
return BrowsersChromeReleaseChannel.CANARY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic launch options that can be passed when launching any browser.
|
||||
|
||||
Reference in New Issue
Block a user