chore: move validateHostRequirements to Registry (#7428)
This is an effort to consolidate all handling of browser binaries in a single place.
This commit is contained in:
parent
8fb0454488
commit
d46eae44d1
|
|
@ -26,7 +26,6 @@ import { PipeTransport } from './pipeTransport';
|
|||
import { Progress, ProgressController } from './progress';
|
||||
import * as types from './types';
|
||||
import { DEFAULT_TIMEOUT, TimeoutSettings } from '../utils/timeoutSettings';
|
||||
import { validateHostRequirements } from './validateDependencies';
|
||||
import { debugMode, existsAsync } from '../utils/utils';
|
||||
import { helper } from './helper';
|
||||
import { RecentLogsCollector } from '../utils/debugLogger';
|
||||
|
|
@ -171,10 +170,9 @@ export abstract class BrowserType extends SdkObject {
|
|||
}
|
||||
|
||||
// Only validate dependencies for downloadable browsers.
|
||||
if (!executablePath && !options.channel)
|
||||
await validateHostRequirements(this._registry, this._name);
|
||||
else if (!executablePath && options.channel && this._registry.isSupportedBrowser(options.channel))
|
||||
await validateHostRequirements(this._registry, options.channel as registry.BrowserName);
|
||||
const browserName: registry.BrowserName = (options.channel || this._name) as registry.BrowserName;
|
||||
if (!executablePath && this._registry.isSupportedBrowser(browserName))
|
||||
await this._registry.validateHostRequirements(browserName);
|
||||
|
||||
let wsEndpointCallback: ((wsEndpoint: string) => void) | undefined;
|
||||
const shouldWaitForWSListening = options.useWebSocket || options.args?.some(a => a.startsWith('--remote-debugging-port'));
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export function printDepsWindowsExecutable(): string | undefined {
|
||||
return pathToExecutable(['bin', 'PrintDeps.exe']);
|
||||
}
|
||||
|
||||
function pathToExecutable(relative: string[]): string | undefined {
|
||||
try {
|
||||
const defaultPath = path.join(__dirname, '..', '..', ...relative);
|
||||
if (fs.existsSync(defaultPath))
|
||||
return defaultPath;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18,8 +18,9 @@
|
|||
import * as os from 'os';
|
||||
import path from 'path';
|
||||
import * as util from 'util';
|
||||
import { getUbuntuVersionSync } from './ubuntuVersion';
|
||||
import { assert, getFromENV } from './utils';
|
||||
import { getUbuntuVersion, getUbuntuVersionSync } from './ubuntuVersion';
|
||||
import { assert, getFromENV, getAsBooleanFromENV } from './utils';
|
||||
import { validateDependenciesLinux, validateDependenciesWindows } from './validateDependencies';
|
||||
|
||||
export type BrowserName = 'chromium'|'chromium-with-symbols'|'webkit'|'firefox'|'firefox-beta'|'ffmpeg';
|
||||
export const allBrowserNames: Set<BrowserName> = new Set(['chromium', 'chromium-with-symbols', 'webkit', 'firefox', 'ffmpeg', 'firefox-beta']);
|
||||
|
|
@ -293,40 +294,6 @@ export class Registry {
|
|||
return parseInt(browser.revision, 10);
|
||||
}
|
||||
|
||||
linuxLddDirectories(browserName: BrowserName): string[] {
|
||||
const browserDirectory = this.browserDirectory(browserName);
|
||||
switch (browserName) {
|
||||
case 'chromium':
|
||||
case 'chromium-with-symbols':
|
||||
return [path.join(browserDirectory, 'chrome-linux')];
|
||||
case 'webkit':
|
||||
return [
|
||||
path.join(browserDirectory, 'minibrowser-gtk'),
|
||||
path.join(browserDirectory, 'minibrowser-gtk', 'bin'),
|
||||
path.join(browserDirectory, 'minibrowser-gtk', 'lib'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe', 'bin'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe', 'lib'),
|
||||
];
|
||||
case 'firefox':
|
||||
case 'firefox-beta':
|
||||
return [path.join(browserDirectory, 'firefox')];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
windowsExeAndDllDirectories(browserName: BrowserName): string[] {
|
||||
const browserDirectory = this.browserDirectory(browserName);
|
||||
if (browserName === 'chromium' || browserName === 'chromium-with-symbols')
|
||||
return [path.join(browserDirectory, 'chrome-win')];
|
||||
if (browserName === 'firefox' || browserName === 'firefox-beta')
|
||||
return [path.join(browserDirectory, 'firefox')];
|
||||
if (browserName === 'webkit')
|
||||
return [browserDirectory];
|
||||
return [];
|
||||
}
|
||||
|
||||
executablePath(browserName: BrowserName): string | undefined {
|
||||
const browserDirectory = this.browserDirectory(browserName);
|
||||
const tokens = EXECUTABLE_PATHS[browserName][hostPlatform];
|
||||
|
|
@ -364,4 +331,47 @@ export class Registry {
|
|||
installByDefault(): BrowserName[] {
|
||||
return this._descriptors.filter(browser => browser.installByDefault).map(browser => browser.name);
|
||||
}
|
||||
|
||||
async validateHostRequirements(browserName: BrowserName) {
|
||||
if (getAsBooleanFromENV('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {
|
||||
process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');
|
||||
return;
|
||||
}
|
||||
const ubuntuVersion = await getUbuntuVersion();
|
||||
if ((browserName === 'firefox' || browserName === 'firefox-beta') && ubuntuVersion === '16.04')
|
||||
throw new Error(`Cannot launch ${browserName} on Ubuntu 16.04! Minimum required Ubuntu version for Firefox browser is 18.04`);
|
||||
const browserDirectory = this.browserDirectory(browserName);
|
||||
|
||||
if (os.platform() === 'linux') {
|
||||
const dlOpenLibraries: string[] = [];
|
||||
const linuxLddDirectories: string[] = [];
|
||||
if (browserName === 'chromium' || browserName === 'chromium-with-symbols')
|
||||
linuxLddDirectories.push(path.join(browserDirectory, 'chrome-linux'));
|
||||
if (browserName === 'webkit') {
|
||||
linuxLddDirectories.push(
|
||||
path.join(browserDirectory, 'minibrowser-gtk'),
|
||||
path.join(browserDirectory, 'minibrowser-gtk', 'bin'),
|
||||
path.join(browserDirectory, 'minibrowser-gtk', 'lib'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe', 'bin'),
|
||||
path.join(browserDirectory, 'minibrowser-wpe', 'lib'),
|
||||
);
|
||||
dlOpenLibraries.push('libGLESv2.so.2', 'libx264.so');
|
||||
}
|
||||
if (browserName === 'firefox' || browserName === 'firefox-beta')
|
||||
linuxLddDirectories.push(path.join(browserDirectory, 'firefox'));
|
||||
return await validateDependenciesLinux(linuxLddDirectories, dlOpenLibraries);
|
||||
}
|
||||
|
||||
if (os.platform() === 'win32' && os.arch() === 'x64') {
|
||||
const windowsExeAndDllDirectories: string[] = [];
|
||||
if (browserName === 'chromium' || browserName === 'chromium-with-symbols')
|
||||
windowsExeAndDllDirectories.push(path.join(browserDirectory, 'chrome-win'));
|
||||
if (browserName === 'firefox' || browserName === 'firefox-beta')
|
||||
windowsExeAndDllDirectories.push(path.join(browserDirectory, 'firefox'));
|
||||
if (browserName === 'webkit')
|
||||
windowsExeAndDllDirectories.push(browserDirectory);
|
||||
return await validateDependenciesWindows(windowsExeAndDllDirectories);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,34 +13,15 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import * as os from 'os';
|
||||
import { getUbuntuVersion } from '../utils/ubuntuVersion';
|
||||
import * as registry from '../utils/registry';
|
||||
import * as utils from '../utils/utils';
|
||||
import { printDepsWindowsExecutable } from '../utils/binaryPaths';
|
||||
import { getUbuntuVersion } from './ubuntuVersion';
|
||||
import * as utils from './utils';
|
||||
|
||||
const checkExecutable = (filePath: string) => fs.promises.access(filePath, fs.constants.X_OK).then(() => true).catch(e => false);
|
||||
|
||||
export async function validateHostRequirements(registry: registry.Registry, browserName: registry.BrowserName) {
|
||||
if (utils.getAsBooleanFromENV('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {
|
||||
process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');
|
||||
return;
|
||||
}
|
||||
const ubuntuVersion = await getUbuntuVersion();
|
||||
if (browserName === 'firefox' && ubuntuVersion === '16.04')
|
||||
throw new Error(`Cannot launch firefox on Ubuntu 16.04! Minimum required Ubuntu version for Firefox browser is 18.04`);
|
||||
if (os.platform() === 'linux')
|
||||
return await validateDependenciesLinux(registry, browserName);
|
||||
if (os.platform() === 'win32' && os.arch() === 'x64')
|
||||
return await validateDependenciesWindows(registry, browserName);
|
||||
}
|
||||
|
||||
const DL_OPEN_LIBRARIES = {
|
||||
'webkit': ['libGLESv2.so.2', 'libx264.so'],
|
||||
};
|
||||
|
||||
function isSupportedWindowsVersion(): boolean {
|
||||
if (os.platform() !== 'win32' || os.arch() !== 'x64')
|
||||
return false;
|
||||
|
|
@ -51,8 +32,8 @@ function isSupportedWindowsVersion(): boolean {
|
|||
return major > 6 || (major === 6 && minor > 1);
|
||||
}
|
||||
|
||||
async function validateDependenciesWindows(registry: registry.Registry, browserName: registry.BrowserName) {
|
||||
const directoryPaths = registry.windowsExeAndDllDirectories(browserName);
|
||||
export async function validateDependenciesWindows(windowsExeAndDllDirectories: string[]) {
|
||||
const directoryPaths = windowsExeAndDllDirectories;
|
||||
const lddPaths: string[] = [];
|
||||
for (const directoryPath of directoryPaths)
|
||||
lddPaths.push(...(await executablesOrSharedLibraries(directoryPath)));
|
||||
|
|
@ -112,8 +93,8 @@ async function validateDependenciesWindows(registry: registry.Registry, browserN
|
|||
}
|
||||
}
|
||||
|
||||
async function validateDependenciesLinux(registry: registry.Registry, browserName: registry.BrowserName) {
|
||||
const directoryPaths = registry.linuxLddDirectories(browserName);
|
||||
export async function validateDependenciesLinux(linuxLddDirectories: string[], dlOpenLibraries: string[]) {
|
||||
const directoryPaths = linuxLddDirectories;
|
||||
const lddPaths: string[] = [];
|
||||
for (const directoryPath of directoryPaths)
|
||||
lddPaths.push(...(await executablesOrSharedLibraries(directoryPath)));
|
||||
|
|
@ -123,7 +104,7 @@ async function validateDependenciesLinux(registry: registry.Registry, browserNam
|
|||
for (const dep of deps)
|
||||
missingDeps.add(dep);
|
||||
}
|
||||
for (const dep of (await missingDLOPENLibraries(browserName)))
|
||||
for (const dep of (await missingDLOPENLibraries(dlOpenLibraries)))
|
||||
missingDeps.add(dep);
|
||||
if (!missingDeps.size)
|
||||
return;
|
||||
|
|
@ -202,10 +183,7 @@ async function executablesOrSharedLibraries(directoryPath: string): Promise<stri
|
|||
}
|
||||
|
||||
async function missingFileDependenciesWindows(filePath: string): Promise<Array<string>> {
|
||||
const executable = printDepsWindowsExecutable();
|
||||
if (!executable)
|
||||
return [];
|
||||
|
||||
const executable = path.join(__dirname, '..', '..', 'bin', 'PrintDeps.exe');
|
||||
const dirname = path.dirname(filePath);
|
||||
const {stdout, code} = await utils.spawnAsync(executable, [filePath], {
|
||||
cwd: dirname,
|
||||
|
|
@ -238,8 +216,7 @@ async function missingFileDependencies(filePath: string, extraLDPaths: string[])
|
|||
return missingDeps;
|
||||
}
|
||||
|
||||
async function missingDLOPENLibraries(browserName: registry.BrowserName): Promise<string[]> {
|
||||
const libraries: string[] = (DL_OPEN_LIBRARIES as any)[browserName] || [];
|
||||
async function missingDLOPENLibraries(libraries: string[]): Promise<string[]> {
|
||||
if (!libraries.length)
|
||||
return [];
|
||||
// NOTE: Using full-qualified path to `ldconfig` since `/sbin` is not part of the
|
||||
Loading…
Reference in a new issue