v1.39.0
microsoft/playwrightv1.39.0Oct 11, 2023by dgozman
AI Summary
Introduced custom matchers, fixture merging, and 'boxed' test steps to hide implementation details. Added toHaveAttribute matcher.
Key Highlights
- Custom matchers via expect.extend
- Merge test fixtures and custom matchers from multiple files
- Boxed test steps to point errors to the call site
New Features
- Custom matchers
- mergeTests() function
- mergeExpects() function
- Boxed test steps
- expect(locator).toHaveAttribute(name)
Full Release Notes
## Add custom matchers to your expect
You can extend Playwright assertions by providing custom matchers. These matchers will be available on the expect object.
```js
import { expect as baseExpect } from '@playwright/test';
export const expect = baseExpect.extend({
async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
// ... see documentation for how to write matchers.
},
});
test('pass', async ({ page }) => {
await expect(page.getByTestId('cart')).toHaveAmount(5);
});
```
See the documentation [for a full example](https://playwright.dev/docs/test-configuration#add-custom-matchers-using-expectextend).
## Merge test fixtures
You can now merge test fixtures from multiple files or modules:
```js
import { mergeTests } from '@playwright/test';
import { test as dbTest } from 'database-test-utils';
import { test as a11yTest } from 'a11y-test-utils';
export const test = mergeTests(dbTest, a11yTest);
```
```js
import { test } from './fixtures';
test('passes', async ({ database, page, a11y }) => {
// use database and a11y fixtures.
});
```
## Merge custom expect matchers
You can now merge custom expect matchers from multiple files or modules:
```js
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 test = mergeTests(dbTest, a11yTest);
export const expect = mergeExpects(dbExpect, a11yExpect);
```
```js
import { test, expect } from './fixtures';
test('passes', async ({ page, database }) => {
await expect(database).toHaveDatabaseUser('admin');
await expect(page).toPassA11yAudit();
});
```
## Hide implementation details: box test steps
You can mark a [`test.step()`](https://playwright.dev/docs/api/class-test#test-step) as "boxed" so that errors inside it point to the step call site.
```js
async function login(page) {
await test.step('login', async () => {
// ...
}, { box: true }); // Note the "box" option here.
}
```
```txt
Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
... error details omitted ...
14 | await page.goto('https://github.com/login');
> 15 | await login(page);
| ^
16 | });
```
See [`test.step()`](https://playwright.dev/docs/api/class-test#test-step) documentation for a full example.
## New APIs
- [`expect(locator).toHaveAttribute(name)`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-attribute-2)
## Browser Versions
* Chromium 119.0.6045.9
* Mozilla Firefox 118.0.1
* WebKit 17.4
This version was also tested against the following stable channels:
* Google Chrome 118
* Microsoft Edge 118