--- id: release-notes title: "Release notes" --- ## Version 1.24 ### 🐂 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 | ✅ | ✅ | ✅ | ✅ | ### New introduction docs We rewrote our Getting Started docs to be more end-to-end testing focused. Check them out on [playwright.dev](https://playwright.dev/python/docs/intro). ## 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: ```python async context = await browser.new_context(record_har_path="github.har.zip") # ... do stuff ... await context.close() ``` ```python sync context = browser.new_context(record_har_path="github.har.zip") # ... do stuff ... 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: ```python async await context.route_from_har("github.har.zip") ``` ```python sync context.route_from_har("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: ```python async # Remove a header from all requests async def remove_header_handler(route: Route) -> None: headers = await route.request.all_headers() if "if-none-match" in headers: del headers["if-none-match"] await route.fallback(headers=headers) await page.route("**/*", remove_header_handler) # Abort all images async def abort_images_handler(route: Route) -> None: if route.request.resource_type == "image": await route.abort() else: await route.fallback() await page.route("**/*", abort_images_handler) ``` ```python sync # Remove a header from all requests def remove_header_handler(route: Route) -> None: headers = route.request.all_headers() if "if-none-match" in headers: del headers["if-none-match"] route.fallback(headers=headers) page.route("**/*", remove_header_handler) # Abort all images def abort_images_handler(route: Route) -> None: if route.request.resource_type == "image": route.abort() else: route.fallback() page.route("**/*", abort_images_handler) ``` 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 `