From ad9d6cc31f689aa3527712351ed4c4bcae42c1bc Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Tue, 11 Feb 2020 11:33:48 -0800 Subject: [PATCH] feat: introduce browserType.downloadBrowserIfNeeded() (#834) Fixes #823 --- docs/api.md | 7 +++++++ download-browser.js | 2 +- src/server/browserType.ts | 2 ++ src/server/chromium.ts | 11 ++++++++++- src/server/firefox.ts | 11 ++++++++++- src/server/webkit.ts | 11 ++++++++++- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/api.md b/docs/api.md index e8b6f26907..6432f8bd8d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -3478,6 +3478,7 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. - [browserType.connect(options)](#browsertypeconnectoptions) - [browserType.devices](#browsertypedevices) +- [browserType.downloadBrowserIfNeeded([progress])](#browsertypedownloadbrowserifneededprogress) - [browserType.errors](#browsertypeerrors) - [browserType.executablePath()](#browsertypeexecutablepath) - [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 - returns: <[Object]> - `TimeoutError` <[function]> A class of [TimeoutError]. diff --git a/download-browser.js b/download-browser.js index 5cbb6ba5ca..c2a72e755e 100644 --- a/download-browser.js +++ b/download-browser.js @@ -38,7 +38,7 @@ async function downloadBrowser(browser) { // Do nothing if the revision is already downloaded. if (revisionInfo.local) return revisionInfo; - await fetcher.download(revisionInfo.revision, onProgress); + await browserType.downloadBrowserIfNeeded(onProgress); logPolitely(`${browser} downloaded to ${revisionInfo.folderPath}`); return revisionInfo; } diff --git a/src/server/browserType.ts b/src/server/browserType.ts index b7a15387c2..3c1c970c47 100644 --- a/src/server/browserType.ts +++ b/src/server/browserType.ts @@ -19,6 +19,7 @@ import { TimeoutError } from '../errors'; import { Browser, ConnectOptions } from '../browser'; import { BrowserContext } from '../browserContext'; import { BrowserServer } from './browserServer'; +import { OnProgressCallback } from './browserFetcher'; export type BrowserArgOptions = { headless?: boolean, @@ -44,6 +45,7 @@ export interface BrowserType { launchServer(options?: LaunchOptions & { port?: number }): Promise; launchPersistent(userDataDir: string, options?: LaunchOptions): Promise; connect(options: ConnectOptions): Promise; + downloadBrowserIfNeeded(progress?: OnProgressCallback): Promise; devices: types.Devices; errors: { TimeoutError: typeof TimeoutError }; } diff --git a/src/server/chromium.ts b/src/server/chromium.ts index e987437360..833965f998 100644 --- a/src/server/chromium.ts +++ b/src/server/chromium.ts @@ -19,7 +19,7 @@ import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; import * as util from 'util'; -import { BrowserFetcher, BrowserFetcherOptions } from '../server/browserFetcher'; +import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from '../server/browserFetcher'; import { DeviceDescriptors } from '../deviceDescriptors'; import * as types from '../types'; import { assert } from '../helper'; @@ -194,6 +194,15 @@ export class Chromium implements BrowserType { 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 { const downloadURLs = { linux: '%s/chromium-browser-snapshots/Linux_x64/%d/%s.zip', diff --git a/src/server/firefox.ts b/src/server/firefox.ts index a1b6b1ba61..67c0c66810 100644 --- a/src/server/firefox.ts +++ b/src/server/firefox.ts @@ -16,7 +16,7 @@ */ import { FFBrowser } from '../firefox/ffBrowser'; -import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher'; +import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from './browserFetcher'; import { DeviceDescriptors } from '../deviceDescriptors'; import { launchProcess, waitForLine } from './processLauncher'; import * as types from '../types'; @@ -44,6 +44,15 @@ export class Firefox implements BrowserType { 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() { return 'firefox'; } diff --git a/src/server/webkit.ts b/src/server/webkit.ts index ff45332816..9a3297ef3c 100644 --- a/src/server/webkit.ts +++ b/src/server/webkit.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher'; +import { BrowserFetcher, OnProgressCallback, BrowserFetcherOptions } from './browserFetcher'; import { DeviceDescriptors } from '../deviceDescriptors'; import { TimeoutError } from '../errors'; import * as types from '../types'; @@ -52,6 +52,15 @@ export class WebKit implements BrowserType { 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 { const { browserServer, transport } = await this._launchServer(options, 'local'); const browser = await WKBrowser.connect(transport!, options && options.slowMo);