chore: improve handling with missing xserver (#12724)

This commit is contained in:
Max Schmitt 2022-03-18 22:39:11 +01:00 committed by GitHub
parent daff643516
commit dd32956ccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 5 deletions

View File

@ -31,6 +31,9 @@ import { helper } from './helper';
import { RecentLogsCollector } from '../utils/debugLogger';
import { CallMetadata, SdkObject } from './instrumentation';
export const kNoXServerRunningError = 'Looks like you launched a headed browser without having a XServer running.\n' +
'Set either \'headless: false\' or use \'xvfb-run <your-playwright-app>\' before running Playwright.\n\n<3 Playwright Team';
export abstract class BrowserType extends SdkObject {
private _name: BrowserName;
readonly _playwrightOptions: PlaywrightOptions;
@ -76,7 +79,7 @@ export abstract class BrowserType extends SdkObject {
async _innerLaunchWithRetries(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, userDataDir?: string): Promise<Browser> {
try {
return this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
return await this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
} catch (error) {
// @see https://github.com/microsoft/playwright/issues/5214
const errorMessage = typeof error === 'object' && typeof error.message === 'string' ? error.message : '';

View File

@ -22,12 +22,12 @@ import { CRBrowser } from './crBrowser';
import { Env, gracefullyCloseSet } from '../../utils/processLauncher';
import { kBrowserCloseMessageId } from './crConnection';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { BrowserType } from '../browserType';
import { BrowserType, kNoXServerRunningError } from '../browserType';
import { ConnectionTransport, ProtocolRequest, WebSocketTransport } from '../transport';
import { CRDevTools } from './crDevTools';
import { Browser, BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
import * as types from '../types';
import { debugMode, fetchData, getUserAgent, headersArrayToObject, HTTPRequestParams, removeFolders, streamToString } from '../../utils/utils';
import { debugMode, fetchData, getUserAgent, headersArrayToObject, HTTPRequestParams, removeFolders, streamToString, wrapInASCIIBox } from '../../utils/utils';
import { RecentLogsCollector } from '../../utils/debugLogger';
import { Progress, ProgressController } from '../progress';
import { TimeoutSettings } from '../../utils/timeoutSettings';
@ -126,6 +126,8 @@ export class Chromium extends BrowserType {
}
_rewriteStartupError(error: Error): Error {
if (error.message.includes('Missing X server'))
return rewriteErrorMessage(error, '\n' + wrapInASCIIBox(kNoXServerRunningError, 1));
// These error messages are taken from Chromium source code as of July, 2020:
// https://github.com/chromium/chromium/blob/70565f67e79f79e17663ad1337dc6e63ee207ce9/content/browser/zygote_host/zygote_host_impl_linux.cc
if (!error.message.includes('crbug.com/357670') && !error.message.includes('No usable sandbox!') && !error.message.includes('crbug.com/638180'))

View File

@ -20,11 +20,13 @@ import fs from 'fs';
import path from 'path';
import { FFBrowser } from './ffBrowser';
import { kBrowserCloseMessageId } from './ffConnection';
import { BrowserType } from '../browserType';
import { BrowserType, kNoXServerRunningError } from '../browserType';
import { Env } from '../../utils/processLauncher';
import { ConnectionTransport } from '../transport';
import { BrowserOptions, PlaywrightOptions } from '../browser';
import * as types from '../types';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { wrapInASCIIBox } from '../../utils/utils';
export class Firefox extends BrowserType {
constructor(playwrightOptions: PlaywrightOptions) {
@ -36,6 +38,8 @@ export class Firefox extends BrowserType {
}
_rewriteStartupError(error: Error): Error {
if (error.message.includes('no DISPLAY environment variable specified'))
return rewriteErrorMessage(error, '\n' + wrapInASCIIBox(kNoXServerRunningError, 1));
return error;
}

View File

@ -19,10 +19,12 @@ import { WKBrowser } from '../webkit/wkBrowser';
import { Env } from '../../utils/processLauncher';
import path from 'path';
import { kBrowserCloseMessageId } from './wkConnection';
import { BrowserType } from '../browserType';
import { BrowserType, kNoXServerRunningError } from '../browserType';
import { ConnectionTransport } from '../transport';
import { BrowserOptions, PlaywrightOptions } from '../browser';
import * as types from '../types';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { wrapInASCIIBox } from '../../utils/utils';
export class WebKit extends BrowserType {
constructor(playwrightOptions: PlaywrightOptions) {
@ -38,6 +40,8 @@ export class WebKit extends BrowserType {
}
_rewriteStartupError(error: Error): Error {
if (error.message.includes('cannot open display'))
return rewriteErrorMessage(error, '\n' + wrapInASCIIBox(kNoXServerRunningError, 1));
return error;
}

View File

@ -40,3 +40,17 @@ it('should kill browser process on timeout after close', async ({ browserType, m
await browser.close();
expect(stalled).toBeTruthy();
});
it('should throw a friendly error if its headed and there is no xserver on linux running', async ({ browserType, platform }) => {
it.skip(platform !== 'linux');
const error: Error = await browserType.launch({
headless: false,
env: {
...process.env,
DISPLAY: undefined,
},
}).catch(e => e);
expect(error).toBeInstanceOf(Error);
expect(error.message).toMatch(/Looks like you launched a headed browser without having a XServer running./);
expect(error.message).toMatch(/xvfb-run/);
});