feat: Suppress logs during playwright install
This adds --quiet option to suppress logs when running npx playwright install References #32000
This commit is contained in:
parent
81e28a8854
commit
abab0fee0e
|
|
@ -146,7 +146,8 @@ program
|
||||||
.option('--force', 'force reinstall of stable browser channels')
|
.option('--force', 'force reinstall of stable browser channels')
|
||||||
.option('--only-shell', 'only install headless shell when installing chromium')
|
.option('--only-shell', 'only install headless shell when installing chromium')
|
||||||
.option('--no-shell', 'do not install chromium headless shell')
|
.option('--no-shell', 'do not install chromium headless shell')
|
||||||
.action(async function(args: string[], options: { withDeps?: boolean, force?: boolean, dryRun?: boolean, shell?: boolean, noShell?: boolean, onlyShell?: boolean }) {
|
.option('--quiet', 'hide logs while installing')
|
||||||
|
.action(async function(args: string[], options: { withDeps?: boolean, force?: boolean, dryRun?: boolean, shell?: boolean, noShell?: boolean, onlyShell?: boolean, quiet?: boolean }) {
|
||||||
// For '--no-shell' option, commander sets `shell: false` instead.
|
// For '--no-shell' option, commander sets `shell: false` instead.
|
||||||
if (options.shell === false)
|
if (options.shell === false)
|
||||||
options.noShell = true;
|
options.noShell = true;
|
||||||
|
|
@ -190,7 +191,8 @@ program
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const forceReinstall = hasNoArguments ? false : !!options.force;
|
const forceReinstall = hasNoArguments ? false : !!options.force;
|
||||||
await registry.install(executables, forceReinstall);
|
const suppressLogs = options.quiet;
|
||||||
|
await registry.install(executables, forceReinstall, suppressLogs);
|
||||||
await registry.validateHostRequirementsForExecutablesIfNeeded(executables, process.env.PW_LANG_NAME || 'javascript').catch((e: Error) => {
|
await registry.validateHostRequirementsForExecutablesIfNeeded(executables, process.env.PW_LANG_NAME || 'javascript').catch((e: Error) => {
|
||||||
e.name = 'Playwright Host validation warning';
|
e.name = 'Playwright Host validation warning';
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { browserDirectoryToMarkerFilePath } from '.';
|
||||||
import { getUserAgent } from '../../utils/userAgent';
|
import { getUserAgent } from '../../utils/userAgent';
|
||||||
import type { DownloadParams } from './oopDownloadBrowserMain';
|
import type { DownloadParams } from './oopDownloadBrowserMain';
|
||||||
|
|
||||||
export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string | undefined, downloadURLs: string[], downloadFileName: string, downloadConnectionTimeout: number): Promise<boolean> {
|
export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string | undefined, downloadURLs: string[], downloadFileName: string, downloadConnectionTimeout: number, quiet?: boolean): Promise<boolean> {
|
||||||
if (await existsAsync(browserDirectoryToMarkerFilePath(browserDirectory))) {
|
if (await existsAsync(browserDirectoryToMarkerFilePath(browserDirectory))) {
|
||||||
// Already downloaded.
|
// Already downloaded.
|
||||||
debugLogger.log('install', `${title} is already downloaded.`);
|
debugLogger.log('install', `${title} is already downloaded.`);
|
||||||
|
|
@ -40,8 +40,10 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
||||||
for (let attempt = 1; attempt <= retryCount; ++attempt) {
|
for (let attempt = 1; attempt <= retryCount; ++attempt) {
|
||||||
debugLogger.log('install', `downloading ${title} - attempt #${attempt}`);
|
debugLogger.log('install', `downloading ${title} - attempt #${attempt}`);
|
||||||
const url = downloadURLs[(attempt - 1) % downloadURLs.length];
|
const url = downloadURLs[(attempt - 1) % downloadURLs.length];
|
||||||
logPolitely(`Downloading ${title}` + colors.dim(` from ${url}`));
|
if (!quiet) {
|
||||||
const { error } = await downloadBrowserWithProgressBarOutOfProcess(title, browserDirectory, url, zipPath, executablePath, downloadConnectionTimeout);
|
logPolitely(`Downloading ${title}` + colors.dim(` from ${url}`));
|
||||||
|
}
|
||||||
|
const { error } = await downloadBrowserWithProgressBarOutOfProcess(title, browserDirectory, url, zipPath, executablePath, downloadConnectionTimeout, quiet);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
debugLogger.log('install', `SUCCESS installing ${title}`);
|
debugLogger.log('install', `SUCCESS installing ${title}`);
|
||||||
break;
|
break;
|
||||||
|
|
@ -63,7 +65,9 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
||||||
if (await existsAsync(zipPath))
|
if (await existsAsync(zipPath))
|
||||||
await fs.promises.unlink(zipPath);
|
await fs.promises.unlink(zipPath);
|
||||||
}
|
}
|
||||||
logPolitely(`${title} downloaded to ${browserDirectory}`);
|
if (!quiet) {
|
||||||
|
logPolitely(`${title} downloaded to ${browserDirectory}`);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,16 +76,18 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
||||||
* Thats why we execute it in a separate process and check manually if the destination file exists.
|
* Thats why we execute it in a separate process and check manually if the destination file exists.
|
||||||
* https://github.com/microsoft/playwright/issues/17394
|
* https://github.com/microsoft/playwright/issues/17394
|
||||||
*/
|
*/
|
||||||
function downloadBrowserWithProgressBarOutOfProcess(title: string, browserDirectory: string, url: string, zipPath: string, executablePath: string | undefined, connectionTimeout: number): Promise<{ error: Error | null }> {
|
function downloadBrowserWithProgressBarOutOfProcess(title: string, browserDirectory: string, url: string, zipPath: string, executablePath: string | undefined, connectionTimeout: number, quiet?: boolean): Promise<{ error: Error | null }> {
|
||||||
const cp = childProcess.fork(path.join(__dirname, 'oopDownloadBrowserMain.js'));
|
const cp = childProcess.fork(path.join(__dirname, 'oopDownloadBrowserMain.js'));
|
||||||
const promise = new ManualPromise<{ error: Error | null }>();
|
const promise = new ManualPromise<{ error: Error | null }>();
|
||||||
const progress = getDownloadProgress();
|
if (!quiet) {
|
||||||
cp.on('message', (message: any) => {
|
const progress = getDownloadProgress();
|
||||||
if (message?.method === 'log')
|
cp.on('message', (message: any) => {
|
||||||
debugLogger.log('install', message.params.message);
|
if (message?.method === 'log')
|
||||||
if (message?.method === 'progress')
|
debugLogger.log('install', message.params.message);
|
||||||
progress(message.params.done, message.params.total);
|
if (message?.method === 'progress')
|
||||||
});
|
progress(message.params.done, message.params.total);
|
||||||
|
});
|
||||||
|
}
|
||||||
cp.on('exit', code => {
|
cp.on('exit', code => {
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
promise.resolve({ error: new Error(`Download failure, code=${code}`) });
|
promise.resolve({ error: new Error(`Download failure, code=${code}`) });
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ export interface Executable {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExecutableImpl extends Executable {
|
interface ExecutableImpl extends Executable {
|
||||||
_install?: () => Promise<void>;
|
_install?: (quiet?: boolean) => Promise<void>;
|
||||||
_dependencyGroup?: DependencyGroup;
|
_dependencyGroup?: DependencyGroup;
|
||||||
_isHermeticInstallation?: boolean;
|
_isHermeticInstallation?: boolean;
|
||||||
}
|
}
|
||||||
|
|
@ -491,7 +491,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||||
downloadURLs: this._downloadURLs(chromium),
|
downloadURLs: this._downloadURLs(chromium),
|
||||||
browserVersion: chromium.browserVersion,
|
browserVersion: chromium.browserVersion,
|
||||||
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(chromium, chromiumExecutable, quiet),
|
||||||
_dependencyGroup: 'chromium',
|
_dependencyGroup: 'chromium',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -509,7 +509,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ['chrome-linux'], [], ['chrome-win']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||||
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
|
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
|
||||||
browserVersion: chromium.browserVersion,
|
browserVersion: chromium.browserVersion,
|
||||||
_install: () => this._downloadExecutable(chromiumHeadlessShell, chromiumHeadlessShellExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(chromiumHeadlessShell, chromiumHeadlessShellExecutable, quiet),
|
||||||
_dependencyGroup: 'chromium',
|
_dependencyGroup: 'chromium',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -527,7 +527,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ['chrome-linux'], [], ['chrome-win']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||||
downloadURLs: this._downloadURLs(chromiumTipOfTree),
|
downloadURLs: this._downloadURLs(chromiumTipOfTree),
|
||||||
browserVersion: chromiumTipOfTree.browserVersion,
|
browserVersion: chromiumTipOfTree.browserVersion,
|
||||||
_install: () => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable, quiet),
|
||||||
_dependencyGroup: 'chromium',
|
_dependencyGroup: 'chromium',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -637,7 +637,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||||
downloadURLs: this._downloadURLs(chromium),
|
downloadURLs: this._downloadURLs(chromium),
|
||||||
browserVersion: chromium.browserVersion,
|
browserVersion: chromium.browserVersion,
|
||||||
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(chromium, chromiumExecutable, quiet),
|
||||||
_dependencyGroup: 'chromium',
|
_dependencyGroup: 'chromium',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -655,7 +655,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, firefox.dir, ['firefox'], [], ['firefox']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, firefox.dir, ['firefox'], [], ['firefox']),
|
||||||
downloadURLs: this._downloadURLs(firefox),
|
downloadURLs: this._downloadURLs(firefox),
|
||||||
browserVersion: firefox.browserVersion,
|
browserVersion: firefox.browserVersion,
|
||||||
_install: () => this._downloadExecutable(firefox, firefoxExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(firefox, firefoxExecutable, quiet),
|
||||||
_dependencyGroup: 'firefox',
|
_dependencyGroup: 'firefox',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -673,7 +673,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ['firefox'], [], ['firefox']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ['firefox'], [], ['firefox']),
|
||||||
downloadURLs: this._downloadURLs(firefoxBeta),
|
downloadURLs: this._downloadURLs(firefoxBeta),
|
||||||
browserVersion: firefoxBeta.browserVersion,
|
browserVersion: firefoxBeta.browserVersion,
|
||||||
_install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable, quiet),
|
||||||
_dependencyGroup: 'firefox',
|
_dependencyGroup: 'firefox',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -701,7 +701,7 @@ export class Registry {
|
||||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),
|
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),
|
||||||
downloadURLs: this._downloadURLs(webkit),
|
downloadURLs: this._downloadURLs(webkit),
|
||||||
browserVersion: webkit.browserVersion,
|
browserVersion: webkit.browserVersion,
|
||||||
_install: () => this._downloadExecutable(webkit, webkitExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(webkit, webkitExecutable, quiet),
|
||||||
_dependencyGroup: 'webkit',
|
_dependencyGroup: 'webkit',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -718,7 +718,7 @@ export class Registry {
|
||||||
installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand',
|
installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||||
_validateHostRequirements: () => Promise.resolve(),
|
_validateHostRequirements: () => Promise.resolve(),
|
||||||
downloadURLs: this._downloadURLs(ffmpeg),
|
downloadURLs: this._downloadURLs(ffmpeg),
|
||||||
_install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable),
|
_install: (quiet?: boolean) => this._downloadExecutable(ffmpeg, ffmpegExecutable, quiet),
|
||||||
_dependencyGroup: 'tools',
|
_dependencyGroup: 'tools',
|
||||||
_isHermeticInstallation: true,
|
_isHermeticInstallation: true,
|
||||||
});
|
});
|
||||||
|
|
@ -911,7 +911,7 @@ export class Registry {
|
||||||
return await installDependenciesLinux(targets, dryRun);
|
return await installDependenciesLinux(targets, dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
async install(executablesToInstall: Executable[], forceReinstall: boolean) {
|
async install(executablesToInstall: Executable[], forceReinstall: boolean, quiet?: boolean) {
|
||||||
const executables = this._dedupe(executablesToInstall);
|
const executables = this._dedupe(executablesToInstall);
|
||||||
await fs.promises.mkdir(registryDirectory, { recursive: true });
|
await fs.promises.mkdir(registryDirectory, { recursive: true });
|
||||||
const lockfilePath = path.join(registryDirectory, '__dirlock');
|
const lockfilePath = path.join(registryDirectory, '__dirlock');
|
||||||
|
|
@ -963,7 +963,7 @@ export class Registry {
|
||||||
`<3 Playwright Team`,
|
`<3 Playwright Team`,
|
||||||
].join('\n'), 1));
|
].join('\n'), 1));
|
||||||
}
|
}
|
||||||
await executable._install();
|
await executable._install(quiet);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code === 'ELOCKED') {
|
if (e.code === 'ELOCKED') {
|
||||||
|
|
@ -1060,7 +1060,7 @@ export class Registry {
|
||||||
return downloadURLs;
|
return downloadURLs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath?: string) {
|
private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath?: string, quiet?: boolean) {
|
||||||
const downloadURLs = this._downloadURLs(descriptor);
|
const downloadURLs = this._downloadURLs(descriptor);
|
||||||
if (!downloadURLs.length)
|
if (!downloadURLs.length)
|
||||||
throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${hostPlatform}`);
|
throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${hostPlatform}`);
|
||||||
|
|
@ -1084,7 +1084,7 @@ export class Registry {
|
||||||
const downloadFileName = `playwright-download-${descriptor.name}-${hostPlatform}-${descriptor.revision}.zip`;
|
const downloadFileName = `playwright-download-${descriptor.name}-${hostPlatform}-${descriptor.revision}.zip`;
|
||||||
const downloadConnectionTimeoutEnv = getFromENV('PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT');
|
const downloadConnectionTimeoutEnv = getFromENV('PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT');
|
||||||
const downloadConnectionTimeout = +(downloadConnectionTimeoutEnv || '0') || 30_000;
|
const downloadConnectionTimeout = +(downloadConnectionTimeoutEnv || '0') || 30_000;
|
||||||
await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadConnectionTimeout).catch(e => {
|
await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadConnectionTimeout, quiet).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}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue