chore(stable): throw user-friendly message when ffmpeg is missing (#5865)

This commit is contained in:
Pavel Feldman 2021-03-18 10:19:44 +08:00 committed by GitHub
parent 141583c79f
commit 2367039a2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 19 deletions

View File

@ -36,7 +36,7 @@ import { CRBrowserContext } from './crBrowser';
import * as types from '../types';
import { ConsoleMessage } from '../console';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { assert, headersArrayToObject, createGuid } from '../../utils/utils';
import { assert, headersArrayToObject, createGuid, canAccessFile } from '../../utils/utils';
import { VideoRecorder } from './videoRecorder';
@ -816,6 +816,22 @@ class FrameSession {
const ffmpegPath = this._crPage._browserContext._browser.options.registry.executablePath('ffmpeg');
if (!ffmpegPath)
throw new Error('ffmpeg executable was not found');
if (!canAccessFile(ffmpegPath)) {
let message: string = '';
switch (this._page._browserContext._options.sdkLanguage) {
case 'python': message = 'playwright install ffmpeg'; break;
case 'python-async': message = 'playwright install ffmpeg'; break;
case 'javascript': message = 'npx playwright install ffmpeg'; break;
case 'java': message = 'mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install ffmpeg"'; break;
}
throw new Error(`
============================================================
Please install ffmpeg in order to record video.
$ ${message}
============================================================
`);
}
this._videoRecorder = await VideoRecorder.launch(this._crPage._page, ffmpegPath, options);
this._screencastId = screencastId;
const gotFirstFrame = new Promise(f => this._client.once('Page.screencastFrame', f));

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
import fs from 'fs';
import path from 'path';
import { canAccessFile } from '../../utils/utils';
function darwin(channel: string): string | undefined {
switch (channel) {
@ -60,24 +60,12 @@ function win32(channel: string): string | undefined {
let result: string | undefined;
prefixes.forEach(prefix => {
const chromePath = path.join(prefix, suffix!);
if (canAccess(chromePath))
if (canAccessFile(chromePath))
result = chromePath;
});
return result;
}
function canAccess(file: string) {
if (!file)
return false;
try {
fs.accessSync(file);
return true;
} catch (e) {
return false;
}
}
export function findChromiumChannel(channel: string): string {
let result: string | undefined;
if (process.platform === 'linux')
@ -90,7 +78,7 @@ export function findChromiumChannel(channel: string): string {
if (!result)
throw new Error(`Chromium distribution '${channel}' is not supported on ${process.platform}`);
if (canAccess(result))
if (canAccessFile(result))
return result;
throw new Error(`Chromium distribution was not found: ${channel}`);
}

View File

@ -86,7 +86,7 @@ export async function launchProcess(options: LaunchProcessOptions): Promise<Laun
let failed: (e: Error) => void;
const failedPromise = new Promise<Error>((f, r) => failed = f);
spawnedProcess.once('error', error => {
failed(new Error('Failed to launch browser: ' + error));
failed(new Error('Failed to launch: ' + error));
});
return cleanup().then(() => failedPromise).then(e => Promise.reject(e));
}
@ -164,7 +164,7 @@ export async function launchProcess(options: LaunchProcessOptions): Promise<Laun
// Force kill the browser.
try {
if (process.platform === 'win32')
childProcess.execSync(`taskkill /pid ${spawnedProcess.pid} /T /F`);
childProcess.execSync(`taskkill /pid ${spawnedProcess.pid} /T /F`, { stdio: 'ignore' });
else
process.kill(-spawnedProcess.pid, 'SIGKILL');
} catch (e) {

View File

@ -158,3 +158,15 @@ export async function removeFolders(dirs: string[]) {
});
}));
}
export function canAccessFile(file: string) {
if (!file)
return false;
try {
fs.accessSync(file);
return true;
} catch (e) {
return false;
}
}

View File

@ -107,8 +107,9 @@ it('should restore state from userDataDir', (test, { browserName }) => {
await browserContext3.close();
});
it('should restore cookies from userDataDir', (test, { browserName }) => {
it('should restore cookies from userDataDir', (test, { platform, browserChannel }) => {
test.slow();
test.fixme(platform === 'win32' && browserChannel === 'chrome');
}, async ({browserType, browserOptions, server, createUserDataDir}) => {
const userDataDir = await createUserDataDir();
const browserContext = await browserType.launchPersistentContext(userDataDir, browserOptions);