mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
docs: move expect.extend docs from "test configuration" to "assertions" (#28039)
This commit is contained in:
parent
2afd857642
commit
c759e6a6f6
@ -30,7 +30,7 @@ test('pass', async ({ page }) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
See the documentation [for a full example](./test-configuration.md#add-custom-matchers-using-expectextend).
|
See the documentation [for a full example](./test-assertions.md#add-custom-matchers-using-expectextend).
|
||||||
|
|
||||||
### Merge test fixtures
|
### Merge test fixtures
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ Prefer [auto-retrying](#auto-retrying-assertions) assertions whenever possible.
|
|||||||
| [`method: GenericAssertions.stringContaining`] | String contains a substring |
|
| [`method: GenericAssertions.stringContaining`] | String contains a substring |
|
||||||
| [`method: GenericAssertions.stringMatching`] | String matches a regular expression |
|
| [`method: GenericAssertions.stringMatching`] | String matches a regular expression |
|
||||||
|
|
||||||
## Negating Matchers
|
## Negating matchers
|
||||||
|
|
||||||
In general, we can expect the opposite to be true by adding a `.not` to the front
|
In general, we can expect the opposite to be true by adding a `.not` to the front
|
||||||
of the matchers:
|
of the matchers:
|
||||||
@ -104,7 +104,7 @@ expect(value).not.toEqual(0);
|
|||||||
await expect(locator).not.toContainText('some text');
|
await expect(locator).not.toContainText('some text');
|
||||||
```
|
```
|
||||||
|
|
||||||
## Soft Assertions
|
## Soft assertions
|
||||||
|
|
||||||
By default, failed assertion will terminate test execution. Playwright also
|
By default, failed assertion will terminate test execution. Playwright also
|
||||||
supports *soft assertions*: failed soft assertions **do not** terminate test execution,
|
supports *soft assertions*: failed soft assertions **do not** terminate test execution,
|
||||||
@ -134,7 +134,7 @@ expect(test.info().errors).toHaveLength(0);
|
|||||||
|
|
||||||
Note that soft assertions only work with Playwright test runner.
|
Note that soft assertions only work with Playwright test runner.
|
||||||
|
|
||||||
## Custom Expect Message
|
## Custom expect message
|
||||||
|
|
||||||
You can specify a custom error message as a second argument to the `expect` function, for example:
|
You can specify a custom error message as a second argument to the `expect` function, for example:
|
||||||
|
|
||||||
@ -236,3 +236,86 @@ await expect(async () => {
|
|||||||
timeout: 60_000
|
timeout: 60_000
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Add custom matchers using expect.extend
|
||||||
|
|
||||||
|
You can extend Playwright assertions by providing custom matchers. These matchers will be available on the `expect` object.
|
||||||
|
|
||||||
|
In this example we add a custom `toHaveAmount` function. Custom matcher should return a `message` callback and a `pass` flag indicating whether the assertion passed.
|
||||||
|
|
||||||
|
```js title="fixtures.ts"
|
||||||
|
import { expect as baseExpect } from '@playwright/test';
|
||||||
|
import type { Page, Locator } from '@playwright/test';
|
||||||
|
|
||||||
|
export { test } from '@playwright/test';
|
||||||
|
|
||||||
|
export const expect = baseExpect.extend({
|
||||||
|
async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
|
||||||
|
const assertionName = 'toHaveAmount';
|
||||||
|
let pass: boolean;
|
||||||
|
let matcherResult: any;
|
||||||
|
try {
|
||||||
|
await baseExpect(locator).toHaveAttribute('data-amount', String(expected), options);
|
||||||
|
pass = true;
|
||||||
|
} catch (e: any) {
|
||||||
|
matcherResult = e.matcherResult;
|
||||||
|
pass = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = pass
|
||||||
|
? () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
|
||||||
|
'\n\n' +
|
||||||
|
`Locator: ${locator}\n` +
|
||||||
|
`Expected: ${this.isNot ? 'not' : ''}${this.utils.printExpected(expected)}\n` +
|
||||||
|
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
|
||||||
|
: () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
|
||||||
|
'\n\n' +
|
||||||
|
`Locator: ${locator}\n` +
|
||||||
|
`Expected: ${this.utils.printExpected(expected)}\n` +
|
||||||
|
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');
|
||||||
|
|
||||||
|
return {
|
||||||
|
message,
|
||||||
|
pass,
|
||||||
|
name: assertionName,
|
||||||
|
expected,
|
||||||
|
actual: matcherResult?.actual,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we can use `toHaveAmount` in the test.
|
||||||
|
|
||||||
|
```js title="example.spec.ts"
|
||||||
|
import { test, expect } from './fixtures';
|
||||||
|
|
||||||
|
test('amount', async () => {
|
||||||
|
await expect(page.locator('.cart')).toHaveAmount(4);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Do not confuse Playwright's `expect` with the [`expect` library](https://jestjs.io/docs/expect). The latter is not fully integrated with Playwright test runner, so make sure to use Playwright's own `expect`.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Combine custom matchers from multiple modules
|
||||||
|
|
||||||
|
You can combine custom matchers from multiple files or modules.
|
||||||
|
|
||||||
|
```js title="fixtures.ts"
|
||||||
|
import { mergeTests, mergeExpects } from '@playwright/test';
|
||||||
|
import { test as dbTest, expect as dbExpect } from 'database-test-utils';
|
||||||
|
import { test as a11yTest, expect as a11yExpect } from 'a11y-test-utils';
|
||||||
|
|
||||||
|
export const expect = mergeExpects(dbExpect, a11yExpect);
|
||||||
|
export const test = mergeTests(dbTest, a11yTest);
|
||||||
|
```
|
||||||
|
|
||||||
|
```js title="test.spec.ts"
|
||||||
|
import { test, expect } from './fixtures';
|
||||||
|
|
||||||
|
test('passes', async ({ database }) => {
|
||||||
|
await expect(database).toHaveDatabaseUser('admin');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|||||||
@ -150,86 +150,3 @@ export default defineConfig({
|
|||||||
| [`method: PageAssertions.toHaveScreenshot#1`] | Configuration for the `expect(locator).toHaveScreeshot()` method. |
|
| [`method: PageAssertions.toHaveScreenshot#1`] | Configuration for the `expect(locator).toHaveScreeshot()` method. |
|
||||||
| [`method: SnapshotAssertions.toMatchSnapshot#1`]| Configuration for the `expect(locator).toMatchSnapshot()` method.|
|
| [`method: SnapshotAssertions.toMatchSnapshot#1`]| Configuration for the `expect(locator).toMatchSnapshot()` method.|
|
||||||
|
|
||||||
|
|
||||||
### Add custom matchers using expect.extend
|
|
||||||
|
|
||||||
You can extend Playwright assertions by providing custom matchers. These matchers will be available on the `expect` object.
|
|
||||||
|
|
||||||
In this example we add a custom `toHaveAmount` function. Custom matcher should return a `message` callback and a `pass` flag indicating whether the assertion passed.
|
|
||||||
|
|
||||||
```js title="fixtures.ts"
|
|
||||||
import { expect as baseExpect } from '@playwright/test';
|
|
||||||
import type { Page, Locator } from '@playwright/test';
|
|
||||||
|
|
||||||
export { test } from '@playwright/test';
|
|
||||||
|
|
||||||
export const expect = baseExpect.extend({
|
|
||||||
async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
|
|
||||||
const assertionName = 'toHaveAmount';
|
|
||||||
let pass: boolean;
|
|
||||||
let matcherResult: any;
|
|
||||||
try {
|
|
||||||
await baseExpect(locator).toHaveAttribute('data-amount', String(expected), options);
|
|
||||||
pass = true;
|
|
||||||
} catch (e: any) {
|
|
||||||
matcherResult = e.matcherResult;
|
|
||||||
pass = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = pass
|
|
||||||
? () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
|
|
||||||
'\n\n' +
|
|
||||||
`Locator: ${locator}\n` +
|
|
||||||
`Expected: ${this.isNot ? 'not' : ''}${this.utils.printExpected(expected)}\n` +
|
|
||||||
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
|
|
||||||
: () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
|
|
||||||
'\n\n' +
|
|
||||||
`Locator: ${locator}\n` +
|
|
||||||
`Expected: ${this.utils.printExpected(expected)}\n` +
|
|
||||||
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');
|
|
||||||
|
|
||||||
return {
|
|
||||||
message,
|
|
||||||
pass,
|
|
||||||
name: assertionName,
|
|
||||||
expected,
|
|
||||||
actual: matcherResult?.actual,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we can use `toHaveAmount` in the test.
|
|
||||||
|
|
||||||
```js title="example.spec.ts"
|
|
||||||
import { test, expect } from './fixtures';
|
|
||||||
|
|
||||||
test('amount', async () => {
|
|
||||||
await expect(page.locator('.cart')).toHaveAmount(4);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
:::note
|
|
||||||
Do not confuse Playwright's `expect` with the [`expect` library](https://jestjs.io/docs/expect). The latter is not fully integrated with Playwright test runner, so make sure to use Playwright's own `expect`.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Combine custom matchers from multiple modules
|
|
||||||
|
|
||||||
You can combine custom matchers from multiple files or modules.
|
|
||||||
|
|
||||||
```js title="fixtures.ts"
|
|
||||||
import { mergeTests, mergeExpects } from '@playwright/test';
|
|
||||||
import { test as dbTest, expect as dbExpect } from 'database-test-utils';
|
|
||||||
import { test as a11yTest, expect as a11yExpect } from 'a11y-test-utils';
|
|
||||||
|
|
||||||
export const expect = mergeExpects(dbExpect, a11yExpect);
|
|
||||||
export const test = mergeTests(dbTest, a11yTest);
|
|
||||||
```
|
|
||||||
|
|
||||||
```js title="test.spec.ts"
|
|
||||||
import { test, expect } from './fixtures';
|
|
||||||
|
|
||||||
test('passes', async ({ database }) => {
|
|
||||||
await expect(database).toHaveDatabaseUser('admin');
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user