fix: put browserVersion in the browsers.json (#13946)

This patch:
- adds `browserVersion` field to the `browsers.json`. This is
  updated every time we roll browser.
- starts using `browserVersion` to display browser version that's
  been downloaded.

The downloading output now looks like this:

```bash
Downloading Chromium 101.0.4951.41 (playwright build v1003) - 118.9 Mb [====================] 100% 0.0s
Chromium 101.0.4951.41 (playwright build v1003) downloaded to /Users/andreylushnikov/Library/Caches/ms-playwright/chromium-1003
Downloading FFMPEG playwright build v1007 - 1 Mb [====================] 100% 0.0s
FFMPEG playwright build v1007 downloaded to /Users/andreylushnikov/Library/Caches/ms-playwright/ffmpeg-1007
Downloading Firefox 99.0.1 (playwright build v1323) - 67.5 Mb [====================] 100% 0.0s
Firefox 99.0.1 (playwright build v1323) downloaded to /Users/andreylushnikov/Library/Caches/ms-playwright/firefox-1323
Downloading Webkit 15.4 (playwright build v1632) - 52.7 Mb [====================] 100% 0.0s
Webkit 15.4 (playwright build v1632) downloaded to /Users/andreylushnikov/Library/Caches/ms-playwright/webkit-1632
```

Fixes #13198
This commit is contained in:
Andrey Lushnikov 2022-05-05 05:17:13 -06:00 committed by GitHub
parent d845a5a181
commit bfafb2680d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 29 deletions

View file

@ -4,27 +4,32 @@
{ {
"name": "chromium", "name": "chromium",
"revision": "1003", "revision": "1003",
"installByDefault": true "installByDefault": true,
"browserVersion": "101.0.4951.41"
}, },
{ {
"name": "chromium-with-symbols", "name": "chromium-with-symbols",
"revision": "1003", "revision": "1003",
"installByDefault": false "installByDefault": false,
"browserVersion": "101.0.4951.41"
}, },
{ {
"name": "chromium-tip-of-tree", "name": "chromium-tip-of-tree",
"revision": "1000", "revision": "1000",
"installByDefault": false "installByDefault": false,
"browserVersion": "103.0.5015.0"
}, },
{ {
"name": "firefox", "name": "firefox",
"revision": "1323", "revision": "1323",
"installByDefault": true "installByDefault": true,
"browserVersion": "99.0.1"
}, },
{ {
"name": "firefox-beta", "name": "firefox-beta",
"revision": "1323", "revision": "1323",
"installByDefault": false "installByDefault": false,
"browserVersion": "100.0b8"
}, },
{ {
"name": "webkit", "name": "webkit",
@ -33,7 +38,8 @@
"revisionOverrides": { "revisionOverrides": {
"mac10.14": "1446", "mac10.14": "1446",
"mac10.15": "1616" "mac10.15": "1616"
} },
"browserVersion": "15.4"
}, },
{ {
"name": "ffmpeg", "name": "ffmpeg",

View file

@ -25,10 +25,9 @@ import { download } from './download';
import { extract } from '../../zipBundle'; import { extract } from '../../zipBundle';
export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string, downloadURL: string, downloadFileName: string): Promise<boolean> { export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string, downloadURL: string, downloadFileName: string): Promise<boolean> {
const progressBarName = `Playwright build of ${title}`;
if (await existsAsync(browserDirectory)) { if (await existsAsync(browserDirectory)) {
// Already downloaded. // Already downloaded.
debugLogger.log('install', `browser ${title} is already downloaded.`); debugLogger.log('install', `${title} is already downloaded.`);
return false; return false;
} }
@ -36,7 +35,7 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
const zipPath = path.join(os.tmpdir(), downloadFileName); const zipPath = path.join(os.tmpdir(), downloadFileName);
try { try {
await download(url, zipPath, { await download(url, zipPath, {
progressBarName, progressBarName: title,
log: debugLogger.log.bind(debugLogger, 'install'), log: debugLogger.log.bind(debugLogger, 'install'),
userAgent: getUserAgent(), userAgent: getUserAgent(),
}); });
@ -47,14 +46,14 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
debugLogger.log('install', `fixing permissions at ${executablePath}`); debugLogger.log('install', `fixing permissions at ${executablePath}`);
await fs.promises.chmod(executablePath, 0o755); await fs.promises.chmod(executablePath, 0o755);
} catch (e) { } catch (e) {
debugLogger.log('install', `FAILED installation ${progressBarName} with error: ${e}`); debugLogger.log('install', `FAILED installation ${title} with error: ${e}`);
process.exitCode = 1; process.exitCode = 1;
throw e; throw e;
} finally { } finally {
if (await existsAsync(zipPath)) if (await existsAsync(zipPath))
await fs.promises.unlink(zipPath); await fs.promises.unlink(zipPath);
} }
logPolitely(`${progressBarName} downloaded to ${browserDirectory}`); logPolitely(`${title} downloaded to ${browserDirectory}`);
return true; return true;
} }

View file

@ -227,6 +227,7 @@ type BrowsersJSON = {
browsers: { browsers: {
name: string, name: string,
revision: string, revision: string,
browserVersion?: string,
installByDefault: boolean, installByDefault: boolean,
revisionOverrides?: {[os: string]: string}, revisionOverrides?: {[os: string]: string},
}[] }[]
@ -235,6 +236,7 @@ type BrowsersJSON = {
type BrowsersJSONDescriptor = { type BrowsersJSONDescriptor = {
name: string, name: string,
revision: string, revision: string,
browserVersion?: string,
installByDefault: boolean, installByDefault: boolean,
dir: string, dir: string,
}; };
@ -248,6 +250,8 @@ function readDescriptors(browsersJSON: BrowsersJSON) {
const descriptor: BrowsersJSONDescriptor = { const descriptor: BrowsersJSONDescriptor = {
name, name,
revision, revision,
// We only put browser version for the supported operating systems.
browserVersion: revisionOverride ? undefined : obj.browserVersion,
installByDefault: !!obj.installByDefault, installByDefault: !!obj.installByDefault,
// Method `isBrowserDirectory` determines directory to be browser iff // Method `isBrowserDirectory` determines directory to be browser iff
// it starts with some browser name followed by '-'. Some browser names // it starts with some browser name followed by '-'. Some browser names
@ -689,7 +693,14 @@ export class Registry {
'https://playwright.azureedge.net'; 'https://playwright.azureedge.net';
const downloadPath = util.format(downloadPathTemplate, descriptor.revision); const downloadPath = util.format(downloadPathTemplate, descriptor.revision);
const downloadURL = `${downloadHost}/${downloadPath}`; const downloadURL = `${downloadHost}/${downloadPath}`;
const title = `${descriptor.name} v${descriptor.revision}`;
const displayName = descriptor.name.split('-').map(word => {
return word === 'ffmpeg' ? 'FFMPEG' : word.charAt(0).toUpperCase() + word.slice(1);
}).join(' ');
const title = descriptor.browserVersion
? `${displayName} ${descriptor.browserVersion} (playwright build v${descriptor.revision})`
: `${displayName} playwright build v${descriptor.revision}`;
const downloadFileName = `playwright-download-${descriptor.name}-${hostPlatform}-${descriptor.revision}.zip`; const downloadFileName = `playwright-download-${descriptor.name}-${hostPlatform}-${descriptor.revision}.zip`;
await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURL, downloadFileName).catch(e => { await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURL, downloadFileName).catch(e => {
throw new Error(`Failed to download ${title}, caused by\n${e.stack}`); throw new Error(`Failed to download ${title}, caused by\n${e.stack}`);

View file

@ -44,8 +44,8 @@ _expect.extend({
throw new Error(`Expected argument to be a string.`); throw new Error(`Expected argument to be a string.`);
const downloaded = new Set(); const downloaded = new Set();
for (const [, browser] of received.matchAll(/^.*(chromium|firefox|webkit|ffmpeg) v\d+ downloaded.*$/img)) for (const [, browser] of received.matchAll(/^.*(chromium|firefox|webkit|ffmpeg).*playwright build v\d+\)? downloaded.*$/img))
downloaded.add(browser); downloaded.add(browser.toLowerCase());
const expected = browsers; const expected = browsers;
if (expected.length === downloaded.size && expected.every(browser => downloaded.has(browser))) if (expected.length === downloaded.size && expected.every(browser => downloaded.has(browser)))

View file

@ -21,6 +21,7 @@ const { Registry } = require('../packages/playwright-core/lib/server');
const fs = require('fs'); const fs = require('fs');
const protocolGenerator = require('./protocol-types-generator'); const protocolGenerator = require('./protocol-types-generator');
const {execSync} = require('child_process'); const {execSync} = require('child_process');
const playwright = require('playwright-core');
const SCRIPT_NAME = path.basename(__filename); const SCRIPT_NAME = path.basename(__filename);
const CORE_PATH = path.resolve(path.join(__dirname, '..', 'packages', 'playwright-core')); const CORE_PATH = path.resolve(path.join(__dirname, '..', 'packages', 'playwright-core'));
@ -54,35 +55,52 @@ Example:
} }
const browsersJSON = require(path.join(CORE_PATH, 'browsers.json')); const browsersJSON = require(path.join(CORE_PATH, 'browsers.json'));
const browserName = args[0].toLowerCase(); const browserName = args[0].toLowerCase();
const descriptor = browsersJSON.browsers.find(b => b.name === browserName); const descriptors = [browsersJSON.browsers.find(b => b.name === browserName)];
if (!descriptor) { if (browserName === 'chromium')
descriptors.push(browsersJSON.browsers.find(b => b.name === 'chromium-with-symbols'));
if (!descriptors.every(d => !!d)) {
console.log(`Unknown browser "${browserName}"`); console.log(`Unknown browser "${browserName}"`);
console.log(`Try running ${SCRIPT_NAME} --help`); console.log(`Try running ${SCRIPT_NAME} --help`);
process.exit(1); process.exit(1);
} }
const revision = args[1]; const revision = args[1];
console.log(`Rolling ${browserName} to ${revision}`); console.log(`Rolling ${browserName} to ${revision}`);
// 2. Update browsers.json. // 2. Update browser revisions in browsers.json.
console.log('\nUpdating browsers.json...'); console.log('\nUpdating revision in browsers.json...');
descriptor.revision = String(revision); for (const descriptor of descriptors)
if (browserName === 'chromium') descriptor.revision = String(revision);
browsersJSON.browsers.find(b => b.name === 'chromium-with-symbols').revision = String(revision);
fs.writeFileSync(path.join(CORE_PATH, 'browsers.json'), JSON.stringify(browsersJSON, null, 2) + '\n'); fs.writeFileSync(path.join(CORE_PATH, 'browsers.json'), JSON.stringify(browsersJSON, null, 2) + '\n');
if (descriptor.installByDefault) { // 3. Download new browser.
// 3. Download new browser. console.log('\nDownloading new browser...');
console.log('\nDownloading new browser...'); const registry = new Registry(browsersJSON);
const registry = new Registry(browsersJSON); const executable = registry.findExecutable(browserName);
const executables = registry.defaultExecutables(); await registry.install([...registry.defaultExecutables(), executable]);
await registry.install(executables);
// 4. Generate types. // 4. Update browser version if rolling WebKit / Firefox / Chromium.
const browserType = playwright[browserName.split('-')[0]];
if (browserType) {
const browser = await browserType.launch({
executablePath: executable.executablePath('javascript'),
});
const browserVersion = await browser.version();
await browser.close();
console.log('\nUpdating browser version in browsers.json...');
for (const descriptor of descriptors)
descriptor.browserVersion = browserVersion;
fs.writeFileSync(path.join(CORE_PATH, 'browsers.json'), JSON.stringify(browsersJSON, null, 2) + '\n');
}
if (browserType && descriptors[0].installByDefault) {
// 5. Generate types.
console.log('\nGenerating protocol types...'); console.log('\nGenerating protocol types...');
const executablePath = registry.findExecutable(browserName).executablePathOrDie(); const executablePath = registry.findExecutable(browserName).executablePathOrDie();
await protocolGenerator.generateProtocol(browserName, executablePath).catch(console.warn); await protocolGenerator.generateProtocol(browserName, executablePath).catch(console.warn);
// 5. Update docs. // 6. Update docs.
console.log('\nUpdating documentation...'); console.log('\nUpdating documentation...');
try { try {
process.stdout.write(execSync('npm run --silent doc')); process.stdout.write(execSync('npm run --silent doc'));