chore: a nicer message to urge updating docker image with Playwright (#16758)

This will result in the following message:

```
root@docker-desktop:/playwright# node a.mjs
node:internal/process/esm_loader:94
    internalBinding('errors').triggerUncaughtException(
                              ^

browserType.launch: Executable doesn't exist at /ms-playwright/chromium-1021/chrome-linux/chrome
╔══════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just updated to 1.26.0. ║
║ Please update docker image as well.                                  ║
║ -  current: mcr.microsoft.com/playwright:v1.23.0-focal               ║
║ - required: mcr.microsoft.com/playwright:v1.26.0-focal               ║
║                                                                      ║
║ <3 Playwright Team                                                   ║
╚══════════════════════════════════════════════════════════════════════╝
    at file:///playwright/a.mjs:3:43 {
  name: 'Error'
}
```

Fixes #15483
This commit is contained in:
Andrey Lushnikov 2022-08-23 10:39:59 -07:00 committed by GitHub
parent 42491ecc08
commit 1cedd805ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 11 deletions

View File

@ -31,18 +31,28 @@ const packageJSON = require('../../../package.json');
const dockerVersionFilePath = '/ms-playwright/.docker-info';
export async function writeDockerVersion(dockerImageNameTemplate: string) {
await fs.promises.mkdir(path.dirname(dockerVersionFilePath), { recursive: true });
await fs.promises.writeFile(dockerVersionFilePath, JSON.stringify({
driverVersion: packageJSON.version,
dockerImageName: dockerImageNameTemplate.replace('%version%', packageJSON.version),
}, null, 2), 'utf8');
await fs.promises.writeFile(dockerVersionFilePath, JSON.stringify(dockerVersion(dockerImageNameTemplate), null, 2), 'utf8');
// Make sure version file is globally accessible.
await fs.promises.chmod(dockerVersionFilePath, 0o777);
}
async function readDockerVersion(): Promise<null | { driverVersion: string, dockerImageName: string }> {
return await fs.promises.readFile(dockerVersionFilePath, 'utf8')
.then(text => JSON.parse(text))
.catch(e => null);
export function dockerVersion(dockerImageNameTemplate: string): { driverVersion: string, dockerImageName: string } {
return {
driverVersion: packageJSON.version,
dockerImageName: dockerImageNameTemplate.replace('%version%', packageJSON.version),
};
}
export function readDockerVersionSync(): null | { driverVersion: string, dockerImageName: string, dockerImageNameTemplate: string } {
try {
const data = JSON.parse(fs.readFileSync(dockerVersionFilePath, 'utf8'));
return {
...data,
dockerImageNameTemplate: data.dockerImageName.replace(data.driverVersion, '%version%'),
};
} catch (e) {
return null;
}
}
const checkExecutable = (filePath: string) => fs.promises.access(filePath, fs.constants.X_OK).then(() => true).catch(e => false);
@ -206,7 +216,7 @@ export async function validateDependenciesLinux(sdkLanguage: string, linuxLddDir
}
const maybeSudo = (process.getuid() !== 0) && os.platform() !== 'win32' ? 'sudo ' : '';
const dockerInfo = await readDockerVersion();
const dockerInfo = readDockerVersionSync();
const errorLines = [
`Host system is missing dependencies to run browsers.`,
];

View File

@ -28,7 +28,7 @@ import { removeFolders, existsAsync, canAccessFile } from '../../utils/fileUtils
import { hostPlatform } from '../../utils/hostPlatform';
import { spawnAsync } from '../../utils/spawnAsync';
import type { DependencyGroup } from './dependencies';
import { transformCommandsForRoot } from './dependencies';
import { transformCommandsForRoot, dockerVersion, readDockerVersionSync } from './dependencies';
import { installDependenciesLinux, installDependenciesWindows, validateDependenciesLinux, validateDependenciesWindows } from './dependencies';
import { downloadBrowserWithProgressBar, logPolitely } from './browserFetcher';
export { writeDockerVersion } from './dependencies';
@ -341,7 +341,17 @@ export class Registry {
throw new Error(`${name} is not supported on ${hostPlatform}`);
const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install${installByDefault ? '' : ' ' + name}`);
if (!canAccessFile(e)) {
const prettyMessage = [
const currentDockerVersion = readDockerVersionSync();
const preferredDockerVersion = currentDockerVersion ? dockerVersion(currentDockerVersion.dockerImageNameTemplate) : null;
const isOutdatedDockerImage = currentDockerVersion && preferredDockerVersion && currentDockerVersion.dockerImageName !== preferredDockerVersion.dockerImageName;
const prettyMessage = isOutdatedDockerImage ? [
`Looks like ${sdkLanguage === 'javascript' ? 'Playwright Test or ' : ''}Playwright was just updated to ${preferredDockerVersion.driverVersion}.`,
`Please update docker image as well.`,
`- current: ${currentDockerVersion.dockerImageName}`,
`- required: ${preferredDockerVersion.dockerImageName}`,
``,
`<3 Playwright Team`,
].join('\n') : [
`Looks like ${sdkLanguage === 'javascript' ? 'Playwright Test or ' : ''}Playwright was just installed or updated.`,
`Please run the following command to download new browser${installByDefault ? 's' : ''}:`,
``,