--- id: release-notes title: "Release notes" --- ## Version 1.24 ### 🌍 Multiple Web Servers in `playwright.config.ts` Launch multiple web servers, databases, or other processes by passing an array of configurations: ```ts // playwright.config.ts import type { PlaywrightTestConfig } from '@playwright/test'; const config: PlaywrightTestConfig = { webServer: [ { command: 'npm run start', port: 3000, timeout: 120 * 1000, reuseExistingServer: !process.env.CI, }, { command: 'npm run backend', port: 3333, timeout: 120 * 1000, reuseExistingServer: !process.env.CI, } ], use: { baseURL: 'http://localhost:3000/', }, }; export default config; ``` ### πŸ‚ Debian 11 Bullseye Support Playwright now supports Debian 11 Bullseye on x86_64 for Chromium, Firefox and WebKit. Let us know if you encounter any issues! Linux support looks like this: | | Ubuntu 18.04 | Ubuntu 20.04 | Ubuntu 22.04 | Debian 11 | :--- | :---: | :---: | :---: | :---: | | Chromium | βœ… | βœ… | βœ… | βœ… | | WebKit | βœ… | βœ… | βœ… | βœ… | | Firefox | βœ… | βœ… | βœ… | βœ… | ### πŸ•΅οΈ Anonymous Describe It is now possible to call [`method: Test.describe#2`] to create suites without a title. This is useful for giving a group of tests a common option with [`method: Test.use`]. ```ts test.describe(() => { test.use({ colorScheme: 'dark' }); test('one', async ({ page }) => { // ... }); test('two', async ({ page }) => { // ... }); }); ``` ### 🧩 Component Tests Update Playwright 1.24 Component Tests introduce `beforeMount` and `afterMount` hooks. Use these to configure your app for tests. For example, this could be used to setup App router in Vue.js: ```js // src/component.spec.ts import { test } from '@playwright/experimental-ct-vue'; import { Component } from './mycomponent'; test('should work', async ({ mount }) => { const component = await mount(Component, { hooksConfig: { /* anything to configure your app */ } }); }); ``` ```js // playwright/index.ts import { router } from '../router'; import { beforeMount } from '@playwright/experimental-ct-vue/hooks'; beforeMount(async ({ app, hooksConfig }) => { app.use(router); }); ``` A similar configuration in Next.js would look like this: ```js // src/component.spec.jsx import { test } from '@playwright/experimental-ct-react'; import { Component } from './mycomponent'; test('should work', async ({ mount }) => { const component = await mount(, { // Pass mock value from test into `beforeMount`. hooksConfig: { router: { query: { page: 1, per_page: 10 }, asPath: '/posts' } } }); }); ``` ```js // playwright/index.js import router from 'next/router'; import { beforeMount } from '@playwright/experimental-ct-react/hooks'; beforeMount(async ({ hooksConfig }) => { // Before mount, redefine useRouter to return mock value from test. router.useRouter = () => hooksConfig.router; }); ``` ## Version 1.23
### Network Replay Now you can record network traffic into a HAR file and re-use this traffic in your tests. To record network into HAR file: ```bash npx playwright open --save-har=github.har.zip https://github.com/microsoft ``` Alternatively, you can record HAR programmatically: ```ts const context = await browser.newContext({ recordHar: { path: 'github.har.zip' } }); // ... do stuff ... await context.close(); ``` Use the new methods [`method: Page.routeFromHAR`] or [`method: BrowserContext.routeFromHAR`] to serve matching responses from the [HAR](http://www.softwareishard.com/blog/har-12-spec/) file: ```ts await context.routeFromHAR('github.har.zip'); ``` Read more in [our documentation](./network#record-and-replay-requests). ### Advanced Routing You can now use [`method: Route.fallback`] to defer routing to other handlers. Consider the following example: ```ts // Remove a header from all requests. test.beforeEach(async ({ page }) => { await page.route('**/*', async route => { const headers = await route.request().allHeaders(); delete headers['if-none-match']; route.fallback({ headers }); }); }); test('should work', async ({ page }) => { await page.route('**/*', route => { if (route.request().resourceType() === 'image') route.abort(); else route.fallback(); }); }); ``` Note that the new methods [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`] also participate in routing and could be deferred to. ### Web-First Assertions Update * New method [`method: LocatorAssertions.toHaveValues`] that asserts all selected values of `