Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
249 commits
Select commit Hold shift + click to select a range
b8c915f
docs(python): document expect.soft() (#40665)
Skn0tt May 6, 2026
9a533e1
test: unflake/fix/skip a few tests (#40662)
dgozman May 6, 2026
2f1d9c0
feat(dashboard): annotate multiple screenshots (#40664)
Skn0tt May 6, 2026
dd468b4
fix(dashboard): fix Windows named pipe race on daemon shutdown (#40642)
Skn0tt May 6, 2026
3254f06
fix(trace-viewer): sanitize snapshot renderer against XSS from crafte…
SebTardif May 6, 2026
7eb960f
fix(trace): await pending stack writer before deleting stack session …
Skn0tt May 6, 2026
04cd7ef
feat(firefox): roll to r1522 (#40667)
microsoft-playwright-automation[bot] May 6, 2026
cc8ba29
fix(cli): prevent shell injection in --only-changed ref argument (#40…
SebTardif May 6, 2026
b4bae37
fix(security): prevent Zip Slip path traversal in harUnzip (#40623)
SebTardif May 6, 2026
fa852c4
fix(mcp): auto-recover when remote browser disconnects mid-session (#…
pavelfeldman May 6, 2026
a1f668d
fix(mcp): propagate abort signal to stop test execution (#40582)
mxschmitt May 6, 2026
b3691fe
fix(server): advertise bound IP literal in wsEndpoint and URL prefix …
yury-s May 6, 2026
91f0807
refactor(client): replace remote-object switch with a factory registr…
dgozman May 6, 2026
bb6c009
chore(extension): mark 0.2.1 (#40679)
yury-s May 6, 2026
3649db5
chore(mcp): bump default extension protocol to v2 (#40678)
yury-s May 6, 2026
9fa531d
fix(screencast): unblock frame ack when an async client disconnects (…
pavelfeldman May 6, 2026
54012f5
chore(deps): bump ip-address and express-rate-limit (#40680)
dependabot[bot] May 6, 2026
299704f
chore: bump version to v1.61.0-next (#40685)
yury-s May 7, 2026
49c053c
chore(python): formdata path type (#40693)
Skn0tt May 7, 2026
d3abc83
test(mcp): simplify PLAYWRIGHT_SOCKETS_DIR to hash of outputDir (#40690)
Skn0tt May 7, 2026
a2f2e02
fix(mcp): prevent unhandled rejection in test op queue (#40698)
Skn0tt May 7, 2026
cb03945
fix(trace): replay sub-resources from archive in trace snapshot CLI (…
Skn0tt May 7, 2026
4b00518
fix(mcp): forward browser-level CDP commands in extension mode (#40706)
yury-s May 7, 2026
c8604ec
chore: roll browser patches from upstream (#40707)
yury-s May 7, 2026
5c35287
fix(mcp): serialize shared browser launch in --isolated mode (#40709)
yury-s May 7, 2026
da0b103
chore(docs): include electron-api and mobile-api in render_release_no…
yury-s May 7, 2026
a437150
docs: release notes v1.60 (#40710)
yury-s May 7, 2026
50ae1ab
feat(chromium): roll to r1224 (#40712)
microsoft-playwright-automation[bot] May 7, 2026
1938c9f
fix(reporter): strip ansi from test stdout when colors are disabled (…
pavelfeldman May 7, 2026
ead11df
chore(deps-dev): bump hono from 4.12.14 to 4.12.18 (#40686)
dependabot[bot] May 7, 2026
2e65b4b
fix(ci): pass args to git as array in gitCommitInfoPlugin (#40684)
SebTardif May 7, 2026
90c413e
fix(trace-viewer): strip event handlers and neutralize IFRAME srcdoc/…
SebTardif May 7, 2026
6b85e42
test: reenable test for #39160 (#40719)
dgozman May 7, 2026
e1f429b
test(bidi): allow firefoxUserPrefs in Playwright's own tests (#40660)
hbenl May 7, 2026
5790370
chore(bidi): fix support for downloads (#40659)
hbenl May 7, 2026
d8c56b0
fix(cli): wait for dashboard daemon READY signal before returning fro…
Skn0tt May 8, 2026
3d541ac
test: roll stable-test-runner to 1.60.0-beta-1778191499000 (#40721)
yury-s May 8, 2026
5f9fc90
test(bidi): unskip tests that work with Firefox/Bidi (#40666)
hbenl May 8, 2026
168aacd
test(mcp): mark test_run abort test as slow (#40731)
mxschmitt May 8, 2026
cf15ff4
Revert "feat(electron): add timeout option to electronApp.close() for…
yury-s May 8, 2026
31b3163
fix(android): reject pending callbacks on device close (#40722)
SebTardif May 8, 2026
e1145c8
feat(test-runner): support toHaveScreenshot timeout in expect config …
pavelfeldman May 8, 2026
7d3bea0
fix(server): add path traversal checks to static file serving routes …
SebTardif May 8, 2026
3cf3619
fix(mcp): do not mark response as close when there are no tabs (#40743)
pavelfeldman May 9, 2026
1cffc10
chore(mcp): remove stray console.error in cli-json test (#40744)
pavelfeldman May 9, 2026
7d13982
chore(electron): revert #40184 (move Electron API to a separate packa…
yury-s May 9, 2026
062c9f5
docs(cli): document `&` URL escaping on Windows (#40742)
yury-s May 9, 2026
c17e0b4
fix(yauzl): vendor yauzl with destroy-lifecycle fix (#40747)
pavelfeldman May 9, 2026
dc4d41f
fix(server): use fs.promises.rm to delete temp upload directories (#4…
SebTardif May 9, 2026
5614c60
fix(server): validate file paths in createTempFiles (#40754)
SebTardif May 9, 2026
f993f90
fix(tools): validate user-provided regex patterns in MCP tools (#40752)
SebTardif May 9, 2026
4d09792
fix(dashboard): clean up temp recording directory on close (#40751)
SebTardif May 9, 2026
b3c9a9b
fix(chromium): close file descriptor on protocol stream save error (#…
SebTardif May 9, 2026
5327da1
fix(server): destroy stream in StreamDispatcher._onDispose (#40759)
SebTardif May 10, 2026
cb3312b
fix(server): guard JSON.parse in protocol message handlers (#40756)
SebTardif May 10, 2026
a26b361
chore(protocol): replace EventTarget interface with __waitInfo__ mess…
dgozman May 10, 2026
bd35ed9
chore: move expect log statements out of frame/page into dispatchers …
dgozman May 10, 2026
c8ce3aa
chore(server): pass action point/box as onBeforeInputAction args (#40…
dgozman May 10, 2026
c6a06ed
fix(trace-viewer): neutralize object and embed tags in snapshot rende…
SebTardif May 10, 2026
b08db6d
fix(tracing): add missing error handlers in zip repack path (#40760)
SebTardif May 10, 2026
e029ba2
fix(server): destroy stream in WritableStreamDispatcher._onDispose (#…
SebTardif May 10, 2026
00dcb5c
fix(tracing): mkdir tracesDir before live .stacks writes (#40730)
Skn0tt May 11, 2026
64c117a
fix(dashboard): retry pending reveal on TabsChanged (#40775)
Skn0tt May 11, 2026
cdfe71c
chore(cli): mirror cli-daemon spawn pattern in `cli show` (#40770)
Skn0tt May 11, 2026
3ee7f2c
chore(build): always build html-reporter and trace-viewer in watch mo…
pavelfeldman May 11, 2026
e8fa99c
fix(utils): fix polynomial backtracking in ansiRegex (#40762)
SebTardif May 11, 2026
9a6cdf0
chore(deps-dev): bump fast-uri from 3.1.0 to 3.1.2 (#40746)
dependabot[bot] May 11, 2026
01eca5e
test: roll stable-test-runner to 1.60.0-beta-1778518825000 (#40782)
yury-s May 11, 2026
8a06fc0
chore(fetch): own per-request log array (#40778)
dgozman May 11, 2026
73d4649
chore: remove missingDocs (#40777)
dgozman May 11, 2026
da681cf
chore(trace): track snapshot targets via generation counter (#40766)
dgozman May 11, 2026
8cdbd39
chore(page): split protocol close into close and runBeforeUnload (#40…
dgozman May 11, 2026
7397f8e
docs: 1.60 release notes for Java, Python and C# (#40785)
yury-s May 11, 2026
10bf172
fix(cli): accept single --modifiers value for click and dblclick (#40…
yury-s May 11, 2026
8c6a7e7
fix(test-runner): match file paths containing spaces on Windows (#40783)
yury-s May 11, 2026
b7bdd3f
fix(client-certificates): pass through non-matching origins (#40789)
yury-s May 11, 2026
330ed41
feat(webkit): roll to r2290 (#40745)
microsoft-playwright-automation[bot] May 12, 2026
ca16d01
test: fix flaky 'should filter actions by text' (#40804)
yury-s May 12, 2026
a92f69d
test: unflake console timestamp tests on Windows (#40803)
yury-s May 12, 2026
62d1ea1
fix(trace-viewer): keep selected action in view after "Show all" (#40…
yury-s May 13, 2026
cea53f4
test(mcp): use 1 worker on CI (#40796)
Skn0tt May 13, 2026
9416959
chore: simplify daemon/client handshake (#40802)
dgozman May 13, 2026
fa03e2b
fix(cli): persist traces when CLI attaches to existing CDP browser (#…
yury-s May 13, 2026
d14fa5f
feat(webkit): roll to r2291 (#40813)
microsoft-playwright-automation[bot] May 13, 2026
2094c00
chore(docs): use * for object type alias markers (#40821)
dgozman May 13, 2026
d2edf45
devops: add android bot to tests_secondary (#40799)
dgozman May 13, 2026
c0bcc84
fix(mcp): support remoteHeaders for remote browser endpoint (#40828)
yury-s May 13, 2026
ee2c20b
feat(ui-mode): show pass/fail/skip counters in status bar (#40830)
yury-s May 14, 2026
23c41bd
chore(deps): bump fast-xml-builder from 1.1.4 to 1.2.0 in /utils/flak…
dependabot[bot] May 14, 2026
1459f98
fix(html-reporter): render compound ANSI SGR codes (#40829)
yury-s May 14, 2026
f2a317f
feat(ui-mode): add "Stop on first failure" toggle (#40831)
yury-s May 14, 2026
8a21fee
chore(dispatcher): move potentiallyClosesScope into protocol metainfo…
dgozman May 14, 2026
dbc2810
chore(expect): unify aria-snapshot baseline-generation paths (#40835)
dgozman May 14, 2026
5adbc68
devops(docker): split browser layers and use zstd compression for fas…
KRRT7 May 14, 2026
bd6a3b7
feat(trace): add retain-all-failures trace mode (#40838)
yury-s May 14, 2026
954bd91
feat(page): add localStorage / sessionStorage API (#40843)
pavelfeldman May 14, 2026
fc39cf7
feat(test): allow testIdAttribute to be a comma-separated list of nam…
yury-s May 14, 2026
daa2146
feat(expect): support expect.soft.poll chain (#40848)
pavelfeldman May 15, 2026
e67f2a3
chore(protocol): auto-serialize SerializedValue in validators (#40798)
dgozman May 15, 2026
409d6d0
Revert "chore(protocol): auto-serialize SerializedValue in validators…
dgozman May 15, 2026
7583f47
test: skip a few (#40859)
dgozman May 15, 2026
2cf08d0
fix(recorder): skip click action on <input type=file> (#40861)
yury-s May 15, 2026
09a4057
feat(webkit): roll to r2293 (#40846)
microsoft-playwright-automation[bot] May 15, 2026
b07c76f
feat(agents): add Codex --loop=codex generator (#40817)
0xharkirat May 15, 2026
cd26ed8
fix(recorder): use light color-scheme for highlight overlay (#40863)
yury-s May 15, 2026
5422254
feat(test): expose runner process.argv as FullConfig.argv (#40850)
yury-s May 15, 2026
bb7af07
fix(test): allow any return type for test body (#40852)
dword-design May 16, 2026
72bbd1d
feat(credentials): add context.credentials WebAuthn virtual authentic…
pavelfeldman May 16, 2026
23edf71
fix(mcp): report missing ffmpeg distinctly from missing browser (#40867)
yury-s May 18, 2026
7d0e90a
chore(registry): dedupe executables in resolveBrowsers (#40717)
pavelfeldman May 18, 2026
7f13406
feat(keyboard): add array overload to pressSequentially (#40748)
SebTardif May 18, 2026
b93e350
feat(firefox-beta): roll to r1516 (#40841)
microsoft-playwright-automation[bot] May 18, 2026
780f941
fix(test): import EventEmitter from 'events', not 'stream' (#40872)
ofcRS May 18, 2026
65d2ca1
Fix broken "Full CLI documentation" link in README (#40870)
TuongDoan May 18, 2026
561bb37
feat: Allow configuring last-run output file location (#40806)
twk3 May 18, 2026
ed91850
feat(test): support per-project webServer configuration (#40869)
yury-s May 18, 2026
9e17ff5
test(proxy): cover CONNECT 407 with socket-close reconnection (#40866)
yury-s May 18, 2026
9afece0
fix(recorder): skip click on file inputs and use hoveredModel (#40899)
yury-s May 18, 2026
0523914
fix(cli): trim overlong session names to fit unix socket path limit (…
yury-s May 18, 2026
474d3c1
test: roll stable-test-runner to 1.61.0-alpha-2026-05-18 (#40888)
microsoft-playwright-automation[bot] May 19, 2026
a512630
fix(dashboard): block `show -s` until the controller acks the reveal …
Skn0tt May 19, 2026
93ec56f
fix(test): increase timeouts for slow annotate startup assertions (#4…
Skn0tt May 19, 2026
de13224
chore(dashboard): report daemon PID via reveal ack (#40906)
Skn0tt May 19, 2026
618eb46
fix(dashboard): treat EEXIST as singleton-already-running (#40908)
Skn0tt May 19, 2026
2817e7f
test: skip 'should play audio' on webkit macOS 15 (#40913)
yury-s May 19, 2026
329f8af
devops: remove macOS microphone TCC workaround (#40896)
yury-s May 19, 2026
20e51e7
feat(mcp): add video-show-actions / video-hide-actions tools and CLI …
pavelfeldman May 19, 2026
83ef991
feat(screencast): animate a mouse cursor between action points (#40916)
pavelfeldman May 19, 2026
43629c0
refactor(dashboard): turn emitAnnotate into a request/response API (#…
Skn0tt May 20, 2026
eb5c9f7
feat(chromium): roll to r1225 (#40842)
microsoft-playwright-automation[bot] May 20, 2026
e4d8313
chore: do not abort operations upon dispatcher being disposed (#40893)
dgozman May 20, 2026
dfab418
test: allow PWTEST_CHANNEL in stress tests (#40931)
dgozman May 20, 2026
c3deeff
feat(devices): add Pixel 6 through Pixel 10 device descriptors (#40928)
dgozman May 20, 2026
936183e
fix(proxy): ensure the host field is correct when using proxy (#40797)
Archkon May 20, 2026
92dcf5d
fix(reporter): honor NO_COLOR in list/line/dot reporters (#40903)
williamdes May 21, 2026
b2c94d4
chore: fix device descriptors build (#40939)
dgozman May 21, 2026
3acf045
feat(reporter): expose failOnFlakyTests on FullConfig (#40935)
dgozman May 21, 2026
b949df5
feat(fetch): expose securityDetails() and serverAddr() on APIResponse…
dgozman May 21, 2026
7749f55
feat(webkit): roll to r2295 (#40937)
microsoft-playwright-automation[bot] May 21, 2026
0f9632b
fix(chromium): properly handle CBOR stack limit error (#40947)
dgozman May 21, 2026
c1b1aa6
docs(electron): document mocking the native main-process dialog API (…
yury-s May 21, 2026
cee6800
feat(chromium): roll to r1226 (#40951)
microsoft-playwright-automation[bot] May 22, 2026
b37fb15
chore(deps): bump uuid and @azure/identity in /utils/flakiness-dashbo…
dependabot[bot] May 22, 2026
a052a36
docs(cli-client/skill): fix small typos in skill references (#40942)
AllDmeat May 22, 2026
7eb4045
chore(bidi): emit load events after browsingContext.create (#40944)
hbenl May 22, 2026
bfae350
docs: add junit breaking change to 1.59 release notes (#40957)
dgozman May 22, 2026
da60217
fix(trace-viewer): highlight network/console timeframe on timeline on…
dgozman May 22, 2026
4cd7f68
feat(devices): add iPhone 16 and iPhone 17 device families (#40917)
dimkin-eu May 22, 2026
de3aa6a
devops: bots for Node 26 (#40945)
dgozman May 22, 2026
f31b8fe
fix(ci): use GraphQL variables for fork-sourced report content (#40973)
yury-s May 22, 2026
8f50322
feat(browserType): allow passing a ConnectionTransport to connectOver…
yury-s May 22, 2026
b4d8076
chore: snapshot main-world globals for no-utility-world contexts (#40…
pavelfeldman May 22, 2026
4d28901
feat(list-reporter): add printFailuresInline option (#40875)
pavelfeldman May 24, 2026
c758b15
fix(test): use synchronous module customization hooks (#40891)
dgozman May 26, 2026
d92ef24
chore(deps): bump qs from 6.14.2 to 6.15.2 (#40975)
dependabot[bot] May 26, 2026
907f8b7
docs(tap): fix awkward grammar in hasTouch note (#40958)
adityasingh2400 May 26, 2026
54d0f8c
feat(firefox): roll to r1525 (#40965)
microsoft-playwright-automation[bot] May 26, 2026
e88823e
feat(webkit): roll to r2296 (#40963)
microsoft-playwright-automation[bot] May 26, 2026
872105a
feat(devices): add Galaxy Z Fold and Galaxy Z Flip device families (#…
dimkin-eu May 26, 2026
8651b89
Revert "fix(trace-viewer): validate origin of postMessage trace blob"…
Skn0tt May 26, 2026
23a55b2
docs: evaluate/evaluateHandle handle examples (#41002)
Skn0tt May 26, 2026
74fc94e
feat(browserType): throw on remote connectOverCDP(transport) (#40997)
Skn0tt May 26, 2026
142582c
fix(mcp): tear down dashboard server on cli show --kill (#40968)
Skn0tt May 26, 2026
bd4d83f
fix(mcp): disconnect tracked browser on BrowserTracker.dispose (#40967)
Skn0tt May 26, 2026
2fc9d1c
fix(mcp): use writable cache dir for MCP user data, not browsers path…
adityasingh2400 May 26, 2026
25f22d2
chore: wk_webview experiment (#41010)
pavelfeldman May 26, 2026
f2afe40
docs(cli-client/skill): use the real requests command in heal diagnos…
adityasingh2400 May 26, 2026
d8a08fe
chore(webview): keep ios_webkit_debug_proxy alive after setup script …
pavelfeldman May 26, 2026
624ef28
devops(webview): enable manual + path-scoped triggers for webview wor…
yury-s May 27, 2026
e32f907
feat(webkit): roll to r2297 (#41008)
microsoft-playwright-automation[bot] May 27, 2026
1845d3f
test: roll stable-test-runner to 1.61.0-alpha-2026-05-27 (#41018)
microsoft-playwright-automation[bot] May 27, 2026
4afdd64
chore(browserType): merge connectOverCDP and connectOverCDPTransport …
pavelfeldman May 27, 2026
f98da23
feat(linux): support Ubuntu 26.04 (#41025)
yury-s May 27, 2026
08a37f2
fix(webview): handle cross-origin process swap (#41024)
yury-s May 27, 2026
10d6473
fixed the omnibox issue (#41023)
Yugenjr May 28, 2026
67241ff
fix(mcp): report invalid tool arguments (#40979)
Steve-whb May 28, 2026
2d04b34
feat(aria-snapshot): expose aria-invalid in ARIA snapshots (#40966)
adityasingh2400 May 28, 2026
dc8836a
fix(server): clearCookies({name}) should not transiently delete other…
adityasingh2400 May 28, 2026
414fa0b
Remove unnecessary tabIndex from gantt chart SVG rect elements for im…
Yugenjr May 28, 2026
7444bca
chore: roll driver/Dockerfile to recent Node.js LTS version (#41033)
microsoft-playwright-automation[bot] May 28, 2026
dfe5ab5
fix(fetch): preserve error code in decompression pipeline for retry l…
SebTardif May 28, 2026
17c003c
fix(reporter): print inline failure for non-retriable errors (#41026)
yury-s May 28, 2026
f14741d
feat(webkit): support connectOverCDP(transport) for direct WVPage att…
pavelfeldman May 28, 2026
37a5aa6
fix(tools): pass time parameter to page.evaluate in waitForTimeout (#…
SebTardif May 29, 2026
a44a2d8
fix(codegen): never generate getByRole with mismatched name/descripti…
Skn0tt May 29, 2026
1081eda
feat(webkit): roll to r2298 (#41039)
microsoft-playwright-automation[bot] May 29, 2026
79b8f72
feat(firefox-beta): roll to r1519 (#41043)
microsoft-playwright-automation[bot] May 29, 2026
bb8d775
feat(firefox-beta): roll to r1520 (#41049)
microsoft-playwright-automation[bot] May 29, 2026
fda3cd3
feat(webkit): roll to r2299 (#41048)
microsoft-playwright-automation[bot] May 29, 2026
525f375
feat(mcp): --output-max-size with post-response disk eviction (#41031)
Skn0tt May 29, 2026
054a3f8
test(webkit): skip cookieStore change event test on Windows (#41052)
csaavedra May 29, 2026
adbcd7e
test: update image baseline for webview (#41053)
pavelfeldman May 29, 2026
c27ccc4
fix(webview): support site isolation and fix postData (#41041)
yury-s May 29, 2026
ee5a51e
fix(core): show friendly error for unsupported Node.js versions (#41050)
Skn0tt May 29, 2026
bc29607
chore: consolidate vite SW+main builds via Environment API (#41047)
Skn0tt May 29, 2026
9fe284a
feat(webview): synthesize keyboard and mouse input (#41055)
yury-s May 29, 2026
3edc77f
fix(html-reporter): add keyboard navigation to TabbedPane component (…
padmarajnidagundi May 30, 2026
c3c74e4
test(bidi): remove fail expectation for Firefox/Bidi (#41064)
hbenl Jun 1, 2026
e8d5386
fix(reporter): spread AggregateError sub-errors into testInfo.errors …
Skn0tt Jun 1, 2026
cadf83c
fix(ui-mode): include project outputDirs in allowedFileRoots (#41065)
Skn0tt Jun 1, 2026
48ad094
feat(firefox-beta): roll to r1521 (#41058)
microsoft-playwright-automation[bot] Jun 1, 2026
8727a66
feat(firefox): roll to r1528 (#41057)
microsoft-playwright-automation[bot] Jun 1, 2026
1aa42fa
fix(screenshotter): race cleanup against progress to honor timeout (#…
Skn0tt Jun 1, 2026
899c7a5
feat(mcp): accept ConnectOptions object for remoteEndpoint (#40964)
adityasingh2400 Jun 1, 2026
1ac9a57
feat(har): include `WebSocket` in `.har` (#41015)
dcrousso Jun 1, 2026
dc51ddb
fix(webview): dispatch key events in their own tasks (#41056)
yury-s Jun 1, 2026
34e7d3e
chore(webkit): extract webview dialog bridge into an injected source …
yury-s Jun 1, 2026
f439350
devops: remove test bots covered by browser builds (#41066)
dgozman Jun 1, 2026
cd08dfa
test(heap): run heap leak tests across all browsers (#41069)
dgozman Jun 1, 2026
3ee6e87
fix(webview): dispatch mouse events in their own tasks (#41078)
yury-s Jun 1, 2026
67930e8
Revert "devops(docker): split browser layers and use zstd compression…
dgozman Jun 1, 2026
6c05bfb
feat(har): add `_resourceType` to all requests (#41077)
dcrousso Jun 1, 2026
2d4f0d1
fix(fileUpload): reject localPaths when client is not collocated with…
pavelfeldman Jun 1, 2026
2ff4137
feat(test): support more video recording modes (#41085)
yury-s Jun 2, 2026
9587e73
fix(download): clear error when saving downloads from a non-collocate…
yury-s Jun 2, 2026
794a382
fix(webserver): strip ANSI escape codes before matching wait regex (#…
yury-s Jun 2, 2026
6ac1e4c
devops: run Docker container tests in a dedicated reusable workflow (…
dgozman Jun 2, 2026
5dd0a9b
devops: remove trigger_tests workflow (#41079)
dgozman Jun 2, 2026
4859f65
fix(yauzl): use upstream yauzl 3.3.2 instead of vendored copy (#41102)
yury-s Jun 2, 2026
ae9e0ce
test: roll stable-test-runner to 1.61.0-alpha-2026-06-01 (#41067)
microsoft-playwright-automation[bot] Jun 2, 2026
edeefe0
feat(webkit): roll to r2300 (#41059)
microsoft-playwright-automation[bot] Jun 2, 2026
3b799ab
feat(test runner): add -G alias for grep-invert (#41075)
KirtiRamchandani Jun 2, 2026
5662da6
devops: reduce the number of chromium channels bots (#41097)
dgozman Jun 2, 2026
deea3cb
test: merge frames.spec.ts into heap.spec.ts (#41096)
dgozman Jun 2, 2026
d0151c4
devops: remove video bots (#41094)
dgozman Jun 2, 2026
83df35a
feat(har): use engine timestamps instead of server `Date` (#41082)
dcrousso Jun 2, 2026
d94e89d
feat(install): add --no-progress to silence download progress bar (#4…
yury-s Jun 2, 2026
0ce8e85
feat(webview): attach Web Workers over the WebView backend (#41103)
yury-s Jun 2, 2026
dfee7ac
fix(socks): handle IPv4-mapped IPv6 addresses in ipToSocksAddress (#4…
yury-s Jun 2, 2026
158eade
test: skip large file upload test in all non-default modes (#41111)
pavelfeldman Jun 2, 2026
426cc4e
feat(har): calculate `request.headerSize`, `response.headerSize`, and…
dcrousso Jun 3, 2026
dd15119
fix(client-certificates): do not intercept TLS for non-matching origi…
yury-s Jun 3, 2026
205a006
fix(chromium): attribute worker to the right frame (#41116)
dgozman Jun 3, 2026
db88251
chore: serialize non-inprocess uploads (#41112)
pavelfeldman Jun 3, 2026
9fbc0a6
fix(trace): capture attribute mutations after a popup document swap (…
yury-s Jun 3, 2026
f5f0bef
chore(mcp): remove dead saveTrace config references (#41119)
yury-s Jun 3, 2026
f1c2981
docs: remove stray HTML comment from webview2 guide (#41122)
yury-s Jun 3, 2026
1660114
chore(trace): remove retain-all-failures trace and video mode (#41123)
yury-s Jun 3, 2026
93ac74a
chore: fix leaks and tests (#41115)
dgozman Jun 4, 2026
fd47b67
feat: add `AbortSignal` support to client-side Waiter methods (#41136)
Skn0tt Jun 4, 2026
b1f4bb5
feat(webkit): roll to r2301 (#41109)
microsoft-playwright-automation[bot] Jun 4, 2026
08e2d03
docs: clarify behavior of each trace and video mode (#41127)
yury-s Jun 4, 2026
b0f1008
feat(webkit): roll to r2302 (#41130)
microsoft-playwright-automation[bot] Jun 4, 2026
78c9dfd
fix(test): pass file:// URL to the ESM resolver in the sync loader (#…
dgozman Jun 4, 2026
e3f61c1
feat(firefox-beta): roll to r1522 (#41140)
microsoft-playwright-automation[bot] Jun 4, 2026
0492b3b
fix(mcp): use waitUntil commit for navigate back/forward (#41153)
yury-s Jun 5, 2026
017cfab
fix(cli): do not pass PLAYWRIGHT_CLI_SESSION as daemon --endpoint (#4…
Skn0tt Jun 5, 2026
e8916e8
chore(build): spawn watcher tools directly instead of via npx (#41034)
Skn0tt Jun 5, 2026
8213652
fix(mcp): implement signalToPromise dispose to remove abort listener
Skn0tt Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .claude/skills/playwright-dev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ See [CLAUDE.md](../../../CLAUDE.md) for monorepo structure, build/test/lint comm
- [MCP Tools and CLI Commands](tools.md) — add MCP tools, CLI commands, config options
- [Vendor Dependencies & Bundling](vendor.md) — utilsBundle, coreBundle, babelBundle; adding vendored npm packages; DEPS.list; `check_deps`
- [Updating WebKit Safari Version](webkit-safari-version.md) — update the Safari version string in the WebKit user-agent
- [WebView (iOS Safari) Backend](webview.md) — `webkit/webview/` against stock Mobile Safari; provisional-target pause/resume; what's upstream vs Playwright patches; local + CI test setup
- [Bisecting Across Published Versions](bisect-published-versions.md) — reproduce regressions side-by-side from npm and diff `node_modules/playwright/lib/` between versions
- [Dashboard](dashboard.md) - the UI powering the "playwright cli show" command, and how to work on it
4 changes: 0 additions & 4 deletions .claude/skills/playwright-dev/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ Manages the client-server transport:
| `Locator` | `locator.ts` | Delegates to `Frame` methods with selector + `strict: true` |
| `ElementHandle` | `elementHandle.ts` | DOM element reference |

### Public API Exports

`packages/playwright-core/src/client/api.ts` exports all public classes.

## Server Layer

### SdkObject — Base Class
Expand Down
149 changes: 149 additions & 0 deletions .claude/skills/playwright-dev/webview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# WebView (iOS Safari) Backend Reference

Notes for developing the **stock-Mobile-Safari** backend in
[packages/playwright-core/src/server/webkit/webview/](../../../packages/playwright-core/src/server/webkit/webview/).
The regular WebKit backend one level up (`webkit/`) runs against a
Playwright-patched WebKit build; the `webview/` folder targets unmodified
Safari on real iOS/iPadOS or the iOS Simulator over the standard Web Inspector
Protocol.

## What is and isn't available

Stock Mobile Safari only exposes the upstream Web Inspector Protocol. Anything
Playwright added to its forked WebKit is not available here.

**Available** — methods/events in `Source/JavaScriptCore/inspector/protocol/*.json`
on `browser_upstream/main`:

```bash
git -C ~/webkit show browser_upstream/main:Source/JavaScriptCore/inspector/protocol/<Domain>.json
```

**Not available** — anything added by the Playwright WebKit patches:

```bash
ls ~/playwright-browsers/browser_patches/webkit/patches/ # bootstrap.diff lives here
```

Quick provenance check for a symbol — in `~/webkit`:

```bash
git log --all -S "<symbol>" -- <path>
```

If every hit is a `chore(webkit): bootstrap build` commit, it's a Playwright
patch. Some traps where the upstream name overlaps with a Playwright-only
helper of similar intent:

- `Target.setPauseOnStart` / `Target.resume` (**upstream**, gates loading of
provisional process-swap targets) vs `PageInspectorController::pauseOnStart`
/ `resumeIfPausedInNewWindow` (**Playwright patch**, for `window.open`
popups). They sound the same; they aren't.
- `Playwright.*` domain (cookies, navigate, all global controls) — entirely
Playwright. Use stock equivalents on the page session (e.g. `Page.getCookies`).
- `Network.continueWithAuth`, intercepted-response body access via Network —
Playwright extensions.

## Architecture

This backend deliberately mirrors the regular WebKit backend one level up
(`wkConnection.ts` / `wkPage.ts` / `wkProvisionalPage.ts`). When in doubt,
read the WK equivalent — the WV class should look almost the same. The
`outerSession` is the WV analogue of WK's page-proxy session.

```
WebSocketTransport (ws://localhost:9222/devtools/page/<n>, via ios_webkit_debug_proxy)
→ WVConnection — dumb transport; owns only outerSession
→ WVConnection.outerSession (sessionId "") — Target.sendMessageToTarget bridge
→ WVPage — owns per-target WVSessions, routes
Target.dispatchMessageFromTarget, manages swaps
→ _session (current) + WVProvisionalPage (during a swap)
→ WVExecutionContext, WVWorkers, RawKeyboard/Mouse/Touchscreen
(all hold a session reference, all have setSession() for swap)
```

`WVConnection` is intentionally minimal: it pumps the transport into
`outerSession` and back. `WVPage` creates the per-target `WVSession`s
(`_createSession`), routes `Target.dispatchMessageFromTarget` by `targetId` to
either `_session` or `_provisionalPage._session`, and handles
`Target.targetCreated/targetDestroyed/didCommitProvisionalTarget` — exactly
like `WKPage`. `WVPage` is constructed with the outer session (not a target
session); `_session` starts undefined and is bound on the first
`Target.targetCreated` via `_setSession`. `WVBrowser._attachTab` awaits
`page.waitForInitialized()` (resolves after the first target is reported as
new) instead of waiting on the connection.

## Process swap / provisional targets

Cross-origin navigation in an existing tab can make Mobile Safari spawn a new
process. The protocol sequence is:

```
Target.targetCreated targetInfo:{ isProvisional:true, isPaused:true }
... events on the provisional target during the navigation ...
Target.didCommitProvisionalTarget oldTargetId, newTargetId
Target.targetDestroyed oldTargetId
```

Handling mirrors WK — `WVProvisionalPage` ≈ `WKProvisionalPage`, swapped in by
`WVPage._onDidCommitProvisionalTarget`. The one essential trick:
`Target.setPauseOnStart` (sent in `WVBrowser._attachTab`) makes provisional
targets arrive `isPaused`, so `WVPage` can set up interception / bootstrap
before resuming them with `Target.resume`; otherwise the new process races
ahead and `page.route(...)` never fires.

Not to be confused with the **popup-pause** path (`window.open`), which is a
Playwright patch (`PageInspectorController::pauseOnStart`) with no stock-Safari
equivalent.

## Test infrastructure

```
tests/webview/
playwright.config.ts — single project "webkit-webview-page", runs tests/page/
webviewTest.ts — fixture: discovers tab via ios_webkit_debug_proxy /json,
resets Mobile Safari between tests
expectations/
webkit-webview-page.txt — `<test path> › <name> [fail|flaky|timeout|skip]`
expectationUtil.ts — loader + skip-decision logic
```

`[fail]` entries cause `it.skip()` to fire before the test body runs — so a
formerly-failing test that now passes won't be flagged automatically, you have
to remove the line and re-run. The marker also has prefix-match semantics for
`it.step` children.

### Running locally

```bash
./utils/run_webview_tests.sh # ensures ios_webkit_debug_proxy is up on 9222
npm run wvtest -- -g "<test title>" # single test
npm run wvtest -- tests/page/foo.spec.ts
DEBUG=pw:protocol npm run wvtest -- -g "<title>" > /tmp/log 2>&1
```

The simulator needs to be booted with one Mobile Safari tab. The script's only
job is keeping a single
`ios_webkit_debug_proxy -F -d -s unix:<socket> -c null:9221,:9222-9322` alive;
everything else is done by the fixture.

### Common local pitfalls

- **Multiple `ios_webkit_debug_proxy` processes** — every protocol event is
delivered through each instance, so debug logs show events duplicated and
some tests flake. `pgrep -lf ios_webkit_debug_proxy` and clean up.
- **Chrome bound to `127.0.0.1:9222`** — Chrome's `--remote-debugging-port=9222`
shadows iwdp's `*:9222` listener for traffic addressed to `localhost`.
Kill the Chrome instance (`lsof -nP -iTCP -sTCP:LISTEN | grep 9222`).
- **Stale launchd socket** — `lsof -aUc launchd_sim` should show
`com.apple.webinspectord_sim.socket` for the currently booted simulator. If
iwdp was started against an older `launchd_sim` socket path it will silently
serve nothing.

## CI

[.github/workflows/tests_webview_simulator.yml](../../../.github/workflows/tests_webview_simulator.yml)
runs the same suite on `macos-15` (booted iOS Simulator +
`brew install ios-webkit-debug-proxy`). Triggers: `workflow_dispatch`, and
`pull_request` only when paths under `tests/webview/**`, the `webview/` source
folder, or the workflow file itself change.
25 changes: 0 additions & 25 deletions .github/actions/enable-microphone-access/action.yml

This file was deleted.

1 change: 0 additions & 1 deletion .github/actions/run-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ runs:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- uses: ./.github/actions/enable-microphone-access
- run: |
echo "::group::npm ci"
npm ci
Expand Down
5 changes: 4 additions & 1 deletion .github/actions/upload-blob-report/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ runs:
steps:
- name: Integrity check
shell: bash
run: find "${{ inputs.report_dir }}" -name "*.zip" -exec unzip -t {} \;
run: |
echo "::group::extracting blob archives"
find "${{ inputs.report_dir }}" -name "*.zip" -exec unzip -t {} \;
echo "::endgroup::"
- name: Upload blob report to GitHub
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
Expand Down
131 changes: 131 additions & 0 deletions .github/workflows/tests_docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: tests docker

on:
workflow_call:

env:
FORCE_COLOR: 1

jobs:
test_linux_docker:
name: "Docker ${{ matrix.docker_tag }} ${{ matrix.docker_arch }}"
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
strategy:
fail-fast: false
matrix:
include:
- docker_tag: jammy
docker_arch: amd64
host_os: ubuntu-22.04
- docker_tag: jammy
docker_arch: arm64
host_os: ubuntu-22.04-arm
- docker_tag: noble
docker_arch: amd64
host_os: ubuntu-22.04
- docker_tag: noble
docker_arch: arm64
host_os: ubuntu-22.04-arm
runs-on: ${{ matrix.host_os }}
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
contents: read # This is required for actions/checkout to succeed
steps:
- name: Create ~/.azure directory
run: mkdir -p ~/.azure
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 22
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
- run: npm ci
- run: npm run build
# Used as a Pull-through cache for the Docker images. Only available on the
# main repo, where the secrets are present; forks fall back to Docker Hub.
- name: Azure Login
if: ${{ github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- name: Login to ACR via OIDC
if: ${{ github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
run: az acr login --name playwright
- name: Add Dockerfile cache
if: ${{ github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
run: sed -i 's/FROM ubuntu/FROM playwright.azurecr.io\/cached\/ubuntu/' utils/docker/Dockerfile.${{matrix.docker_tag}}
- run: ./utils/docker/build.sh --${{ matrix.docker_arch }} ${{ matrix.docker_tag }} playwright:localbuild
shell: bash
- name: Launch container
run: |
docker run \
--rm \
--name docker-tests \
--platform linux/${{ matrix.docker_arch }} \
--user=pwuser \
--workdir /home/pwuser \
--env CI \
--env INSIDE_DOCKER=1 \
-v ~/.azure:/root/.azure \
-d \
-t \
playwright:localbuild /bin/bash
- name: Copy repository inside docker container
run: |
# Note: we cannot do explicit `git clone` inside container because it requires some smarts to decide if github.sha or
# github.ref should be used for checkout.
# The actions/checkout action already handled this complexity for us, so we'll just copy checkout.
docker cp . docker-tests:/home/pwuser/playwright
docker exec --user root docker-tests chown -R pwuser /home/pwuser/playwright

# GIT is now picky on directory ownership
# See https://github.blog/2022-04-12-git-security-vulnerability-announced/
docker exec \
--user root \
--workdir /home/pwuser/playwright docker-tests /bin/bash -c '
git config --global --add safe.directory /home/pwuser/playwright
'
- name: Run "npm ci" inside docker
run: docker exec --workdir /home/pwuser/playwright docker-tests npm ci

- name: Run "npm run build" inside docker
run: docker exec --workdir /home/pwuser/playwright docker-tests npm run build

- name: "Run @smoke tests inside docker"
run: docker exec --workdir /home/pwuser/playwright docker-tests xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" npm run test -- --grep "@smoke"

- name: Azure Login
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- name: Upload Flakiness dashboard
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
run: |
# Flakiness dashboard has to be uploaded from-inside docker container so that it can collect meta information, e.g. arch
# See https://github.com/microsoft/playwright/blob/13b1e52d95df416fdfa7846c8a840aad8df263af/utils/upload_flakiness_dashboard.sh#L71-L86
docker exec \
--env GITHUB_REPOSITORY \
--env GITHUB_REF \
--env GITHUB_RUN_ID \
--user root \
--workdir /home/pwuser/playwright docker-tests /bin/bash -c '
set -e
# Azure-CLI is needed for upload_flakiness_dashboard.sh script.
curl -sL https://aka.ms/InstallAzureCLIDeb | bash
./utils/upload_flakiness_dashboard.sh "./test-results/report.json"
'
- name: Copy blob report from container
if: ${{ !cancelled() && (github.event_name == 'pull_request' || failure()) }}
run: docker cp "docker-tests:/home/pwuser/playwright/blob-report" "./blob-report"

- name: Upload blob report
if: ${{ !cancelled() && (github.event_name == 'pull_request' || failure()) }}
uses: ./.github/actions/upload-blob-report
with:
report_dir: blob-report
job_name: docker-${{ matrix.docker_tag }}-${{ matrix.docker_arch }}
24 changes: 24 additions & 0 deletions .github/workflows/tests_docker_changes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: tests docker (changes)

on:
push:
branches:
- main
paths:
- 'utils/docker/**'
- '.github/workflows/tests_docker*.yml'
pull_request:
branches:
- main
- release-*
paths:
- 'utils/docker/**'
- '.github/workflows/tests_docker*.yml'

jobs:
test_linux_docker:
uses: ./.github/workflows/tests_docker.yml
permissions:
id-token: write
contents: read
secrets: inherit
14 changes: 14 additions & 0 deletions .github/workflows/tests_docker_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: tests docker (release)

on:
push:
branches:
- release-*

jobs:
test_linux_docker:
uses: ./.github/workflows/tests_docker.yml
permissions:
id-token: write
contents: read
secrets: inherit
Loading
Loading