test: rework port forwarding server tests to launch server out of process (#7693)

This commit is contained in:
Max Schmitt 2021-07-19 07:53:12 +02:00 committed by GitHub
parent 66ea613c4d
commit 2ff25522cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 12 deletions

View file

@ -243,7 +243,7 @@ if (!process.env.PW_CLI_TARGET_LANG) {
if (process.argv[2] === 'run-driver')
runDriver();
else if (process.argv[2] === 'run-server')
runServer(process.argv[3] ? +process.argv[3] : undefined);
runServer(process.argv[3] ? +process.argv[3] : undefined, process.argv[4]).catch(logErrorAndExit);
else if (process.argv[2] === 'print-api-json')
printApiJson();
else if (process.argv[2] === 'launch-server')

View file

@ -23,7 +23,7 @@ import { LaunchServerOptions } from '../client/types';
import { DispatcherConnection } from '../dispatchers/dispatcher';
import { PlaywrightDispatcher } from '../dispatchers/playwrightDispatcher';
import { Transport } from '../protocol/transport';
import { PlaywrightServer } from '../remote/playwrightServer';
import { PlaywrightServer, PlaywrightServerOptions } from '../remote/playwrightServer';
import { createPlaywright } from '../server/playwright';
import { gracefullyCloseAll } from '../utils/processLauncher';
@ -51,8 +51,13 @@ export function runDriver() {
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
}
export async function runServer(port: number | undefined) {
const wsEndpoint = await (await PlaywrightServer.startDefault()).listen(port);
export async function runServer(port: number | undefined, configFile?: string) {
let options: PlaywrightServerOptions = {};
if (configFile)
options = JSON.parse(fs.readFileSync(configFile).toString());
const server = await PlaywrightServer.startDefault(options);
const wsEndpoint = await server.listen(port);
process.on('exit', () => server.close().catch(console.error));
console.log('Listening on ' + wsEndpoint); // eslint-disable-line no-console
}

View file

@ -14,16 +14,51 @@
* limitations under the License.
*/
import childProcess from 'child_process';
import http from 'http';
import path from 'path';
import os from 'os';
import fs from 'fs';
import net from 'net';
import { PlaywrightClient } from '../lib/remote/playwrightClient';
import { PlaywrightServer } from '../lib/remote/playwrightServer';
import { contextTest, expect } from './config/browserTest';
import { PlaywrightClient } from '../lib/remote/playwrightClient';
import { createGuid } from '../src/utils/utils';
import type { PlaywrightServerOptions } from '../src/remote/playwrightServer';
import type { LaunchOptions, ConnectOptions } from '../index';
import type { Page, BrowserServer } from '..';
class OutOfProcessPlaywrightServer {
private _driverProcess: childProcess.ChildProcess;
private _receivedPortPromise: Promise<string>;
constructor(port: number, config: PlaywrightServerOptions) {
const configFile = path.join(os.tmpdir(), `playwright-server-config-${createGuid()}.json`);
fs.writeFileSync(configFile, JSON.stringify(config));
this._driverProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'cli', 'cli.js'), ['run-server', port.toString(), configFile], {
stdio: 'pipe',
detached: true,
});
this._driverProcess.unref();
this._receivedPortPromise = new Promise<string>((resolve, reject) => {
this._driverProcess.stdout.on('data', (data: Buffer) => {
const prefix = 'Listening on ';
const line = data.toString();
if (line.startsWith(prefix))
resolve(line.substr(prefix.length));
});
this._driverProcess.on('exit', () => reject());
});
}
async kill() {
const waitForExit = new Promise<void>(resolve => this._driverProcess.on('exit', () => resolve()));
this._driverProcess.kill('SIGKILL');
await waitForExit;
}
public async wsEndpoint(): Promise<string> {
return await this._receivedPortPromise;
}
}
type PageFactoryOptions = {
acceptForwardedPorts: boolean
forwardPorts: number[]
@ -35,17 +70,16 @@ const it = contextTest.extend<{ pageFactory: (options?: PageFactoryOptions) => P
launchMode: [ 'launchServer', { scope: 'test' }],
pageFactory: async ({ launchMode, browserType, browserName, browserOptions }, run) => {
const browserServers: BrowserServer[] = [];
const playwrightServers: PlaywrightServer[] = [];
const playwrightServers: OutOfProcessPlaywrightServer[] = [];
await run(async (options?: PageFactoryOptions): Promise<Page> => {
const { acceptForwardedPorts, forwardPorts } = options;
if (launchMode === 'playwrightclient') {
const server = await PlaywrightServer.startDefault({
const server = new OutOfProcessPlaywrightServer(0, {
acceptForwardedPorts,
});
playwrightServers.push(server);
const wsEndpoint = await server.listen(0);
const service = await PlaywrightClient.connect({
wsEndpoint,
wsEndpoint: await server.wsEndpoint(),
forwardPorts,
});
const playwright = service.playwright();
@ -66,7 +100,7 @@ const it = contextTest.extend<{ pageFactory: (options?: PageFactoryOptions) => P
for (const browserServer of browserServers)
await browserServer.close();
for (const playwrightServer of playwrightServers)
await playwrightServer.close();
await playwrightServer.kill();
},
});