From f1b337e78b7bcc5fd30442feb96b5855a69364bf Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Tue, 21 Feb 2023 08:27:02 +0100 Subject: [PATCH] chore: resolve Firefox revisions for the latest keyword (#9708) --- packages/browsers/src/CLI.ts | 8 +++++ packages/browsers/src/browsers/browsers.ts | 17 ++++++++++- packages/browsers/src/browsers/firefox.ts | 34 ++++++++++++++++++++++ packages/browsers/src/browsers/types.ts | 4 +++ packages/browsers/test/src/cli.spec.ts | 13 ++++++++- 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/packages/browsers/src/CLI.ts b/packages/browsers/src/CLI.ts index b39cfea3..fa02349f 100644 --- a/packages/browsers/src/CLI.ts +++ b/packages/browsers/src/CLI.ts @@ -18,6 +18,7 @@ import ProgressBar from 'progress'; import yargs from 'yargs'; import {hideBin} from 'yargs/helpers'; +import {resolveRevision} from './browsers/browsers.js'; import {Browser, BrowserPlatform} from './browsers/types.js'; import {fetch} from './fetch.js'; import {computeExecutablePath, launch} from './launcher.js'; @@ -67,6 +68,10 @@ export class CLI { }, async argv => { const args = argv as unknown as InstallArgs; + args.browser.revision = await resolveRevision( + args.browser.name, + args.browser.revision + ); await fetch({ browser: args.browser.name, revision: args.browser.revision, @@ -77,6 +82,9 @@ export class CLI { args.browser.revision ), }); + console.log( + `${args.browser.name}@${args.browser.revision} downloaded successfully.` + ); } ) .option('path', { diff --git a/packages/browsers/src/browsers/browsers.ts b/packages/browsers/src/browsers/browsers.ts index 266bbaf1..defcb74b 100644 --- a/packages/browsers/src/browsers/browsers.ts +++ b/packages/browsers/src/browsers/browsers.ts @@ -16,7 +16,7 @@ import * as chrome from './chrome.js'; import * as firefox from './firefox.js'; -import {Browser, BrowserPlatform} from './types.js'; +import {Browser, BrowserPlatform, BrowserTag} from './types.js'; export const downloadUrls = { [Browser.CHROME]: chrome.resolveDownloadUrl, @@ -29,3 +29,18 @@ export const executablePathByBrowser = { }; export {Browser, BrowserPlatform}; + +export async function resolveRevision( + browser: Browser, + tag: string +): Promise { + switch (browser) { + case Browser.FIREFOX: + switch (tag as BrowserTag) { + case BrowserTag.LATEST: + return await firefox.resolveRevision('FIREFOX_NIGHTLY'); + } + } + // We assume the tag is the revision if it didn't match any keywords. + return tag; +} diff --git a/packages/browsers/src/browsers/firefox.ts b/packages/browsers/src/browsers/firefox.ts index f717f4b1..530da121 100644 --- a/packages/browsers/src/browsers/firefox.ts +++ b/packages/browsers/src/browsers/firefox.ts @@ -16,6 +16,8 @@ import path from 'path'; +import {httpRequest} from '../httpUtil.js'; + import {BrowserPlatform} from './types.js'; function archive(platform: BrowserPlatform, revision: string): string { @@ -54,3 +56,35 @@ export function relativeExecutablePath( return path.join('firefox', 'firefox.exe'); } } + +export async function resolveRevision( + channel: 'FIREFOX_NIGHTLY' = 'FIREFOX_NIGHTLY' +): Promise { + return new Promise((resolve, reject) => { + const request = httpRequest( + new URL('https://product-details.mozilla.org/1.0/firefox_versions.json'), + 'GET', + response => { + let data = ''; + if (response.statusCode && response.statusCode >= 400) { + return reject(new Error(`Got status code ${response.statusCode}`)); + } + response.on('data', chunk => { + data += chunk; + }); + response.on('end', () => { + try { + const versions = JSON.parse(data); + return resolve(versions[channel]); + } catch { + return reject(new Error('Firefox version not found')); + } + }); + }, + false + ); + request.on('error', err => { + reject(err); + }); + }); +} diff --git a/packages/browsers/src/browsers/types.ts b/packages/browsers/src/browsers/types.ts index 4cc46d19..89592dab 100644 --- a/packages/browsers/src/browsers/types.ts +++ b/packages/browsers/src/browsers/types.ts @@ -41,3 +41,7 @@ export const downloadUrls = { [Browser.CHROME]: chrome.resolveDownloadUrl, [Browser.FIREFOX]: firefox.resolveDownloadUrl, }; + +export enum BrowserTag { + LATEST = 'latest', +} diff --git a/packages/browsers/test/src/cli.spec.ts b/packages/browsers/test/src/cli.spec.ts index aa26511a..e317b151 100644 --- a/packages/browsers/test/src/cli.spec.ts +++ b/packages/browsers/test/src/cli.spec.ts @@ -22,7 +22,7 @@ import path from 'path'; import {CLI} from '../../lib/cjs/CLI.js'; describe('CLI', function () { - this.timeout(60000); + this.timeout(90000); let tmpDir = '/tmp/puppeteer-browsers-test'; const testChromeRevision = '1083080'; @@ -72,4 +72,15 @@ describe('CLI', function () { ) ); }); + + it('should download latest Firefox binaries', async () => { + await new CLI(tmpDir).run([ + 'npx', + '@puppeteer/browsers', + 'install', + `firefox@latest`, + `--path=${tmpDir}`, + '--platform=linux', + ]); + }); });