Commit Graph

17826 Commits

Author SHA1 Message Date
Yury Semikhatsky be99977b69 docs: address review comments on 1.63 release notes 2026-09-03 16:13:14 -07:00
Yury Semikhatsky 660238abef docs: release notes for v1.63 2026-09-03 12:37:36 -07:00
Dmitry Gozman 2b7a5f2ea1 test: response.body() for content-encoding:identity (#42537) 2026-09-03 20:06:24 +01:00
Dmitry Gozman 648a67c7c1 fix(mcp): create parent directories for explicitly named files (#42540) 2026-09-03 20:05:45 +01:00
Dmitry Gozman 7894f5653e docs(mcp): clarify how tool file names are resolved (#42538) 2026-09-03 20:05:33 +01:00
Yury Semikhatsky 52900a1b99 devops: restore npm publishing from GitHub Actions (#42550) 2026-09-03 11:37:56 -07:00
Super-Eric 8c47f596ed docs(csharp): fix nonexistent method names in guide examples (#42507)
Co-authored-by: Super-Eric <9334019+Super-Eric@users.noreply.github.com>
2026-09-03 17:42:52 +01:00
Pavel Feldman bd6e552a63 chore(video): emit frames with real timestamps, drop frame number quantization (#42480) 2026-09-03 09:02:50 -07:00
Pavel Feldman a76bdda1f3 docs(tracing): enable snapshots options in other languages (#42526) 2026-09-03 09:02:40 -07:00
Pavel Feldman bfb42e5993 feat(ct): type mount() story ids through a generated Stories registry (#42518) 2026-09-03 08:32:35 -07:00
dependabot[bot] 3dd248776a chore(deps): bump actions/setup-java from 5.7.0 to 6.0.0 in the github-actions group across 1 directory (#42523)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 14:14:53 +01:00
microsoft-playwright-automation[bot] 34d23028f3 feat(firefox): roll to r1543 (#42524)
Co-authored-by: microsoft-playwright-automation[bot] <203992400+microsoft-playwright-automation[bot]@users.noreply.github.com>
2026-09-03 11:39:45 +01:00
Dmitry Gozman 612050ebe6 fix(test): support multiple contexts with --debug=cli (#42503) 2026-09-03 08:34:13 +01:00
Yury Semikhatsky e9163e238d feat(mcp): add --profile-dir-name to select the Chrome profile in extension mode (#42527) 2026-09-02 15:36:09 -07:00
Yury Semikhatsky df01cf969b fix(mcp): time out extension connection when a token is passed (#42525) 2026-09-02 15:16:41 -07:00
Dmitry Gozman 855c734916 chore(ci): bump azure/login to v3.0.2 (#42509) 2026-09-02 20:11:29 +01:00
Dmitry Gozman 3be4b29b5d fix(trace-viewer): serve snapshots with a strict script-src policy (#42508) 2026-09-02 20:10:47 +01:00
Dmitry Gozman bcf53b58af test(connect): fix unsafe launch options test with channels and tracing (#42504) 2026-09-02 20:10:33 +01:00
Yury Semikhatsky 3283349730 chore: bump WebKit version to 26.6 (#42514) 2026-09-02 11:12:13 -07:00
Pavel Feldman c874c8a7be docs(cli): use npx playwright cli for local installs (#42512) 2026-09-02 10:29:07 -07:00
Pavel Feldman 14f3c0cf01 fix(reporter): include host in navigation and request subtitles (#42515) 2026-09-02 10:28:19 -07:00
Devin Rousso 8e11a5b67d test(webkit): reenable WebSocket handshake HAR coverage (#42513)
the upstream WebKit fix restores the reported WebSocket handshake headers on macOS 26

remove the platform skip so the existing HAR assertions run again

see <https://github.com/microsoft/playwright/issues/42205>
2026-09-02 10:51:55 -06:00
Dmitry Gozman 0f5a946a03 test: skip crash tests on webkit debian-13 (#42510) 2026-09-02 09:51:44 -07:00
Lazizbek Ergashev ace1bc1337 fix(android): include the from point in the swipe path (#42349) 2026-09-02 08:31:26 -07:00
microsoft-playwright-automation[bot] 2dec18d7e4 feat(webkit): roll to r2359 (#42493)
Co-authored-by: microsoft-playwright-automation[bot] <203992400+microsoft-playwright-automation[bot]@users.noreply.github.com>
2026-09-02 15:44:50 +01:00
Ashraf Ali b34b234713 fix(debug-controller): drop recorded actions when recording session ends (#42458) 2026-09-02 13:28:58 +01:00
Devin Rousso 350d24a344 chore(firefox): remove the WebSocket handshake Worker workaround (#42455) 2026-09-02 08:39:17 +01:00
Yury Semikhatsky 9e3157b5c5 fix(mcp): refuse browser_close when the browser context is shared (#42495) 2026-09-01 14:58:32 -07:00
Yury Semikhatsky 902a864ac6 feat(storage): capture OPFS in storage state (#42248) 2026-09-01 14:57:55 -07:00
Yury Semikhatsky b12432801c Revert "fix(mcp): drop the backend after browser_close with a shared browser" (#42492) 2026-09-01 13:44:49 -07:00
Devin Rousso 8f206e1c4f fix(trace): keep client paths out of remote launch options (#42436)
remote browser servers can receive Playwright Test worker paths and try to write trace files on the client filesystem

remove `artifactsDir` and `tracesDir` from remote launch options

fixes <https://github.com/microsoft/playwright/issues/42394>
2026-09-01 13:30:56 -06:00
Yury Semikhatsky 03a69df918 fix(mcp): disable the chromium sandbox for the bundled browser on linux (#42490) 2026-09-01 11:08:06 -07:00
Yury Semikhatsky 260eae3111 chore(extension): bump version to 0.4.0 (#42482) 2026-09-01 10:12:25 -07:00
Pavel Feldman 104597f4b5 feat(locator): introduce locator.visible() (#42479) 2026-09-01 09:17:21 -07:00
Lazizbek Ergashev 4810881999 docs(auth): escape session storage before embedding in init script (#42477) 2026-09-01 13:49:45 +01:00
Changsu Seong ba0b817d40 fix(trace-viewer): label filter inputs and keyboard-accessible error source (#42469)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 13:35:43 +01:00
Yury Semikhatsky de214f440b chore(utils): always use setImmediate in makeWaitForNextTask (#42456) 2026-08-28 18:43:34 -07:00
microsoft-playwright-automation[bot] ba0b5128d0 feat(firefox): roll to r1542 (#42453) 2026-08-28 16:40:17 -07:00
Huzaifa Iftikhar b276e33a88 fix(ui-mode): make the filter summary reachable from the keyboard (#42449)
Closes #42439

## problem

the filter summary under the search input in UI Mode toggles the status and project filters when you click it, but it is a `div` with an `onClick`:

```tsx
<div className='filter-summary' title={...} onClick={() => setExpanded(!expanded)}>
```

so tab skips it, enter and space do nothing, and a screen reader announces it as ordinary text rather than a control that expands something. the chevron next to it is already a button, which makes the summary the odd one out rather than a deliberate choice.

## fix

make it a real `button` with `aria-expanded`.

using a native button rather than `role='button'` plus `tabIndex` plus a keydown handler means focus, enter, space and the button role all come from the platform. it also matches `Expandable` right above it, which already renders its toggle as a `button` with `aria-expanded`.

the css resets the button chrome the same way `.expandable-title-button` does and adds the same focus ring, so it looks the way it did:

```css
.filter-summary {
  all: unset;
  display: block;
  /* ...the previous properties... */
}

.filter-summary:focus-visible {
  outline: 1px solid var(--vscode-focusBorder);
  outline-offset: -1px;
}
```

one thing worth calling out: the original properties lived in a rule shared with `.filter-title`, so the reset is in its own `.filter-summary` block rather than added to the shared one. `.filter-title` is untouched.

## test

`should toggle filters from the keyboard` in `ui-mode-test-filters.spec.ts`, close to your snippet in the issue, plus the aria state and the space key:

```ts
await expect(summary).toHaveRole('button');
await expect(summary).toHaveAttribute('aria-expanded', 'false');
await summary.focus();
await expect(summary).toBeFocused();
await summary.press('Enter');
await expect(page.getByTestId('status-filters')).toBeVisible();
await expect(summary).toHaveAttribute('aria-expanded', 'true');
await summary.press('Space');
await expect(page.getByTestId('status-filters')).toBeHidden();
```

on `main` it fails at the first assertion, `toHaveRole('button')`.

## verification

| check | result |
|---|---|
| new test on `main`, rebuilt | fails |
| new test with the change | passes |
| `ui-mode-test-filters` | 12 passed |
| every `ui-mode` spec | 139 passed |
| eslint on both changed files | clean |

---

disclaimer: this contribution was prepared with the assistance of an ai agent. i reproduced the behaviour, checked how `Expandable` solves the same problem before picking an approach, and ran the ui mode suites locally before opening this.
2026-08-28 16:58:04 -06:00
Devin Rousso 419e1e05ee feat(trace-viewer): signal message readiness (#42451)
callers cannot know when Trace Viewer installs its `message` listener

notify the opener or parent once trace messages can be received

fixes <https://github.com/microsoft/playwright/issues/42414>
2026-08-28 16:54:34 -06:00
om singhal e65229f19f fix(mcp): drop the backend after browser_close with a shared browser (#42365)
Fixes #42363

### What happens

With the HTTP transport and `--shared-browser-context`, `browser_close` disposes the calling client's `BrowserBackend`: the `Context` is cleared and the dispose callback only decrements the client count, because another client keeps the shared browser alive. `server.ts` caches `backendPromise` per session and clears it only on the backend's `disconnected` event, which `BrowserBackend` emits only when the browser context closes or the browser disconnects. Neither happens here, so the next tool call from that client reuses the disposed backend: `ensureBrowserContext` returns the already resolved promise without re registering the page listener, `newTab` finds no tab, and `browser_tabs` (new) or `browser_navigate` fail with

```
TypeError: Cannot read properties of undefined (reading 'checkUrlAndNavigate')
TypeError: Cannot read properties of undefined (reading 'waitForInitialized')
```

until the server restarts. In the CLI server, non shared and isolated modes are unaffected because they close the context or the browser and the event fires.

### The change

`BrowserBackend.dispose()` now emits `disconnected` (guarded so it fires once) after the context and the dispose callback have run. `server.ts` already drops the cached backend in its existing `once('disconnected')` listener, so the next call creates a fresh backend through the factory. The listener also calls `backend.dispose()` again, which is a no op through the existing `_disposed` guard.

This was chosen over special casing the close result in `server.ts`: `callTool` already strips `isClose` from the result before returning it, so the server cannot see a close without widening the `ServerBackend` contract, and the event approach makes every disposal path invalidate the cache, not only `browser_close`. No debug line is logged from `dispose`, so the tests that count `browser disconnected` lines are unaffected.

The library entry point (`createConnection` in `mcp/index.ts`) goes through the same `createServer`, so it picks up the same behaviour: after `browser_close` the next call now drops the disposed backend and asks the factory for a new one (a fresh `BrowserBackend` on the context the getter returns when a `contextGetter` is supplied), instead of failing with the TypeError. Without a getter the factory launches a second browser while the first stays open, because `createConnection` passes no dispose callback and `browser_close` never closed the browser in library mode before or after this change; that is pre existing. The other `BrowserBackend` consumers (`cli-daemon`, `traceSnapshot`, the test backend under `playwright/src/mcp`) register no `disconnected` listener, and an emit with no listener is harmless.

### Test

New `http transport shared context survives browser_close` in `tests/mcp/http.spec.ts`, modelled on the neighbouring shared context test: two HTTP clients with `--shared-browser-context`, both navigate, client 1 calls `browser_close` then `browser_tabs` (new) and must get a snapshot, client 2's `browser_snapshot` must still work, and the log counts must match (`create context 3`, `close browser 1`).

```
# chromium project, tests/mcp/http.spec.ts
with the change:                     20 passed, 1 failed
source reverted, test kept:          the new test fails with TypeError ... 'checkUrlAndNavigate' at the browser_tabs assertion
# chromium project, tests/mcp/launch.spec.ts and cdp.spec.ts (the tests that count browser disconnected lines)
with the change:                     19 passed
```

The one failure in `http.spec.ts` is `should close session when heartbeat ping is not answered`, and it fails identically with the source reverted, so it is unrelated to this change: on the machine used here the default `chrome` channel takes 7 to 8 seconds to launch a fresh persistent profile, and the heartbeat only starts once the backend exists, so the session delete lands after `expect.poll`'s default 5 second timeout. With `--browser=chromium` the same scenario reaps the session in under 3 seconds.

The issue's three step scenario was also run end to end against a built `mcp.js` with two streamable HTTP clients before and after the change; before, step 3 returns the TypeError above and the second client keeps working; after, all steps succeed.

`eslint`, `tsc`, `lint-tests` and `check-deps` pass. Only the chromium project was run locally; chrome, firefox and webkit were not.
2026-08-28 16:52:57 -06:00
Pavel Feldman eca9e03e04 fix(chromium): replay execution contexts when connecting to Android WebView (#42447) 2026-08-28 15:47:40 -07:00
Yury Semikhatsky a30296c9ea fix(tracing): allow restarting tracing after a failed stop (#42425) 2026-08-28 15:00:14 -07:00
Dmitry Gozman c4479bdc4c chore(recorder): move fill coalescing back to collapseActions (#42442) 2026-08-28 20:59:28 +01:00
Dmitry Gozman 8e708fbd1f chore(trace): move trace types into isomorphic/trace/versions (#42444) 2026-08-28 17:57:12 +01:00
microsoft-playwright-automation[bot] 437ddf4220 feat(webkit): roll to r2358 (#42438) 2026-08-28 10:51:24 -06:00
Dmitry Gozman fab1c044c8 chore(chromium): switch linux arm64 to cft builds (#42440) 2026-08-28 16:47:03 +01:00
Dmitry Gozman 80ef914382 test(mcp): activate page before reading the clipboard (#42443) 2026-08-28 16:46:45 +01:00
Dmitry Gozman 9a450a2ff5 chore(trace): remove snapshot pointers from action events (#42431) 2026-08-28 11:01:41 +01:00
Dmitry Gozman 6748802c89 feat(selectors): replace pierceFrames() with frameLocator() (#42395) 2026-08-28 09:59:17 +01:00