chore(docker): consolidate docker code (#17314)

This patch consolidates all of docker implementation under the
`docker/` folder.
This commit is contained in:
Andrey Lushnikov 2022-09-13 16:14:49 -07:00 committed by GitHub
parent 35a86a2d02
commit 881f3101bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 66 deletions

View File

@ -21,7 +21,6 @@ import * as docker from './docker/docker';
import fs from 'fs';
import url from 'url';
import path from 'path';
import { colors } from 'playwright-core/lib/utilsBundle';
import { Runner, builtInReporters, kDefaultConfigFiles } from './runner';
import type { ConfigCLIOverrides } from './runner';
import { stopProfiling, startProfiling } from './profiler';
@ -44,44 +43,25 @@ function addDockerCommand(program: Command) {
dockerCommand.command('build')
.description('build local docker image')
.action(async function(options) {
await docker.ensureDockerEngineIsRunningOrDie();
await docker.buildImage();
await docker.buildPlaywrightImage();
});
dockerCommand.command('start')
.description('start docker container')
.action(async function(options) {
await docker.ensureDockerEngineIsRunningOrDie();
let info = await docker.containerInfo();
if (!info) {
process.stdout.write(`Starting docker container... `);
const time = Date.now();
info = await docker.ensureContainerOrDie();
const deltaMs = (Date.now() - time);
console.log('Done in ' + (deltaMs / 1000).toFixed(1) + 's');
}
console.log([
`- View screen:`,
` ${info.vncSession}`,
`- Run tests with browsers inside container:`,
` npx playwright docker test`,
`- Stop background container *manually* when you are done working with tests:`,
` npx playwright docker stop`,
].join('\n'));
});
dockerCommand.command('delete-image', { hidden: true })
.description('delete docker image, if any')
.action(async function(options) {
await docker.ensureDockerEngineIsRunningOrDie();
await docker.deleteImage();
await docker.startPlaywrightContainer();
});
dockerCommand.command('stop')
.description('stop docker container')
.action(async function(options) {
await docker.ensureDockerEngineIsRunningOrDie();
await docker.stopContainer();
await docker.stopPlaywrightContainer();
});
dockerCommand.command('delete-image', { hidden: true })
.description('delete docker image, if any')
.action(async function(options) {
await docker.deletePlaywrightImage();
});
addTestCommand(dockerCommand, true /* isDocker */);
@ -121,27 +101,8 @@ function addTestCommand(program: Command, isDocker: boolean) {
command.action(async (args, opts) => {
try {
isDocker = isDocker || !!process.env.PLAYWRIGHT_DOCKER;
if (isDocker && !process.env.PW_TS_ESM_ON) {
console.log(colors.dim('Using docker container to run browsers.'));
await docker.ensureDockerEngineIsRunningOrDie();
let info = await docker.containerInfo();
if (!info) {
process.stdout.write(colors.dim(`Starting docker container... `));
const time = Date.now();
info = await docker.ensureContainerOrDie();
const deltaMs = (Date.now() - time);
console.log(colors.dim('Done in ' + (deltaMs / 1000).toFixed(1) + 's'));
console.log(colors.dim('The Docker container will keep running after tests finished.'));
console.log(colors.dim('Stop manually using:'));
console.log(colors.dim(' npx playwright docker stop'));
}
console.log(colors.dim(`View screen: ${info.vncSession}`));
process.env.PW_TEST_CONNECT_WS_ENDPOINT = info.wsEndpoint;
process.env.PW_TEST_CONNECT_HEADERS = JSON.stringify({
'x-playwright-proxy': '*',
});
process.env.PLAYWRIGHT_DOCKER = '1';
}
if (isDocker && !process.env.PW_TS_ESM_ON)
await docker.configureTestRunnerToUseDocker();
await runTests(args, opts);
} catch (e) {
console.error(e);

View File

@ -17,6 +17,7 @@
import path from 'path';
import fs from 'fs';
import { colors } from 'playwright-core/lib/utilsBundle';
import { spawnAsync } from 'playwright-core/lib/utils/spawnAsync';
import * as utils from 'playwright-core/lib/utils';
import { getPlaywrightVersion } from 'playwright-core/lib/common/userAgent';
@ -26,17 +27,54 @@ const VRT_IMAGE_DISTRO = 'focal';
const VRT_IMAGE_NAME = `playwright:local-${getPlaywrightVersion()}-${VRT_IMAGE_DISTRO}`;
const VRT_CONTAINER_NAME = `playwright-${getPlaywrightVersion()}-${VRT_IMAGE_DISTRO}`;
export async function deleteImage() {
export async function startPlaywrightContainer() {
await checkDockerEngineIsRunningOrDie();
let info = await containerInfo();
if (!info) {
process.stdout.write(`Starting docker container... `);
const time = Date.now();
info = await ensurePlaywrightContainerOrDie();
const deltaMs = (Date.now() - time);
console.log('Done in ' + (deltaMs / 1000).toFixed(1) + 's');
}
console.log([
`- View screen:`,
` ${info.vncSession}`,
`- Run tests with browsers inside container:`,
` npx playwright docker test`,
`- Stop background container *manually* when you are done working with tests:`,
` npx playwright docker stop`,
].join('\n'));
}
export async function stopPlaywrightContainer() {
await checkDockerEngineIsRunningOrDie();
const container = await findRunningDockerContainer();
if (!container)
return;
await dockerApi.stopContainer({
containerId: container.containerId,
waitUntil: 'removed',
});
}
export async function deletePlaywrightImage() {
await checkDockerEngineIsRunningOrDie();
const dockerImage = await findDockerImage(VRT_IMAGE_NAME);
if (!dockerImage)
return;
if (await containerInfo())
await stopContainer();
await stopPlaywrightContainer();
await dockerApi.removeImage(dockerImage.imageId);
}
export async function buildImage() {
export async function buildPlaywrightImage() {
await checkDockerEngineIsRunningOrDie();
const isDevelopmentMode = getPlaywrightVersion().includes('next');
let baseImageName = `mcr.microsoft.com/playwright:v${getPlaywrightVersion()}-${VRT_IMAGE_DISTRO}`;
// 1. Build or pull base image.
@ -90,12 +128,35 @@ export async function buildImage() {
console.log(`Done!`);
}
export async function configureTestRunnerToUseDocker() {
console.log(colors.dim('Using docker container to run browsers.'));
await checkDockerEngineIsRunningOrDie();
let info = await containerInfo();
if (!info) {
process.stdout.write(colors.dim(`Starting docker container... `));
const time = Date.now();
info = await ensurePlaywrightContainerOrDie();
const deltaMs = (Date.now() - time);
console.log(colors.dim('Done in ' + (deltaMs / 1000).toFixed(1) + 's'));
console.log(colors.dim('The Docker container will keep running after tests finished.'));
console.log(colors.dim('Stop manually using:'));
console.log(colors.dim(' npx playwright docker stop'));
}
console.log(colors.dim(`View screen: ${info.vncSession}`));
process.env.PW_TEST_CONNECT_WS_ENDPOINT = info.wsEndpoint;
process.env.PW_TEST_CONNECT_HEADERS = JSON.stringify({
'x-playwright-proxy': '*',
});
process.env.PLAYWRIGHT_DOCKER = '1';
}
interface ContainerInfo {
wsEndpoint: string;
vncSession: string;
}
export async function containerInfo(): Promise<ContainerInfo|undefined> {
async function containerInfo(): Promise<ContainerInfo|undefined> {
const container = await findRunningDockerContainer();
if (!container)
return undefined;
@ -123,7 +184,7 @@ export async function containerInfo(): Promise<ContainerInfo|undefined> {
return wsEndpoint && vncSession ? { wsEndpoint, vncSession } : undefined;
}
export async function ensureContainerOrDie(): Promise<ContainerInfo> {
async function ensurePlaywrightContainerOrDie(): Promise<ContainerInfo> {
const pwImage = await findDockerImage(VRT_IMAGE_NAME);
if (!pwImage) {
console.error('\n' + utils.wrapInASCIIBox([
@ -161,17 +222,7 @@ export async function ensureContainerOrDie(): Promise<ContainerInfo> {
return info;
}
export async function stopContainer() {
const container = await findRunningDockerContainer();
if (!container)
return;
await dockerApi.stopContainer({
containerId: container.containerId,
waitUntil: 'removed',
});
}
export async function ensureDockerEngineIsRunningOrDie() {
async function checkDockerEngineIsRunningOrDie() {
if (await dockerApi.checkEngineRunning())
return;
console.error(utils.wrapInASCIIBox([