mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: use configuration files (#9140)
This PR adds configurations files to `puppeteer`'s methods for configuration. Under the hood, `puppeteer` relies on https://www.npmjs.com/package/cosmiconfig which resolves several formats of configuration: - a `puppeteer` property in package.json - a `.puppeteerrc` file in JSON or YAML format - a `.puppeteerrc.json`, `.puppeteerrc.yaml`, `.puppeteerrc.yml`, `.puppeteerrc.js`, or `.puppeteerrc.cjs` file - a `puppeteer.config.js` or `puppeteer.config.cjs` CommonJS module exporting an object Documentation will be added later. Fixed: #9128
This commit is contained in:
parent
efcbc97c60
commit
ec201744f0
@ -30,6 +30,7 @@ sidebar_label: API
|
||||
| [Keyboard](./puppeteer.keyboard.md) | Keyboard provides an api for managing a virtual keyboard. The high level api is [Keyboard.type()](./puppeteer.keyboard.type.md), which takes raw characters and generates proper keydown, keypress/input, and keyup events on your page. |
|
||||
| [Mouse](./puppeteer.mouse.md) | The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport. |
|
||||
| [Page](./puppeteer.page.md) | <p>Page provides methods to interact with a single tab or [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium.</p><p>:::note</p><p>One Browser instance might have multiple Page instances.</p><p>:::</p> |
|
||||
| [ProductLauncher](./puppeteer.productlauncher.md) | Describes a launcher - a class that is able to create and launch a browser instance. |
|
||||
| [ProtocolError](./puppeteer.protocolerror.md) | ProtocolError is emitted whenever there is an error from the protocol. |
|
||||
| [Puppeteer](./puppeteer.puppeteer.md) | <p>The main Puppeteer class.</p><p>IMPORTANT: if you are using Puppeteer in a Node environment, you will get an instance of [PuppeteerNode](./puppeteer.puppeteernode.md) when you import or require <code>puppeteer</code>. That class extends <code>Puppeteer</code>, so has all the methods documented below as well as all that are defined on [PuppeteerNode](./puppeteer.puppeteernode.md).</p> |
|
||||
| [PuppeteerNode](./puppeteer.puppeteernode.md) | <p>Extends the main [Puppeteer](./puppeteer.puppeteer.md) class with Node specific behaviour for fetching and downloading browsers.</p><p>If you're using Puppeteer in a Node environment, this is the class you'll get when you run <code>require('puppeteer')</code> (or the equivalent ES <code>import</code>).</p> |
|
||||
@ -72,6 +73,7 @@ sidebar_label: API
|
||||
| [CDPSessionOnMessageObject](./puppeteer.cdpsessiononmessageobject.md) | |
|
||||
| [ClickOptions](./puppeteer.clickoptions.md) | |
|
||||
| [CommonEventEmitter](./puppeteer.commoneventemitter.md) | |
|
||||
| [Configuration](./puppeteer.configuration.md) | |
|
||||
| [ConnectionCallback](./puppeteer.connectioncallback.md) | |
|
||||
| [ConnectionTransport](./puppeteer.connectiontransport.md) | |
|
||||
| [ConnectOptions](./puppeteer.connectoptions.md) | |
|
||||
@ -102,7 +104,6 @@ sidebar_label: API
|
||||
| [PDFOptions](./puppeteer.pdfoptions.md) | Valid options to configure PDF generation via [Page.pdf()](./puppeteer.page.pdf.md). |
|
||||
| [Point](./puppeteer.point.md) | |
|
||||
| [PressOptions](./puppeteer.pressoptions.md) | |
|
||||
| [ProductLauncher](./puppeteer.productlauncher.md) | Describes a launcher - a class that is able to create and launch a browser instance. |
|
||||
| [PuppeteerErrors](./puppeteer.puppeteererrors.md) | |
|
||||
| [PuppeteerLaunchOptions](./puppeteer.puppeteerlaunchoptions.md) | |
|
||||
| [RemoteAddress](./puppeteer.remoteaddress.md) | |
|
||||
|
@ -10,12 +10,12 @@ Constructs a browser fetcher for the given options.
|
||||
|
||||
```typescript
|
||||
class BrowserFetcher {
|
||||
constructor(options?: BrowserFetcherOptions);
|
||||
constructor(options: BrowserFetcherOptions);
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------------------------------------------------------------- | ----------------- |
|
||||
| options | [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | <i>(Optional)</i> |
|
||||
| --------- | ------------------------------------------------------------- | ----------- |
|
||||
| options | [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | |
|
||||
|
@ -8,15 +8,15 @@ sidebar_label: BrowserFetcher.localRevisions
|
||||
|
||||
```typescript
|
||||
class BrowserFetcher {
|
||||
localRevisions(): Promise<string[]>;
|
||||
localRevisions(): string[];
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
|
||||
Promise<string\[\]>
|
||||
string\[\]
|
||||
|
||||
A promise with a list of all revision strings (for the current `product`) available locally on disk.
|
||||
A list of all revision strings (for the current `product`) available locally on disk.
|
||||
|
||||
## Remarks
|
||||
|
||||
|
@ -21,7 +21,7 @@ BrowserFetcher is not designed to work concurrently with other instances of Brow
|
||||
An example of using BrowserFetcher to download a specific version of Chromium and running Puppeteer against it:
|
||||
|
||||
```ts
|
||||
const browserFetcher = new BrowserFetcher();
|
||||
const browserFetcher = new BrowserFetcher({path: 'path/to/download/folder'});
|
||||
const revisionInfo = await browserFetcher.download('533271');
|
||||
const browser = await puppeteer.launch({
|
||||
executablePath: revisionInfo.executablePath,
|
||||
|
@ -13,8 +13,9 @@ export interface BrowserFetcherOptions
|
||||
## Properties
|
||||
|
||||
| Property | Modifiers | Type | Description |
|
||||
| ---------------------------------------------------------- | --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| ---------------------------------------------------------------------------- | --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| [host?](./puppeteer.browserfetcheroptions.host.md) | | string | <i>(Optional)</i> Determines the host that will be used for downloading. |
|
||||
| [path?](./puppeteer.browserfetcheroptions.path.md) | | string | <i>(Optional)</i> Determines the path to download browsers to. |
|
||||
| [path](./puppeteer.browserfetcheroptions.path.md) | | string | Determines the path to download browsers to. |
|
||||
| [platform?](./puppeteer.browserfetcheroptions.platform.md) | | [Platform](./puppeteer.platform.md) | <i>(Optional)</i> Determines which platform the browser will be suited for. |
|
||||
| [product?](./puppeteer.browserfetcheroptions.product.md) | | 'chrome' \| 'firefox' | <i>(Optional)</i> Determines which product the [BrowserFetcher](./puppeteer.browserfetcher.md) is for. |
|
||||
| [useMacOSARMBinary?](./puppeteer.browserfetcheroptions.usemacosarmbinary.md) | | boolean | <i>(Optional)</i> Enables the use of the Chromium binary for macOS ARM. |
|
||||
|
@ -10,6 +10,6 @@ Determines the path to download browsers to.
|
||||
|
||||
```typescript
|
||||
interface BrowserFetcherOptions {
|
||||
path?: string;
|
||||
path: string;
|
||||
}
|
||||
```
|
||||
|
@ -0,0 +1,15 @@
|
||||
---
|
||||
sidebar_label: BrowserFetcherOptions.useMacOSARMBinary
|
||||
---
|
||||
|
||||
# BrowserFetcherOptions.useMacOSARMBinary property
|
||||
|
||||
Enables the use of the Chromium binary for macOS ARM.
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface BrowserFetcherOptions {
|
||||
useMacOSARMBinary?: boolean;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.browserrevision.md
Normal file
13
docs/api/puppeteer.configuration.browserrevision.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.browserRevision
|
||||
---
|
||||
|
||||
# Configuration.browserRevision property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
browserRevision?: string;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.cachedirectory.md
Normal file
13
docs/api/puppeteer.configuration.cachedirectory.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.cacheDirectory
|
||||
---
|
||||
|
||||
# Configuration.cacheDirectory property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
cacheDirectory?: string;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.defaultproduct.md
Normal file
13
docs/api/puppeteer.configuration.defaultproduct.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.defaultProduct
|
||||
---
|
||||
|
||||
# Configuration.defaultProduct property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
defaultProduct?: Product;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.downloadhost.md
Normal file
13
docs/api/puppeteer.configuration.downloadhost.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.downloadHost
|
||||
---
|
||||
|
||||
# Configuration.downloadHost property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
downloadHost?: string;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.downloadpath.md
Normal file
13
docs/api/puppeteer.configuration.downloadpath.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.downloadPath
|
||||
---
|
||||
|
||||
# Configuration.downloadPath property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
downloadPath?: string;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.executablepath.md
Normal file
13
docs/api/puppeteer.configuration.executablepath.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.executablePath
|
||||
---
|
||||
|
||||
# Configuration.executablePath property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
executablePath?: string;
|
||||
}
|
||||
```
|
15
docs/api/puppeteer.configuration.experiments.md
Normal file
15
docs/api/puppeteer.configuration.experiments.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
sidebar_label: Configuration.experiments
|
||||
---
|
||||
|
||||
# Configuration.experiments property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
experiments?: {
|
||||
macArmChromiumEnabled?: boolean;
|
||||
};
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.loglevel.md
Normal file
13
docs/api/puppeteer.configuration.loglevel.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.logLevel
|
||||
---
|
||||
|
||||
# Configuration.logLevel property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
logLevel?: 'silent' | 'error' | 'warn';
|
||||
}
|
||||
```
|
26
docs/api/puppeteer.configuration.md
Normal file
26
docs/api/puppeteer.configuration.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
sidebar_label: Configuration
|
||||
---
|
||||
|
||||
# Configuration interface
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
export interface Configuration
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Modifiers | Type | Description |
|
||||
| ---------------------------------------------------------------------- | --------- | ------------------------------------ | ----------------- |
|
||||
| [browserRevision?](./puppeteer.configuration.browserrevision.md) | | string | <i>(Optional)</i> |
|
||||
| [cacheDirectory?](./puppeteer.configuration.cachedirectory.md) | | string | <i>(Optional)</i> |
|
||||
| [defaultProduct?](./puppeteer.configuration.defaultproduct.md) | | [Product](./puppeteer.product.md) | <i>(Optional)</i> |
|
||||
| [downloadHost?](./puppeteer.configuration.downloadhost.md) | | string | <i>(Optional)</i> |
|
||||
| [downloadPath?](./puppeteer.configuration.downloadpath.md) | | string | <i>(Optional)</i> |
|
||||
| [executablePath?](./puppeteer.configuration.executablepath.md) | | string | <i>(Optional)</i> |
|
||||
| [experiments?](./puppeteer.configuration.experiments.md) | | { macArmChromiumEnabled?: boolean; } | <i>(Optional)</i> |
|
||||
| [logLevel?](./puppeteer.configuration.loglevel.md) | | 'silent' \| 'error' \| 'warn' | <i>(Optional)</i> |
|
||||
| [skipDownload?](./puppeteer.configuration.skipdownload.md) | | boolean | <i>(Optional)</i> |
|
||||
| [temporaryDirectory?](./puppeteer.configuration.temporarydirectory.md) | | string | <i>(Optional)</i> |
|
13
docs/api/puppeteer.configuration.skipdownload.md
Normal file
13
docs/api/puppeteer.configuration.skipdownload.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.skipDownload
|
||||
---
|
||||
|
||||
# Configuration.skipDownload property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
skipDownload?: boolean;
|
||||
}
|
||||
```
|
13
docs/api/puppeteer.configuration.temporarydirectory.md
Normal file
13
docs/api/puppeteer.configuration.temporarydirectory.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: Configuration.temporaryDirectory
|
||||
---
|
||||
|
||||
# Configuration.temporaryDirectory property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface Configuration {
|
||||
temporaryDirectory?: string;
|
||||
}
|
||||
```
|
@ -9,5 +9,5 @@ sidebar_label: connect
|
||||
```typescript
|
||||
connect: (
|
||||
options: import('puppeteer-core/internal/common/Puppeteer.js').ConnectOptions
|
||||
) => Promise<import('./types').Browser>;
|
||||
) => Promise<import('./types.js').Browser>;
|
||||
```
|
||||
|
@ -8,6 +8,8 @@ sidebar_label: createBrowserFetcher
|
||||
|
||||
```typescript
|
||||
createBrowserFetcher: (
|
||||
options: import('puppeteer-core/internal/node/BrowserFetcher.js').BrowserFetcherOptions
|
||||
options: Partial<
|
||||
import('puppeteer-core/internal/node/BrowserFetcher.js').BrowserFetcherOptions
|
||||
>
|
||||
) => import('puppeteer-core/internal/node/BrowserFetcher.js').BrowserFetcher;
|
||||
```
|
||||
|
@ -7,5 +7,9 @@ sidebar_label: executablePath
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
executablePath: (channel?: string | undefined) => string;
|
||||
executablePath: (
|
||||
channel?:
|
||||
| import('puppeteer-core/internal/node/LaunchOptions.js').ChromeReleaseChannel
|
||||
| undefined
|
||||
) => string;
|
||||
```
|
||||
|
@ -11,5 +11,5 @@ launch: (
|
||||
options?:
|
||||
| import('puppeteer-core/internal/node/PuppeteerNode.js').PuppeteerLaunchOptions
|
||||
| undefined
|
||||
) => Promise<import('./types').Browser>;
|
||||
) => Promise<import('./types.js').Browser>;
|
||||
```
|
||||
|
@ -7,7 +7,7 @@ sidebar_label: ProductLauncher.defaultArgs
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface ProductLauncher {
|
||||
class ProductLauncher {
|
||||
defaultArgs(object: BrowserLaunchArgumentOptions): string[];
|
||||
}
|
||||
```
|
||||
|
@ -2,12 +2,22 @@
|
||||
sidebar_label: ProductLauncher.executablePath
|
||||
---
|
||||
|
||||
# ProductLauncher.executablePath property
|
||||
# ProductLauncher.executablePath() method
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface ProductLauncher {
|
||||
executablePath: (path?: any) => string;
|
||||
class ProductLauncher {
|
||||
executablePath(channel?: ChromeReleaseChannel): string;
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ----------------------------------------------------------- | ----------------- |
|
||||
| channel | [ChromeReleaseChannel](./puppeteer.chromereleasechannel.md) | <i>(Optional)</i> |
|
||||
|
||||
**Returns:**
|
||||
|
||||
string
|
||||
|
@ -7,7 +7,7 @@ sidebar_label: ProductLauncher.launch
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface ProductLauncher {
|
||||
class ProductLauncher {
|
||||
launch(object: PuppeteerNodeLaunchOptions): Promise<Browser>;
|
||||
}
|
||||
```
|
||||
|
@ -2,26 +2,30 @@
|
||||
sidebar_label: ProductLauncher
|
||||
---
|
||||
|
||||
# ProductLauncher interface
|
||||
# ProductLauncher class
|
||||
|
||||
Describes a launcher - a class that is able to create and launch a browser instance.
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
export interface ProductLauncher
|
||||
export declare class ProductLauncher
|
||||
```
|
||||
|
||||
## Remarks
|
||||
|
||||
The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `ProductLauncher` class.
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Modifiers | Type | Description |
|
||||
| --------------------------------------------------------------- | --------- | --------------------------------- | ----------- |
|
||||
| [executablePath](./puppeteer.productlauncher.executablepath.md) | | (path?: any) => string | |
|
||||
| [product](./puppeteer.productlauncher.product.md) | | [Product](./puppeteer.product.md) | |
|
||||
| ------------------------------------------------- | --------------------- | --------------------------------- | ----------- |
|
||||
| [product](./puppeteer.productlauncher.product.md) | <code>readonly</code> | [Product](./puppeteer.product.md) | |
|
||||
|
||||
## Methods
|
||||
|
||||
| Method | Description |
|
||||
| ----------------------------------------------------------------- | ----------- |
|
||||
| [defaultArgs(object)](./puppeteer.productlauncher.defaultargs.md) | |
|
||||
| [launch(object)](./puppeteer.productlauncher.launch.md) | |
|
||||
| Method | Modifiers | Description |
|
||||
| ------------------------------------------------------------------------ | --------- | ----------- |
|
||||
| [defaultArgs(object)](./puppeteer.productlauncher.defaultargs.md) | | |
|
||||
| [executablePath(channel)](./puppeteer.productlauncher.executablepath.md) | | |
|
||||
| [launch(object)](./puppeteer.productlauncher.launch.md) | | |
|
||||
|
@ -7,7 +7,7 @@ sidebar_label: ProductLauncher.product
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
interface ProductLauncher {
|
||||
product: Product;
|
||||
class ProductLauncher {
|
||||
get product(): Product;
|
||||
}
|
||||
```
|
||||
|
@ -12,15 +12,15 @@ sidebar_label: PuppeteerNode.createBrowserFetcher
|
||||
|
||||
```typescript
|
||||
class PuppeteerNode {
|
||||
createBrowserFetcher(options: BrowserFetcherOptions): BrowserFetcher;
|
||||
createBrowserFetcher(options: Partial<BrowserFetcherOptions>): BrowserFetcher;
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| options | [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | Set of configurable options to specify the settings of the BrowserFetcher. |
|
||||
| --------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| options | Partial<[BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md)> | Set of configurable options to specify the settings of the BrowserFetcher. |
|
||||
|
||||
**Returns:**
|
||||
|
||||
|
13
docs/api/puppeteer.puppeteernode.defaultproduct.md
Normal file
13
docs/api/puppeteer.puppeteernode.defaultproduct.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: PuppeteerNode.defaultProduct
|
||||
---
|
||||
|
||||
# PuppeteerNode.defaultProduct property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
class PuppeteerNode {
|
||||
get defaultProduct(): Product;
|
||||
}
|
||||
```
|
@ -8,22 +8,18 @@ sidebar_label: PuppeteerNode.executablePath
|
||||
|
||||
```typescript
|
||||
class PuppeteerNode {
|
||||
executablePath(channel?: string): string;
|
||||
executablePath(channel?: ChromeReleaseChannel): string;
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------ | ----------------- |
|
||||
| channel | string | <i>(Optional)</i> |
|
||||
| --------- | ----------------------------------------------------------- | ----------------- |
|
||||
| channel | [ChromeReleaseChannel](./puppeteer.chromereleasechannel.md) | <i>(Optional)</i> |
|
||||
|
||||
**Returns:**
|
||||
|
||||
string
|
||||
|
||||
A path where Puppeteer expects to find the bundled browser. The browser binary might not be there if the download was skipped with the `PUPPETEER_SKIP_DOWNLOAD` environment variable.
|
||||
|
||||
## Remarks
|
||||
|
||||
**NOTE** `puppeteer.executablePath()` is affected by the `PUPPETEER_EXECUTABLE_PATH` and `PUPPETEER_CHROMIUM_REVISION` environment variables.
|
||||
The executable path.
|
||||
|
13
docs/api/puppeteer.puppeteernode.lastlaunchedproduct.md
Normal file
13
docs/api/puppeteer.puppeteernode.lastlaunchedproduct.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_label: PuppeteerNode.lastLaunchedProduct
|
||||
---
|
||||
|
||||
# PuppeteerNode.lastLaunchedProduct property
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
class PuppeteerNode {
|
||||
get lastLaunchedProduct(): Product;
|
||||
}
|
||||
```
|
@ -4,7 +4,7 @@ sidebar_label: PuppeteerNode.launch
|
||||
|
||||
# PuppeteerNode.launch() method
|
||||
|
||||
Launches puppeteer and launches a browser instance with given arguments and options when specified.
|
||||
Launches a browser instance with given arguments and options when specified.
|
||||
|
||||
**Signature:**
|
||||
|
||||
@ -17,18 +17,16 @@ class PuppeteerNode {
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | --------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
| options | [PuppeteerLaunchOptions](./puppeteer.puppeteerlaunchoptions.md) | <i>(Optional)</i> Set of configurable options to set on the browser. |
|
||||
| --------- | --------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| options | [PuppeteerLaunchOptions](./puppeteer.puppeteerlaunchoptions.md) | <i>(Optional)</i> Options to configure launching behavior. |
|
||||
|
||||
**Returns:**
|
||||
|
||||
Promise<[Browser](./puppeteer.browser.md)>
|
||||
|
||||
Promise which resolves to browser instance.
|
||||
|
||||
## Remarks
|
||||
|
||||
**NOTE** Puppeteer can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. In `puppeteer.launch([options])`, any mention of Chromium also applies to Chrome. See [this article](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
|
||||
Puppeteer can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. In , any mention of Chromium also applies to Chrome. See [this article](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
|
||||
|
||||
## Example
|
||||
|
||||
|
@ -45,15 +45,17 @@ Once you have created a `page` you have access to a large API to interact with t
|
||||
## Properties
|
||||
|
||||
| Property | Modifiers | Type | Description |
|
||||
| ----------------------------------------------- | --------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| [product](./puppeteer.puppeteernode.product.md) | <code>readonly</code> | string | The name of the browser that is under automation (<code>"chrome"</code> or <code>"firefox"</code>) |
|
||||
| ----------------------------------------------------------------------- | --------------------- | --------------------------------- | ----------- |
|
||||
| [defaultProduct](./puppeteer.puppeteernode.defaultproduct.md) | <code>readonly</code> | [Product](./puppeteer.product.md) | |
|
||||
| [lastLaunchedProduct](./puppeteer.puppeteernode.lastlaunchedproduct.md) | <code>readonly</code> | [Product](./puppeteer.product.md) | |
|
||||
| [product](./puppeteer.puppeteernode.product.md) | <code>readonly</code> | string | |
|
||||
|
||||
## Methods
|
||||
|
||||
| Method | Modifiers | Description |
|
||||
| ---------------------------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------- |
|
||||
| ---------------------------------------------------------------------------------- | --------- | ---------------------------------------------------------------------------- |
|
||||
| [connect(options)](./puppeteer.puppeteernode.connect.md) | | This method attaches Puppeteer to an existing browser instance. |
|
||||
| [createBrowserFetcher(options)](./puppeteer.puppeteernode.createbrowserfetcher.md) | | |
|
||||
| [defaultArgs(options)](./puppeteer.puppeteernode.defaultargs.md) | | |
|
||||
| [executablePath(channel)](./puppeteer.puppeteernode.executablepath.md) | | |
|
||||
| [launch(options)](./puppeteer.puppeteernode.launch.md) | | Launches puppeteer and launches a browser instance with given arguments and options when specified. |
|
||||
| [launch(options)](./puppeteer.puppeteernode.launch.md) | | Launches a browser instance with given arguments and options when specified. |
|
||||
|
@ -4,7 +4,9 @@ sidebar_label: PuppeteerNode.product
|
||||
|
||||
# PuppeteerNode.product property
|
||||
|
||||
The name of the browser that is under automation (`"chrome"` or `"firefox"`)
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Do not use as this field as it does not take into account multiple browsers of different types. Use or .
|
||||
|
||||
**Signature:**
|
||||
|
||||
@ -13,7 +15,3 @@ class PuppeteerNode {
|
||||
get product(): string;
|
||||
}
|
||||
```
|
||||
|
||||
## Remarks
|
||||
|
||||
The product is set by the `PUPPETEER_PRODUCT` environment variable or the `product` option in `puppeteer.launch([options])` and defaults to `chrome`. Firefox support is experimental.
|
||||
|
88
package-lock.json
generated
88
package-lock.json
generated
@ -84,7 +84,6 @@
|
||||
"version": "7.12.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
|
||||
"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.10.4"
|
||||
}
|
||||
@ -93,7 +92,6 @@
|
||||
"version": "7.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
|
||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@ -102,7 +100,6 @@
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
|
||||
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"chalk": "^2.0.0",
|
||||
@ -116,7 +113,6 @@
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
@ -128,7 +124,6 @@
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
@ -142,7 +137,6 @@
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
@ -150,14 +144,12 @@
|
||||
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
@ -166,7 +158,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@ -175,7 +166,6 @@
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
@ -1916,8 +1906,7 @@
|
||||
"node_modules/@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"node_modules/@types/pixelmatch": {
|
||||
"version": "5.2.4",
|
||||
@ -2650,7 +2639,6 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@ -2901,7 +2889,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
|
||||
"integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
@ -3135,7 +3122,6 @@
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
@ -4993,7 +4979,6 @@
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
@ -5009,7 +4994,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@ -5111,8 +5095,7 @@
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
|
||||
},
|
||||
"node_modules/is-bigint": {
|
||||
"version": "1.0.4",
|
||||
@ -5558,8 +5541,7 @@
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.13.1",
|
||||
@ -5583,8 +5565,7 @@
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "1.0.0",
|
||||
@ -5684,8 +5665,7 @@
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
||||
},
|
||||
"node_modules/load-json-file": {
|
||||
"version": "4.0.0",
|
||||
@ -6568,7 +6548,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"callsites": "^3.0.0"
|
||||
},
|
||||
@ -6580,7 +6559,6 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"error-ex": "^1.3.1",
|
||||
@ -6638,7 +6616,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -8344,7 +8321,6 @@
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@ -8492,6 +8468,7 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"cosmiconfig": "7.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
@ -8550,7 +8527,6 @@
|
||||
"version": "7.12.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
|
||||
"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.10.4"
|
||||
}
|
||||
@ -8558,14 +8534,12 @@
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
|
||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
|
||||
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"chalk": "^2.0.0",
|
||||
@ -8576,7 +8550,6 @@
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
@ -8585,7 +8558,6 @@
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
@ -8596,7 +8568,6 @@
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
@ -8604,26 +8575,22 @@
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
@ -9828,8 +9795,7 @@
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"@types/pixelmatch": {
|
||||
"version": "5.2.4",
|
||||
@ -10358,8 +10324,7 @@
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
@ -10547,7 +10512,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
|
||||
"integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
@ -10718,7 +10682,6 @@
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
@ -11990,7 +11953,6 @@
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
@ -11999,8 +11961,7 @@
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12083,8 +12044,7 @@
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
|
||||
},
|
||||
"is-bigint": {
|
||||
"version": "1.0.4",
|
||||
@ -12407,8 +12367,7 @@
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
@ -12429,8 +12388,7 @@
|
||||
"json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "1.0.0",
|
||||
@ -12507,8 +12465,7 @@
|
||||
"lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "4.0.0",
|
||||
@ -13171,7 +13128,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"callsites": "^3.0.0"
|
||||
}
|
||||
@ -13180,7 +13136,6 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"error-ex": "^1.3.1",
|
||||
@ -13222,8 +13177,7 @@
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
||||
},
|
||||
"pend": {
|
||||
"version": "1.2.0",
|
||||
@ -13343,6 +13297,7 @@
|
||||
"puppeteer": {
|
||||
"version": "file:packages/puppeteer",
|
||||
"requires": {
|
||||
"cosmiconfig": "7.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
@ -14494,8 +14449,7 @@
|
||||
"yaml": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.6.0",
|
||||
|
@ -14,11 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {homedir} from 'os';
|
||||
import {join} from 'path';
|
||||
import {Product} from './Product.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @public
|
||||
*/
|
||||
export const PUPPETEER_CACHE_DIR =
|
||||
process.env['PUPPETEER_CACHE_DIR'] ?? join(homedir(), '.cache', 'puppeteer');
|
||||
export interface Configuration {
|
||||
browserRevision?: string;
|
||||
cacheDirectory?: string;
|
||||
downloadHost?: string;
|
||||
downloadPath?: string;
|
||||
executablePath?: string;
|
||||
defaultProduct?: Product;
|
||||
temporaryDirectory?: string;
|
||||
skipDownload?: boolean;
|
||||
logLevel?: 'silent' | 'error' | 'warn';
|
||||
experiments?: {
|
||||
macArmChromiumEnabled?: boolean;
|
||||
};
|
||||
}
|
@ -107,7 +107,7 @@ export class Puppeteer {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected _isPuppeteerCore: boolean;
|
||||
_isPuppeteerCore: boolean;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import {exec as execChildProcess} from 'child_process';
|
||||
import extractZip from 'extract-zip';
|
||||
import {createReadStream, createWriteStream, existsSync} from 'fs';
|
||||
import {createReadStream, createWriteStream, existsSync, readdirSync} from 'fs';
|
||||
import {chmod, mkdir, readdir, unlink} from 'fs/promises';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
@ -35,13 +35,8 @@ import * as util from 'util';
|
||||
import {promisify} from 'util';
|
||||
import {debug} from '../common/Debug.js';
|
||||
import {Product} from '../common/Product.js';
|
||||
import {PUPPETEER_CACHE_DIR} from '../constants.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
|
||||
const experimentalChromiumMacArm =
|
||||
process.env['PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM'] ||
|
||||
process.env['npm_config_puppeteer_experimental_chromium_mac_arm'];
|
||||
|
||||
const debugFetcher = debug('puppeteer:fetcher');
|
||||
|
||||
const downloadURLs: Record<Product, Partial<Record<Platform, string>>> = {
|
||||
@ -140,24 +135,39 @@ function handleArm64(): void {
|
||||
* @public
|
||||
*/
|
||||
export interface BrowserFetcherOptions {
|
||||
/**
|
||||
* Determines the path to download browsers to.
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* Determines which platform the browser will be suited for.
|
||||
*
|
||||
* @defaultValue Auto-detected.
|
||||
*/
|
||||
platform?: Platform;
|
||||
/**
|
||||
* Determines which product the {@link BrowserFetcher} is for.
|
||||
*
|
||||
* @defaultValue `"chrome"`
|
||||
* @defaultValue `"chrome"`.
|
||||
*/
|
||||
product?: 'chrome' | 'firefox';
|
||||
/**
|
||||
* Determines the path to download browsers to.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* Determines the host that will be used for downloading.
|
||||
*
|
||||
* @defaultValue Either
|
||||
*
|
||||
* - https://storage.googleapis.com or
|
||||
* - https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central
|
||||
*
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Enables the use of the Chromium binary for macOS ARM.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
useMacOSARMBinary?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,7 +206,7 @@ export interface BrowserFetcherRevisionInfo {
|
||||
* and running Puppeteer against it:
|
||||
*
|
||||
* ```ts
|
||||
* const browserFetcher = new BrowserFetcher();
|
||||
* const browserFetcher = new BrowserFetcher({path: 'path/to/download/folder'});
|
||||
* const revisionInfo = await browserFetcher.download('533271');
|
||||
* const browser = await puppeteer.launch({
|
||||
* executablePath: revisionInfo.executablePath,
|
||||
@ -208,23 +218,17 @@ export interface BrowserFetcherRevisionInfo {
|
||||
|
||||
export class BrowserFetcher {
|
||||
#product: Product;
|
||||
#downloadFolder: string;
|
||||
#downloadPath: string;
|
||||
#downloadHost: string;
|
||||
#platform: Platform;
|
||||
|
||||
/**
|
||||
* Constructs a browser fetcher for the given options.
|
||||
*/
|
||||
constructor(options: BrowserFetcherOptions = {}) {
|
||||
this.#product = (options.product || 'chrome').toLowerCase() as Product;
|
||||
assert(
|
||||
this.#product === 'chrome' || this.#product === 'firefox',
|
||||
`Unknown product: "${options.product}"`
|
||||
);
|
||||
|
||||
this.#downloadFolder =
|
||||
options.path || path.join(PUPPETEER_CACHE_DIR, this.#product);
|
||||
this.#downloadHost = options.host || browserConfig[this.#product].host;
|
||||
constructor(options: BrowserFetcherOptions) {
|
||||
this.#product = options.product ?? 'chrome';
|
||||
this.#downloadPath = options.path;
|
||||
this.#downloadHost = options.host ?? browserConfig[this.#product].host;
|
||||
|
||||
if (options.platform) {
|
||||
this.#platform = options.platform;
|
||||
@ -235,7 +239,7 @@ export class BrowserFetcher {
|
||||
switch (this.#product) {
|
||||
case 'chrome':
|
||||
this.#platform =
|
||||
os.arch() === 'arm64' && experimentalChromiumMacArm
|
||||
os.arch() === 'arm64' && options.useMacOSARMBinary
|
||||
? 'mac_arm'
|
||||
: 'mac';
|
||||
break;
|
||||
@ -342,13 +346,13 @@ export class BrowserFetcher {
|
||||
);
|
||||
const fileName = url.split('/').pop();
|
||||
assert(fileName, `A malformed download URL was found: ${url}.`);
|
||||
const archivePath = path.join(this.#downloadFolder, fileName);
|
||||
const archivePath = path.join(this.#downloadPath, fileName);
|
||||
const outputPath = this.#getFolderPath(revision);
|
||||
if (existsSync(outputPath)) {
|
||||
return this.revisionInfo(revision);
|
||||
}
|
||||
if (!existsSync(this.#downloadFolder)) {
|
||||
await mkdir(this.#downloadFolder, {recursive: true});
|
||||
if (!existsSync(this.#downloadPath)) {
|
||||
await mkdir(this.#downloadPath, {recursive: true});
|
||||
}
|
||||
|
||||
// Use system Chromium builds on Linux ARM devices
|
||||
@ -374,25 +378,21 @@ export class BrowserFetcher {
|
||||
/**
|
||||
* @remarks
|
||||
* This method is affected by the current `product`.
|
||||
* @returns A promise with a list of all revision strings (for the current `product`)
|
||||
* @returns A list of all revision strings (for the current `product`)
|
||||
* available locally on disk.
|
||||
*/
|
||||
async localRevisions(): Promise<string[]> {
|
||||
if (!existsSync(this.#downloadFolder)) {
|
||||
localRevisions(): string[] {
|
||||
if (!existsSync(this.#downloadPath)) {
|
||||
return [];
|
||||
}
|
||||
const fileNames = await readdir(this.#downloadFolder);
|
||||
const fileNames = readdirSync(this.#downloadPath);
|
||||
return fileNames
|
||||
.map(fileName => {
|
||||
return parseFolderPath(this.#product, fileName);
|
||||
})
|
||||
.filter(
|
||||
(
|
||||
entry
|
||||
): entry is {product: string; platform: string; revision: string} => {
|
||||
.filter((entry): entry is Exclude<typeof entry, undefined> => {
|
||||
return (entry && entry.platform === this.#platform) ?? false;
|
||||
}
|
||||
)
|
||||
})
|
||||
.map(entry => {
|
||||
return entry.revision;
|
||||
});
|
||||
@ -502,7 +502,7 @@ export class BrowserFetcher {
|
||||
}
|
||||
|
||||
#getFolderPath(revision: string): string {
|
||||
return path.resolve(this.#downloadFolder, `${this.#platform}-${revision}`);
|
||||
return path.resolve(this.#downloadPath, `${this.#platform}-${revision}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import fs from 'fs';
|
||||
import {accessSync} from 'fs';
|
||||
import {mkdtemp} from 'fs/promises';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import {CDPBrowser} from '../common/Browser.js';
|
||||
import {Product} from '../common/Product.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {BrowserRunner} from './BrowserRunner.js';
|
||||
import {
|
||||
@ -9,32 +10,20 @@ import {
|
||||
ChromeReleaseChannel,
|
||||
PuppeteerNodeLaunchOptions,
|
||||
} from './LaunchOptions.js';
|
||||
import {
|
||||
executablePathForChannel,
|
||||
ProductLauncher,
|
||||
resolveExecutablePath,
|
||||
} from './ProductLauncher.js';
|
||||
import {tmpdir} from './util.js';
|
||||
import {ProductLauncher} from './ProductLauncher.js';
|
||||
import {PuppeteerNode} from './PuppeteerNode.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class ChromeLauncher implements ProductLauncher {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_preferredRevision: string;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_isPuppeteerCore: boolean;
|
||||
|
||||
constructor(preferredRevision: string, isPuppeteerCore: boolean) {
|
||||
this._preferredRevision = preferredRevision;
|
||||
this._isPuppeteerCore = isPuppeteerCore;
|
||||
export class ChromeLauncher extends ProductLauncher {
|
||||
constructor(puppeteer: PuppeteerNode) {
|
||||
super(puppeteer, 'chrome');
|
||||
}
|
||||
|
||||
async launch(options: PuppeteerNodeLaunchOptions = {}): Promise<CDPBrowser> {
|
||||
override async launch(
|
||||
options: PuppeteerNodeLaunchOptions = {}
|
||||
): Promise<CDPBrowser> {
|
||||
const {
|
||||
ignoreDefaultArgs = false,
|
||||
args = [],
|
||||
@ -93,9 +82,7 @@ export class ChromeLauncher implements ProductLauncher {
|
||||
if (userDataDirIndex < 0) {
|
||||
isTempUserDataDir = true;
|
||||
chromeArguments.push(
|
||||
`--user-data-dir=${await fs.promises.mkdtemp(
|
||||
path.join(tmpdir(), 'puppeteer_dev_chrome_profile-')
|
||||
)}`
|
||||
`--user-data-dir=${await mkdtemp(this.getProfilePath())}`
|
||||
);
|
||||
userDataDirIndex = chromeArguments.length - 1;
|
||||
}
|
||||
@ -104,20 +91,12 @@ export class ChromeLauncher implements ProductLauncher {
|
||||
assert(typeof userDataDir === 'string', '`--user-data-dir` is malformed');
|
||||
|
||||
let chromeExecutable = executablePath;
|
||||
if (channel) {
|
||||
// executablePath is detected by channel, so it should not be specified by user.
|
||||
if (!chromeExecutable) {
|
||||
assert(
|
||||
!chromeExecutable,
|
||||
'`executablePath` must not be specified when `channel` is given.'
|
||||
channel || !this.puppeteer._isPuppeteerCore,
|
||||
`An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``
|
||||
);
|
||||
|
||||
chromeExecutable = executablePathForChannel(channel);
|
||||
} else if (!chromeExecutable) {
|
||||
const {missingText, executablePath} = resolveExecutablePath(this);
|
||||
if (missingText) {
|
||||
throw new Error(missingText);
|
||||
}
|
||||
chromeExecutable = executablePath;
|
||||
chromeExecutable = this.executablePath(channel);
|
||||
}
|
||||
|
||||
const usePipe = chromeArguments.includes('--remote-debugging-pipe');
|
||||
@ -143,7 +122,7 @@ export class ChromeLauncher implements ProductLauncher {
|
||||
usePipe,
|
||||
timeout,
|
||||
slowMo,
|
||||
preferredRevision: this._preferredRevision,
|
||||
preferredRevision: this.puppeteer.browserRevision,
|
||||
});
|
||||
browser = await CDPBrowser._create(
|
||||
this.product,
|
||||
@ -177,7 +156,7 @@ export class ChromeLauncher implements ProductLauncher {
|
||||
return browser;
|
||||
}
|
||||
|
||||
defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] {
|
||||
override defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] {
|
||||
const chromeArguments = [
|
||||
'--allow-pre-commit-input',
|
||||
'--disable-background-networking',
|
||||
@ -241,16 +220,88 @@ export class ChromeLauncher implements ProductLauncher {
|
||||
return chromeArguments;
|
||||
}
|
||||
|
||||
executablePath(channel?: ChromeReleaseChannel): string {
|
||||
override executablePath(channel?: ChromeReleaseChannel): string {
|
||||
if (channel) {
|
||||
return executablePathForChannel(channel);
|
||||
return this.#executablePathForChannel(channel);
|
||||
} else {
|
||||
const results = resolveExecutablePath(this);
|
||||
return results.executablePath;
|
||||
return this.resolveExecutablePath();
|
||||
}
|
||||
}
|
||||
|
||||
get product(): Product {
|
||||
return 'chrome';
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
#executablePathForChannel(channel: ChromeReleaseChannel): string {
|
||||
const platform = os.platform();
|
||||
|
||||
let chromePath: string | undefined;
|
||||
switch (platform) {
|
||||
case 'win32':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome Beta\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-canary':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome SxS\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome Dev\\Application\\chrome.exe`;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'darwin':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta';
|
||||
break;
|
||||
case 'chrome-canary':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary';
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'linux':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath = '/opt/google/chrome/chrome';
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath = '/opt/google/chrome-beta/chrome';
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath = '/opt/google/chrome-unstable/chrome';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!chromePath) {
|
||||
throw new Error(
|
||||
`Unable to detect browser executable path for '${channel}' on ${platform}.`
|
||||
);
|
||||
}
|
||||
|
||||
// Check if Chrome exists and is accessible.
|
||||
try {
|
||||
accessSync(chromePath);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Could not find Google Chrome executable for channel '${channel}' at '${chromePath}'.`
|
||||
);
|
||||
}
|
||||
|
||||
return chromePath;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import path from 'path';
|
||||
import {Browser} from '../api/Browser.js';
|
||||
import {Browser as BiDiBrowser} from '../common/bidi/Browser.js';
|
||||
import {CDPBrowser} from '../common/Browser.js';
|
||||
import {Product} from '../common/Product.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {BrowserFetcher} from './BrowserFetcher.js';
|
||||
import {BrowserRunner} from './BrowserRunner.js';
|
||||
@ -12,33 +11,25 @@ import {
|
||||
BrowserLaunchArgumentOptions,
|
||||
PuppeteerNodeLaunchOptions,
|
||||
} from './LaunchOptions.js';
|
||||
import {ProductLauncher, resolveExecutablePath} from './ProductLauncher.js';
|
||||
import {tmpdir} from './util.js';
|
||||
import {ProductLauncher} from './ProductLauncher.js';
|
||||
import {PuppeteerNode} from './PuppeteerNode.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class FirefoxLauncher implements ProductLauncher {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_preferredRevision: string;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_isPuppeteerCore: boolean;
|
||||
|
||||
constructor(preferredRevision: string, isPuppeteerCore: boolean) {
|
||||
this._preferredRevision = preferredRevision;
|
||||
this._isPuppeteerCore = isPuppeteerCore;
|
||||
export class FirefoxLauncher extends ProductLauncher {
|
||||
constructor(puppeteer: PuppeteerNode) {
|
||||
super(puppeteer, 'firefox');
|
||||
}
|
||||
|
||||
async launch(options: PuppeteerNodeLaunchOptions = {}): Promise<Browser> {
|
||||
override async launch(
|
||||
options: PuppeteerNodeLaunchOptions = {}
|
||||
): Promise<Browser> {
|
||||
const {
|
||||
ignoreDefaultArgs = false,
|
||||
args = [],
|
||||
dumpio = false,
|
||||
executablePath = null,
|
||||
executablePath,
|
||||
pipe = false,
|
||||
env = process.env,
|
||||
handleSIGINT = true,
|
||||
@ -107,20 +98,15 @@ export class FirefoxLauncher implements ProductLauncher {
|
||||
firefoxArguments.push(userDataDir);
|
||||
}
|
||||
|
||||
if (!this._isPuppeteerCore) {
|
||||
await this._updateRevision();
|
||||
}
|
||||
let firefoxExecutable = executablePath;
|
||||
if (!executablePath) {
|
||||
const {missingText, executablePath} = resolveExecutablePath(this);
|
||||
if (missingText) {
|
||||
throw new Error(missingText);
|
||||
}
|
||||
let firefoxExecutable: string;
|
||||
if (this.puppeteer._isPuppeteerCore || executablePath) {
|
||||
assert(
|
||||
executablePath,
|
||||
`An \`executablePath\` must be specified for \`puppeteer-core\``
|
||||
);
|
||||
firefoxExecutable = executablePath;
|
||||
}
|
||||
|
||||
if (!firefoxExecutable) {
|
||||
throw new Error('firefoxExecutable is not found.');
|
||||
} else {
|
||||
firefoxExecutable = this.executablePath();
|
||||
}
|
||||
|
||||
const runner = new BrowserRunner(
|
||||
@ -145,7 +131,7 @@ export class FirefoxLauncher implements ProductLauncher {
|
||||
const connection = await runner.setupWebDriverBiDiConnection({
|
||||
timeout,
|
||||
slowMo,
|
||||
preferredRevision: this._preferredRevision,
|
||||
preferredRevision: this.puppeteer.browserRevision,
|
||||
});
|
||||
browser = await BiDiBrowser.create({
|
||||
connection,
|
||||
@ -166,7 +152,7 @@ export class FirefoxLauncher implements ProductLauncher {
|
||||
usePipe: pipe,
|
||||
timeout,
|
||||
slowMo,
|
||||
preferredRevision: this._preferredRevision,
|
||||
preferredRevision: this.puppeteer.browserRevision,
|
||||
});
|
||||
browser = await CDPBrowser._create(
|
||||
this.product,
|
||||
@ -200,28 +186,22 @@ export class FirefoxLauncher implements ProductLauncher {
|
||||
return browser;
|
||||
}
|
||||
|
||||
executablePath(): string {
|
||||
return resolveExecutablePath(this).executablePath;
|
||||
}
|
||||
|
||||
async _updateRevision(): Promise<void> {
|
||||
override executablePath(): string {
|
||||
// replace 'latest' placeholder with actual downloaded revision
|
||||
if (this._preferredRevision === 'latest') {
|
||||
if (this.puppeteer.browserRevision === 'latest') {
|
||||
const browserFetcher = new BrowserFetcher({
|
||||
product: this.product,
|
||||
path: this.puppeteer.defaultDownloadPath!,
|
||||
});
|
||||
const localRevisions = await browserFetcher.localRevisions();
|
||||
const localRevisions = browserFetcher.localRevisions();
|
||||
if (localRevisions[0]) {
|
||||
this._preferredRevision = localRevisions[0];
|
||||
this.puppeteer.configuration.browserRevision = localRevisions[0];
|
||||
}
|
||||
}
|
||||
return this.resolveExecutablePath();
|
||||
}
|
||||
|
||||
get product(): Product {
|
||||
return 'firefox';
|
||||
}
|
||||
|
||||
defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] {
|
||||
override defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] {
|
||||
const {
|
||||
devtools = false,
|
||||
headless = !devtools,
|
||||
@ -503,7 +483,7 @@ export class FirefoxLauncher implements ProductLauncher {
|
||||
|
||||
async _createProfile(extraPrefs: {[x: string]: unknown}): Promise<string> {
|
||||
const temporaryProfilePath = await fs.promises.mkdtemp(
|
||||
path.join(tmpdir(), 'puppeteer_dev_firefox_profile-')
|
||||
this.getProfilePath()
|
||||
);
|
||||
|
||||
const prefs = this.defaultPreferences(extraPrefs);
|
||||
|
@ -13,192 +13,118 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {accessSync, existsSync} from 'fs';
|
||||
import os from 'os';
|
||||
import {existsSync} from 'fs';
|
||||
import os, {tmpdir} from 'os';
|
||||
import {join} from 'path';
|
||||
import {Browser} from '../api/Browser.js';
|
||||
import {Product} from '../common/Product.js';
|
||||
import {BrowserFetcher} from './BrowserFetcher.js';
|
||||
import {ChromeLauncher} from './ChromeLauncher.js';
|
||||
import {FirefoxLauncher} from './FirefoxLauncher.js';
|
||||
import {
|
||||
BrowserLaunchArgumentOptions,
|
||||
ChromeReleaseChannel,
|
||||
PuppeteerNodeLaunchOptions,
|
||||
} from './LaunchOptions.js';
|
||||
import {PuppeteerNode} from './PuppeteerNode.js';
|
||||
|
||||
/**
|
||||
* Describes a launcher - a class that is able to create and launch a browser instance.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ProductLauncher {
|
||||
export class ProductLauncher {
|
||||
#product: Product;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
puppeteer: PuppeteerNode;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(puppeteer: PuppeteerNode, product: Product) {
|
||||
this.puppeteer = puppeteer;
|
||||
this.#product = product;
|
||||
}
|
||||
|
||||
get product(): Product {
|
||||
return this.#product;
|
||||
}
|
||||
|
||||
launch(object: PuppeteerNodeLaunchOptions): Promise<Browser>;
|
||||
executablePath: (path?: any) => string;
|
||||
launch(): Promise<Browser> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
executablePath(channel?: ChromeReleaseChannel): string;
|
||||
executablePath(): string {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
defaultArgs(object: BrowserLaunchArgumentOptions): string[];
|
||||
product: Product;
|
||||
}
|
||||
defaultArgs(): string[] {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function executablePathForChannel(
|
||||
channel: ChromeReleaseChannel
|
||||
): string {
|
||||
const platform = os.platform();
|
||||
|
||||
let chromePath: string | undefined;
|
||||
switch (platform) {
|
||||
case 'win32':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome Beta\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-canary':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome SxS\\Application\\chrome.exe`;
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath = `${process.env['PROGRAMFILES']}\\Google\\Chrome Dev\\Application\\chrome.exe`;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'darwin':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta';
|
||||
break;
|
||||
case 'chrome-canary':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary';
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath =
|
||||
'/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'linux':
|
||||
switch (channel) {
|
||||
case 'chrome':
|
||||
chromePath = '/opt/google/chrome/chrome';
|
||||
break;
|
||||
case 'chrome-beta':
|
||||
chromePath = '/opt/google/chrome-beta/chrome';
|
||||
break;
|
||||
case 'chrome-dev':
|
||||
chromePath = '/opt/google/chrome-unstable/chrome';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!chromePath) {
|
||||
throw new Error(
|
||||
`Unable to detect browser executable path for '${channel}' on ${platform}.`
|
||||
protected getProfilePath(): string {
|
||||
return join(
|
||||
this.puppeteer.configuration.temporaryDirectory ?? tmpdir(),
|
||||
`puppeteer_dev_${this.product}_profile-`
|
||||
);
|
||||
}
|
||||
|
||||
// Check if Chrome exists and is accessible.
|
||||
try {
|
||||
accessSync(chromePath);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Could not find Google Chrome executable for channel '${channel}' at '${chromePath}'.`
|
||||
);
|
||||
}
|
||||
|
||||
return chromePath;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function resolveExecutablePath(
|
||||
launcher: ChromeLauncher | FirefoxLauncher
|
||||
): {
|
||||
executablePath: string;
|
||||
missingText?: string;
|
||||
} {
|
||||
const {product, _isPuppeteerCore, _preferredRevision} = launcher;
|
||||
let downloadPath: string | undefined;
|
||||
// puppeteer-core doesn't take into account PUPPETEER_* env variables.
|
||||
if (!_isPuppeteerCore) {
|
||||
const executablePath =
|
||||
process.env['PUPPETEER_EXECUTABLE_PATH'] ||
|
||||
process.env['npm_config_puppeteer_executable_path'] ||
|
||||
process.env['npm_package_config_puppeteer_executable_path'];
|
||||
protected resolveExecutablePath(): string {
|
||||
const executablePath = this.puppeteer.configuration.executablePath;
|
||||
if (executablePath) {
|
||||
const missingText = !existsSync(executablePath)
|
||||
? 'Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: ' +
|
||||
executablePath
|
||||
: undefined;
|
||||
return {executablePath, missingText};
|
||||
if (!existsSync(executablePath)) {
|
||||
throw new Error(
|
||||
`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`
|
||||
);
|
||||
}
|
||||
return executablePath;
|
||||
}
|
||||
|
||||
const ubuntuChromiumPath = '/usr/bin/chromium-browser';
|
||||
if (
|
||||
product === 'chrome' &&
|
||||
this.product === 'chrome' &&
|
||||
os.platform() !== 'darwin' &&
|
||||
os.arch() === 'arm64' &&
|
||||
existsSync(ubuntuChromiumPath)
|
||||
) {
|
||||
return {executablePath: ubuntuChromiumPath, missingText: undefined};
|
||||
}
|
||||
downloadPath =
|
||||
process.env['PUPPETEER_DOWNLOAD_PATH'] ||
|
||||
process.env['npm_config_puppeteer_download_path'] ||
|
||||
process.env['npm_package_config_puppeteer_download_path'];
|
||||
return ubuntuChromiumPath;
|
||||
}
|
||||
|
||||
const browserFetcher = new BrowserFetcher({
|
||||
product: product,
|
||||
path: downloadPath,
|
||||
product: this.product,
|
||||
path: this.puppeteer.defaultDownloadPath!,
|
||||
});
|
||||
|
||||
if (!_isPuppeteerCore) {
|
||||
let revision = process.env['PUPPETEER_BROWSER_REVISION'];
|
||||
if (product === 'chrome') {
|
||||
revision ??= process.env['PUPPETEER_CHROMIUM_REVISION'];
|
||||
const revisionInfo = browserFetcher.revisionInfo(
|
||||
this.puppeteer.browserRevision
|
||||
);
|
||||
if (!revisionInfo.local) {
|
||||
if (this.puppeteer.configuration.browserRevision) {
|
||||
throw new Error(
|
||||
`Tried to find the browser at the configured path (${revisionInfo.executablePath}) for revision ${this.puppeteer.browserRevision}, but no executable was found.`
|
||||
);
|
||||
}
|
||||
if (revision) {
|
||||
const revisionInfo = browserFetcher.revisionInfo(revision);
|
||||
const missingText = !revisionInfo.local
|
||||
? 'Tried to use PUPPETEER_CHROMIUM_REVISION env variable to launch browser but did not find executable at: ' +
|
||||
revisionInfo.executablePath
|
||||
: undefined;
|
||||
return {executablePath: revisionInfo.executablePath, missingText};
|
||||
}
|
||||
}
|
||||
const revisionInfo = browserFetcher.revisionInfo(_preferredRevision);
|
||||
|
||||
const firefoxHelp = `Run \`PUPPETEER_PRODUCT=firefox npm install\` to download a supported Firefox browser binary.`;
|
||||
const chromeHelp = `Run \`npm install\` to download the correct Chromium revision (${launcher._preferredRevision}).`;
|
||||
const missingText = !revisionInfo.local
|
||||
? `Could not find expected browser (${product}) locally. ${
|
||||
product === 'chrome' ? chromeHelp : firefoxHelp
|
||||
}`
|
||||
: undefined;
|
||||
return {executablePath: revisionInfo.executablePath, missingText};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function createLauncher(
|
||||
preferredRevision: string,
|
||||
isPuppeteerCore: boolean,
|
||||
product: Product = 'chrome'
|
||||
): ProductLauncher {
|
||||
switch (product) {
|
||||
case 'firefox':
|
||||
return new FirefoxLauncher(preferredRevision, isPuppeteerCore);
|
||||
switch (this.product) {
|
||||
case 'chrome':
|
||||
return new ChromeLauncher(preferredRevision, isPuppeteerCore);
|
||||
default:
|
||||
throw new Error(`Unknown product: ${product}`);
|
||||
throw new Error(
|
||||
`Run \`npm install\` to download the correct Chromium revision (${this.puppeteer.browserRevision}).`
|
||||
);
|
||||
case 'firefox':
|
||||
throw new Error(
|
||||
`Run \`PUPPETEER_PRODUCT=firefox npm install\` to download a supported Firefox browser binary.`
|
||||
);
|
||||
}
|
||||
}
|
||||
return revisionInfo.executablePath;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {join} from 'path';
|
||||
import {Browser} from '../api/Browser.js';
|
||||
import {BrowserConnectOptions} from '../common/BrowserConnector.js';
|
||||
import {Product} from '../common/Product.js';
|
||||
@ -22,10 +23,17 @@ import {
|
||||
ConnectOptions,
|
||||
Puppeteer,
|
||||
} from '../common/Puppeteer.js';
|
||||
import {Configuration} from '../common/Configuration.js';
|
||||
import {PUPPETEER_REVISIONS} from '../revisions.js';
|
||||
import {BrowserFetcher, BrowserFetcherOptions} from './BrowserFetcher.js';
|
||||
import {BrowserLaunchArgumentOptions, LaunchOptions} from './LaunchOptions.js';
|
||||
import {createLauncher, ProductLauncher} from './ProductLauncher.js';
|
||||
import {ChromeLauncher} from './ChromeLauncher.js';
|
||||
import {FirefoxLauncher} from './FirefoxLauncher.js';
|
||||
import {
|
||||
BrowserLaunchArgumentOptions,
|
||||
ChromeReleaseChannel,
|
||||
LaunchOptions,
|
||||
} from './LaunchOptions.js';
|
||||
import {ProductLauncher} from './ProductLauncher.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -74,28 +82,40 @@ export interface PuppeteerLaunchOptions
|
||||
* @public
|
||||
*/
|
||||
export class PuppeteerNode extends Puppeteer {
|
||||
#launcher?: ProductLauncher;
|
||||
#productName?: Product;
|
||||
#_launcher?: ProductLauncher;
|
||||
#lastLaunchedProduct?: Product;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_preferredRevision = PUPPETEER_REVISIONS.chromium;
|
||||
defaultBrowserRevision: string;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
configuration: Configuration = {};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(
|
||||
settings: {
|
||||
preferredRevision?: string;
|
||||
productName?: Product;
|
||||
configuration?: Configuration;
|
||||
} & CommonPuppeteerSettings
|
||||
) {
|
||||
const {preferredRevision, productName, ...commonSettings} = settings;
|
||||
const {configuration, ...commonSettings} = settings;
|
||||
super(commonSettings);
|
||||
this.#productName = productName;
|
||||
if (preferredRevision) {
|
||||
this._preferredRevision = preferredRevision;
|
||||
if (configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
switch (this.configuration.defaultProduct) {
|
||||
case 'firefox':
|
||||
this.defaultBrowserRevision = PUPPETEER_REVISIONS.firefox;
|
||||
break;
|
||||
default:
|
||||
this.configuration.defaultProduct = 'chrome';
|
||||
this.defaultBrowserRevision = PUPPETEER_REVISIONS.chromium;
|
||||
break;
|
||||
}
|
||||
|
||||
this.connect = this.connect.bind(this);
|
||||
@ -116,21 +136,8 @@ export class PuppeteerNode extends Puppeteer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get _productName(): Product | undefined {
|
||||
return this.#productName;
|
||||
}
|
||||
set _productName(name: Product | undefined) {
|
||||
if (this.#productName !== name) {
|
||||
this._changedProduct = true;
|
||||
}
|
||||
this.#productName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches puppeteer and launches a browser instance with given arguments and
|
||||
* options when specified.
|
||||
* Launches a browser instance with given arguments and options when
|
||||
* specified.
|
||||
*
|
||||
* @example
|
||||
* You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments:
|
||||
@ -142,90 +149,118 @@ export class PuppeteerNode extends Puppeteer {
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* **NOTE** Puppeteer can also be used to control the Chrome browser, but it
|
||||
* works best with the version of Chromium it is bundled with. There is no
|
||||
* guarantee it will work with any other version. Use `executablePath` option
|
||||
* with extreme caution. If Google Chrome (rather than Chromium) is preferred,
|
||||
* a {@link https://www.google.com/chrome/browser/canary.html | Chrome Canary}
|
||||
* Puppeteer can also be used to control the Chrome browser, but it works best
|
||||
* with the version of Chromium it is bundled with. There is no guarantee it
|
||||
* will work with any other version. Use `executablePath` option with extreme
|
||||
* caution. If Google Chrome (rather than Chromium) is preferred, a
|
||||
* {@link https://www.google.com/chrome/browser/canary.html | Chrome Canary}
|
||||
* or
|
||||
* {@link https://www.chromium.org/getting-involved/dev-channel | Dev Channel}
|
||||
* build is suggested. In `puppeteer.launch([options])`, any mention of
|
||||
* Chromium also applies to Chrome. See
|
||||
* build is suggested. In {@link Puppeteer.launch}, any mention of Chromium
|
||||
* also applies to Chrome. See
|
||||
* {@link https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/ | this article}
|
||||
* for a description of the differences between Chromium and Chrome.
|
||||
* {@link https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md | This article}
|
||||
* describes some differences for Linux users.
|
||||
*
|
||||
* @param options - Set of configurable options to set on the browser.
|
||||
* @returns Promise which resolves to browser instance.
|
||||
* @param options - Options to configure launching behavior.
|
||||
*/
|
||||
launch(options: PuppeteerLaunchOptions = {}): Promise<Browser> {
|
||||
if (options.product) {
|
||||
this._productName = options.product;
|
||||
}
|
||||
return this._launcher.launch(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @remarks
|
||||
* **NOTE** `puppeteer.executablePath()` is affected by the
|
||||
* `PUPPETEER_EXECUTABLE_PATH` and `PUPPETEER_CHROMIUM_REVISION` environment
|
||||
* variables.
|
||||
*
|
||||
* @returns A path where Puppeteer expects to find the bundled browser. The
|
||||
* browser binary might not be there if the download was skipped with the
|
||||
* `PUPPETEER_SKIP_DOWNLOAD` environment variable.
|
||||
*/
|
||||
executablePath(channel?: string): string {
|
||||
return this._launcher.executablePath(channel);
|
||||
const {product = this.defaultProduct} = options;
|
||||
this.#lastLaunchedProduct = product;
|
||||
return this.#launcher.launch(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get _launcher(): ProductLauncher {
|
||||
get #launcher(): ProductLauncher {
|
||||
if (
|
||||
!this.#launcher ||
|
||||
this.#launcher.product !== this._productName ||
|
||||
this._changedProduct
|
||||
this.#_launcher &&
|
||||
this.#_launcher.product === this.lastLaunchedProduct
|
||||
) {
|
||||
switch (this._productName) {
|
||||
case 'firefox':
|
||||
this._preferredRevision = PUPPETEER_REVISIONS.firefox;
|
||||
break;
|
||||
return this.#_launcher;
|
||||
}
|
||||
switch (this.lastLaunchedProduct) {
|
||||
case 'chrome':
|
||||
this.defaultBrowserRevision = PUPPETEER_REVISIONS.chromium;
|
||||
this.#_launcher = new ChromeLauncher(this);
|
||||
break;
|
||||
case 'firefox':
|
||||
this.defaultBrowserRevision = PUPPETEER_REVISIONS.firefox;
|
||||
this.#_launcher = new FirefoxLauncher(this);
|
||||
break;
|
||||
default:
|
||||
this._preferredRevision = PUPPETEER_REVISIONS.chromium;
|
||||
throw new Error(`Unknown product: ${this.#lastLaunchedProduct}`);
|
||||
}
|
||||
this._changedProduct = false;
|
||||
this.#launcher = createLauncher(
|
||||
this._preferredRevision,
|
||||
this._isPuppeteerCore,
|
||||
this._productName
|
||||
);
|
||||
}
|
||||
return this.#launcher;
|
||||
return this.#_launcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the browser that is under automation (`"chrome"` or
|
||||
* `"firefox"`)
|
||||
* @returns The executable path.
|
||||
*/
|
||||
executablePath(channel?: ChromeReleaseChannel): string {
|
||||
return this.#launcher.executablePath(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get browserRevision(): string {
|
||||
return this.configuration.browserRevision ?? this.defaultBrowserRevision!;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns The default download path for puppeteer. For puppeteer-core, this
|
||||
* code should never be called as it is never defined.
|
||||
*
|
||||
* @remarks
|
||||
* The product is set by the `PUPPETEER_PRODUCT` environment variable or the
|
||||
* `product` option in `puppeteer.launch([options])` and defaults to `chrome`.
|
||||
* Firefox support is experimental.
|
||||
* @internal
|
||||
*/
|
||||
get defaultDownloadPath(): string | undefined {
|
||||
return (
|
||||
this.configuration.downloadPath ??
|
||||
join(this.configuration.cacheDirectory!, this.product)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns The name of the browser that was last launched.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get lastLaunchedProduct(): Product {
|
||||
return this.#lastLaunchedProduct ?? this.defaultProduct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns The name of the browser that will be launched by default. For
|
||||
* `puppeteer`, this is influenced by your configuration. Otherwise, it's
|
||||
* `chrome`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get defaultProduct(): Product {
|
||||
return this.configuration.defaultProduct ?? 'chrome';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not use as this field as it does not take into account
|
||||
* multiple browsers of different types. Use {@link defaultProduct} or
|
||||
* {@link lastLaunchedProduct}.
|
||||
*
|
||||
* @returns The name of the browser that is under automation.
|
||||
*/
|
||||
get product(): string {
|
||||
return this._launcher.product;
|
||||
return this.#launcher.product;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options - Set of configurable options to set on the browser.
|
||||
*
|
||||
* @returns The default flags that Chromium will be launched with.
|
||||
*/
|
||||
defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] {
|
||||
return this._launcher.defaultArgs(options);
|
||||
return this.#launcher.defaultArgs(options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,7 +272,22 @@ export class PuppeteerNode extends Puppeteer {
|
||||
*
|
||||
* @returns A new BrowserFetcher instance.
|
||||
*/
|
||||
createBrowserFetcher(options: BrowserFetcherOptions): BrowserFetcher {
|
||||
return new BrowserFetcher(options);
|
||||
createBrowserFetcher(
|
||||
options: Partial<BrowserFetcherOptions>
|
||||
): BrowserFetcher {
|
||||
const downloadPath = this.defaultDownloadPath;
|
||||
if (downloadPath) {
|
||||
options.path = downloadPath;
|
||||
}
|
||||
if (!options.path) {
|
||||
throw new Error('A `path` must be specified for `puppeteer-core`.');
|
||||
}
|
||||
if (this.configuration.experiments?.macArmChromiumEnabled) {
|
||||
options.useMacOSARMBinary = true;
|
||||
}
|
||||
if (this.configuration.downloadHost) {
|
||||
options.host = this.configuration.downloadHost;
|
||||
}
|
||||
return new BrowserFetcher(options as BrowserFetcherOptions);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import {tmpdir as osTmpDir} from 'os';
|
||||
|
||||
/**
|
||||
* Gets the temporary directory, either from the environmental variable
|
||||
* `PUPPETEER_TMP_DIR` or the `os.tmpdir`.
|
||||
*
|
||||
* @returns The temporary directory path.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export const tmpdir = (): string => {
|
||||
return process.env['PUPPETEER_TMP_DIR'] || osTmpDir();
|
||||
};
|
@ -9,6 +9,7 @@ export * from './common/Browser.js';
|
||||
export * from './common/BrowserConnector.js';
|
||||
export * from './common/BrowserWebSocketTransport.js';
|
||||
export * from './common/ChromeTargetManager.js';
|
||||
export * from './common/Configuration.js';
|
||||
export * from './common/Connection.js';
|
||||
export * from './common/ConnectionTransport.js';
|
||||
export * from './common/ConsoleMessage.js';
|
||||
@ -55,7 +56,6 @@ export * from './common/USKeyboardLayout.js';
|
||||
export * from './common/util.js';
|
||||
export * from './common/WaitTask.js';
|
||||
export * from './common/WebWorker.js';
|
||||
export * from './constants.js';
|
||||
export * from './environment.js';
|
||||
export * from './generated/injected.js';
|
||||
export * from './generated/version.js';
|
||||
@ -67,7 +67,6 @@ export * from './node/LaunchOptions.js';
|
||||
export * from './node/PipeTransport.js';
|
||||
export * from './node/ProductLauncher.js';
|
||||
export * from './node/PuppeteerNode.js';
|
||||
export * from './node/util.js';
|
||||
export * from './puppeteer-core.js';
|
||||
export * from './revisions.js';
|
||||
export * from './util/assert.js';
|
||||
|
@ -28,69 +28,13 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
const {execSync} = require('child_process');
|
||||
|
||||
async function download() {
|
||||
if (!fs.existsSync(path.join(__dirname, 'lib'))) {
|
||||
// Need to ensure TS is compiled before loading the installer
|
||||
if (!fs.existsSync(path.join(__dirname, 'lib'))) {
|
||||
console.log('It seems we are installing from the git repo.');
|
||||
console.log('Building install tools from scratch...');
|
||||
execSync('npm run build');
|
||||
}
|
||||
|
||||
// need to ensure TS is compiled before loading the installer
|
||||
const {
|
||||
downloadBrowser,
|
||||
logPolitely,
|
||||
} = require('puppeteer/lib/cjs/puppeteer/node/install.js');
|
||||
|
||||
if (process.env.PUPPETEER_SKIP_DOWNLOAD) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" environment variable was found.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
process.env.NPM_CONFIG_PUPPETEER_SKIP_DOWNLOAD ||
|
||||
process.env.npm_config_puppeteer_skip_download
|
||||
) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in npm config.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_DOWNLOAD ||
|
||||
process.env.npm_package_config_puppeteer_skip_download
|
||||
) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in project config.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" environment variable was found.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
process.env.NPM_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD ||
|
||||
process.env.npm_config_puppeteer_skip_chromium_download
|
||||
) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in npm config.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD ||
|
||||
process.env.npm_package_config_puppeteer_skip_chromium_download
|
||||
) {
|
||||
logPolitely(
|
||||
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in project config.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
downloadBrowser();
|
||||
execSync('npm run build --workspace puppeteer');
|
||||
}
|
||||
|
||||
download();
|
||||
const {downloadBrowser} = require('puppeteer/internal/node/install.js');
|
||||
|
||||
downloadBrowser();
|
||||
|
@ -135,6 +135,7 @@
|
||||
"author": "The Chromium Authors",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"cosmiconfig": "7.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
|
95
packages/puppeteer/src/getConfiguration.ts
Normal file
95
packages/puppeteer/src/getConfiguration.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import {cosmiconfigSync} from 'cosmiconfig';
|
||||
import {homedir} from 'os';
|
||||
import {join} from 'path';
|
||||
import {Configuration, Product} from 'puppeteer-core';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function isSupportedProduct(product: unknown): product is Product {
|
||||
switch (product) {
|
||||
case 'chrome':
|
||||
case 'firefox':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const getConfiguration = (): Configuration => {
|
||||
const result = cosmiconfigSync('puppeteer').search();
|
||||
const configuration: Configuration = result ? result.config : {};
|
||||
|
||||
// Merging environment variables.
|
||||
configuration.browserRevision =
|
||||
process.env['PUPPETEER_CHROMIUM_REVISION'] ??
|
||||
process.env['PUPPETEER_BROWSER_REVISION'] ??
|
||||
process.env['npm_config_puppeteer_browser_revision'] ??
|
||||
process.env['npm_package_config_puppeteer_browser_revision'] ??
|
||||
configuration.browserRevision;
|
||||
configuration.cacheDirectory =
|
||||
process.env['PUPPETEER_CACHE_DIR'] ??
|
||||
process.env['npm_config_puppeteer_cache_dir'] ??
|
||||
process.env['npm_package_config_puppeteer_cache_dir'] ??
|
||||
configuration.cacheDirectory ??
|
||||
join(homedir(), '.cache', 'puppeteer');
|
||||
configuration.downloadHost =
|
||||
process.env['PUPPETEER_DOWNLOAD_HOST'] ??
|
||||
process.env['npm_config_puppeteer_download_host'] ??
|
||||
process.env['npm_package_config_puppeteer_download_host'] ??
|
||||
configuration.downloadHost;
|
||||
configuration.downloadPath =
|
||||
process.env['PUPPETEER_DOWNLOAD_PATH'] ??
|
||||
process.env['npm_config_puppeteer_download_path'] ??
|
||||
process.env['npm_package_config_puppeteer_download_path'] ??
|
||||
configuration.downloadPath;
|
||||
configuration.executablePath =
|
||||
process.env['PUPPETEER_EXECUTABLE_PATH'] ??
|
||||
process.env['npm_config_puppeteer_executable_path'] ??
|
||||
process.env['npm_package_config_puppeteer_executable_path'] ??
|
||||
configuration.executablePath;
|
||||
configuration.defaultProduct = (process.env['PUPPETEER_PRODUCT'] ??
|
||||
process.env['npm_config_puppeteer_product'] ??
|
||||
process.env['npm_package_config_puppeteer_product'] ??
|
||||
configuration.defaultProduct ??
|
||||
'chrome') as Product;
|
||||
configuration.temporaryDirectory =
|
||||
process.env['PUPPETEER_TMP_DIR'] ??
|
||||
process.env['npm_config_puppeteer_tmp_dir'] ??
|
||||
process.env['npm_package_config_puppeteer_tmp_dir'] ??
|
||||
configuration.temporaryDirectory;
|
||||
|
||||
configuration.experiments ??= {};
|
||||
configuration.experiments.macArmChromiumEnabled = Boolean(
|
||||
process.env['PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM'] ??
|
||||
process.env['npm_config_puppeteer_experimental_chromium_mac_arm'] ??
|
||||
process.env[
|
||||
'npm_package_config_puppeteer_experimental_chromium_mac_arm'
|
||||
] ??
|
||||
configuration.experiments.macArmChromiumEnabled
|
||||
);
|
||||
|
||||
configuration.skipDownload = Boolean(
|
||||
process.env['PUPPETEER_SKIP_DOWNLOAD'] ??
|
||||
process.env['npm_config_puppeteer_skip_download'] ??
|
||||
process.env['npm_package_config_puppeteer_skip_download'] ??
|
||||
process.env['PUPPETEER_SKIP_CHROMIUM_DOWNLOAD'] ??
|
||||
process.env['npm_config_puppeteer_skip_chromium_download'] ??
|
||||
process.env['npm_package_config_puppeteer_skip_chromium_download'] ??
|
||||
configuration.skipDownload
|
||||
);
|
||||
configuration.logLevel = (process.env['PUPPETEER_LOGLEVEL'] ??
|
||||
process.env['npm_config_LOGLEVEL'] ??
|
||||
process.env['npm_package_config_LOGLEVEL'] ??
|
||||
configuration.logLevel) as 'silent' | 'error' | 'warn';
|
||||
|
||||
// Validate configuration.
|
||||
if (!isSupportedProduct(configuration.defaultProduct)) {
|
||||
throw new Error(`Unsupported product ${configuration.defaultProduct}`);
|
||||
}
|
||||
|
||||
return configuration;
|
||||
};
|
@ -16,13 +16,13 @@
|
||||
|
||||
import https, {RequestOptions} from 'https';
|
||||
import createHttpsProxyAgent, {HttpsProxyAgentOptions} from 'https-proxy-agent';
|
||||
import {join} from 'path';
|
||||
import ProgressBar from 'progress';
|
||||
import {getProxyForUrl} from 'proxy-from-env';
|
||||
import {BrowserFetcher} from 'puppeteer-core';
|
||||
import {PuppeteerNode} from 'puppeteer-core/internal/node/PuppeteerNode.js';
|
||||
import {PUPPETEER_REVISIONS} from 'puppeteer-core/internal/revisions.js';
|
||||
import URL from 'url';
|
||||
import puppeteer from '../puppeteer.js';
|
||||
import {getConfiguration} from '../getConfiguration.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -32,61 +32,40 @@ const supportedProducts = {
|
||||
firefox: 'Firefox Nightly',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function getProduct(input: string): 'chrome' | 'firefox' {
|
||||
if (input !== 'chrome' && input !== 'firefox') {
|
||||
throw new Error(`Unsupported product ${input}`);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export async function downloadBrowser(): Promise<void> {
|
||||
const downloadHost =
|
||||
process.env['PUPPETEER_DOWNLOAD_HOST'] ||
|
||||
process.env['npm_config_puppeteer_download_host'] ||
|
||||
process.env['npm_package_config_puppeteer_download_host'];
|
||||
const product = getProduct(
|
||||
process.env['PUPPETEER_PRODUCT'] ||
|
||||
process.env['npm_config_puppeteer_product'] ||
|
||||
process.env['npm_package_config_puppeteer_product'] ||
|
||||
'chrome'
|
||||
);
|
||||
const downloadPath =
|
||||
process.env['PUPPETEER_DOWNLOAD_PATH'] ||
|
||||
process.env['npm_config_puppeteer_download_path'] ||
|
||||
process.env['npm_package_config_puppeteer_download_path'];
|
||||
const configuration = getConfiguration();
|
||||
if (configuration.skipDownload) {
|
||||
logPolitely('**INFO** Skipping browser download as instructed.');
|
||||
}
|
||||
|
||||
const product = configuration.defaultProduct!;
|
||||
const browserFetcher = new BrowserFetcher({
|
||||
product,
|
||||
host: downloadHost,
|
||||
path: downloadPath,
|
||||
host: configuration.downloadHost,
|
||||
path:
|
||||
configuration.downloadPath ??
|
||||
join(configuration.cacheDirectory!, product),
|
||||
});
|
||||
const revision = await getRevision();
|
||||
await fetchBinary(revision);
|
||||
|
||||
async function getRevision(): Promise<string> {
|
||||
if (product === 'chrome') {
|
||||
return (
|
||||
process.env['PUPPETEER_CHROMIUM_REVISION'] ||
|
||||
process.env['npm_config_puppeteer_chromium_revision'] ||
|
||||
PUPPETEER_REVISIONS.chromium
|
||||
);
|
||||
} else if (product === 'firefox') {
|
||||
(puppeteer as PuppeteerNode)._preferredRevision =
|
||||
PUPPETEER_REVISIONS.firefox;
|
||||
return getFirefoxNightlyVersion().catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Unsupported product ${product}`);
|
||||
let revision = configuration.browserRevision;
|
||||
|
||||
if (!revision) {
|
||||
switch (product) {
|
||||
case 'chrome':
|
||||
revision = PUPPETEER_REVISIONS.chromium;
|
||||
break;
|
||||
case 'firefox':
|
||||
revision = PUPPETEER_REVISIONS.firefox;
|
||||
revision = await getFirefoxNightlyVersion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await fetchBinary(revision);
|
||||
|
||||
function fetchBinary(revision: string) {
|
||||
const revisionInfo = browserFetcher.revisionInfo(revision);
|
||||
|
||||
@ -222,7 +201,7 @@ export async function downloadBrowser(): Promise<void> {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function logPolitely(toBeLogged: unknown): void {
|
||||
function logPolitely(toBeLogged: unknown): void {
|
||||
const logLevel = process.env['npm_config_loglevel'] || '';
|
||||
const logLevelDisplay = ['silent', 'error', 'warn'].indexOf(logLevel) > -1;
|
||||
|
||||
|
@ -19,37 +19,24 @@ export * from 'puppeteer-core/internal/common/Device.js';
|
||||
export * from 'puppeteer-core/internal/common/Errors.js';
|
||||
export * from 'puppeteer-core/internal/common/PredefinedNetworkConditions.js';
|
||||
export * from 'puppeteer-core/internal/common/Puppeteer.js';
|
||||
export * from 'puppeteer-core/internal/node/BrowserFetcher.js';
|
||||
/**
|
||||
* @deprecated Use the query handler API defined on {@link Puppeteer}
|
||||
*/
|
||||
export * from 'puppeteer-core/internal/common/QueryHandler.js';
|
||||
export * from 'puppeteer-core/internal/node/BrowserFetcher.js';
|
||||
export {LaunchOptions} from 'puppeteer-core/internal/node/LaunchOptions.js';
|
||||
|
||||
import {Product} from 'puppeteer-core';
|
||||
import {PuppeteerNode} from 'puppeteer-core/internal/node/PuppeteerNode.js';
|
||||
import {PUPPETEER_REVISIONS} from 'puppeteer-core/internal/revisions.js';
|
||||
import {getConfiguration} from './getConfiguration.js';
|
||||
|
||||
const productName = (process.env['PUPPETEER_PRODUCT'] ||
|
||||
process.env['npm_config_puppeteer_product'] ||
|
||||
process.env['npm_package_config_puppeteer_product']) as Product;
|
||||
|
||||
let preferredRevision: string;
|
||||
switch (productName) {
|
||||
case 'firefox':
|
||||
preferredRevision = PUPPETEER_REVISIONS.firefox;
|
||||
break;
|
||||
default:
|
||||
preferredRevision = PUPPETEER_REVISIONS.chromium;
|
||||
}
|
||||
const configuration = getConfiguration();
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const puppeteer = new PuppeteerNode({
|
||||
preferredRevision,
|
||||
isPuppeteerCore: false,
|
||||
productName,
|
||||
configuration,
|
||||
});
|
||||
|
||||
export const {
|
||||
|
@ -9,6 +9,7 @@ export * from 'puppeteer-core/internal/common/Browser.js';
|
||||
export * from 'puppeteer-core/internal/common/BrowserConnector.js';
|
||||
export * from 'puppeteer-core/internal/common/BrowserWebSocketTransport.js';
|
||||
export * from 'puppeteer-core/internal/common/ChromeTargetManager.js';
|
||||
export * from 'puppeteer-core/internal/common/Configuration.js';
|
||||
export * from 'puppeteer-core/internal/common/Connection.js';
|
||||
export * from 'puppeteer-core/internal/common/ConnectionTransport.js';
|
||||
export * from 'puppeteer-core/internal/common/ConsoleMessage.js';
|
||||
@ -55,7 +56,6 @@ export * from 'puppeteer-core/internal/common/USKeyboardLayout.js';
|
||||
export * from 'puppeteer-core/internal/common/util.js';
|
||||
export * from 'puppeteer-core/internal/common/WaitTask.js';
|
||||
export * from 'puppeteer-core/internal/common/WebWorker.js';
|
||||
export * from 'puppeteer-core/internal/constants.js';
|
||||
export * from 'puppeteer-core/internal/environment.js';
|
||||
export * from 'puppeteer-core/internal/generated/injected.js';
|
||||
export * from 'puppeteer-core/internal/generated/version.js';
|
||||
@ -67,10 +67,10 @@ export * from 'puppeteer-core/internal/node/LaunchOptions.js';
|
||||
export * from 'puppeteer-core/internal/node/PipeTransport.js';
|
||||
export * from 'puppeteer-core/internal/node/ProductLauncher.js';
|
||||
export * from 'puppeteer-core/internal/node/PuppeteerNode.js';
|
||||
export * from 'puppeteer-core/internal/node/util.js';
|
||||
export * from 'puppeteer-core/internal/revisions.js';
|
||||
export * from 'puppeteer-core/internal/util/assert.js';
|
||||
export * from 'puppeteer-core/internal/util/DebuggableDeferredPromise.js';
|
||||
export * from 'puppeteer-core/internal/util/DeferredPromise.js';
|
||||
export * from 'puppeteer-core/internal/util/ErrorLike.js';
|
||||
export * from './getConfiguration.js';
|
||||
export * from './puppeteer.js';
|
||||
|
@ -0,0 +1,8 @@
|
||||
const {join} = require('path');
|
||||
|
||||
/**
|
||||
* @type {import("puppeteer").PuppeteerConfiguration}
|
||||
*/
|
||||
module.exports = {
|
||||
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
|
||||
};
|
@ -51,6 +51,7 @@ export interface DescribeInstallationOptions {
|
||||
* This should be idempotent.
|
||||
*/
|
||||
env?: ((cwd: string) => NodeJS.ProcessEnv) | NodeJS.ProcessEnv;
|
||||
before?: (cwd: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface DescribeInstallationContext {
|
||||
@ -92,6 +93,10 @@ export const describeInstallation = (
|
||||
};
|
||||
}
|
||||
env = {...process.env, ...getEnv(sandbox)};
|
||||
|
||||
if (options.before) {
|
||||
await options.before(sandbox);
|
||||
}
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
43
test/installation/src/puppeteer-configuration.spec.ts
Normal file
43
test/installation/src/puppeteer-configuration.spec.ts
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright 2022 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import assert from 'assert';
|
||||
import {readdir, writeFile} from 'fs/promises';
|
||||
import {join} from 'path';
|
||||
import {describeInstallation} from './describeInstallation.js';
|
||||
import {readAsset} from './util.js';
|
||||
|
||||
describeInstallation(
|
||||
'`puppeteer` with configuration',
|
||||
{
|
||||
dependencies: ['puppeteer-core', 'puppeteer'],
|
||||
before: async cwd => {
|
||||
await writeFile(
|
||||
join(cwd, '.puppeteerrc.cjs'),
|
||||
await readAsset('puppeteer', 'configuration', '.puppeteerrc.cjs')
|
||||
);
|
||||
},
|
||||
},
|
||||
({itEvaluates}) => {
|
||||
itEvaluates('properly', async cwd => {
|
||||
const files = await readdir(join(cwd, '.cache', 'puppeteer'));
|
||||
assert.equal(files.length, 1);
|
||||
assert.equal(files[0], 'chrome');
|
||||
|
||||
return readAsset('puppeteer', 'basic.js');
|
||||
});
|
||||
}
|
||||
);
|
@ -20,7 +20,6 @@ import os from 'os';
|
||||
import path from 'path';
|
||||
import {BrowserFetcher, TimeoutError} from 'puppeteer';
|
||||
import {Page} from 'puppeteer-core/internal/api/Page.js';
|
||||
import {Product} from 'puppeteer-core/internal/common/Product.js';
|
||||
import rimraf from 'rimraf';
|
||||
import sinon from 'sinon';
|
||||
import {TLSSocket} from 'tls';
|
||||
@ -259,7 +258,8 @@ describe('Launcher specs', function () {
|
||||
const testTmpDir = await fs.promises.mkdtemp(
|
||||
path.join(os.tmpdir(), 'puppeteer_test_chrome_profile-')
|
||||
);
|
||||
process.env['PUPPETEER_TMP_DIR'] = testTmpDir;
|
||||
const oldTmpDir = puppeteer.configuration.temporaryDirectory;
|
||||
puppeteer.configuration.temporaryDirectory = testTmpDir;
|
||||
|
||||
// Path should be empty before starting the browser.
|
||||
expect(fs.readdirSync(testTmpDir).length).toEqual(0);
|
||||
@ -277,8 +277,9 @@ describe('Launcher specs', function () {
|
||||
await browser.close();
|
||||
// Profile should be deleted after closing the browser
|
||||
expect(fs.readdirSync(testTmpDir).length).toEqual(0);
|
||||
|
||||
// Restore env var
|
||||
process.env['PUPPETEER_TMP_DIR'] = '';
|
||||
puppeteer.configuration.temporaryDirectory = oldTmpDir;
|
||||
});
|
||||
it('userDataDir option restores preferences', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
@ -624,21 +625,6 @@ describe('Launcher specs', function () {
|
||||
});
|
||||
|
||||
describe('Puppeteer.launch', function () {
|
||||
let productName!: Product;
|
||||
|
||||
before(async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
productName = puppeteer._productName!;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
// @ts-expect-error launcher is a private property that users can't
|
||||
// touch, but for testing purposes we need to reset it.
|
||||
puppeteer._lazyLauncher = undefined;
|
||||
puppeteer._productName = productName;
|
||||
});
|
||||
|
||||
itOnlyRegularInstall('should be able to launch Chrome', async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
const browser = await puppeteer.launch({product: 'chrome'});
|
||||
@ -890,26 +876,29 @@ describe('Launcher specs', function () {
|
||||
const executablePath = puppeteer.executablePath('chrome');
|
||||
expect(executablePath).toBeTruthy();
|
||||
});
|
||||
describe('when PUPPETEER_EXECUTABLE_PATH is set', () => {
|
||||
describe('when executable path is configured', () => {
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['PUPPETEER_EXECUTABLE_PATH'] = '';
|
||||
const {puppeteer} = getTestState();
|
||||
sandbox
|
||||
.stub(process.env, 'PUPPETEER_EXECUTABLE_PATH')
|
||||
.stub(puppeteer.configuration, 'executablePath')
|
||||
.value('SOME_CUSTOM_EXECUTABLE');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
return sandbox.restore();
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('its value is returned', async () => {
|
||||
it('its value is used', async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
|
||||
const executablePath = puppeteer.executablePath();
|
||||
|
||||
expect(executablePath).toEqual('SOME_CUSTOM_EXECUTABLE');
|
||||
try {
|
||||
puppeteer.executablePath();
|
||||
} catch (error) {
|
||||
expect((error as Error).message).toContain(
|
||||
'SOME_CUSTOM_EXECUTABLE'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -930,26 +919,29 @@ describe('Launcher specs', function () {
|
||||
osArchStub.restore();
|
||||
fsExistsStub.restore();
|
||||
});
|
||||
describe('and PUPPETEER_EXECUTABLE_PATH is set', () => {
|
||||
describe('and the executable path is configured', () => {
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['PUPPETEER_EXECUTABLE_PATH'] = '';
|
||||
const {puppeteer} = getTestState();
|
||||
sandbox
|
||||
.stub(process.env, 'PUPPETEER_EXECUTABLE_PATH')
|
||||
.stub(puppeteer.configuration, 'executablePath')
|
||||
.value('SOME_CUSTOM_EXECUTABLE');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
return sandbox.restore();
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('its value is returned', async () => {
|
||||
it('its value is used', async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
|
||||
const executablePath = puppeteer.executablePath();
|
||||
|
||||
expect(executablePath).toEqual('SOME_CUSTOM_EXECUTABLE');
|
||||
try {
|
||||
puppeteer.executablePath();
|
||||
} catch (error) {
|
||||
expect((error as Error).message).toContain(
|
||||
'SOME_CUSTOM_EXECUTABLE'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -961,9 +953,9 @@ describe('Launcher specs', function () {
|
||||
const fsExistsStub = sinon.stub(fs, 'existsSync');
|
||||
fsExistsStub.withArgs('/usr/bin/chromium-browser').returns(false);
|
||||
|
||||
const executablePath = puppeteer.executablePath();
|
||||
|
||||
expect(executablePath).not.toEqual('/usr/bin/chromium-browser');
|
||||
expect(() => {
|
||||
return puppeteer.executablePath();
|
||||
}).toThrowError();
|
||||
|
||||
osPlatformStub.restore();
|
||||
osArchStub.restore();
|
||||
|
@ -101,14 +101,6 @@ const defaultBrowserOptions = Object.assign(
|
||||
`WARN: running ${product} tests with ${defaultBrowserOptions.executablePath}`
|
||||
);
|
||||
} else {
|
||||
// TODO(jackfranklin): declare updateRevision in some form for the Firefox
|
||||
// launcher.
|
||||
if (product === 'firefox') {
|
||||
// @ts-expect-error _updateRevision is defined on the FF launcher
|
||||
// but not the Chrome one. The types need tidying so that TS can infer that
|
||||
// properly and not error here.
|
||||
await puppeteer._launcher._updateRevision();
|
||||
}
|
||||
const executablePath = puppeteer.executablePath();
|
||||
if (!fs.existsSync(executablePath)) {
|
||||
throw new Error(
|
||||
|
Loading…
Reference in New Issue
Block a user