mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(rpc): run fixtures.jest.js with channel (#3227)
Also, introduce setupInProcess wrapper to be used for in-process rpc.
This commit is contained in:
parent
4961c2ddbb
commit
cefb1b9727
@ -66,6 +66,10 @@ export class Connection {
|
||||
return new Promise(f => this._waitingForObject.set(guid, f));
|
||||
}
|
||||
|
||||
getObjectWithKnownName(guid: string): any {
|
||||
return this._objects.get(guid)!;
|
||||
}
|
||||
|
||||
async sendMessageToServer(type: string, guid: string, method: string, params: any): Promise<any> {
|
||||
const id = ++this._lastId;
|
||||
const validated = method === 'debugScopeState' ? params : validateParams(type, method, params);
|
||||
|
||||
46
src/rpc/inprocess.ts
Normal file
46
src/rpc/inprocess.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DispatcherConnection } from './server/dispatcher';
|
||||
import type { Playwright as PlaywrightImpl } from '../server/playwright';
|
||||
import type { Playwright as PlaywrightAPI } from './client/playwright';
|
||||
import { PlaywrightDispatcher } from './server/playwrightDispatcher';
|
||||
import { setUseApiName } from '../progress';
|
||||
import { Connection } from './client/connection';
|
||||
import { isUnderTest } from '../helper';
|
||||
|
||||
export function setupInProcess(playwright: PlaywrightImpl): PlaywrightAPI {
|
||||
setUseApiName(false);
|
||||
|
||||
const clientConnection = new Connection();
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
|
||||
// Dispatch synchronously at first.
|
||||
dispatcherConnection.onmessage = message => clientConnection.dispatch(message);
|
||||
clientConnection.onmessage = message => dispatcherConnection.dispatch(message);
|
||||
|
||||
// Initialize Playwright channel.
|
||||
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
||||
const playwrightAPI = clientConnection.getObjectWithKnownName('Playwright');
|
||||
|
||||
// Switch to async dispatch after we got Playwright object.
|
||||
dispatcherConnection.onmessage = message => setImmediate(() => clientConnection.dispatch(message));
|
||||
clientConnection.onmessage = message => setImmediate(() => dispatcherConnection.dispatch(message));
|
||||
|
||||
if (isUnderTest())
|
||||
playwrightAPI._toImpl = (x: any) => dispatcherConnection._dispatchers.get(x._guid)!._object;
|
||||
return playwrightAPI;
|
||||
}
|
||||
@ -19,7 +19,7 @@ import * as childProcess from 'child_process';
|
||||
import * as readline from 'readline';
|
||||
import * as removeFolder from 'rimraf';
|
||||
import * as stream from 'stream';
|
||||
import { helper } from '../helper';
|
||||
import { helper, isUnderTest } from '../helper';
|
||||
import { Progress } from '../progress';
|
||||
|
||||
export type Env = {[key: string]: string | number | boolean | undefined};
|
||||
@ -113,7 +113,13 @@ export async function launchProcess(options: LaunchProcessOptions): Promise<Laun
|
||||
const listeners = [ helper.addEventListener(process, 'exit', killProcess) ];
|
||||
if (options.handleSIGINT) {
|
||||
listeners.push(helper.addEventListener(process, 'SIGINT', () => {
|
||||
gracefullyClose().then(() => process.exit(130));
|
||||
gracefullyClose().then(() => {
|
||||
// Give tests a chance to dispatch any async calls.
|
||||
if (isUnderTest())
|
||||
setTimeout(() => process.exit(130), 0);
|
||||
else
|
||||
process.exit(130);
|
||||
});
|
||||
}));
|
||||
}
|
||||
if (options.handleSIGTERM)
|
||||
|
||||
6
test/fixtures/closeme.js
vendored
6
test/fixtures/closeme.js
vendored
@ -9,10 +9,12 @@
|
||||
|
||||
const path = require('path');
|
||||
const { setUnderTest } = require(path.join(playwrightPath, 'lib', 'helper'));
|
||||
const { setupInProcess } = require(path.join(playwrightPath, 'lib', 'rpc', 'inprocess'));
|
||||
setUnderTest();
|
||||
const playwrightFile = path.join(playwrightPath, 'index');
|
||||
const playwrightImpl = require(path.join(playwrightPath, 'index'));
|
||||
const playwright = process.env.PWCHANNEL ? setupInProcess(playwrightImpl) : playwrightImpl;
|
||||
|
||||
const browserServer = await require(playwrightFile)[browserTypeName].launchServer(launchOptions);
|
||||
const browserServer = await playwright[browserTypeName].launchServer(launchOptions);
|
||||
browserServer.on('close', (exitCode, signal) => {
|
||||
console.log(`(exitCode=>${exitCode})`);
|
||||
console.log(`(signal=>${signal})`);
|
||||
|
||||
@ -16,14 +16,12 @@
|
||||
|
||||
const path = require('path');
|
||||
const childProcess = require('child_process');
|
||||
const playwrightImpl = require('../../index');
|
||||
|
||||
const playwright = require('../../index');
|
||||
const { TestServer } = require('../../utils/testserver/');
|
||||
const { DispatcherConnection } = require('../../lib/rpc/server/dispatcher');
|
||||
const { Connection } = require('../../lib/rpc/client/connection');
|
||||
const { Transport } = require('../../lib/rpc/transport');
|
||||
const { PlaywrightDispatcher } = require('../../lib/rpc/server/playwrightDispatcher');
|
||||
const { setUseApiName } = require('../../lib/progress');
|
||||
const { setupInProcess } = require('../../lib/rpc/inprocess');
|
||||
const { setUnderTest } = require('../../lib/helper');
|
||||
setUnderTest();
|
||||
|
||||
@ -80,57 +78,38 @@ module.exports = function registerFixtures(global) {
|
||||
});
|
||||
|
||||
global.registerWorkerFixture('playwright', async({}, test) => {
|
||||
Error.stackTraceLimit = 15;
|
||||
if (process.env.PWCHANNEL) {
|
||||
setUseApiName(false);
|
||||
if (process.env.PWCHANNEL === 'wire') {
|
||||
const connection = new Connection();
|
||||
let toImpl;
|
||||
let spawnedProcess;
|
||||
let onExit;
|
||||
if (process.env.PWCHANNEL === 'wire') {
|
||||
spawnedProcess = childProcess.fork(path.join(__dirname, '..', '..', 'lib', 'rpc', 'server'), [], {
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
});
|
||||
spawnedProcess.unref();
|
||||
onExit = (exitCode, signal) => {
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
};
|
||||
spawnedProcess.on('exit', onExit);
|
||||
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||
} else {
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
dispatcherConnection.onmessage = async message => {
|
||||
setImmediate(() => connection.dispatch(message));
|
||||
};
|
||||
connection.onmessage = async message => {
|
||||
const result = await dispatcherConnection.dispatch(message);
|
||||
await new Promise(f => setImmediate(f));
|
||||
return result;
|
||||
};
|
||||
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
||||
toImpl = x => dispatcherConnection._dispatchers.get(x._guid)._object;
|
||||
}
|
||||
|
||||
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', '..', 'lib', 'rpc', 'server'), [], {
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
});
|
||||
spawnedProcess.unref();
|
||||
const onExit = (exitCode, signal) => {
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
};
|
||||
spawnedProcess.on('exit', onExit);
|
||||
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||
const playwrightObject = await connection.waitForObjectWithKnownName('Playwright');
|
||||
playwrightObject.toImpl = toImpl;
|
||||
await test(playwrightObject);
|
||||
if (spawnedProcess) {
|
||||
spawnedProcess.removeListener('exit', onExit);
|
||||
spawnedProcess.stdin.destroy();
|
||||
spawnedProcess.stdout.destroy();
|
||||
spawnedProcess.stderr.destroy();
|
||||
}
|
||||
spawnedProcess.removeListener('exit', onExit);
|
||||
spawnedProcess.stdin.destroy();
|
||||
spawnedProcess.stdout.destroy();
|
||||
spawnedProcess.stderr.destroy();
|
||||
} else if (process.env.PWCHANNEL) {
|
||||
const playwright = setupInProcess(playwrightImpl);
|
||||
await test(playwright);
|
||||
} else {
|
||||
playwright.toImpl = x => x;
|
||||
const playwright = playwrightImpl;
|
||||
playwright._toImpl = x => x;
|
||||
await test(playwright);
|
||||
}
|
||||
});
|
||||
|
||||
global.registerFixture('toImpl', async ({playwright}, test) => {
|
||||
await test(playwright.toImpl);
|
||||
await test(playwright._toImpl);
|
||||
});
|
||||
|
||||
global.registerWorkerFixture('browserType', async ({playwright}, test) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user