feat: introduce browserType.downloadBrowserIfNeeded() (#834)

Fixes #823
This commit is contained in:
Andrey Lushnikov 2020-02-11 11:33:48 -08:00 committed by GitHub
parent 9ea8f49cd1
commit ad9d6cc31f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 4 deletions

View file

@ -3478,6 +3478,7 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
<!-- GEN:toc --> <!-- GEN:toc -->
- [browserType.connect(options)](#browsertypeconnectoptions) - [browserType.connect(options)](#browsertypeconnectoptions)
- [browserType.devices](#browsertypedevices) - [browserType.devices](#browsertypedevices)
- [browserType.downloadBrowserIfNeeded([progress])](#browsertypedownloadbrowserifneededprogress)
- [browserType.errors](#browsertypeerrors) - [browserType.errors](#browsertypeerrors)
- [browserType.executablePath()](#browsertypeexecutablepath) - [browserType.executablePath()](#browsertypeexecutablepath)
- [browserType.launch([options])](#browsertypelaunchoptions) - [browserType.launch([options])](#browsertypelaunchoptions)
@ -3516,6 +3517,12 @@ const iPhone = webkit.devices['iPhone 6'];
})(); })();
``` ```
#### browserType.downloadBrowserIfNeeded([progress])
- `progress` <[function]> If download is initiated, this function is called with two parameters: `downloadedBytes` and `totalBytes`.
- returns: <[Promise]> promise that resolves when browser is successfully downloaded.
Download browser binary if it is missing.
#### browserType.errors #### browserType.errors
- returns: <[Object]> - returns: <[Object]>
- `TimeoutError` <[function]> A class of [TimeoutError]. - `TimeoutError` <[function]> A class of [TimeoutError].

View file

@ -38,7 +38,7 @@ async function downloadBrowser(browser) {
// Do nothing if the revision is already downloaded. // Do nothing if the revision is already downloaded.
if (revisionInfo.local) if (revisionInfo.local)
return revisionInfo; return revisionInfo;
await fetcher.download(revisionInfo.revision, onProgress); await browserType.downloadBrowserIfNeeded(onProgress);
logPolitely(`${browser} downloaded to ${revisionInfo.folderPath}`); logPolitely(`${browser} downloaded to ${revisionInfo.folderPath}`);
return revisionInfo; return revisionInfo;
} }

View file

@ -19,6 +19,7 @@ import { TimeoutError } from '../errors';
import { Browser, ConnectOptions } from '../browser'; import { Browser, ConnectOptions } from '../browser';
import { BrowserContext } from '../browserContext'; import { BrowserContext } from '../browserContext';
import { BrowserServer } from './browserServer'; import { BrowserServer } from './browserServer';
import { OnProgressCallback } from './browserFetcher';
export type BrowserArgOptions = { export type BrowserArgOptions = {
headless?: boolean, headless?: boolean,
@ -44,6 +45,7 @@ export interface BrowserType {
launchServer(options?: LaunchOptions & { port?: number }): Promise<BrowserServer>; launchServer(options?: LaunchOptions & { port?: number }): Promise<BrowserServer>;
launchPersistent(userDataDir: string, options?: LaunchOptions): Promise<BrowserContext>; launchPersistent(userDataDir: string, options?: LaunchOptions): Promise<BrowserContext>;
connect(options: ConnectOptions): Promise<Browser>; connect(options: ConnectOptions): Promise<Browser>;
downloadBrowserIfNeeded(progress?: OnProgressCallback): Promise<void>;
devices: types.Devices; devices: types.Devices;
errors: { TimeoutError: typeof TimeoutError }; errors: { TimeoutError: typeof TimeoutError };
} }

View file

@ -19,7 +19,7 @@ import * as fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as util from 'util'; import * as util from 'util';
import { BrowserFetcher, BrowserFetcherOptions } from '../server/browserFetcher'; import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from '../server/browserFetcher';
import { DeviceDescriptors } from '../deviceDescriptors'; import { DeviceDescriptors } from '../deviceDescriptors';
import * as types from '../types'; import * as types from '../types';
import { assert } from '../helper'; import { assert } from '../helper';
@ -194,6 +194,15 @@ export class Chromium implements BrowserType {
return chromeArguments; return chromeArguments;
} }
async downloadBrowserIfNeeded(onProgress?: OnProgressCallback) {
const fetcher = this._createBrowserFetcher();
const revisionInfo = fetcher.revisionInfo();
// Do nothing if the revision is already downloaded.
if (revisionInfo.local)
return;
await fetcher.download(revisionInfo.revision, onProgress);
}
_createBrowserFetcher(options: BrowserFetcherOptions = {}): BrowserFetcher { _createBrowserFetcher(options: BrowserFetcherOptions = {}): BrowserFetcher {
const downloadURLs = { const downloadURLs = {
linux: '%s/chromium-browser-snapshots/Linux_x64/%d/%s.zip', linux: '%s/chromium-browser-snapshots/Linux_x64/%d/%s.zip',

View file

@ -16,7 +16,7 @@
*/ */
import { FFBrowser } from '../firefox/ffBrowser'; import { FFBrowser } from '../firefox/ffBrowser';
import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher'; import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from './browserFetcher';
import { DeviceDescriptors } from '../deviceDescriptors'; import { DeviceDescriptors } from '../deviceDescriptors';
import { launchProcess, waitForLine } from './processLauncher'; import { launchProcess, waitForLine } from './processLauncher';
import * as types from '../types'; import * as types from '../types';
@ -44,6 +44,15 @@ export class Firefox implements BrowserType {
this._revision = preferredRevision; this._revision = preferredRevision;
} }
async downloadBrowserIfNeeded(onProgress?: OnProgressCallback) {
const fetcher = this._createBrowserFetcher();
const revisionInfo = fetcher.revisionInfo();
// Do nothing if the revision is already downloaded.
if (revisionInfo.local)
return;
await fetcher.download(revisionInfo.revision, onProgress);
}
name() { name() {
return 'firefox'; return 'firefox';
} }

View file

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher'; import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from './browserFetcher';
import { DeviceDescriptors } from '../deviceDescriptors'; import { DeviceDescriptors } from '../deviceDescriptors';
import { TimeoutError } from '../errors'; import { TimeoutError } from '../errors';
import * as types from '../types'; import * as types from '../types';
@ -52,6 +52,15 @@ export class WebKit implements BrowserType {
return 'webkit'; return 'webkit';
} }
async downloadBrowserIfNeeded(onProgress?: OnProgressCallback) {
const fetcher = this._createBrowserFetcher();
const revisionInfo = fetcher.revisionInfo();
// Do nothing if the revision is already downloaded.
if (revisionInfo.local)
return;
await fetcher.download(revisionInfo.revision, onProgress);
}
async launch(options?: LaunchOptions & { slowMo?: number }): Promise<WKBrowser> { async launch(options?: LaunchOptions & { slowMo?: number }): Promise<WKBrowser> {
const { browserServer, transport } = await this._launchServer(options, 'local'); const { browserServer, transport } = await this._launchServer(options, 'local');
const browser = await WKBrowser.connect(transport!, options && options.slowMo); const browser = await WKBrowser.connect(transport!, options && options.slowMo);