{"url":"https://api.github.com/repos/microsoft/playwright/releases/405900480","assets_url":"https://api.github.com/repos/microsoft/playwright/releases/405900480/assets","upload_url":"https://uploads.github.com/repos/microsoft/playwright/releases/405900480/assets{?name,label}","html_url":"https://github.com/microsoft/playwright/releases/tag/v1.64.0","id":405900480,"author":{"login":"dgozman","id":9881434,"node_id":"MDQ6VXNlcjk4ODE0MzQ=","avatar_url":"https://avatars.githubusercontent.com/u/9881434?v=4","gravatar_id":"","url":"https://api.github.com/users/dgozman","html_url":"https://github.com/dgozman","followers_url":"https://api.github.com/users/dgozman/followers","following_url":"https://api.github.com/users/dgozman/following{/other_user}","gists_url":"https://api.github.com/users/dgozman/gists{/gist_id}","starred_url":"https://api.github.com/users/dgozman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgozman/subscriptions","organizations_url":"https://api.github.com/users/dgozman/orgs","repos_url":"https://api.github.com/users/dgozman/repos","events_url":"https://api.github.com/users/dgozman/events{/privacy}","received_events_url":"https://api.github.com/users/dgozman/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDODTssw84YMYzA","tag_name":"v1.64.0","target_commitish":"release-1.64","name":"v1.64.0","draft":false,"immutable":false,"prerelease":false,"created_at":"2026-10-07T18:04:13Z","updated_at":"2026-10-07T20:40:43Z","published_at":"2026-10-07T20:40:43Z","assets":[],"tarball_url":"https://api.github.com/repos/microsoft/playwright/tarball/v1.64.0","zipball_url":"https://api.github.com/repos/microsoft/playwright/zipball/v1.64.0","body":"## 🧰 WebMCP\r\n\r\nNew [page.webmcp](https://playwright.dev/docs/api/class-page#page-webmcp) and [frame.webmcp](https://playwright.dev/docs/api/class-frame#frame-webmcp) give access to the tools that a page registers through the experimental [WebMCP](https://playwright.dev/docs/api/class-webmcp) browser API, so you can test them like any other part of your app:\r\n\r\n```js\r\nconst browser = await chromium.launch({ args: ['--enable-features=WebMCP'] });\r\nconst page = await browser.newPage();\r\nawait page.goto('https://example.com');\r\n\r\nfor (const tool of await page.webmcp.tools())\r\n  console.log(tool.name, tool.description);\r\n\r\nconst result = await page.webmcp.callTool('add', { a: 2, b: 40 });\r\nconsole.log(result.content[0].text); // \"42\"\r\n```\r\n\r\n[Playwright MCP](https://playwright.dev/docs/getting-started-mcp) also supports WebMCP by default, with page-defined tools offered to the agent as `webmcp_<tool>`. Pass `--no-webmcp` to opt out.\r\n\r\n[`playwright-cli`](https://playwright.dev/docs/getting-started-cli) exposes them as well:\r\n\r\n```bash\r\nplaywright-cli webmcp-list\r\nplaywright-cli webmcp-call search_catalog --params '{\"query\":\"cats\"}'\r\n```\r\n\r\n## 🎬 Better videos\r\n\r\nVideos can now be recorded at a custom frame rate, and the decorations for actions are styled with plain CSS:\r\n\r\n```js\r\n// playwright.config.ts\r\nimport { defineConfig } from '@playwright/test';\r\n\r\nexport default defineConfig({\r\n  use: {\r\n    video: {\r\n      mode: 'on',\r\n      size: { width: 1920, height: 1080 },\r\n      fps: 60,\r\n      show: {\r\n        actions: {\r\n          style: {\r\n            point: 'width: 20px; height: 20px; border-radius: 50%; background: red',\r\n            highlight: 'outline: 2px solid #333; background: rgba(0, 128, 255, .15)',\r\n            title: 'font-size: 16px',\r\n          },\r\n        },\r\n      },\r\n    },\r\n  },\r\n});\r\n```\r\n\r\n- New `fps` option in [testOptions.video](https://playwright.dev/docs/api/class-testoptions#test-options-video), [`recordVideo`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-video) and\r\n  [screencast.start()](https://playwright.dev/docs/api/class-screencast#screencast-start). Firefox and WebKit currently capture up to 25 frames per second.\r\n- New [`style`](https://playwright.dev/docs/api/class-screencast#screencast-show-actions-option-style) option takes CSS declarations for the `point` marker, the target\r\n  `highlight` and the action `title`. It replaces the `fontSize` option, which is now deprecated.\r\n- The cursor stays visible at the last action point, survives navigations and travels along a natural, eased path.\r\n- Videos are encoded with VP9 instead of VP8, which takes less CPU and produces smaller files of the same or better\r\n  quality.\r\n- All video options are also available in [Playwright MCP](https://playwright.dev/docs/getting-started-mcp) and [`playwright-cli`](https://playwright.dev/docs/getting-started-cli).\r\n\r\n## 🎯 Test runner\r\n- New [testProject.default](https://playwright.dev/docs/api/class-testproject#test-project-default) option keeps a project in the config without running it by default. You can configure every browser you care about, and let a plain `npx playwright test` run just your favourite one:\r\n  \r\n  ```js\r\n  // playwright.config.ts\r\n  import { defineConfig, devices } from '@playwright/test';\r\n  \r\n  export default defineConfig({\r\n    projects: [\r\n      { name: 'chromium', use: devices['Desktop Chrome'] },\r\n      { name: 'firefox', use: devices['Desktop Firefox'], default: false },\r\n      { name: 'webkit', use: devices['Desktop Safari'], default: false },\r\n    ],\r\n  });\r\n  ```\r\n  \r\n  ```bash\r\n  npx playwright test                     # runs chromium only\r\n  npx playwright test --project=firefox   # runs firefox\r\n  npx playwright test --project=\"*\"       # runs all three, for example on CI\r\n  ```\r\n  \r\n- New `--shuffle` command line option schedules tests in a random order, which helps to find tests that accidentally depend on each other.\r\n  \r\n  ```bash\r\n  npx playwright test --shuffle\r\n  # Running 42 tests using 4 workers, shuffle seed 271828182\r\n  # ...\r\n  \r\n  # Pass the seed to reproduce the same order.\r\n  npx playwright test --shuffle 271828182\r\n  ```\r\n  \r\n- New `lock` option in [test.describe.configure()](https://playwright.dev/docs/api/class-test#test-describe-configure) adds [test locks](https://playwright.dev/docs/test-parallel#test-locks) to all tests in a file or a group:\r\n  \r\n  ```js\r\n  test.describe.configure({ lock: 'user-settings' });\r\n  ```\r\n  \r\n- New `type` option of `toHaveScreenshot` in [testConfig.expect](https://playwright.dev/docs/api/class-testconfig#test-config-expect) stores all unnamed screenshots as WebP:\r\n  \r\n  ```js\r\n  // playwright.config.ts\r\n  export default defineConfig({\r\n    expect: {\r\n      toHaveScreenshot: { type: 'webp' },\r\n    },\r\n  });\r\n  ```\r\n  \r\n## 🪆 Locator.within()\r\n\r\nNew [locator.within()](https://playwright.dev/docs/api/class-locator#locator-within) combines two locators that you already have, reading in the natural order —\r\n\"this button, within that dialog\":\r\n\r\n```js\r\nconst saveButton = page.getByRole('button', { name: 'Save' });\r\nconst dialog = page.getByTestId('settings-dialog');\r\n\r\nawait saveButton.within(dialog).click();\r\n```\r\n\r\nRelative locators such as [locator.nth()](https://playwright.dev/docs/api/class-locator#locator-nth) or [locator.first()](https://playwright.dev/docs/api/class-locator#locator-first) are resolved inside each parent\r\nseparately, which makes column-like queries straightforward:\r\n\r\n```js\r\n// The third cell of every row, not the third cell in the table.\r\nconst thirdColumn = page.getByRole('cell').nth(2).within(page.getByRole('row'));\r\nawait expect(thirdColumn).toHaveText(['Apple', 'Banana', 'Cherry']);\r\n```\r\n\r\n## New APIs\r\n- New [page.getByRef()](https://playwright.dev/docs/api/class-page#page-get-by-ref) locates an element by its aria ref, such as `e2`, reported by [page.ariaSnapshot()](https://playwright.dev/docs/api/class-page#page-aria-snapshot) in the `'ai'` mode.\r\n- New option [`includeShadow`](https://playwright.dev/docs/api/class-page#page-content-option-include-shadow) in [page.content()](https://playwright.dev/docs/api/class-page#page-content) and [frame.content()](https://playwright.dev/docs/api/class-frame#frame-content) serializes open shadow roots as [declarative shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM#declaratively_with_html).\r\n- New option [`signCount`](https://playwright.dev/docs/api/class-credentials#credentials-create-option-sign-count) sets the initial signature counter of a virtual credential. [credentials.create()](https://playwright.dev/docs/api/class-credentials#credentials-create) and [credentials.get()](https://playwright.dev/docs/api/class-credentials#credentials-get) return the current `signCount`, and it is saved and restored together with the credentials in the storage state.\r\n- New [fullConfig.filteredProjects](https://playwright.dev/docs/api/class-fullconfig#full-config-filtered-projects) lists the projects that were selected to run after applying the `--project` filter. It is available in global setup and reporters.\r\n- New [apiRequestContext.addCookies()](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-add-cookies), [apiRequestContext.cookies()](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-cookies) and [apiRequestContext.clearCookies()](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-clear-cookies) manage cookies of a request context, mirroring the [BrowserContext](https://playwright.dev/docs/api/class-browsercontext) methods:\r\n  \r\n  ```js\r\n  await request.addCookies([{ name: 'session-id', value: '42', url: 'https://example.com' }]);\r\n  console.log(await request.cookies('https://example.com'));\r\n  await request.clearCookies({ name: 'session-id' });\r\n  ```\r\n  \r\n## Breaking changes ⚠️\r\n- `screen` property is now forwarded from the [device descriptors](https://playwright.dev/docs/emulation#devices). If you use `...devices['Desktop Chrome']` and alike, `window.screen` and media queries now see the emulated screen size. You can opt-out by explicitly setting `screen` to `undefined`:\r\n  \r\n  ```js\r\n  // playwright.config.ts\r\n  export default defineConfig({\r\n    use: {\r\n      ...devices['Desktop Chrome'],\r\n      screen: undefined,\r\n    },\r\n  });\r\n  ```\r\n  \r\n- JSX in your test files now follows your `tsconfig.json`. Playwright compiles JSX in test files according to the `jsx`, `jsxFactory`, `jsxFragmentFactory` and `jsxImportSource` [tsconfig options](https://playwright.dev/docs/test-typescript#tsconfig-jsx-options), and defaults to the automatic runtime from `react/jsx-runtime`.\r\n- `--update-snapshots=missing` now passes the test run. Tests that only create missing snapshots now pass in the `'missing'` mode of [testConfig.updateSnapshots](https://playwright.dev/docs/api/class-testconfig#test-config-update-snapshots), so that CI can generate new snapshots and verify the existing ones in a single run. The mode used when the option is not specified is now called `'default'` and behaves as before: missing snapshots are written and the test fails.\r\n- Elements inside hidden iframes are considered hidden. Elements inside an iframe that is not visible, for example with `visibility: hidden`, are now considered hidden by actions, [locator.isVisible()](https://playwright.dev/docs/api/class-locator#locator-is-visible) and [expect(locator).toBeVisible()](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-visible).\r\n\r\n## Browser Versions\r\n- Chromium 156.0.8078.4\r\n- Mozilla Firefox 157.0\r\n- WebKit 27.2\r\n\r\nThis version was also tested against the following stable channels:\r\n- Google Chrome 155\r\n- Microsoft Edge 155\r\n","reactions":{"url":"https://api.github.com/repos/microsoft/playwright/releases/405900480/reactions","total_count":13,"+1":6,"-1":0,"laugh":0,"hooray":4,"confused":0,"heart":0,"rocket":3,"eyes":0}}