mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-02 23:27:28 +03:00
chore(docker): address docker offline comments (#17377)
This patch: - Removes all `process.exit(1)` from `docker.ts` and instead throws errors. - Drops the `npx playwright docker test` command. We agreed to engage docker when `PLAYWRIGHT_DOCKER` environment variable is set. - Introduces hidden `npx playwright docker status` command that dumps a JSON with docker status: ```sh aslushnikov:~/prog/playwright$ npx playwright docker status { "dockerEngineRunning": true, "imageName": "playwright:local-1.27.0-next-focal", "imageIsPulled": true, "containerWSEndpoing": "ws://127.0.0.1:55077/eafeb84c-571b-4d12-ac51-f6a2b43e9155", "containerVNCEndpoint": "http://127.0.0.1:55076/?path=fb6d4add-9adf-4c3c-b335-893bdc235cd7&resize=scale&autoconnect=1" } ```
This commit is contained in:
parent
30ff27843a
commit
b09ea69024
@ -179,14 +179,22 @@ Docker integration usage:
|
||||
npx playwright docker start
|
||||
```
|
||||
|
||||
1. Run tests inside Docker container. Note that this command accepts all the same arguments
|
||||
as a regular `npx playwright test` command.
|
||||
1. Run tests inside Docker container using the `PLAYWRIGHT_DOCKER` environment variable.
|
||||
You can set this environment variable as a part of your config:
|
||||
|
||||
```bash js
|
||||
npx playwright docker test
|
||||
```ts
|
||||
// playwright.config.ts
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
process.env.PLAYWRIGHT_DOCKER = '1';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
/* ... configuration ... */
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
Note that this command will detect running Docker container, and auto-launch it if needed.
|
||||
NOTE: Playwright will automatically detect a running Docker container or start it if needed.
|
||||
|
||||
1. Finally, stop background Docker container when you're done working with tests:
|
||||
|
||||
@ -194,17 +202,3 @@ Docker integration usage:
|
||||
npx playwright docker stop
|
||||
```
|
||||
|
||||
Playwright Test sets `PLAYWRIGHT_DOCKER` environment variable when it uses Docker integration.
|
||||
You can use this variable to customize config or tests behavior, for example:
|
||||
|
||||
```ts
|
||||
// playwright.config.ts
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
// Ignore all snapshot expectations when running outside
|
||||
// of docker integration.
|
||||
ignoreSnapshots: !process.env.PLAYWRIGHT_DOCKER,
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
@ -30,7 +30,7 @@ import { baseFullConfig, defaultTimeout, fileIsModule } from './loader';
|
||||
import type { TraceMode } from './types';
|
||||
|
||||
export function addTestCommands(program: Command) {
|
||||
addTestCommand(program, false /* isDocker */);
|
||||
addTestCommand(program);
|
||||
addShowReportCommand(program);
|
||||
addListFilesCommand(program);
|
||||
addDockerCommand(program);
|
||||
@ -38,41 +38,58 @@ export function addTestCommands(program: Command) {
|
||||
|
||||
function addDockerCommand(program: Command) {
|
||||
const dockerCommand = program.command('docker')
|
||||
.description(`run tests in Docker (EXPERIMENTAL)`);
|
||||
.description(`Manage Docker integration (EXPERIMENTAL)`);
|
||||
|
||||
dockerCommand.command('build')
|
||||
.description('build local docker image')
|
||||
.action(async function(options) {
|
||||
await docker.buildPlaywrightImage();
|
||||
try {
|
||||
await docker.buildPlaywrightImage();
|
||||
} catch (e) {
|
||||
console.error(e.stack ? e : e.message);
|
||||
}
|
||||
});
|
||||
|
||||
dockerCommand.command('start')
|
||||
.description('start docker container')
|
||||
.action(async function(options) {
|
||||
await docker.startPlaywrightContainer();
|
||||
try {
|
||||
await docker.startPlaywrightContainer();
|
||||
} catch (e) {
|
||||
console.error(e.stack ? e : e.message);
|
||||
}
|
||||
});
|
||||
|
||||
dockerCommand.command('stop')
|
||||
.description('stop docker container')
|
||||
.action(async function(options) {
|
||||
await docker.stopAllPlaywrightContainers();
|
||||
try {
|
||||
await docker.stopAllPlaywrightContainers();
|
||||
} catch (e) {
|
||||
console.error(e.stack ? e : e.message);
|
||||
}
|
||||
});
|
||||
|
||||
dockerCommand.command('delete-image', { hidden: true })
|
||||
.description('delete docker image, if any')
|
||||
.action(async function(options) {
|
||||
await docker.deletePlaywrightImage();
|
||||
try {
|
||||
await docker.deletePlaywrightImage();
|
||||
} catch (e) {
|
||||
console.error(e.stack ? e : e.message);
|
||||
}
|
||||
});
|
||||
|
||||
addTestCommand(dockerCommand, true /* isDocker */);
|
||||
dockerCommand.command('print-status-json', { hidden: true })
|
||||
.description('print docker status')
|
||||
.action(async function(options) {
|
||||
await docker.printDockerStatus();
|
||||
});
|
||||
}
|
||||
|
||||
function addTestCommand(program: Command, isDocker: boolean) {
|
||||
function addTestCommand(program: Command) {
|
||||
const command = program.command('test [test-filter...]');
|
||||
if (isDocker)
|
||||
command.description('run tests with Playwright Test and browsers inside docker container');
|
||||
else
|
||||
command.description('run tests with Playwright Test');
|
||||
command.description('run tests with Playwright Test');
|
||||
command.option('--browser <browser>', `Browser to use for tests, one of "all", "chromium", "firefox" or "webkit" (default: "chromium")`);
|
||||
command.option('--headed', `Run tests in headed browsers (default: headless)`);
|
||||
command.option('--debug', `Run tests with Playwright Inspector. Shortcut for "PWDEBUG=1" environment variable and "--timeout=0 --maxFailures=1 --headed --workers=1" options`);
|
||||
@ -100,8 +117,6 @@ function addTestCommand(program: Command, isDocker: boolean) {
|
||||
command.option('-x', `Stop after the first failure`);
|
||||
command.action(async (args, opts) => {
|
||||
try {
|
||||
if (isDocker)
|
||||
process.env.PLAYWRIGHT_DOCKER = '1';
|
||||
await runTests(args, opts);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@ -113,10 +128,10 @@ Arguments [test-filter...]:
|
||||
Pass arguments to filter test files. Each argument is treated as a regular expression.
|
||||
|
||||
Examples:
|
||||
$ npx playwright${isDocker ? ' docker ' : ' '}test my.spec.ts
|
||||
$ npx playwright${isDocker ? ' docker ' : ' '}test some.spec.ts:42
|
||||
$ npx playwright${isDocker ? ' docker ' : ' '}test --headed
|
||||
$ npx playwright${isDocker ? ' docker ' : ' '}test --browser=webkit`);
|
||||
$ npx playwright test my.spec.ts
|
||||
$ npx playwright test some.spec.ts:42
|
||||
$ npx playwright test --headed
|
||||
$ npx playwright test --browser=webkit`);
|
||||
}
|
||||
|
||||
function addListFilesCommand(program: Command) {
|
||||
|
@ -85,7 +85,7 @@ export async function buildPlaywrightImage() {
|
||||
// Use our docker build scripts in development mode!
|
||||
if (!process.env.PWTEST_DOCKER_BASE_IMAGE) {
|
||||
const arch = process.arch === 'arm64' ? '--arm64' : '--amd64';
|
||||
console.error(utils.wrapInASCIIBox([
|
||||
throw createStacklessError(utils.wrapInASCIIBox([
|
||||
`You are in DEVELOPMENT mode!`,
|
||||
``,
|
||||
`1. Build local base image`,
|
||||
@ -93,7 +93,6 @@ export async function buildPlaywrightImage() {
|
||||
`2. Use the local base to build VRT image:`,
|
||||
` PWTEST_DOCKER_BASE_IMAGE=playwright:localbuild npx playwright docker build`,
|
||||
].join('\n'), 1));
|
||||
process.exit(1);
|
||||
}
|
||||
baseImageName = process.env.PWTEST_DOCKER_BASE_IMAGE;
|
||||
} else {
|
||||
@ -168,6 +167,19 @@ interface ContainerInfo {
|
||||
vncSession: string;
|
||||
}
|
||||
|
||||
export async function printDockerStatus() {
|
||||
const isDockerEngine = await dockerApi.checkEngineRunning();
|
||||
const imageIsPulled = isDockerEngine && !!(await findDockerImage(VRT_IMAGE_NAME));
|
||||
const info = isDockerEngine ? await containerInfo() : undefined;
|
||||
console.log(JSON.stringify({
|
||||
dockerEngineRunning: isDockerEngine,
|
||||
imageName: VRT_IMAGE_NAME,
|
||||
imageIsPulled,
|
||||
containerWSEndpoing: info?.wsEndpoint ?? '',
|
||||
containerVNCEndpoint: info?.vncSession ?? '',
|
||||
}, null, 2));
|
||||
}
|
||||
|
||||
async function containerInfo(): Promise<ContainerInfo|undefined> {
|
||||
const allContainers = await dockerApi.listContainers();
|
||||
const pwDockerImage = await findDockerImage(VRT_IMAGE_NAME);
|
||||
@ -201,7 +213,7 @@ async function containerInfo(): Promise<ContainerInfo|undefined> {
|
||||
async function ensurePlaywrightContainerOrDie(): Promise<ContainerInfo> {
|
||||
const pwImage = await findDockerImage(VRT_IMAGE_NAME);
|
||||
if (!pwImage) {
|
||||
console.error('\n' + utils.wrapInASCIIBox([
|
||||
throw createStacklessError('\n' + utils.wrapInASCIIBox([
|
||||
`Failed to find local docker image.`,
|
||||
`Please build local docker image with the following command:`,
|
||||
``,
|
||||
@ -209,7 +221,6 @@ async function ensurePlaywrightContainerOrDie(): Promise<ContainerInfo> {
|
||||
``,
|
||||
`<3 Playwright Team`,
|
||||
].join('\n'), 1));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let info = await containerInfo();
|
||||
@ -242,14 +253,13 @@ async function ensurePlaywrightContainerOrDie(): Promise<ContainerInfo> {
|
||||
async function checkDockerEngineIsRunningOrDie() {
|
||||
if (await dockerApi.checkEngineRunning())
|
||||
return;
|
||||
console.error(utils.wrapInASCIIBox([
|
||||
throw createStacklessError(utils.wrapInASCIIBox([
|
||||
`Docker is not running!`,
|
||||
`Please install and launch docker:`,
|
||||
``,
|
||||
` https://docs.docker.com/get-docker`,
|
||||
``,
|
||||
].join('\n'), 1));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function findDockerImage(imageName: string): Promise<dockerApi.DockerImage|undefined> {
|
||||
@ -257,3 +267,8 @@ async function findDockerImage(imageName: string): Promise<dockerApi.DockerImage
|
||||
return images.find(image => image.names.includes(imageName));
|
||||
}
|
||||
|
||||
function createStacklessError(message: string) {
|
||||
const error = new Error(message);
|
||||
error.stack = '';
|
||||
return error;
|
||||
}
|
||||
|
@ -30,8 +30,9 @@ test.beforeAll(async ({ exec }) => {
|
||||
|
||||
test('make sure it tells to run `npx playwright docker build` when image is not instaleld', async ({ exec }) => {
|
||||
await exec('npm i --foreground-scripts @playwright/test');
|
||||
const result = await exec('npx playwright docker test docker.spec.js', {
|
||||
const result = await exec('npx playwright test docker.spec.js', {
|
||||
expectToExitWithError: true,
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('npx playwright docker build');
|
||||
});
|
||||
@ -52,7 +53,9 @@ test.describe('installed image', () => {
|
||||
test('make sure it auto-starts container', async ({ exec }) => {
|
||||
await exec('npm i --foreground-scripts @playwright/test');
|
||||
await exec('npx playwright docker stop');
|
||||
const result = await exec('npx playwright docker test docker.spec.js --grep platform');
|
||||
const result = await exec('npx playwright test docker.spec.js --grep platform', {
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('@chromium Linux');
|
||||
});
|
||||
|
||||
@ -71,7 +74,9 @@ test.describe('installed image', () => {
|
||||
|
||||
test('all browsers work headless', async ({ exec }) => {
|
||||
await exec('npm i --foreground-scripts @playwright/test');
|
||||
const result = await exec('npx playwright docker test docker.spec.js --grep platform --browser all');
|
||||
const result = await exec('npx playwright test docker.spec.js --grep platform --browser all', {
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('@chromium Linux');
|
||||
expect(result).toContain('@webkit Linux');
|
||||
expect(result).toContain('@firefox Linux');
|
||||
@ -92,18 +97,24 @@ test.describe('installed image', () => {
|
||||
test('all browsers work headed', async ({ exec }) => {
|
||||
await exec('npm i --foreground-scripts @playwright/test');
|
||||
{
|
||||
const result = await exec(`npx playwright docker test docker.spec.js --headed --grep userAgent --browser chromium`);
|
||||
const result = await exec(`npx playwright test docker.spec.js --headed --grep userAgent --browser chromium`, {
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('@chromium');
|
||||
expect(result).not.toContain('Headless');
|
||||
expect(result).toContain(' Chrome/');
|
||||
}
|
||||
{
|
||||
const result = await exec(`npx playwright docker test docker.spec.js --headed --grep userAgent --browser webkit`);
|
||||
const result = await exec(`npx playwright test docker.spec.js --headed --grep userAgent --browser webkit`, {
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('@webkit');
|
||||
expect(result).toContain(' Version/');
|
||||
}
|
||||
{
|
||||
const result = await exec(`npx playwright docker test docker.spec.js --headed --grep userAgent --browser firefox`);
|
||||
const result = await exec(`npx playwright test docker.spec.js --headed --grep userAgent --browser firefox`, {
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
expect(result).toContain('@firefox');
|
||||
expect(result).toContain(' Firefox/');
|
||||
}
|
||||
@ -111,8 +122,9 @@ test.describe('installed image', () => {
|
||||
|
||||
test('screenshots should use __screenshots__ folder', async ({ exec, tmpWorkspace }) => {
|
||||
await exec('npm i --foreground-scripts @playwright/test');
|
||||
await exec('npx playwright docker test docker.spec.js --grep screenshot --browser all', {
|
||||
await exec('npx playwright test docker.spec.js --grep screenshot --browser all', {
|
||||
expectToExitWithError: true,
|
||||
env: { PLAYWRIGHT_DOCKER: '1' },
|
||||
});
|
||||
await expect(path.join(tmpWorkspace, '__screenshots__', 'firefox', 'docker.spec.js', 'img.png')).toExistOnFS();
|
||||
await expect(path.join(tmpWorkspace, '__screenshots__', 'chromium', 'docker.spec.js', 'img.png')).toExistOnFS();
|
||||
@ -126,8 +138,9 @@ test.describe('installed image', () => {
|
||||
server.setRoute('/', (request, response) => {
|
||||
response.end('Hello from host');
|
||||
});
|
||||
const result = await exec('npx playwright docker test docker.spec.js --grep localhost --browser all', {
|
||||
const result = await exec('npx playwright test docker.spec.js --grep localhost --browser all', {
|
||||
env: {
|
||||
PLAYWRIGHT_DOCKER: '1',
|
||||
TEST_PORT: TEST_PORT + '',
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user