diff --git a/docs/api.md b/docs/api.md index 591eca296c0..106fb644bdd 100644 --- a/docs/api.md +++ b/docs/api.md @@ -10,9 +10,17 @@ - [Environment Variables](#environment-variables) - [class: Puppeteer](#class-puppeteer) * [puppeteer.connect(options)](#puppeteerconnectoptions) + * [puppeteer.createBrowserFetcher([options])](#puppeteercreatebrowserfetcheroptions) * [puppeteer.defaultArgs()](#puppeteerdefaultargs) * [puppeteer.executablePath()](#puppeteerexecutablepath) * [puppeteer.launch([options])](#puppeteerlaunchoptions) +- [class: BrowserFetcher](#class-browserfetcher) + * [browserFetcher.canDownload(revision)](#browserfetchercandownloadrevision) + * [browserFetcher.download(revision[, progressCallback])](#browserfetcherdownloadrevision-progresscallback) + * [browserFetcher.localRevisions()](#browserfetcherlocalrevisions) + * [browserFetcher.platform()](#browserfetcherplatform) + * [browserFetcher.remove(revision)](#browserfetcherremoverevision) + * [browserFetcher.revisionInfo(revision)](#browserfetcherrevisioninforevision) - [class: Browser](#class-browser) * [event: 'disconnected'](#event-disconnected) * [event: 'targetchanged'](#event-targetchanged) @@ -273,6 +281,13 @@ puppeteer.launch().then(async browser => { This methods attaches Puppeteer to an existing Chromium instance. +#### puppeteer.createBrowserFetcher([options]) +- `options` <[Object]> + - `host` <[string]> A download host to be used. Defaults to `https://storage.googleapis.com`. + - `path` <[string]> A path for the downloads folder. Defaults to `/.local-chromium`, where `` is puppeteer's package root. + - `platform` <[string]> Possible values are: `mac`, `win32`, `win64`, `linux`. Defaults to the current platform. +- returns: <[BrowserFetcher]> + #### puppeteer.defaultArgs() - returns: <[Array]<[string]>> The default flags that Chromium will be launched with. @@ -307,6 +322,63 @@ If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https:// > > 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/+/lkcr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users. + +### class: BrowserFetcher + +BrowserFetcher can download and manage different versions of Chromium. + +BrowserFetcher operates on revision strings that specify a precise version of Chromium, e.g. `"533271"`. Revision strings can be obtained from [omahaproxy.appspot.com](http://omahaproxy.appspot.com/). + +Example on how to use BrowserFetcher to download a specific version of Chromium and run +puppeteer against it: + +```js +const browserFetcher = puppeteer.createBrowserFetcher(); +const revisionInfo = await browserFetcher.download('533271'); +const browser = await puppeteer.launch({executablePath: revisionInfo.executablePath}) +``` + +> **NOTE** BrowserFetcher is not designed to work concurrently with other +> instances of BrowserFetcher that share the same downloads directory. + +#### browserFetcher.canDownload(revision) +- `revision` <[string]> a revision to check availability. +- returns: <[Promise]<[boolean]>> returns `true` if the revision could be downloaded from the host. + +The method initiates a HEAD request to check if the revision is available. + +#### browserFetcher.download(revision[, progressCallback]) +- `revision` <[string]> a revision to download. +- `progressCallback` <[function]([number], [number])> A function that will be called with two arguments: + - `downloadedBytes` <[number]> how many bytes have been downloaded + - `totalBytes` <[number]> how large is the total download. +- returns: <[Promise]<[Object]>> Resolves with revision information when the revision is downloaded and extracted + - `revision` <[string]> the revision the info was created from + - `folderPath` <[string]> path to the extracted revision folder + - `executablePath` <[string]> path to the revision executable + - `url` <[string]> URL this revision can be downloaded from + - `local` <[boolean]> whether the revision is locally available on disk + +The method initiates a GET request to download the revision from the host. + +#### browserFetcher.localRevisions() +- returns: <[Promise]<[Array]<[string]>>> A list of all revisions available locally on disk. + +#### browserFetcher.platform() +- returns: <[string]> Returns one of `mac`, `linux`, `win32` or `win64`. + +#### browserFetcher.remove(revision) +- `revision` <[string]> a revision to remove. The method will throw if the revision has not been downloaded. +- returns: <[Promise]> Resolves when the revision has been removed. + +#### browserFetcher.revisionInfo(revision) +- `revision` <[string]> a revision to get info for. +- returns: <[Object]> + - `revision` <[string]> the revision the info was created from + - `folderPath` <[string]> path to the extracted revision folder + - `executablePath` <[string]> path to the revision executable + - `url` <[string]> URL this revision can be downloaded from + - `local` <[boolean]> whether the revision is locally available on disk ### class: Browser @@ -2489,6 +2561,7 @@ reported. [string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String" [stream.Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "stream.Readable" [CDPSession]: #class-cdpsession "CDPSession" +[BrowserFetcher]: #class-browserfetcher "BrowserFetcher" [Error]: https://nodejs.org/api/errors.html#errors_class_error "Error" [Frame]: #class-frame "Frame" [ConsoleMessage]: #class-consolemessage "ConsoleMessage" diff --git a/install.js b/install.js index a2218017c6b..49541079987 100644 --- a/install.js +++ b/install.js @@ -25,16 +25,16 @@ if (process.env.NPM_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD || process.env.npm_c return; } -const Downloader = require('./lib/Downloader'); -const downloader = Downloader.createDefault(); +const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host; -const platform = downloader.currentPlatform(); -const revision = Downloader.defaultRevision(); -const ProgressBar = require('progress'); +const puppeteer = require('./index'); +const browserFetcher = puppeteer.createBrowserFetcher({ host: downloadHost }); + +const revision = require('./package.json').puppeteer.chromium_revision; +const revisionInfo = browserFetcher.revisionInfo(revision); -const revisionInfo = downloader.revisionInfo(platform, revision); // Do nothing if the revision is already downloaded. -if (revisionInfo.downloaded) +if (revisionInfo.local) return; // Override current environment proxy settings with npm configuration, if any. @@ -49,21 +49,20 @@ if (NPM_HTTP_PROXY) if (NPM_NO_PROXY) process.env.NO_PROXY = NPM_NO_PROXY; -const allRevisions = downloader.downloadedRevisions(); -const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host; -if (downloadHost) - downloader.setDownloadHost(downloadHost); -downloader.downloadRevision(platform, revision, onProgress) +browserFetcher.download(revisionInfo.revision, onProgress) + .then(() => browserFetcher.localRevisions()) .then(onSuccess) .catch(onError); /** + * @param {!Array} * @return {!Promise} */ -function onSuccess() { +function onSuccess(localRevisions) { console.log('Chromium downloaded to ' + revisionInfo.folderPath); + localRevisions = localRevisions.filter(revision => revision !== revisionInfo.revision); // Remove previous chromium revisions. - const cleanupOldVersions = allRevisions.map(({platform, revision}) => downloader.removeRevision(platform, revision)); + const cleanupOldVersions = localRevisions.map(revision => browserFetcher.remove(revision)); return Promise.all(cleanupOldVersions); } @@ -77,15 +76,19 @@ function onError(error) { } let progressBar = null; -function onProgress(bytesTotal, delta) { +let lastDownloadedBytes = 0; +function onProgress(downloadedBytes, totalBytes) { if (!progressBar) { - progressBar = new ProgressBar(`Downloading Chromium r${revision} - ${toMegabytes(bytesTotal)} [:bar] :percent :etas `, { + const ProgressBar = require('progress'); + progressBar = new ProgressBar(`Downloading Chromium r${revision} - ${toMegabytes(totalBytes)} [:bar] :percent :etas `, { complete: '=', incomplete: ' ', width: 20, - total: bytesTotal, + total: totalBytes, }); } + const delta = downloadedBytes - lastDownloadedBytes; + lastDownloadedBytes = downloadedBytes; progressBar.tick(delta); } diff --git a/lib/Downloader.js b/lib/BrowserFetcher.js similarity index 55% rename from lib/Downloader.js rename to lib/BrowserFetcher.js index c7d161a47cd..1e359a6aecd 100644 --- a/lib/Downloader.js +++ b/lib/BrowserFetcher.js @@ -20,6 +20,7 @@ const path = require('path'); const extract = require('extract-zip'); const util = require('util'); const URL = require('url'); +const {helper} = require('./helper'); const removeRecursive = require('rimraf'); // @ts-ignore const ProxyAgent = require('https-proxy-agent'); @@ -34,70 +35,52 @@ const downloadURLs = { win64: '%s/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip', }; -// Project root will be different for node6-transpiled code. -const PROJECT_ROOT = fs.existsSync(path.join(__dirname, '..', 'package.json')) ? path.join(__dirname, '..') : path.join(__dirname, '..', '..'); +const readdirAsync = helper.promisify(fs.readdir.bind(fs)); +const mkdirAsync = helper.promisify(fs.mkdir.bind(fs)); +const unlinkAsync = helper.promisify(fs.unlink.bind(fs)); -class Downloader { +function existsAsync(filePath) { + let fulfill = null; + const promise = new Promise(x => fulfill = x); + fs.access(filePath, err => fulfill(!err)); + return promise; +} + +class BrowserFetcher { /** - * @param {string} downloadsFolder + * @param {!BrowserFetcher.Options=} options */ - constructor(downloadsFolder) { - this._downloadsFolder = downloadsFolder; - this._downloadHost = DEFAULT_DOWNLOAD_HOST; + constructor(options = {}) { + this._downloadsFolder = options.path || path.join(helper.projectRoot(), '.local-chromium'); + this._downloadHost = options.host || DEFAULT_DOWNLOAD_HOST; + this._platform = options.platform || ''; + if (!this._platform) { + const platform = os.platform(); + if (platform === 'darwin') + this._platform = 'mac'; + else if (platform === 'linux') + this._platform = 'linux'; + else if (platform === 'win32') + this._platform = os.arch() === 'x64' ? 'win64' : 'win32'; + console.assert(this._platform, 'Unsupported platform: ' + os.platform()); + } + const supportedPlatforms = ['mac', 'linux', 'win32', 'win64']; + console.assert(supportedPlatforms.includes(this._platform), 'Unsupported platform: ' + this._platform); } /** * @return {string} */ - static defaultRevision() { - return require(path.join(PROJECT_ROOT, 'package.json')).puppeteer.chromium_revision; + platform() { + return this._platform; } /** - * @return {!Downloader} - */ - static createDefault() { - const downloadsFolder = path.join(PROJECT_ROOT, '.local-chromium'); - return new Downloader(downloadsFolder); - } - - /** - * @param {string} downloadHost - */ - setDownloadHost(downloadHost) { - this._downloadHost = downloadHost.replace(/\/+$/, ''); - } - - /** - * @return {!Array} - */ - supportedPlatforms() { - return Object.keys(downloadURLs); - } - - /** - * @return {string} - */ - currentPlatform() { - const platform = os.platform(); - if (platform === 'darwin') - return 'mac'; - if (platform === 'linux') - return 'linux'; - if (platform === 'win32') - return os.arch() === 'x64' ? 'win64' : 'win32'; - return ''; - } - - /** - * @param {string} platform * @param {string} revision * @return {!Promise} */ - canDownloadRevision(platform, revision) { - console.assert(downloadURLs[platform], 'Unknown platform: ' + platform); - - const url = util.format(downloadURLs[platform], this._downloadHost, revision); + canDownload(revision) { + const url = util.format(downloadURLs[this._platform], this._downloadHost, revision); let resolve; const promise = new Promise(x => resolve = x); @@ -112,90 +95,80 @@ class Downloader { } /** - * @param {string} platform * @param {string} revision * @param {?function(number, number)} progressCallback - * @return {!Promise} + * @return {!Promise} */ - downloadRevision(platform, revision, progressCallback) { - let url = downloadURLs[platform]; - console.assert(url, `Unsupported platform: ${platform}`); + async download(revision, progressCallback) { + let url = downloadURLs[this._platform]; url = util.format(url, this._downloadHost, revision); - const zipPath = path.join(this._downloadsFolder, `download-${platform}-${revision}.zip`); - const folderPath = this._getFolderPath(platform, revision); - if (fs.existsSync(folderPath)) - return; - if (!fs.existsSync(this._downloadsFolder)) - fs.mkdirSync(this._downloadsFolder); - return downloadFile(url, zipPath, progressCallback) - .then(() => extractZip(zipPath, folderPath)) - .catch(err => err) - .then(err => { - if (fs.existsSync(zipPath)) - fs.unlinkSync(zipPath); - if (err) - throw err; - }); + const zipPath = path.join(this._downloadsFolder, `download-${this._platform}-${revision}.zip`); + const folderPath = this._getFolderPath(revision); + if (await existsAsync(folderPath)) + return this.revisionInfo(revision); + if (!(await existsAsync(this._downloadsFolder))) + await mkdirAsync(this._downloadsFolder); + try { + await downloadFile(url, zipPath, progressCallback); + await extractZip(zipPath, folderPath); + } finally { + if (await existsAsync(zipPath)) + await unlinkAsync(zipPath); + } + return this.revisionInfo(revision); } /** - * @return {!Array} + * @return {!Promise>} */ - downloadedRevisions() { - if (!fs.existsSync(this._downloadsFolder)) + async localRevisions() { + if (!await existsAsync(this._downloadsFolder)) return []; - const fileNames = fs.readdirSync(this._downloadsFolder); - return fileNames.map(fileName => parseFolderPath(fileName)).filter(revision => !!revision); + const fileNames = await readdirAsync(this._downloadsFolder); + return fileNames.map(fileName => parseFolderPath(fileName)).filter(entry => entry && entry.platform === this._platform).map(entry => entry.revision); } /** - * @param {string} platform * @param {string} revision * @return {!Promise} */ - removeRevision(platform, revision) { - console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`); - const folderPath = this._getFolderPath(platform, revision); - console.assert(fs.existsSync(folderPath)); - return new Promise(fulfill => removeRecursive(folderPath, fulfill)); + async remove(revision) { + const folderPath = this._getFolderPath(revision); + console.assert(await existsAsync(folderPath), `Failed to remove: revision ${revision} is not downloaded`); + await new Promise(fulfill => removeRecursive(folderPath, fulfill)); } /** - * @param {string} platform * @param {string} revision - * @return {!{revision: string, folderPath: string, executablePath: string, downloaded: boolean}} + * @return {!BrowserFetcher.RevisionInfo} */ - revisionInfo(platform, revision) { - console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`); - const folderPath = this._getFolderPath(platform, revision); + revisionInfo(revision) { + const folderPath = this._getFolderPath(revision); let executablePath = ''; - if (platform === 'mac') + if (this._platform === 'mac') executablePath = path.join(folderPath, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'); - else if (platform === 'linux') + else if (this._platform === 'linux') executablePath = path.join(folderPath, 'chrome-linux', 'chrome'); - else if (platform === 'win32' || platform === 'win64') + else if (this._platform === 'win32' || this._platform === 'win64') executablePath = path.join(folderPath, 'chrome-win32', 'chrome.exe'); else - throw 'Unsupported platform: ' + platform; - return { - revision, - executablePath, - folderPath, - downloaded: fs.existsSync(folderPath) - }; + throw 'Unsupported platform: ' + this._platform; + let url = downloadURLs[this._platform]; + url = util.format(url, this._downloadHost, revision); + const local = fs.existsSync(folderPath); + return {revision, executablePath, folderPath, local, url}; } /** - * @param {string} platform * @param {string} revision * @return {string} */ - _getFolderPath(platform, revision) { - return path.join(this._downloadsFolder, platform + '-' + revision); + _getFolderPath(revision) { + return path.join(this._downloadsFolder, this._platform + '-' + revision); } } -module.exports = Downloader; +module.exports = BrowserFetcher; /** * @param {string} folderPath @@ -220,6 +193,8 @@ function parseFolderPath(folderPath) { */ function downloadFile(url, destinationPath, progressCallback) { let fulfill, reject; + let downloadedBytes = 0; + let totalBytes = 0; const promise = new Promise((x, y) => { fulfill = x; reject = y; }); @@ -235,15 +210,16 @@ function downloadFile(url, destinationPath, progressCallback) { file.on('finish', () => fulfill()); file.on('error', error => reject(error)); response.pipe(file); - const totalBytes = parseInt(/** @type {string} */ (response.headers['content-length']), 10); + totalBytes = parseInt(/** @type {string} */ (response.headers['content-length']), 10); if (progressCallback) - response.on('data', onData.bind(null, totalBytes)); + response.on('data', onData); }); request.on('error', error => reject(error)); return promise; - function onData(totalBytes, chunk) { - progressCallback(totalBytes, chunk.length); + function onData(chunk) { + downloadedBytes += chunk.length; + progressCallback(downloadedBytes, totalBytes); } } @@ -281,3 +257,19 @@ function httpRequest(url, method, response) { request.end(); return request; } + +/** + * @typedef {Object} BrowserFetcher.Options + * @property {string=} platform + * @property {string=} path + * @property {string=} host + */ + +/** + * @typedef {Object} BrowserFetcher.RevisionInfo + * @property {string} folderPath + * @property {string} executablePath + * @property {string} url + * @property {boolean} local + * @property {string} revision + */ diff --git a/lib/Launcher.js b/lib/Launcher.js index ea139d216a5..583f1b1acc2 100644 --- a/lib/Launcher.js +++ b/lib/Launcher.js @@ -17,13 +17,13 @@ const os = require('os'); const path = require('path'); const removeFolder = require('rimraf'); const childProcess = require('child_process'); -const Downloader = require('./Downloader'); +const BrowserFetcher = require('./BrowserFetcher'); const {Connection} = require('./Connection'); const {Browser} = require('./Browser'); const readline = require('readline'); const fs = require('fs'); const {helper} = require('./helper'); -const ChromiumRevision = Downloader.defaultRevision(); +const ChromiumRevision = require(path.join(helper.projectRoot(), 'package.json')).puppeteer.chromium_revision; const mkdtempAsync = helper.promisify(fs.mkdtemp); const removeFolderAsync = helper.promisify(removeFolder); @@ -90,9 +90,9 @@ class Launcher { } let chromeExecutable = options.executablePath; if (typeof chromeExecutable !== 'string') { - const downloader = Downloader.createDefault(); - const revisionInfo = downloader.revisionInfo(downloader.currentPlatform(), ChromiumRevision); - console.assert(revisionInfo.downloaded, `Chromium revision is not downloaded. Run "npm install" or "yarn install"`); + const browserFetcher = new BrowserFetcher(); + const revisionInfo = browserFetcher.revisionInfo(ChromiumRevision); + console.assert(revisionInfo.local, `Chromium revision is not downloaded. Run "npm install" or "yarn install"`); chromeExecutable = revisionInfo.executablePath; } if (Array.isArray(options.args)) @@ -187,8 +187,8 @@ class Launcher { * @return {string} */ static executablePath() { - const downloader = Downloader.createDefault(); - const revisionInfo = downloader.revisionInfo(downloader.currentPlatform(), ChromiumRevision); + const browserFetcher = new BrowserFetcher(); + const revisionInfo = browserFetcher.revisionInfo(ChromiumRevision); return revisionInfo.executablePath; } diff --git a/lib/Puppeteer.js b/lib/Puppeteer.js index ac151f257a9..59891cc4b1c 100644 --- a/lib/Puppeteer.js +++ b/lib/Puppeteer.js @@ -15,6 +15,7 @@ */ const {helper} = require('./helper'); const Launcher = require('./Launcher'); +const BrowserFetcher = require('./BrowserFetcher'); class Puppeteer { /** @@ -46,6 +47,14 @@ class Puppeteer { static defaultArgs() { return Launcher.defaultArgs(); } + + /** + * @param {!Object=} options + * @return {!BrowserFetcher} + */ + static createBrowserFetcher(options) { + return new BrowserFetcher(options); + } } module.exports = Puppeteer; diff --git a/lib/helper.js b/lib/helper.js index cd5d038ad6a..f6e7476537a 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -13,10 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +const fs = require('fs'); +const path = require('path'); const debugError = require('debug')(`puppeteer:error`); /** @type {?Map} */ let apiCoverage = null; +let projectRoot = null; class Helper { /** * @param {Function|string} fun @@ -41,6 +44,17 @@ class Helper { } } + /** + * @return {string} + */ + static projectRoot() { + if (!projectRoot) { + // Project root will be different for node6-transpiled code. + projectRoot = fs.existsSync(path.join(__dirname, '..', 'package.json')) ? path.join(__dirname, '..') : path.join(__dirname, '..', '..'); + } + return projectRoot; + } + /** * @param {!Object} exceptionDetails * @return {string} diff --git a/test/assets/chromium-linux.zip b/test/assets/chromium-linux.zip new file mode 100644 index 00000000000..9c00ec080d0 Binary files /dev/null and b/test/assets/chromium-linux.zip differ diff --git a/test/server/SimpleServer.js b/test/server/SimpleServer.js index 2839e16f243..28ab0c8d109 100644 --- a/test/server/SimpleServer.js +++ b/test/server/SimpleServer.js @@ -185,18 +185,20 @@ class SimpleServer { if (this._requestSubscribers.has(pathName)) this._requestSubscribers.get(pathName)[fulfillSymbol].call(null, request); const handler = this._routes.get(pathName); - if (handler) + if (handler) { handler.call(null, request, response); - else - this.defaultHandler(request, response); + } else { + const pathName = url.parse(request.url).path; + this.serveFile(request, response, pathName); + } } /** * @param {!IncomingMessage} request * @param {!ServerResponse} response + * @param {string} pathName */ - defaultHandler(request, response) { - let pathName = url.parse(request.url).path; + serveFile(request, response, pathName) { if (pathName === '/') pathName = '/index.html'; const filePath = path.join(this._dirPath, pathName.substring(1)); diff --git a/test/test.js b/test/test.js index f34cd8d9c57..203015070ce 100644 --- a/test/test.js +++ b/test/test.js @@ -21,6 +21,7 @@ const {helper} = require('../lib/helper'); if (process.env.COVERAGE) helper.recordPublicAPICoverage(); const mkdtempAsync = helper.promisify(fs.mkdtemp); +const readFileAsync = helper.promisify(fs.readFile); const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-'); const PROJECT_ROOT = fs.existsSync(path.join(__dirname, '..', 'package.json')) ? path.join(__dirname, '..') : path.join(__dirname, '..', '..'); @@ -113,6 +114,33 @@ afterAll(async({server, httpsServer}) => { }); describe('Puppeteer', function() { + describe('BrowserFetcher', function() { + it('should download and extract linux binary', async({server}) => { + const downloadsFolder = await mkdtempAsync(TMP_FOLDER); + const browserFetcher = puppeteer.createBrowserFetcher({ + platform: 'linux', + path: downloadsFolder, + host: server.PREFIX + }); + let revisionInfo = browserFetcher.revisionInfo('123456'); + server.setRoute(revisionInfo.url.substring(server.PREFIX.length), (req, res) => { + server.serveFile(req, res, '/chromium-linux.zip'); + }); + + expect(revisionInfo.local).toBe(false); + expect(browserFetcher.platform()).toBe('linux'); + expect(await browserFetcher.canDownload('100000')).toBe(false); + expect(await browserFetcher.canDownload('123456')).toBe(true); + + revisionInfo = await browserFetcher.download('123456'); + expect(revisionInfo.local).toBe(true); + expect(await readFileAsync(revisionInfo.executablePath, 'utf8')).toBe('LINUX BINARY\n'); + expect(await browserFetcher.localRevisions()).toEqual(['123456']); + await browserFetcher.remove('123456'); + expect(await browserFetcher.localRevisions()).toEqual([]); + rm(downloadsFolder); + }); + }); describe('Puppeteer.launch', function() { it('should support ignoreHTTPSErrors option', async({httpsServer}) => { const options = Object.assign({ignoreHTTPSErrors: true}, defaultBrowserOptions); diff --git a/utils/check_availability.js b/utils/check_availability.js index 4aad014208f..5ae40ec7bc1 100755 --- a/utils/check_availability.js +++ b/utils/check_availability.js @@ -15,11 +15,12 @@ * limitations under the License. */ -const Downloader = require('../lib/Downloader'); +const puppeteer = require('..'); const https = require('https'); const OMAHA_PROXY = 'https://omahaproxy.appspot.com/all.json'; +const SUPPORTER_PLATFORMS = ['linux', 'mac', 'win32', 'win64']; -const downloader = Downloader.createDefault(); +const fetchers = SUPPORTER_PLATFORMS.map(platform => puppeteer.createBrowserFetcher({platform})); const colors = { reset: '\x1b[0m', @@ -73,7 +74,7 @@ async function checkOmahaProxyAvailability() { return; } const table = new Table([27, 7, 7, 7, 7]); - table.drawRow([''].concat(downloader.supportedPlatforms())); + table.drawRow([''].concat(SUPPORTER_PLATFORMS)); for (const platform of platforms) { // Trust only to the main platforms. if (platform.os !== 'mac' && platform.os !== 'win' && platform.os !== 'win64' && platform.os !== 'linux') @@ -95,7 +96,7 @@ async function checkOmahaProxyAvailability() { */ async function checkRangeAvailability(fromRevision, toRevision) { const table = new Table([10, 7, 7, 7, 7]); - table.drawRow([''].concat(downloader.supportedPlatforms())); + table.drawRow([''].concat(SUPPORTER_PLATFORMS)); const inc = fromRevision < toRevision ? 1 : -1; for (let revision = fromRevision; revision !== toRevision; revision += inc) await checkAndDrawRevisionAvailability(table, '', revision); @@ -107,9 +108,7 @@ async function checkRangeAvailability(fromRevision, toRevision) { * @param {number} revision */ async function checkAndDrawRevisionAvailability(table, name, revision) { - const promises = []; - for (const platform of downloader.supportedPlatforms()) - promises.push(downloader.canDownloadRevision(platform, revision)); + const promises = fetchers.map(fetcher => fetcher.canDownload(revision)); const availability = await Promise.all(promises); const allAvailable = availability.every(e => !!e); const values = [name + ' ' + (allAvailable ? colors.green + revision + colors.reset : revision)]; diff --git a/utils/doclint/check_public_api/index.js b/utils/doclint/check_public_api/index.js index 2cc6893acc7..251223f1288 100644 --- a/utils/doclint/check_public_api/index.js +++ b/utils/doclint/check_public_api/index.js @@ -22,7 +22,6 @@ const Message = require('../Message'); const EXCLUDE_CLASSES = new Set([ 'CSSCoverage', 'Connection', - 'Downloader', 'EmulationManager', 'FrameManager', 'JSCoverage',