diff --git a/docs/src/test-api/class-test.md b/docs/src/test-api/class-test.md index bf25a47c44..761e93254f 100644 --- a/docs/src/test-api/class-test.md +++ b/docs/src/test-api/class-test.md @@ -61,7 +61,9 @@ Test function that takes one or two arguments: an object with fixtures and optio ## method: Test.afterAll -Declares an `afterAll` hook that is executed once after all tests. When called in the scope of a test file, runs after all tests in the file. When called inside a [`method: Test.describe`] group, runs after all tests in the group. +Declares an `afterAll` hook that is executed once per worker after all tests. When called in the scope of a test file, runs after all tests in the file. When called inside a [`method: Test.describe`] group, runs after all tests in the group. + +Note that worker process is restarted on test failures, and `afterAll` hook runs again in the new worker. Learn more about [workers and failures](./test-retries.md). ### param: Test.afterAll.hookFunction - `hookFunction` <[function]\([Fixtures], [TestInfo]\)> @@ -116,7 +118,7 @@ Hook function that takes one or two arguments: an object with fixtures and optio ## method: Test.beforeAll -Declares a `beforeAll` hook that is executed once before all tests. When called in the scope of a test file, runs before all tests in the file. When called inside a [`method: Test.describe`] group, runs before all tests in the group. +Declares a `beforeAll` hook that is executed once per worker process before all tests. When called in the scope of a test file, runs before all tests in the file. When called inside a [`method: Test.describe`] group, runs before all tests in the group. ```js js-flavor=js // example.spec.js @@ -152,6 +154,8 @@ test('my test', async ({ page }) => { }); ``` +Note that worker process is restarted on test failures, and `beforeAll` hook runs again in the new worker. Learn more about [workers and failures](./test-retries.md). + You can use [`method: Test.afterAll`] to teardown any resources set up in `beforeAll`. ### param: Test.beforeAll.hookFunction diff --git a/docs/src/test-retries-js.md b/docs/src/test-retries-js.md index c10fb9e46d..a8bbbc42f3 100644 --- a/docs/src/test-retries-js.md +++ b/docs/src/test-retries-js.md @@ -15,6 +15,7 @@ Consider the following snippet: const { test } = require('@playwright/test'); test.describe('suite', () => { + test.beforeAll(async () => { /* ... */ }); test('first good', async ({ page }) => { /* ... */ }); test('second flaky', async ({ page }) => { /* ... */ }); test('third good', async ({ page }) => { /* ... */ }); @@ -25,6 +26,7 @@ test.describe('suite', () => { import { test } from '@playwright/test'; test.describe('suite', () => { + test.beforeAll(async () => { /* ... */ }); test('first good', async ({ page }) => { /* ... */ }); test('second flaky', async ({ page }) => { /* ... */ }); test('third good', async ({ page }) => { /* ... */ }); @@ -33,22 +35,27 @@ test.describe('suite', () => { When **all tests pass**, they will run in order in the same worker process. * Worker process starts + * `beforeAll` hook runs * `first good` passes * `second flaky` passes * `third good` passes Should **any test fail**, Playwright Test will discard the entire worker process along with the browser and will start a new one. Testing will continue in the new worker process starting with the next test. * Worker process #1 starts + * `beforeAll` hook runs * `first good` passes * `second flaky` fails * Worker process #2 starts + * `beforeAll` hook runs again * `third good` passes If you **enable [retries](#retries)**, second worker process will start by retrying the failed test and continue from there. * Worker process #1 starts + * `beforeAll` hook runs * `first good` passes * `second flaky` fails * Worker process #2 starts + * `beforeAll` hook runs again * `second flaky` is retried and passes * `third good` passes @@ -115,6 +122,7 @@ Consider the following snippet that uses `test.describe.serial`: const { test } = require('@playwright/test'); test.describe.serial('suite', () => { + test.beforeAll(async () => { /* ... */ }); test('first good', async ({ page }) => { /* ... */ }); test('second flaky', async ({ page }) => { /* ... */ }); test('third good', async ({ page }) => { /* ... */ }); @@ -125,6 +133,7 @@ test.describe.serial('suite', () => { import { test } from '@playwright/test'; test.describe.serial('suite', () => { + test.beforeAll(async () => { /* ... */ }); test('first good', async ({ page }) => { /* ... */ }); test('second flaky', async ({ page }) => { /* ... */ }); test('third good', async ({ page }) => { /* ... */ }); @@ -133,16 +142,19 @@ test.describe.serial('suite', () => { When running without [retries](#retries), all tests after the failure are skipped: * Worker process #1: + * `beforeAll` hook runs * `first good` passes * `second flaky` fails * `third good` is skipped entirely When running with [retries](#retries), all tests are retried together: * Worker process #1: + * `beforeAll` hook runs * `first good` passes * `second flaky` fails * `third good` is skipped * Worker process #2: + * `beforeAll` hook runs again * `first good` passes again * `second flaky` passes * `third good` passes diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index 8e513f5fd1..b04ede3078 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -2282,8 +2282,8 @@ export interface TestType Promise | any): void; /** - * Declares a `beforeAll` hook that is executed once before all tests. When called in the scope of a test file, runs before - * all tests in the file. When called inside a + * Declares a `beforeAll` hook that is executed once per worker process before all tests. When called in the scope of a + * test file, runs before all tests in the file. When called inside a * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe) group, runs before all tests * in the group. * @@ -2304,16 +2304,22 @@ export interface TestType Promise | any): void; /** - * Declares an `afterAll` hook that is executed once after all tests. When called in the scope of a test file, runs after - * all tests in the file. When called inside a + * Declares an `afterAll` hook that is executed once per worker after all tests. When called in the scope of a test file, + * runs after all tests in the file. When called inside a * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe) group, runs after all tests * in the group. + * + * Note that worker process is restarted on test failures, and `afterAll` hook runs again in the new worker. Learn more + * about [workers and failures](https://playwright.dev/docs/test-retries). * @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo]. */ afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | any): void;