feat: support PWTEST_PROFILE_DIR in run-server (#21582)

This creates one profile per connection in the specified directory.
This commit is contained in:
Dmitry Gozman 2023-03-10 19:07:40 -08:00 committed by GitHub
parent fa9edcbbc1
commit ea8aa63f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 11 additions and 5 deletions

View File

@ -24,6 +24,7 @@ import { assert } from '../utils';
import type { LaunchOptions } from '../server/types'; import type { LaunchOptions } from '../server/types';
import { AndroidDevice } from '../server/android/android'; import { AndroidDevice } from '../server/android/android';
import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher'; import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher';
import { startProfiling, stopProfiling } from '../utils';
export type ClientType = 'controller' | 'playwright' | 'launch-browser' | 'reuse-browser' | 'pre-launched-browser-or-android'; export type ClientType = 'controller' | 'playwright' | 'launch-browser' | 'reuse-browser' | 'pre-launched-browser-or-android';
@ -50,6 +51,7 @@ export class PlaywrightConnection {
private _preLaunched: PreLaunched; private _preLaunched: PreLaunched;
private _options: Options; private _options: Options;
private _root: DispatcherScope; private _root: DispatcherScope;
private _profileName: string;
constructor(lock: Promise<void>, clientType: ClientType, ws: WebSocket, options: Options, preLaunched: PreLaunched, log: (m: string) => void, onClose: () => void) { constructor(lock: Promise<void>, clientType: ClientType, ws: WebSocket, options: Options, preLaunched: PreLaunched, log: (m: string) => void, onClose: () => void) {
this._ws = ws; this._ws = ws;
@ -61,6 +63,7 @@ export class PlaywrightConnection {
assert(preLaunched.browser || preLaunched.androidDevice); assert(preLaunched.browser || preLaunched.androidDevice);
this._onClose = onClose; this._onClose = onClose;
this._debugLog = log; this._debugLog = log;
this._profileName = `${new Date().toISOString()}-${clientType}`;
this._dispatcherConnection = new DispatcherConnection(); this._dispatcherConnection = new DispatcherConnection();
this._dispatcherConnection.onmessage = async message => { this._dispatcherConnection.onmessage = async message => {
@ -82,6 +85,7 @@ export class PlaywrightConnection {
} }
this._root = new RootDispatcher(this._dispatcherConnection, async scope => { this._root = new RootDispatcher(this._dispatcherConnection, async scope => {
await startProfiling();
if (clientType === 'reuse-browser') if (clientType === 'reuse-browser')
return await this._initReuseBrowsersMode(scope); return await this._initReuseBrowsersMode(scope);
if (clientType === 'pre-launched-browser-or-android') if (clientType === 'pre-launched-browser-or-android')
@ -237,6 +241,7 @@ export class PlaywrightConnection {
this._debugLog(`starting cleanup`); this._debugLog(`starting cleanup`);
for (const cleanup of this._cleanups) for (const cleanup of this._cleanups)
await cleanup().catch(() => {}); await cleanup().catch(() => {});
await stopProfiling(this._profileName);
this._onClose(); this._onClose();
this._debugLog(`finished cleanup`); this._debugLog(`finished cleanup`);
} }

View File

@ -29,6 +29,7 @@ export * from './mimeType';
export * from './multimap'; export * from './multimap';
export * from './network'; export * from './network';
export * from './processLauncher'; export * from './processLauncher';
export * from './profiler';
export * from './rtti'; export * from './rtti';
export * from './spawnAsync'; export * from './spawnAsync';
export * from './stackTrace'; export * from './stackTrace';

View File

@ -34,14 +34,14 @@ export async function startProfiling() {
}); });
} }
export async function stopProfiling(processName: string | undefined) { export async function stopProfiling(profileName: string) {
if (!profileDir) if (!profileDir)
return; return;
await new Promise<void>(f => session.post('Profiler.stop', (err, { profile }) => { await new Promise<void>(f => session.post('Profiler.stop', (err, { profile }) => {
if (!err) { if (!err) {
fs.mkdirSync(profileDir, { recursive: true }); fs.mkdirSync(profileDir, { recursive: true });
fs.writeFileSync(path.join(profileDir, (processName || 'runner') + '.json'), JSON.stringify(profile)); fs.writeFileSync(path.join(profileDir, profileName + '.json'), JSON.stringify(profile));
} }
f(); f();
})); }));

View File

@ -20,7 +20,7 @@ import type { Command } from 'playwright-core/lib/utilsBundle';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { Runner } from './runner/runner'; import { Runner } from './runner/runner';
import { stopProfiling, startProfiling } from './common/profiler'; import { stopProfiling, startProfiling } from 'playwright-core/lib/utils';
import { experimentalLoaderOption, fileIsModule } from './util'; import { experimentalLoaderOption, fileIsModule } from './util';
import { showHTMLReport } from './reporters/html'; import { showHTMLReport } from './reporters/html';
import { baseFullConfig, builtInReporters, ConfigLoader, defaultTimeout, kDefaultConfigFiles, resolveConfigFile } from './common/configLoader'; import { baseFullConfig, builtInReporters, ConfigLoader, defaultTimeout, kDefaultConfigFiles, resolveConfigFile } from './common/configLoader';
@ -175,7 +175,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
status = await runner.watchAllTests(); status = await runner.watchAllTests();
else else
status = await runner.runAllTests(); status = await runner.runAllTests();
await stopProfiling(undefined); await stopProfiling('runner');
if (status === 'interrupted') if (status === 'interrupted')
process.exit(130); process.exit(130);
process.exit(status === 'passed' ? 0 : 1); process.exit(status === 'passed' ? 0 : 1);

View File

@ -16,7 +16,7 @@
import type { WriteStream } from 'tty'; import type { WriteStream } from 'tty';
import type { ProcessInitParams, TtyParams } from './ipc'; import type { ProcessInitParams, TtyParams } from './ipc';
import { startProfiling, stopProfiling } from './profiler'; import { startProfiling, stopProfiling } from 'playwright-core/lib/utils';
import type { TestInfoError } from './types'; import type { TestInfoError } from './types';
import { serializeError } from '../util'; import { serializeError } from '../util';