mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-12 20:03:03 +03:00
test: add basic end-to-end driver test (#5426)
- Introduce internal "out of process" start()/stop() mode. - This mode is used both in regular tests and installation tests. - Emulate basic driver installation, browser download and running.
This commit is contained in:
parent
8500592326
commit
3e7b8e3d74
41
packages/installation-tests/driver-client.js
Normal file
41
packages/installation-tests/driver-client.js
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const { start } = require('playwright/lib/outofprocess.js');
|
||||
|
||||
(async () => {
|
||||
const playwright = await start();
|
||||
console.log(`driver PID=${playwright.driverProcess.pid}`);
|
||||
for (const browserType of ['chromium', 'firefox', 'webkit']) {
|
||||
try {
|
||||
const browser = await playwright[browserType].launch();
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.evaluate(() => navigator.userAgent);
|
||||
await browser.close();
|
||||
console.log(`${browserType} SUCCESS`);
|
||||
} catch (e) {
|
||||
console.error(`Should be able to launch ${browserType} from ${requireName}`);
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
await playwright.stop();
|
||||
console.log(`driver SUCCESS`);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
@ -38,6 +38,7 @@ function copy_test_scripts {
|
||||
cp "${SCRIPTS_PATH}/esm-playwright-webkit.mjs" .
|
||||
cp "${SCRIPTS_PATH}/sanity-electron.js" .
|
||||
cp "${SCRIPTS_PATH}/electron-app.js" .
|
||||
cp "${SCRIPTS_PATH}/driver-client.js" .
|
||||
}
|
||||
|
||||
function run_tests {
|
||||
@ -57,6 +58,7 @@ function run_tests {
|
||||
test_playwright_cli_screenshot_should_work
|
||||
test_playwright_cli_install_should_work
|
||||
test_playwright_cli_codegen_should_work
|
||||
test_playwright_driver_should_work
|
||||
}
|
||||
|
||||
function test_screencast {
|
||||
@ -430,6 +432,21 @@ function test_playwright_cli_codegen_should_work {
|
||||
echo "${FUNCNAME[0]} success"
|
||||
}
|
||||
|
||||
function test_playwright_driver_should_work {
|
||||
initialize_test "${FUNCNAME[0]}"
|
||||
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install ${PLAYWRIGHT_TGZ}
|
||||
|
||||
echo "Running playwright install"
|
||||
PLAYWRIGHT_BROWSERS_PATH="0" npx playwright install
|
||||
|
||||
copy_test_scripts
|
||||
echo "Running driver-client.js"
|
||||
PLAYWRIGHT_BROWSERS_PATH="0" node driver-client.js
|
||||
|
||||
echo "${FUNCNAME[0]} success"
|
||||
}
|
||||
|
||||
function initialize_test {
|
||||
cd ${TEST_ROOT}
|
||||
local TEST_NAME="./$1"
|
||||
|
65
src/outofprocess.ts
Normal file
65
src/outofprocess.ts
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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 { Connection } from './client/connection';
|
||||
import { Transport } from './protocol/transport';
|
||||
import { Playwright } from './client/playwright';
|
||||
import * as childProcess from 'child_process';
|
||||
import * as path from 'path';
|
||||
|
||||
export async function start() {
|
||||
const client = new PlaywrightClient();
|
||||
const playwright = await client._playwright;
|
||||
(playwright as any).stop = () => client.stop();
|
||||
(playwright as any).driverProcess = client._driverProcess;
|
||||
return playwright;
|
||||
}
|
||||
|
||||
class PlaywrightClient {
|
||||
_playwright: Promise<Playwright>;
|
||||
_driverProcess: childProcess.ChildProcess;
|
||||
private _closePromise: Promise<void>;
|
||||
private _onExit: (exitCode: number | null, signal: string | null) => {};
|
||||
|
||||
constructor() {
|
||||
this._onExit = (exitCode: number | null, signal: string | null) => {
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
};
|
||||
|
||||
this._driverProcess = childProcess.fork(path.join(__dirname, 'cli', 'cli.js'), ['run-driver'], {
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
});
|
||||
this._driverProcess.unref();
|
||||
this._driverProcess.on('exit', this._onExit);
|
||||
|
||||
const connection = new Connection();
|
||||
const transport = new Transport(this._driverProcess.stdin, this._driverProcess.stdout);
|
||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||
this._closePromise = new Promise(f => transport.onclose = f);
|
||||
|
||||
this._playwright = connection.waitForObjectWithKnownName('Playwright');
|
||||
}
|
||||
|
||||
async stop() {
|
||||
this._driverProcess.removeListener('exit', this._onExit);
|
||||
this._driverProcess.stdin.destroy();
|
||||
this._driverProcess.stdout.destroy();
|
||||
this._driverProcess.stderr.destroy();
|
||||
await this._closePromise;
|
||||
}
|
||||
}
|
@ -21,12 +21,11 @@ import path from 'path';
|
||||
import util from 'util';
|
||||
import os from 'os';
|
||||
import type { Browser, BrowserContext, BrowserType, Page } from '../index';
|
||||
import { Connection } from '../lib/client/connection';
|
||||
import { Transport } from '../lib/protocol/transport';
|
||||
import { installCoverageHooks } from './coverage';
|
||||
import { folio as httpFolio } from './http.fixtures';
|
||||
import { folio as playwrightFolio } from './playwright.fixtures';
|
||||
import { PlaywrightClient } from '../lib/remote/playwrightClient';
|
||||
import { start } from '../lib/outofprocess';
|
||||
export { expect, config } from 'folio';
|
||||
|
||||
const removeFolderAsync = util.promisify(require('rimraf'));
|
||||
@ -105,25 +104,9 @@ fixtures.playwright.override(async ({ browserName, testWorkerIndex, platform, mo
|
||||
const { coverage, uninstall } = installCoverageHooks(browserName);
|
||||
require('../lib/utils/utils').setUnderTest();
|
||||
if (mode === 'driver') {
|
||||
const connection = new Connection();
|
||||
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'cli', 'cli.js'), ['run-driver'], {
|
||||
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');
|
||||
const playwrightObject = await start();
|
||||
await run(playwrightObject);
|
||||
spawnedProcess.removeListener('exit', onExit);
|
||||
spawnedProcess.stdin.destroy();
|
||||
spawnedProcess.stdout.destroy();
|
||||
spawnedProcess.stderr.destroy();
|
||||
await playwrightObject.stop();
|
||||
await teardownCoverage();
|
||||
} else if (mode === 'service') {
|
||||
const port = 9407 + testWorkerIndex * 2;
|
||||
|
@ -113,6 +113,7 @@ DEPS['src/install/'] = ['src/utils/'];
|
||||
|
||||
// Client depends on chromium protocol for types.
|
||||
DEPS['src/client/'] = ['src/common/', 'src/utils/', 'src/protocol/', 'src/server/chromium/protocol.ts'];
|
||||
DEPS['src/outofprocess.ts'] = ['src/client/', 'src/protocol/'];
|
||||
|
||||
DEPS['src/dispatchers/'] = ['src/common/', 'src/utils/', 'src/protocol/', 'src/server/**'];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user