mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat: add title for before and after hooks (#26523)
This commit is contained in:
parent
2f6148bcd1
commit
bcc30bc71e
@ -137,7 +137,7 @@ test.describe('Playwright homepage', () => {
|
|||||||
1. Each Playwright Test file has explicit import of the `test` and `expect` functions
|
1. Each Playwright Test file has explicit import of the `test` and `expect` functions
|
||||||
1. Test function is marked with `async`
|
1. Test function is marked with `async`
|
||||||
1. Playwright Test is given a `page` as one of its parameters. This is one of the many [useful fixtures](./api/class-fixtures) in Playwright Test.
|
1. Playwright Test is given a `page` as one of its parameters. This is one of the many [useful fixtures](./api/class-fixtures) in Playwright Test.
|
||||||
Playwright Test creates an isolated [Page] object for each test. However, if you'd like to reuse a single [Page] object between multiple tests, you can create your own in [`method: Test.beforeAll`] and close it in [`method: Test.afterAll`].
|
Playwright Test creates an isolated [Page] object for each test. However, if you'd like to reuse a single [Page] object between multiple tests, you can create your own in [`method: Test.beforeAll#1`] and close it in [`method: Test.afterAll#1`].
|
||||||
1. Locator creation with [`method: Page.locator`] is one of the few methods that is sync.
|
1. Locator creation with [`method: Page.locator`] is one of the few methods that is sync.
|
||||||
1. Use [assertions](./test-assertions) to verify the state instead of `page.$eval()`.
|
1. Use [assertions](./test-assertions) to verify the state instead of `page.$eval()`.
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Test function that takes one or two arguments: an object with fixtures and optio
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## method: Test.afterAll
|
## method: Test.afterAll#1
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
|
|
||||||
Declares an `afterAll` hook that is executed once per worker after all tests.
|
Declares an `afterAll` hook that is executed once per worker after all tests.
|
||||||
@ -64,15 +64,42 @@ test.afterAll(async () => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### param: Test.afterAll.hookFunction
|
### param: Test.afterAll#1.hookFunction
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.afterAll#2
|
||||||
|
* since: v1.38
|
||||||
|
|
||||||
## method: Test.afterEach
|
Declares an `afterAll` hook with a title that is executed once per worker after all tests.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
|
||||||
|
```js
|
||||||
|
test.afterAll('Teardown', async () => {
|
||||||
|
console.log('Done with tests');
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: Test.afterAll#2.title
|
||||||
|
* since: v1.38
|
||||||
|
- `title` <[string]>
|
||||||
|
|
||||||
|
Hook title.
|
||||||
|
|
||||||
|
### param: Test.afterAll#2.hookFunction
|
||||||
|
* since: v1.38
|
||||||
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
|
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.afterEach#1
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
|
|
||||||
Declares an `afterEach` hook that is executed after each test.
|
Declares an `afterEach` hook that is executed after each test.
|
||||||
@ -100,14 +127,50 @@ test('my test', async ({ page }) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### param: Test.afterEach.hookFunction
|
### param: Test.afterEach#1.hookFunction
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
## method: Test.beforeAll
|
## method: Test.afterEach#2
|
||||||
|
* since: v1.38
|
||||||
|
|
||||||
|
Declares an `afterEach` hook with a title that is executed after each test.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
|
||||||
|
```js title="example.spec.ts"
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.afterEach('Status check', async ({ page }, testInfo) => {
|
||||||
|
console.log(`Finished ${testInfo.title} with status ${testInfo.status}`);
|
||||||
|
|
||||||
|
if (testInfo.status !== testInfo.expectedStatus)
|
||||||
|
console.log(`Did not run as expected, ended up at ${page.url()}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('my test', async ({ page }) => {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: Test.afterEach#2.title
|
||||||
|
* since: v1.38
|
||||||
|
- `title` <[string]>
|
||||||
|
|
||||||
|
Hook title.
|
||||||
|
|
||||||
|
### param: Test.afterEach#2.hookFunction
|
||||||
|
* since: v1.38
|
||||||
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
|
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.beforeAll#1
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
|
|
||||||
Declares a `beforeAll` hook that is executed once per worker process before all tests.
|
Declares a `beforeAll` hook that is executed once per worker process before all tests.
|
||||||
@ -118,7 +181,7 @@ When called in the scope of a test file, runs before all tests in the file. When
|
|||||||
|
|
||||||
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).
|
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`.
|
You can use [`method: Test.afterAll#1`] to teardown any resources set up in `beforeAll`.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
@ -138,15 +201,47 @@ test('my test', async ({ page }) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### param: Test.beforeAll.hookFunction
|
### param: Test.beforeAll#1.hookFunction
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.beforeAll#2
|
||||||
|
* since: v1.38
|
||||||
|
|
||||||
## method: Test.beforeEach
|
Declares a `beforeAll` hook with a title that is executed once per worker process before all tests.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
|
||||||
|
```js title="example.spec.ts"
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.beforeAll('Setup', async () => {
|
||||||
|
console.log('Before tests');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('my test', async ({ page }) => {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: Test.beforeAll#2.title
|
||||||
|
* since: v1.38
|
||||||
|
- `title` <[string]>
|
||||||
|
|
||||||
|
Hook title.
|
||||||
|
|
||||||
|
### param: Test.beforeAll#2.hookFunction
|
||||||
|
* since: v1.38
|
||||||
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
|
Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.beforeEach#1
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
|
|
||||||
Declares a `beforeEach` hook that is executed before each test.
|
Declares a `beforeEach` hook that is executed before each test.
|
||||||
@ -157,7 +252,7 @@ When called in the scope of a test file, runs before each test in the file. When
|
|||||||
|
|
||||||
You can access all the same [Fixtures] as the test function itself, and also the [TestInfo] object that gives a lot of useful information. For example, you can navigate the page before starting the test.
|
You can access all the same [Fixtures] as the test function itself, and also the [TestInfo] object that gives a lot of useful information. For example, you can navigate the page before starting the test.
|
||||||
|
|
||||||
You can use [`method: Test.afterEach`] to teardown any resources set up in `beforeEach`.
|
You can use [`method: Test.afterEach#1`] to teardown any resources set up in `beforeEach`.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
@ -174,13 +269,45 @@ test('my test', async ({ page }) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### param: Test.beforeEach.hookFunction
|
### param: Test.beforeEach#1.hookFunction
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
## method: Test.beforeEach#2
|
||||||
|
* since: v1.38
|
||||||
|
|
||||||
|
Declares a `beforeEach` hook with a title that is executed before each test.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
|
||||||
|
```js title="example.spec.ts"
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.beforeEach('Open start URL', async ({ page }, testInfo) => {
|
||||||
|
console.log(`Running ${testInfo.title}`);
|
||||||
|
await page.goto('https://my.start.url/');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('my test', async ({ page }) => {
|
||||||
|
expect(page.url()).toBe('https://my.start.url/');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: Test.beforeEach#2.title
|
||||||
|
* since: v1.38
|
||||||
|
- `title` <[string]>
|
||||||
|
|
||||||
|
Hook title.
|
||||||
|
|
||||||
|
### param: Test.beforeEach#2.hookFunction
|
||||||
|
* since: v1.38
|
||||||
|
- `hookFunction` <[function]\([Fixtures], [TestInfo]\)>
|
||||||
|
|
||||||
|
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## method: Test.describe#1
|
## method: Test.describe#1
|
||||||
@ -1057,7 +1184,7 @@ test('skip in WebKit', async ({ page, browserName }) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Skip from [`method: Test.beforeEach`] hook:
|
Skip from [`method: Test.beforeEach#1`] hook:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* since: v1.10
|
* since: v1.10
|
||||||
* langs: js
|
* langs: js
|
||||||
|
|
||||||
`TestInfo` contains information about currently running test. It is available to test functions, [`method: Test.beforeEach`], [`method: Test.afterEach`], [`method: Test.beforeAll`] and [`method: Test.afterAll`] hooks, and test-scoped fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine which test is currently running and whether it was retried, etc.
|
`TestInfo` contains information about currently running test. It is available to test functions, [`method: Test.beforeEach#1`], [`method: Test.afterEach#1`], [`method: Test.beforeAll#1`] and [`method: Test.afterAll#1`] hooks, and test-scoped fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine which test is currently running and whether it was retried, etc.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
@ -115,7 +115,7 @@ Processed configuration from the [configuration file](../test-configuration.md).
|
|||||||
* since: v1.10
|
* since: v1.10
|
||||||
- type: <[int]>
|
- type: <[int]>
|
||||||
|
|
||||||
The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not. Can be used in [`method: Test.afterEach`] hook.
|
The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not. Can be used in [`method: Test.afterEach#1`] hook.
|
||||||
|
|
||||||
|
|
||||||
## property: TestInfo.error
|
## property: TestInfo.error
|
||||||
@ -403,7 +403,7 @@ Suffix used to differentiate snapshots between multiple test configurations. For
|
|||||||
* since: v1.10
|
* since: v1.10
|
||||||
- type: ?<[TestStatus]<"passed"|"failed"|"timedOut"|"skipped"|"interrupted">>
|
- type: ?<[TestStatus]<"passed"|"failed"|"timedOut"|"skipped"|"interrupted">>
|
||||||
|
|
||||||
Actual status for the currently running test. Available after the test has finished in [`method: Test.afterEach`] hook and fixtures.
|
Actual status for the currently running test. Available after the test has finished in [`method: Test.afterEach#1`] hook and fixtures.
|
||||||
|
|
||||||
Status is usually compared with the [`property: TestInfo.expectedStatus`]:
|
Status is usually compared with the [`property: TestInfo.expectedStatus`]:
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ It is usually better to make your tests isolated, so they can be efficiently run
|
|||||||
|
|
||||||
## Reuse single page between tests
|
## Reuse single page between tests
|
||||||
|
|
||||||
Playwright Test creates an isolated [Page] object for each test. However, if you'd like to reuse a single [Page] object between multiple tests, you can create your own in [`method: Test.beforeAll`] and close it in [`method: Test.afterAll`].
|
Playwright Test creates an isolated [Page] object for each test. However, if you'd like to reuse a single [Page] object between multiple tests, you can create your own in [`method: Test.beforeAll#1`] and close it in [`method: Test.afterAll#1`].
|
||||||
|
|
||||||
```js tab=js-js title="example.spec.js"
|
```js tab=js-js title="example.spec.js"
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
@ -45,7 +45,7 @@ export class Suite extends Base implements SuitePrivate {
|
|||||||
parent?: Suite;
|
parent?: Suite;
|
||||||
_use: FixturesWithLocation[] = [];
|
_use: FixturesWithLocation[] = [];
|
||||||
_entries: (Suite | TestCase)[] = [];
|
_entries: (Suite | TestCase)[] = [];
|
||||||
_hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, location: Location }[] = [];
|
_hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, title: string, location: Location }[] = [];
|
||||||
_timeout: number | undefined;
|
_timeout: number | undefined;
|
||||||
_retries: number | undefined;
|
_retries: number | undefined;
|
||||||
_staticAnnotations: Annotation[] = [];
|
_staticAnnotations: Annotation[] = [];
|
||||||
@ -187,7 +187,7 @@ export class Suite extends Base implements SuitePrivate {
|
|||||||
staticAnnotations: this._staticAnnotations.slice(),
|
staticAnnotations: this._staticAnnotations.slice(),
|
||||||
modifiers: this._modifiers.slice(),
|
modifiers: this._modifiers.slice(),
|
||||||
parallelMode: this._parallelMode,
|
parallelMode: this._parallelMode,
|
||||||
hooks: this._hooks.map(h => ({ type: h.type, location: h.location })),
|
hooks: this._hooks.map(h => ({ type: h.type, location: h.location, title: h.title })),
|
||||||
fileId: this._fileId,
|
fileId: this._fileId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ export class Suite extends Base implements SuitePrivate {
|
|||||||
suite._staticAnnotations = data.staticAnnotations;
|
suite._staticAnnotations = data.staticAnnotations;
|
||||||
suite._modifiers = data.modifiers;
|
suite._modifiers = data.modifiers;
|
||||||
suite._parallelMode = data.parallelMode;
|
suite._parallelMode = data.parallelMode;
|
||||||
suite._hooks = data.hooks.map((h: any) => ({ type: h.type, location: h.location, fn: () => { } }));
|
suite._hooks = data.hooks.map((h: any) => ({ type: h.type, location: h.location, title: h.title, fn: () => { } }));
|
||||||
suite._fileId = data.fileId;
|
suite._fileId = data.fileId;
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
@ -134,11 +134,16 @@ export class TestTypeImpl {
|
|||||||
setCurrentlyLoadingFileSuite(suite);
|
setCurrentlyLoadingFileSuite(suite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, fn: Function) {
|
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, title: string | Function, fn?: Function) {
|
||||||
const suite = this._currentSuite(location, `test.${name}()`);
|
const suite = this._currentSuite(location, `test.${name}()`);
|
||||||
if (!suite)
|
if (!suite)
|
||||||
return;
|
return;
|
||||||
suite._hooks.push({ type: name, fn, location });
|
if (typeof title === 'function') {
|
||||||
|
fn = title;
|
||||||
|
title = `${name} hook`;
|
||||||
|
}
|
||||||
|
|
||||||
|
suite._hooks.push({ type: name, fn: fn!, title, location });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _configure(location: Location, options: { mode?: 'default' | 'parallel' | 'serial', retries?: number, timeout?: number }) {
|
private _configure(location: Location, options: { mode?: 'default' | 'parallel' | 'serial', retries?: number, timeout?: number }) {
|
||||||
|
@ -528,7 +528,7 @@ export class WorkerMain extends ProcessRunner {
|
|||||||
testInfo._timeoutManager.setCurrentRunnable({ type: 'beforeAll', location: hook.location, slot: timeSlot });
|
testInfo._timeoutManager.setCurrentRunnable({ type: 'beforeAll', location: hook.location, slot: timeSlot });
|
||||||
await testInfo._runAsStep({
|
await testInfo._runAsStep({
|
||||||
category: 'hook',
|
category: 'hook',
|
||||||
title: `${hook.type} hook`,
|
title: `${hook.title}`,
|
||||||
location: hook.location,
|
location: hook.location,
|
||||||
}, async () => {
|
}, async () => {
|
||||||
try {
|
try {
|
||||||
@ -564,7 +564,7 @@ export class WorkerMain extends ProcessRunner {
|
|||||||
testInfo._timeoutManager.setCurrentRunnable({ type: 'afterAll', location: hook.location, slot: timeSlot });
|
testInfo._timeoutManager.setCurrentRunnable({ type: 'afterAll', location: hook.location, slot: timeSlot });
|
||||||
await testInfo._runAsStep({
|
await testInfo._runAsStep({
|
||||||
category: 'hook',
|
category: 'hook',
|
||||||
title: `${hook.type} hook`,
|
title: `${hook.title}`,
|
||||||
location: hook.location,
|
location: hook.location,
|
||||||
}, async () => {
|
}, async () => {
|
||||||
try {
|
try {
|
||||||
@ -590,7 +590,7 @@ export class WorkerMain extends ProcessRunner {
|
|||||||
testInfo._timeoutManager.setCurrentRunnable({ type, location: hook.location, slot: timeSlot });
|
testInfo._timeoutManager.setCurrentRunnable({ type, location: hook.location, slot: timeSlot });
|
||||||
await testInfo._runAsStep({
|
await testInfo._runAsStep({
|
||||||
category: 'hook',
|
category: 'hook',
|
||||||
title: `${hook.type} hook`,
|
title: `${hook.title}`,
|
||||||
location: hook.location,
|
location: hook.location,
|
||||||
}, () => this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo, 'test'));
|
}, () => this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo, 'test'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
106
packages/playwright-test/types/test.d.ts
vendored
106
packages/playwright-test/types/test.d.ts
vendored
@ -1900,10 +1900,10 @@ export interface WorkerInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* `TestInfo` contains information about currently running test. It is available to test functions,
|
* `TestInfo` contains information about currently running test. It is available to test functions,
|
||||||
* [test.beforeEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-each),
|
* [test.beforeEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-each-1),
|
||||||
* [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each),
|
* [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each-1),
|
||||||
* [test.beforeAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-all) and
|
* [test.beforeAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-all-1) and
|
||||||
* [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all) hooks, and test-scoped
|
* [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all-1) hooks, and test-scoped
|
||||||
* fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine
|
* fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine
|
||||||
* which test is currently running and whether it was retried, etc.
|
* which test is currently running and whether it was retried, etc.
|
||||||
*
|
*
|
||||||
@ -2150,7 +2150,7 @@ export interface TestInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or
|
* The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or
|
||||||
* not. Can be used in [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each)
|
* not. Can be used in [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each-1)
|
||||||
* hook.
|
* hook.
|
||||||
*/
|
*/
|
||||||
duration: number;
|
duration: number;
|
||||||
@ -2274,7 +2274,7 @@ export interface TestInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Actual status for the currently running test. Available after the test has finished in
|
* Actual status for the currently running test. Available after the test has finished in
|
||||||
* [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each) hook and fixtures.
|
* [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each-1) hook and fixtures.
|
||||||
*
|
*
|
||||||
* Status is usually compared with the
|
* Status is usually compared with the
|
||||||
* [testInfo.expectedStatus](https://playwright.dev/docs/api/class-testinfo#test-info-expected-status):
|
* [testInfo.expectedStatus](https://playwright.dev/docs/api/class-testinfo#test-info-expected-status):
|
||||||
@ -2746,7 +2746,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Skip from [test.beforeEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-each) hook:
|
* Skip from [test.beforeEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-before-each-1) hook:
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* import { test, expect } from '@playwright/test';
|
* import { test, expect } from '@playwright/test';
|
||||||
@ -3071,8 +3071,8 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* You can access all the same {@link Fixtures} as the test function itself, and also the {@link TestInfo} object that
|
* You can access all the same {@link Fixtures} as the test function itself, and also the {@link TestInfo} object that
|
||||||
* gives a lot of useful information. For example, you can navigate the page before starting the test.
|
* gives a lot of useful information. For example, you can navigate the page before starting the test.
|
||||||
*
|
*
|
||||||
* You can use [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each) to teardown
|
* You can use [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each-1) to
|
||||||
* any resources set up in `beforeEach`.
|
* teardown any resources set up in `beforeEach`.
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
@ -3093,6 +3093,29 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
||||||
*/
|
*/
|
||||||
beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
/**
|
||||||
|
* Declares a `beforeEach` hook with a title that is executed before each test.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // example.spec.ts
|
||||||
|
* import { test, expect } from '@playwright/test';
|
||||||
|
*
|
||||||
|
* test.beforeEach('Open start URL', async ({ page }, testInfo) => {
|
||||||
|
* console.log(`Running ${testInfo.title}`);
|
||||||
|
* await page.goto('https://my.start.url/');
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* test('my test', async ({ page }) => {
|
||||||
|
* expect(page.url()).toBe('https://my.start.url/');
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param title Hook title.
|
||||||
|
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
||||||
|
*/
|
||||||
|
beforeEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
/**
|
/**
|
||||||
* Declares an `afterEach` hook that is executed after each test.
|
* Declares an `afterEach` hook that is executed after each test.
|
||||||
*
|
*
|
||||||
@ -3126,6 +3149,31 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
||||||
*/
|
*/
|
||||||
afterEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
afterEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
/**
|
||||||
|
* Declares an `afterEach` hook with a title that is executed after each test.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // example.spec.ts
|
||||||
|
* import { test, expect } from '@playwright/test';
|
||||||
|
*
|
||||||
|
* test.afterEach('Status check', async ({ page }, testInfo) => {
|
||||||
|
* console.log(`Finished ${testInfo.title} with status ${testInfo.status}`);
|
||||||
|
*
|
||||||
|
* if (testInfo.status !== testInfo.expectedStatus)
|
||||||
|
* console.log(`Did not run as expected, ended up at ${page.url()}`);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* test('my test', async ({ page }) => {
|
||||||
|
* // ...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param title Hook title.
|
||||||
|
* @param hookFunction Hook function that takes one or two arguments: an object with fixtures and optional {@link TestInfo}.
|
||||||
|
*/
|
||||||
|
afterEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
/**
|
/**
|
||||||
* Declares a `beforeAll` hook that is executed once per worker process before all tests.
|
* Declares a `beforeAll` hook that is executed once per worker process before all tests.
|
||||||
*
|
*
|
||||||
@ -3138,7 +3186,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* Note that worker process is restarted on test failures, and `beforeAll` hook runs again in the new worker. Learn
|
* Note that worker process is restarted on test failures, and `beforeAll` hook runs again in the new worker. Learn
|
||||||
* more about [workers and failures](https://playwright.dev/docs/test-retries).
|
* more about [workers and failures](https://playwright.dev/docs/test-retries).
|
||||||
*
|
*
|
||||||
* You can use [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all) to teardown
|
* You can use [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all-1) to teardown
|
||||||
* any resources set up in `beforeAll`.
|
* any resources set up in `beforeAll`.
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
@ -3163,6 +3211,28 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
||||||
*/
|
*/
|
||||||
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
/**
|
||||||
|
* Declares a `beforeAll` hook with a title that is executed once per worker process before all tests.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // example.spec.ts
|
||||||
|
* import { test, expect } from '@playwright/test';
|
||||||
|
*
|
||||||
|
* test.beforeAll('Setup', async () => {
|
||||||
|
* console.log('Before tests');
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* test('my test', async ({ page }) => {
|
||||||
|
* // ...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param title Hook title.
|
||||||
|
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
||||||
|
*/
|
||||||
|
beforeAll(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
/**
|
/**
|
||||||
* Declares an `afterAll` hook that is executed once per worker after all tests.
|
* Declares an `afterAll` hook that is executed once per worker after all tests.
|
||||||
*
|
*
|
||||||
@ -3187,6 +3257,22 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
||||||
*/
|
*/
|
||||||
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
/**
|
||||||
|
* Declares an `afterAll` hook with a title that is executed once per worker after all tests.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* test.afterAll('Teardown', async () => {
|
||||||
|
* console.log('Done with tests');
|
||||||
|
* // ...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param title Hook title.
|
||||||
|
* @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional {@link TestInfo}.
|
||||||
|
*/
|
||||||
|
afterAll(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
/**
|
/**
|
||||||
* Specifies options or fixtures to use in a single test file or a
|
* Specifies options or fixtures to use in a single test file or a
|
||||||
* [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group. Most useful to
|
* [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group. Most useful to
|
||||||
|
@ -2063,6 +2063,122 @@ for (const useIntermediateMergeReport of [false, true] as const) {
|
|||||||
await expect(page.getByText('failed title')).not.toBeVisible();
|
await expect(page.getByText('failed title')).not.toBeVisible();
|
||||||
await expect(page.getByText('passes title')).toBeVisible();
|
await expect(page.getByText('passes title')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should properly display beforeEach with and without title', async ({ runInlineTest, showReport, page }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.js': `
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
test.beforeEach('titled hook', () => {
|
||||||
|
console.log('titled hook');
|
||||||
|
});
|
||||||
|
test.beforeEach(() => {
|
||||||
|
console.log('anonymous hook');
|
||||||
|
});
|
||||||
|
test('titles', async ({}) => {
|
||||||
|
expect(1).toBe(1);
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
|
||||||
|
await showReport();
|
||||||
|
await page.click('text=titles');
|
||||||
|
|
||||||
|
await page.click('text=Before Hooks');
|
||||||
|
await expect(page.locator('.tree-item:has-text("Before Hooks") .tree-item')).toContainText([
|
||||||
|
/titled hook/,
|
||||||
|
/beforeEach hook/,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should properly display beforeAll with and without title', async ({ runInlineTest, showReport, page }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.js': `
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
test.beforeAll('titled hook', () => {
|
||||||
|
console.log('titled hook');
|
||||||
|
});
|
||||||
|
test.beforeAll(() => {
|
||||||
|
console.log('anonymous hook');
|
||||||
|
});
|
||||||
|
test('titles', async ({}) => {
|
||||||
|
expect(1).toBe(1);
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
|
||||||
|
await showReport();
|
||||||
|
await page.click('text=titles');
|
||||||
|
|
||||||
|
await page.click('text=Before Hooks');
|
||||||
|
await expect(page.locator('.tree-item:has-text("Before Hooks") .tree-item')).toContainText([
|
||||||
|
/titled hook/,
|
||||||
|
/beforeAll hook/,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should properly display afterEach with and without title', async ({ runInlineTest, showReport, page }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.js': `
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
test.afterEach('titled hook', () => {
|
||||||
|
console.log('titled hook');
|
||||||
|
});
|
||||||
|
test.afterEach(() => {
|
||||||
|
console.log('anonymous hook');
|
||||||
|
});
|
||||||
|
test('titles', async ({}) => {
|
||||||
|
expect(1).toBe(1);
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
|
||||||
|
await showReport();
|
||||||
|
await page.click('text=titles');
|
||||||
|
|
||||||
|
await page.click('text=After Hooks');
|
||||||
|
await expect(page.locator('.tree-item:has-text("After Hooks") .tree-item')).toContainText([
|
||||||
|
/titled hook/,
|
||||||
|
/afterEach hook/,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should properly display afterAll with and without title', async ({ runInlineTest, showReport, page }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.js': `
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
test.afterAll('titled hook', () => {
|
||||||
|
console.log('titled hook');
|
||||||
|
});
|
||||||
|
test.afterAll(() => {
|
||||||
|
console.log('anonymous hook');
|
||||||
|
});
|
||||||
|
test('titles', async ({}) => {
|
||||||
|
expect(1).toBe(1);
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
|
||||||
|
await showReport();
|
||||||
|
await page.click('text=titles');
|
||||||
|
|
||||||
|
await page.click('text=After Hooks');
|
||||||
|
await expect(page.locator('.tree-item:has-text("After Hooks") .tree-item')).toContainText([
|
||||||
|
/titled hook/,
|
||||||
|
/afterAll hook/,
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
utils/generate_types/overrides-test.d.ts
vendored
4
utils/generate_types/overrides-test.d.ts
vendored
@ -149,9 +149,13 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||||||
slow(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void;
|
slow(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void;
|
||||||
setTimeout(timeout: number): void;
|
setTimeout(timeout: number): void;
|
||||||
beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
beforeEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
afterEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
afterEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
afterEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
beforeAll(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
|
afterAll(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||||
use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void;
|
use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void;
|
||||||
step<T>(title: string, body: () => T | Promise<T>): Promise<T>;
|
step<T>(title: string, body: () => T | Promise<T>): Promise<T>;
|
||||||
expect: Expect;
|
expect: Expect;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user