โ ๏ธ Breaking Change
Impact Score: 7/10
Playwright v1.33.0 โ Release Notes & Engineering Impact
Source available โ automated, not human-reviewed
Component: playwright ยท Channel: stable. Automated analysis, not a compatibility certification. How this works.
Analysis updated: 2026-11-01.
Breaking-change evidence from the source
โ ๏ธ Breaking change * The `mcr.microsoft.com/playwright:v1.33.0` now serves a Playwright image based on Ubuntu Jammy.
โก Executive Summary (TL;DR)
Playwright v1.33.0. Source highlight: Playwright v1.33 & v1.34 updates
Who Does This Impact? (Role-Based Analysis)
๐ป Software Engineers & Devs
Check the source notes against the package and APIs you use before upgrading.
๐ Product & Engineering Leads
Use the documented changes to assess relevance to your product; release frequency alone is not a quality measure.
โ๏ธ DevOps & Security
Verify the target version, runtime requirements and rollback procedure in the official documentation.
โ ๏ธ Breaking Changes & Deprecations (1)
- โ ๏ธ Breaking change * The `mcr.microsoft.com/playwright:v1.33.0` now serves a Playwright image based on Ubuntu Jammy.
๐ View Raw Release Notes (Original Developer Log)
<a href="https://youtu.be/JeFD6rqDbBo"><img src="https://github.com/microsoft/playwright/assets/746130/4e165491-1b1b-41c6-8674-4295622b66df" width=340></a>
<a href="https://youtu.be/JeFD6rqDbBo">Playwright v1.33 & v1.34 updates</a>
### Locators Update
* Use [`locator.or()`] to create a locator that matches either of the two locators.
Consider a scenario where you'd like to click on a "New email" button, but sometimes a security settings dialog shows up instead.
In this case, you can wait for either a "New email" button, or a dialog and act accordingly:
```js
const newEmail = page.getByRole('button', { name: 'New' });
const dialog = page.getByText('Confirm security settings');
await expect(newEmail.or(dialog)).toBeVisible();
if (await dialog.isVisible())
await page.getByRole('button', { name: 'Dismiss' }).click();
await newEmail.click();
```
* Use new options `hasNot` and `hasNotText` in [`locator.filter()`]
to find elements that **do not match** certain conditions.
```js
const rowLocator = page.locator('tr');
await rowLocator
.filter({ hasNotText: 'text in column 1' })
.filter({ hasNot: page.getByRole('button', { name: 'column 2 button' }) })
.screenshot();
```
* Use new web-first assertion [`locatorAssertions.toBeAttached()`] to ensure that the element
is present in the page's DOM. Do not confuse with the [`locatorAssertions.toBeVisible()`] that ensures that
element is both attached & visible.
### New APIs
- [`locator.or()`]
- New option `hasNot` in [`locator.filter()`]
- New option `hasNotText` in [`locator.filter()`]
- [`locatorAssertions.toBeAttached()`]
- New option `timeout` in [`route.fetch()`]
- [`reporter.onExit()`]
### โ ๏ธ Breaking change
* The `mcr.microsoft.com/playwright:v1.33.0` now serves a Playwright image based on Ubuntu Jammy.
To use the focal-based image, please use `mcr.microsoft.com/playwright:v1.33.0-focal` instead.
### Browser Versions
* Chromium 113.0.5672.53
* Mozilla Firefox 112.0
* WebKit 16.4
This version was also tested against the following stable channels:
* Google Chrome 112
* Microsoft Edge 112
[`locator.or()`]: https://playwright.dev/docs/api/class-locator#locator-or
[`reporter.onExit()`]: https://playwright.dev/docs/api/class-reporter#reporter-on-exit
[`locator.filter()`]: https://playwright.dev/docs/api/class-locator#locator-filter
[`locatorAssertions.toBeAttached()`]: https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-attached
[`locatorAssertions.toBeVisible()`]: https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-visible
[`route.fetch()`]: https://playwright.dev/docs/api/class-route#route-fetch