From df5834b7c349dce649f6156b410e5049dcce6ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=8E?= Date: Sun, 29 Oct 2023 20:30:31 +0800 Subject: [PATCH] fix(runner): should allocate and dispose on run --- README.md | 3 +- src/cli/api.ts | 2 +- src/server/Runner.ts | 79 +++++++++++++++++++++++--------------------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index b68d631..9b4920f 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,7 @@ If you want Node.js API, ```ts import { Runner } from 'wrightplay/node'; -// Or manually calling `runner.dispose()` to release resources -await using runner = new Runner({ +const runner = new Runner({ setup: 'test/setup.ts', tests: 'test/**/*.spec.ts', }); diff --git a/src/cli/api.ts b/src/cli/api.ts index ad379c2..414c480 100644 --- a/src/cli/api.ts +++ b/src/cli/api.ts @@ -77,7 +77,7 @@ export const program = command const runnerOptionsList = await parseRunnerOptionsFromCLI(testAndEntries, options); await runnerOptionsList.reduce(async (last, runnerOptions) => { await last; - await using runner = new Runner(runnerOptions); + const runner = new Runner(runnerOptions); const exitCode = await runner.runTests(); process.exitCode ||= exitCode; }, Promise.resolve()); diff --git a/src/server/Runner.ts b/src/server/Runner.ts index f789cb1..b7f76aa 100644 --- a/src/server/Runner.ts +++ b/src/server/Runner.ts @@ -70,9 +70,26 @@ export interface RunnerOptions { export type BrowserServer = playwright.BrowserServer; -export default class Runner implements AsyncDisposable { +export default class Runner { readonly cwd: string; + /** + * File to run before the test files. + */ + readonly setupFile: string | undefined; + + /** + * Test file patterns. + */ + readonly testPatterns: string | string[]; + + /** + * Additional entry points to build. The output name must be explicitly specified. + * You can use this option to build workers. + * @see [Entry points | esbuild - API](https://esbuild.github.io/api/#entry-points) + */ + readonly entryPoints: Record; + /** * Monitor test file changes and trigger automatic test reruns. */ @@ -84,20 +101,16 @@ export default class Runner implements AsyncDisposable { readonly browserType: BrowserTypeName; /** - * Whether to run browser in headless mode. - * @see BrowserServerOptions.headless - */ - readonly headless: boolean; - - /** - * File server for the test files. + * Options used to launch the test browser server. Defaults to the Playwright defaults. + * @see playwright.BrowserType.launchServer */ - readonly testServer: TestServer; + readonly browserServerOptions: BrowserServerOptions; /** - * Browser server launch promise. + * Whether to run browser in headless mode. + * @see BrowserServerOptions.headless */ - readonly browserServerPromise: Promise; + readonly headless: boolean; /** * Directory to save the coverage output file. Defaults to `NODE_V8_COVERAGE` @@ -121,25 +134,19 @@ export default class Runner implements AsyncDisposable { headless = browserServerOptions.headless ?? !browserServerOptions.devtools, noCov = browser !== 'chromium', }: RunnerOptions) { + this.setupFile = setup; + this.testPatterns = tests; + this.entryPoints = entryPoints; this.watch = watch; this.browserType = browser; this.headless = headless; this.cwd = path.resolve(cwd); - this.testServer = new TestServer({ - cwd: this.cwd, - setup, - tests, - entryPoints, - watch, - uuid: this.uuid, - }); - - this.browserServerPromise = playwright[browser].launchServer({ + this.browserServerOptions = { ...browserServerOptions, headless, - }); + }; // Resolve coverage folder. Defaults to NODE_V8_COVERAGE if (!noCov && process.env.NODE_V8_COVERAGE && browser === 'chromium') { @@ -153,11 +160,20 @@ export default class Runner implements AsyncDisposable { async runTests(): Promise { await using stack = new AsyncDisposableStack(); + const testServer = stack.use(new TestServer({ + cwd: this.cwd, + setup: this.setupFile, + tests: this.testPatterns, + entryPoints: this.entryPoints, + watch: this.watch, + uuid: this.uuid, + })); + const [addressInfo, browserServer] = await Promise.all([ - this.testServer.launch(), - this.browserServerPromise, + testServer.launch(), + playwright[this.browserType].launchServer(this.browserServerOptions), ]); - stack.defer(() => this.testServer.close()); + stack.defer(() => browserServer.close()); const browser = await playwright[this.browserType].connect(browserServer.wsEndpoint()); stack.defer(() => browser.close()); @@ -176,7 +192,7 @@ export default class Runner implements AsyncDisposable { const page = await browserContext.newPage(); stack.defer(() => page.close()); - const { cwd, browserType, testServer } = this; + const { cwd, browserType } = this; const { sourceMapPayloads, httpServer } = testServer; const bLog = stack.use(new BrowserLogger({ browserType, @@ -262,15 +278,4 @@ export default class Runner implements AsyncDisposable { return exitCodePromise; } - - async dispose() { - await Promise.all([ - this.browserServerPromise.then((browserServer) => browserServer.close()), - this.testServer[Symbol.asyncDispose](), - ]); - } - - [Symbol.asyncDispose]() { - return this.dispose(); - } }