test: rework port forwarding server tests to launch server out of process (#7693)
This commit is contained in:
parent
66ea613c4d
commit
2ff25522cc
|
|
@ -243,7 +243,7 @@ if (!process.env.PW_CLI_TARGET_LANG) {
|
||||||
if (process.argv[2] === 'run-driver')
|
if (process.argv[2] === 'run-driver')
|
||||||
runDriver();
|
runDriver();
|
||||||
else if (process.argv[2] === 'run-server')
|
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')
|
else if (process.argv[2] === 'print-api-json')
|
||||||
printApiJson();
|
printApiJson();
|
||||||
else if (process.argv[2] === 'launch-server')
|
else if (process.argv[2] === 'launch-server')
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { LaunchServerOptions } from '../client/types';
|
||||||
import { DispatcherConnection } from '../dispatchers/dispatcher';
|
import { DispatcherConnection } from '../dispatchers/dispatcher';
|
||||||
import { PlaywrightDispatcher } from '../dispatchers/playwrightDispatcher';
|
import { PlaywrightDispatcher } from '../dispatchers/playwrightDispatcher';
|
||||||
import { Transport } from '../protocol/transport';
|
import { Transport } from '../protocol/transport';
|
||||||
import { PlaywrightServer } from '../remote/playwrightServer';
|
import { PlaywrightServer, PlaywrightServerOptions } from '../remote/playwrightServer';
|
||||||
import { createPlaywright } from '../server/playwright';
|
import { createPlaywright } from '../server/playwright';
|
||||||
import { gracefullyCloseAll } from '../utils/processLauncher';
|
import { gracefullyCloseAll } from '../utils/processLauncher';
|
||||||
|
|
||||||
|
|
@ -51,8 +51,13 @@ export function runDriver() {
|
||||||
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runServer(port: number | undefined) {
|
export async function runServer(port: number | undefined, configFile?: string) {
|
||||||
const wsEndpoint = await (await PlaywrightServer.startDefault()).listen(port);
|
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
|
console.log('Listening on ' + wsEndpoint); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,51 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import childProcess from 'child_process';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
|
import path from 'path';
|
||||||
|
import os from 'os';
|
||||||
|
import fs from 'fs';
|
||||||
import net from 'net';
|
import net from 'net';
|
||||||
|
|
||||||
import { PlaywrightClient } from '../lib/remote/playwrightClient';
|
|
||||||
import { PlaywrightServer } from '../lib/remote/playwrightServer';
|
|
||||||
|
|
||||||
import { contextTest, expect } from './config/browserTest';
|
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 { LaunchOptions, ConnectOptions } from '../index';
|
||||||
import type { Page, BrowserServer } from '..';
|
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 = {
|
type PageFactoryOptions = {
|
||||||
acceptForwardedPorts: boolean
|
acceptForwardedPorts: boolean
|
||||||
forwardPorts: number[]
|
forwardPorts: number[]
|
||||||
|
|
@ -35,17 +70,16 @@ const it = contextTest.extend<{ pageFactory: (options?: PageFactoryOptions) => P
|
||||||
launchMode: [ 'launchServer', { scope: 'test' }],
|
launchMode: [ 'launchServer', { scope: 'test' }],
|
||||||
pageFactory: async ({ launchMode, browserType, browserName, browserOptions }, run) => {
|
pageFactory: async ({ launchMode, browserType, browserName, browserOptions }, run) => {
|
||||||
const browserServers: BrowserServer[] = [];
|
const browserServers: BrowserServer[] = [];
|
||||||
const playwrightServers: PlaywrightServer[] = [];
|
const playwrightServers: OutOfProcessPlaywrightServer[] = [];
|
||||||
await run(async (options?: PageFactoryOptions): Promise<Page> => {
|
await run(async (options?: PageFactoryOptions): Promise<Page> => {
|
||||||
const { acceptForwardedPorts, forwardPorts } = options;
|
const { acceptForwardedPorts, forwardPorts } = options;
|
||||||
if (launchMode === 'playwrightclient') {
|
if (launchMode === 'playwrightclient') {
|
||||||
const server = await PlaywrightServer.startDefault({
|
const server = new OutOfProcessPlaywrightServer(0, {
|
||||||
acceptForwardedPorts,
|
acceptForwardedPorts,
|
||||||
});
|
});
|
||||||
playwrightServers.push(server);
|
playwrightServers.push(server);
|
||||||
const wsEndpoint = await server.listen(0);
|
|
||||||
const service = await PlaywrightClient.connect({
|
const service = await PlaywrightClient.connect({
|
||||||
wsEndpoint,
|
wsEndpoint: await server.wsEndpoint(),
|
||||||
forwardPorts,
|
forwardPorts,
|
||||||
});
|
});
|
||||||
const playwright = service.playwright();
|
const playwright = service.playwright();
|
||||||
|
|
@ -66,7 +100,7 @@ const it = contextTest.extend<{ pageFactory: (options?: PageFactoryOptions) => P
|
||||||
for (const browserServer of browserServers)
|
for (const browserServer of browserServers)
|
||||||
await browserServer.close();
|
await browserServer.close();
|
||||||
for (const playwrightServer of playwrightServers)
|
for (const playwrightServer of playwrightServers)
|
||||||
await playwrightServer.close();
|
await playwrightServer.kill();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue