tests/browser/server.py accepts --port 0: it binds 127.0.0.1:0 before building the app, holds that socket for its whole life and prints PM_TEST_SERVER_PORT=<n> to stdout. startBrowserServer defaults to port 0 and reads the announced port, so no port is reserved and released before the server binds and two launchers can no longer race for one. The "address already in use" retry and free-port.mjs are gone; --port N still works and is checked against the announcement.
30 lines
1.3 KiB
JavaScript
30 lines
1.3 KiB
JavaScript
// Shared `test` for the page workflows: every Playwright worker owns one
|
|
// tests/browser/server.py process on a port the OS chose for it, with its own temp root
|
|
// and database. `baseURL` (and so `page`, `request` and `browser.newContext`)
|
|
// points at that worker's server. A server that dies fails the running test
|
|
// with its stderr tail, and the next test in the worker gets a fresh server.
|
|
import { test as base, expect } from '../../tools/vendor/node_modules/@playwright/test/index.mjs';
|
|
import { createServerSupervisor, startBrowserServer } from '../../tools/vendor/start-browser-server.mjs';
|
|
|
|
const SERVER_FIXTURE_TIMEOUT_MS = 90_000;
|
|
|
|
export const test = base.extend({
|
|
testServer: [async ({}, use) => {
|
|
const supervisor = createServerSupervisor({ start: () => startBrowserServer() });
|
|
try {
|
|
await use(supervisor);
|
|
} finally {
|
|
await supervisor.stop();
|
|
}
|
|
}, { scope: 'worker', timeout: SERVER_FIXTURE_TIMEOUT_MS }],
|
|
workerServer: [async ({ testServer }, use) => {
|
|
const server = await testServer.ensure();
|
|
await use(server);
|
|
const crash = testServer.crash(server);
|
|
if (crash) throw crash;
|
|
}, { auto: true, timeout: SERVER_FIXTURE_TIMEOUT_MS }],
|
|
baseURL: async ({ workerServer }, use) => use(workerServer.url),
|
|
});
|
|
|
|
export { expect };
|