From 7a86e140f5ac006e832114630cca3865ddf94761 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 5 Aug 2022 15:24:30 -0700 Subject: [PATCH] chore: remove TestProject.projectSetup (#16321) There are better ideas to address this issue in more general manner. --- docs/src/test-advanced-js.md | 2 - docs/src/test-api/class-testproject.md | 57 ------------------ packages/playwright-test/src/loader.ts | 6 -- packages/playwright-test/src/runner.ts | 69 ++++++++-------------- packages/playwright-test/src/types.ts | 2 - packages/playwright-test/types/test.d.ts | 43 -------------- tests/playwright-test/config.spec.ts | 2 - tests/playwright-test/global-setup.spec.ts | 26 +------- 8 files changed, 25 insertions(+), 182 deletions(-) diff --git a/docs/src/test-advanced-js.md b/docs/src/test-advanced-js.md index ba6532123a..3d7f35cd38 100644 --- a/docs/src/test-advanced-js.md +++ b/docs/src/test-advanced-js.md @@ -359,8 +359,6 @@ test('test', async ({ page }) => { }); ``` -You can also have project-specific setup with [`property: TestProject.projectSetup`]. It will only be executed if at least one test from a specific project should be run, while global setup is always executed at the start of the test session. - ### Capturing trace of failures during global setup In some instances, it may be useful to capture a trace of failures encountered during the global setup. In order to do this, you must [start tracing](./api/class-tracing.md#tracing-start) in your setup, and you must ensure that you [stop tracing](./api/class-tracing.md#tracing-stop) if an error occurs before that error is thrown. This can be achieved by wrapping your setup in a `try...catch` block. Here is an example that expands the global setup example to capture a trace. diff --git a/docs/src/test-api/class-testproject.md b/docs/src/test-api/class-testproject.md index 9cfc039481..8642b7f435 100644 --- a/docs/src/test-api/class-testproject.md +++ b/docs/src/test-api/class-testproject.md @@ -163,63 +163,6 @@ Metadata that will be put directly to the test report serialized as JSON. Project name is visible in the report and during test execution. -## property: TestProject.projectSetup -* since: v1.25 -- type: ?<[string]> - -Path to the project-specifc setup file. This file will be required and run before all the tests from this project. It must export a single function that takes a [`TestConfig`] argument. - -Project setup is similar to [`property: TestConfig.globalSetup`], but it is only executed if at least one test from this particular project should be run. Learn more about [global setup and teardown](../test-advanced.md#global-setup-and-teardown). - -```js tab=js-js -// playwright.config.js -// @ts-check - -/** @type {import('@playwright/test').PlaywrightTestConfig} */ -const config = { - projects: [ - { - name: 'Admin Portal', - projectSetup: './setup-admin', - }, - { - name: 'Customer Portal', - projectSetup: './setup-customer', - }, - ], -}; - -module.exports = config; -``` - -```js tab=js-ts -// playwright.config.ts -import { type PlaywrightTestConfig } from '@playwright/test'; - -const config: PlaywrightTestConfig = { - projects: [ - { - name: 'Admin Portal', - projectSetup: './setup-admin', - }, - { - name: 'Customer Portal', - projectSetup: './setup-customer', - }, - ], -}; -export default config; -``` - -## property: TestProject.projectTeardown -* since: v1.25 -- type: ?<[string]> - -Path to the project-specifc teardown file. This file will be required and run after all the tests from this project. It must export a single function. See also [`property: TestProject.projectSetup`]. - -Project teardown is similar to [`property: TestConfig.globalTeardown`], but it is only executed if at least one test from this particular project did run. Learn more about [global setup and teardown](../test-advanced.md#global-setup-and-teardown). - - ## property: TestProject.screenshotsDir * since: v1.10 * experimental diff --git a/packages/playwright-test/src/loader.ts b/packages/playwright-test/src/loader.ts index dc3f085167..baf3d6a1bd 100644 --- a/packages/playwright-test/src/loader.ts +++ b/packages/playwright-test/src/loader.ts @@ -257,10 +257,6 @@ export class Loader { projectConfig.testDir = path.resolve(this._configDir, projectConfig.testDir); if (projectConfig.outputDir !== undefined) projectConfig.outputDir = path.resolve(this._configDir, projectConfig.outputDir); - if (projectConfig.projectSetup) - projectConfig.projectSetup = resolveScript(projectConfig.projectSetup, this._configDir); - if (projectConfig.projectTeardown) - projectConfig.projectTeardown = resolveScript(projectConfig.projectTeardown, this._configDir); if ((projectConfig as any).screenshotsDir !== undefined) (projectConfig as any).screenshotsDir = path.resolve(this._configDir, (projectConfig as any).screenshotsDir); if (projectConfig.snapshotDir !== undefined) @@ -285,8 +281,6 @@ export class Loader { retries: takeFirst(projectConfig.retries, config.retries, 0), metadata: takeFirst(projectConfig.metadata, config.metadata, undefined), name, - _projectSetup: projectConfig.projectSetup, - _projectTeardown: projectConfig.projectTeardown, testDir, _respectGitIgnore: respectGitIgnore, snapshotDir, diff --git a/packages/playwright-test/src/runner.ts b/packages/playwright-test/src/runner.ts index c16c5e7efd..d76bfdf9c6 100644 --- a/packages/playwright-test/src/runner.ts +++ b/packages/playwright-test/src/runner.ts @@ -394,7 +394,7 @@ export class Runner { // 13. Run Global setup. const result: FullResult = { status: 'passed' }; - const globalTearDown = await this._performGlobalAndProjectSetup(config, rootSuite, [...filesByProject.keys()], result); + const globalTearDown = await this._performGlobalSetup(config, rootSuite, [...filesByProject.keys()], result); if (result.status !== 'passed') return result; @@ -443,7 +443,7 @@ export class Runner { // 4. Run Global setup. const result: FullResult = { status: 'passed' }; - const globalTearDown = await this._performGlobalAndProjectSetup(config, rootSuite, config.projects.filter(p => !options.projectFilter || options.projectFilter.includes(p.name)), result); + const globalTearDown = await this._performGlobalSetup(config, rootSuite, config.projects.filter(p => !options.projectFilter || options.projectFilter.includes(p.name)), result); if (result.status !== 'passed') return result; @@ -576,43 +576,22 @@ export class Runner { return true; } - private async _performGlobalAndProjectSetup(config: FullConfigInternal, rootSuite: Suite, projects: FullProjectInternal[], result: FullResult): Promise<(() => Promise) | undefined> { - type SetupData = { - setupFile?: string | null; - teardownFile?: string | null; - setupResult?: any; - }; - - const setups: SetupData[] = []; - setups.push({ - setupFile: config.globalSetup, - teardownFile: config.globalTeardown, - setupResult: undefined, - }); - for (const project of projects) { - setups.push({ - setupFile: project._projectSetup, - teardownFile: project._projectTeardown, - setupResult: undefined, - }); - } + private async _performGlobalSetup(config: FullConfigInternal, rootSuite: Suite, projects: FullProjectInternal[], result: FullResult): Promise<(() => Promise) | undefined> { + let globalSetupResult: any = undefined; const pluginsThatWereSetUp: TestRunnerPlugin[] = []; const sigintWatcher = new SigIntWatcher(); const tearDown = async () => { - setups.reverse(); - for (const setup of setups) { - await this._runAndReportError(async () => { - if (setup.setupResult && typeof setup.setupResult === 'function') - await setup.setupResult(this._loader.fullConfig()); - }, result); + await this._runAndReportError(async () => { + if (globalSetupResult && typeof globalSetupResult === 'function') + await globalSetupResult(this._loader.fullConfig()); + }, result); - await this._runAndReportError(async () => { - if (setup.setupResult && setup.teardownFile) - await (await this._loader.loadGlobalHook(setup.teardownFile))(this._loader.fullConfig()); - }, result); - } + await this._runAndReportError(async () => { + if (globalSetupResult && config.globalTeardown) + await (await this._loader.loadGlobalHook(config.globalTeardown))(this._loader.fullConfig()); + }, result); for (const plugin of pluginsThatWereSetUp.reverse()) { await this._runAndReportError(async () => { @@ -637,19 +616,17 @@ export class Runner { pluginsThatWereSetUp.push(plugin); } - // Then do global setup and project setups. - for (const setup of setups) { - if (!sigintWatcher.hadSignal()) { - if (setup.setupFile) { - const hook = await this._loader.loadGlobalHook(setup.setupFile); - await Promise.race([ - Promise.resolve().then(() => hook(this._loader.fullConfig())).then((r: any) => setup.setupResult = r || ''), - sigintWatcher.promise(), - ]); - } else { - // Make sure we run the teardown. - setup.setupResult = ''; - } + // Then do global setup. + if (!sigintWatcher.hadSignal()) { + if (config.globalSetup) { + const hook = await this._loader.loadGlobalHook(config.globalSetup); + await Promise.race([ + Promise.resolve().then(() => hook(this._loader.fullConfig())).then((r: any) => globalSetupResult = r || ''), + sigintWatcher.promise(), + ]); + } else { + // Make sure we run the teardown. + globalSetupResult = ''; } } }, result); diff --git a/packages/playwright-test/src/types.ts b/packages/playwright-test/src/types.ts index 79ed39d5b2..cc70699d38 100644 --- a/packages/playwright-test/src/types.ts +++ b/packages/playwright-test/src/types.ts @@ -68,8 +68,6 @@ export interface FullProjectInternal extends FullProjectPublic { _expect: Project['expect']; _screenshotsDir: string; _respectGitIgnore: boolean; - _projectSetup?: string; - _projectTeardown?: string; } export interface ReporterInternal extends Reporter { diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index cc64c88853..e93a98f736 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -4363,49 +4363,6 @@ interface TestProject { */ name?: string; - /** - * Path to the project-specifc setup file. This file will be required and run before all the tests from this project. It - * must export a single function that takes a [`TestConfig`] argument. - * - * Project setup is similar to - * [testConfig.globalSetup](https://playwright.dev/docs/api/class-testconfig#test-config-global-setup), but it is only - * executed if at least one test from this particular project should be run. Learn more about - * [global setup and teardown](https://playwright.dev/docs/test-advanced#global-setup-and-teardown). - * - * ```js - * // playwright.config.ts - * import { type PlaywrightTestConfig } from '@playwright/test'; - * - * const config: PlaywrightTestConfig = { - * projects: [ - * { - * name: 'Admin Portal', - * projectSetup: './setup-admin', - * }, - * { - * name: 'Customer Portal', - * projectSetup: './setup-customer', - * }, - * ], - * }; - * export default config; - * ``` - * - */ - projectSetup?: string; - - /** - * Path to the project-specifc teardown file. This file will be required and run after all the tests from this project. It - * must export a single function. See also - * [testProject.projectSetup](https://playwright.dev/docs/api/class-testproject#test-project-project-setup). - * - * Project teardown is similar to - * [testConfig.globalTeardown](https://playwright.dev/docs/api/class-testconfig#test-config-global-teardown), but it is - * only executed if at least one test from this particular project did run. Learn more about - * [global setup and teardown](https://playwright.dev/docs/test-advanced#global-setup-and-teardown). - */ - projectTeardown?: string; - /** * The base directory, relative to the config file, for snapshot files created with `toMatchSnapshot`. Defaults to * [testProject.testDir](https://playwright.dev/docs/api/class-testproject#test-project-test-dir). diff --git a/tests/playwright-test/config.spec.ts b/tests/playwright-test/config.spec.ts index bdf7263a94..fe7ce22dec 100644 --- a/tests/playwright-test/config.spec.ts +++ b/tests/playwright-test/config.spec.ts @@ -416,8 +416,6 @@ test('should have correct types for the config', async ({ runTSC }) => { projects: [ { name: 'project name', - projectSetup: './projectSetup', - projectTeardown: './projectTeardown', } ], }; diff --git a/tests/playwright-test/global-setup.spec.ts b/tests/playwright-test/global-setup.spec.ts index 635c4c7e7b..6fbb51cbb1 100644 --- a/tests/playwright-test/global-setup.spec.ts +++ b/tests/playwright-test/global-setup.spec.ts @@ -25,8 +25,8 @@ test('globalSetup and globalTeardown should work', async ({ runInlineTest }) => globalSetup: './globalSetup', globalTeardown: path.join(__dirname, 'globalTeardown.ts'), projects: [ - { name: 'p1', projectSetup: './projectSetup1', projectTeardown: './projectTeardown1' }, - { name: 'p2', projectSetup: './projectSetup2', projectTeardown: './projectTeardown2' }, + { name: 'p1' }, + { name: 'p2' }, ] }; `, @@ -40,26 +40,6 @@ test('globalSetup and globalTeardown should work', async ({ runInlineTest }) => console.log('\\n%%from-global-teardown'); }; `, - 'dir/projectSetup1.ts': ` - module.exports = async () => { - console.log('\\n%%from-project-setup-1'); - }; - `, - 'dir/projectTeardown1.ts': ` - module.exports = async () => { - console.log('\\n%%from-project-teardown-1'); - }; - `, - 'dir/projectSetup2.ts': ` - module.exports = async () => { - console.log('\\n%%from-project-setup-2'); - }; - `, - 'dir/projectTeardown2.ts': ` - module.exports = async () => { - console.log('\\n%%from-project-teardown-2'); - }; - `, 'a.test.js': ` const { test } = pwt; test('should work', async ({}, testInfo) => { @@ -71,9 +51,7 @@ test('globalSetup and globalTeardown should work', async ({ runInlineTest }) => expect(result.failed).toBe(0); expect(stripAnsi(result.output).split('\n').filter(line => line.startsWith('%%'))).toEqual([ '%%from-global-setup', - '%%from-project-setup-2', '%%from-test', - '%%from-project-teardown-2', '%%from-global-teardown', ]); });