News Radar RSS

v1.59.0

microsoft/playwright Releases Developers & Open Source Score 7/10

Summary

<h2>🎬 Screencast</h2> <p>New <a href="https://playwright.dev/docs/api/class-page#page-screencast" rel="nofollow">page.screencast</a> API provides a unified interface for capturing page content with:</p> <ul> <li>Screencast recordings</li> <li>Action annotations</li> <li>Visual overlays</li> <li>Real-time frame capture</li> <li>Agentic video receipts</li> </ul> <p><a target="_blank" rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/microsoft/playwright/main/docs/src/images/release-notes-1.59-screencast-demo.gif"><img src="https://raw.githubusercontent.com/microsoft/playwright/main/docs/src/images/release-notes-1.59-screencast-demo.gif" alt="Demo" width="500" height="313" style="max-width: 100%; height: auto; max-height: 313px;"></a></p> <p><strong>Screencast recording</strong> — record video with precise start/stop control, as an alternative to the <a href="https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-video" rel="nofollow"><code>recordVideo</code></a> option:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.screencast.start({ path: 'video.webm' }); // ... perform actions ... await page.screencast.stop();"><pre><span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">path</span>: <span class="pl-s">'video.webm'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// ... perform actions ...</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><strong>Action annotations</strong> — enable built-in visual annotations that highlight interacted elements and display action titles during recording:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.screencast.showActions({ position: 'top-right' });"><pre><span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showActions</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">position</span>: <span class="pl-s">'top-right'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><a href="https://playwright.dev/docs/api/class-screencast#screencast-show-actions" rel="nofollow">screencast.showActions()</a> accepts <code>position</code> (<code>'top-left'</code>, <code>'top'</code>, <code>'top-right'</code>, <code>'bottom-left'</code>, <code>'bottom'</code>, <code>'bottom-right'</code>), <code>duration</code> (ms per annotation), and <code>fontSize</code> (px). Returns a disposable to stop showing actions.</p> <p>Action annotations can also be enabled in test fixtures via the <code>video</code> option:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="// playwright.config.ts export default defineConfig({ use: { video: { mode: 'on', show: { actions: { position: 'top-left' }, test: { position: 'top-right' }, }, }, }, });"><pre><span class="pl-c">// playwright.config.ts</span> <span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-en">defineConfig</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">use</span>: <span class="pl-kos">{</span> <span class="pl-c1">video</span>: <span class="pl-kos">{</span> <span class="pl-c1">mode</span>: <span class="pl-s">'on'</span><span class="pl-kos">,</span> <span class="pl-c1">show</span>: <span class="pl-kos">{</span> <span class="pl-c1">actions</span>: <span class="pl-kos">{</span> <span class="pl-c1">position</span>: <span class="pl-s">'top-left'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c1">test</span>: <span class="pl-kos">{</span> <span class="pl-c1">position</span>: <span class="pl-s">'top-right'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><strong>Visual overlays</strong> — add chapter titles and custom HTML overlays on top of the page for richer narration:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.screencast.showChapter('Adding TODOs', { description: 'Type and press enter for each TODO', duration: 1000, }); await page.screencast.showOverlay('<div style="color: red">Recording</div>');"><pre><span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showChapter</span><span class="pl-kos">(</span><span class="pl-s">'Adding TODOs'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">description</span>: <span class="pl-s">'Type and press enter for each TODO'</span><span class="pl-kos">,</span> <span class="pl-c1">duration</span>: <span class="pl-c1">1000</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showOverlay</span><span class="pl-kos">(</span><span class="pl-s">'<div style="color: red">Recording</div>'</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><strong>Real-time frame capture</strong> — stream JPEG-encoded frames for custom processing like thumbnails, live previews, AI vision, and more:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.screencast.start({ onFrame: ({ data }) => sendToVisionModel(data), size: { width: 800, height: 600 }, });"><pre><span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-en">onFrame</span>: <span class="pl-kos">(</span><span class="pl-kos">{</span> data <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-en">sendToVisionModel</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">size</span>: <span class="pl-kos">{</span> <span class="pl-c1">width</span>: <span class="pl-c1">800</span><span class="pl-kos">,</span> <span class="pl-c1">height</span>: <span class="pl-c1">600</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><strong>Agentic video receipts</strong> — coding agents can produce video evidence of their work. After completing a task, an agent can record a walkthrough video with rich annotations for human review:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.screencast.start({ path: 'receipt.webm' }); await page.screencast.showActions({ position: 'top-right' }); await page.screencast.showChapter('Verifying checkout flow', { description: 'Added coupon code support per ticket #1234', }); // Agent performs the verification steps... await page.locator('#coupon').fill('SAVE20'); await page.locator('#apply-coupon').click(); await expect(page.locator('.discount')).toContainText('20%'); await page.screencast.showChapter('Done', { description: 'Coupon applied, discount reflected in total', }); await page.screencast.stop();"><pre><span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">path</span>: <span class="pl-s">'receipt.webm'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showActions</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">position</span>: <span class="pl-s">'top-right'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showChapter</span><span class="pl-kos">(</span><span class="pl-s">'Verifying checkout flow'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">description</span>: <span class="pl-s">'Added coupon code support per ticket #1234'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Agent performs the verification steps...</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">locator</span><span class="pl-kos">(</span><span class="pl-s">'#coupon'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">fill</span><span class="pl-kos">(</span><span class="pl-s">'SAVE20'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">locator</span><span class="pl-kos">(</span><span class="pl-s">'#apply-coupon'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">click</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">locator</span><span class="pl-kos">(</span><span class="pl-s">'.discount'</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toContainText</span><span class="pl-kos">(</span><span class="pl-s">'20%'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">showChapter</span><span class="pl-kos">(</span><span class="pl-s">'Done'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">description</span>: <span class="pl-s">'Coupon applied, discount reflected in total'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-c1">screencast</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p>The resulting video serves as a receipt: chapter titles provide context, action annotations highlight each interaction, and the visual walkthrough is faster to review than text logs.</p> <h2>🔗 Interoperability</h2> <p>New <a href="https://playwright.dev/docs/api/class-browser#browser-bind" rel="nofollow">browser.bind()</a> API makes a launched browser available for <code>playwright-cli</code>, <code>@playwright/mcp</code>, and other clients to connect to.</p> <p><strong>Bind a browser</strong> — start a browser and bind it so others can connect:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const { endpoint } = await browser.bind('my-session', { workspaceDir: '/my/project', });"><pre><span class="pl-k">const</span> <span class="pl-kos">{</span> endpoint <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">bind</span><span class="pl-kos">(</span><span class="pl-s">'my-session'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">workspaceDir</span>: <span class="pl-s">'/my/project'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p><strong>Connect from playwright-cli</strong> — connect to the running browser from your favorite coding agent.</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="playwright-cli attach my-session playwright-cli -s my-session snapshot"><pre>playwright-cli attach my-session playwright-cli -s my-session snapshot</pre></div> <p><strong>Connect from @playwright/mcp</strong> — or point your MCP server to the running browser.</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@playwright/mcp --endpoint=my-session"><pre>@playwright/mcp --endpoint=my-session</pre></div> <p><strong>Connect from a Playwright client</strong> — use API to connect to the browser. Multiple clients at a time are supported!</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const browser = await chromium.connect(endpoint);"><pre><span class="pl-k">const</span> <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">chromium</span><span class="pl-kos">.</span><span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-s1">endpoint</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div> <p>Pass <code>host</code> and <code>port</code> options to bind over WebSocket instead of a named pipe:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const { endpoint } = await browser.bind('my-session', { host: 'localhost', port: 0, }); // endpoint is a ws:// URL"><pre><span class="pl-k">const</span> <span class="pl-kos">{</span> endpoint <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">bind</span><span class="pl-kos">(</span><span class="pl-s">'my-session'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">host</span>: <span class="pl-s">'localhost'</span><span class="pl-kos">,</span> <span class="pl-c1">port</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// endpoint is a ws:// URL</span></pre></div> <p>Call <a href="https://playwright.dev/docs/api/class-browser#browser-unbind" rel="nofollow">browser.unbind()</a> to stop accepting new connections.</p> <h2>📊 Observability</h2> <p>Run <code>playwright-cli show</code> to open the Dashboard that lists all the bound browsers, their statuses, and allows interacting with them:</p> <ul> <li>See what your agent is doing on the background browsers</li> <li>Click into the sessions for manual interventions</li> <li>Open DevTools to inspect pages from the background browsers.</li> </ul> <p><a target="_blank" rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/microsoft/playwright/main/docs/src/images/release-notes-1.59-dashboard.png"><img src="https://raw.githubusercontent.com/microsoft/playwright/main/docs/src/images/release-notes-1.59-dashboard.png" alt="Demo" width="1169" height="835" style="max-width: 100%; height: auto; max-height: 835px;"></a></p> - `playwright-cli` binds all of its browsers automatically, so you can see what your agents are doing. - Pass `PLAYWRIGHT_DASHBOARD=1` env variable to see all `@playwright/test` browsers in the dashboard. <h2>🐛 CLI debugger for agents</h2> <p>Coding agents can now run <code>npx playwright test --debug=cli</code> to attach and debug tests over <code>playwright-cli</code> — perfect for automatically fixing tests in agentic workflows:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ npx playwright test --debug=cli ### Debugging Instructions - Run "playwright-cli attach tw-87b59e" to attach to this test $ playwright-cli attach tw-87b59e ### Session `tw-87b59e` created, attached to `tw-87b59e`. Run commands with: playwright-cli --session=tw-87b59e <command> ### Paused - Navigate to "/" at output/tests/example.spec.ts:4 $ playwright-cli --session tw-87b59e step-over ### Page - Page URL: https://playwright.dev/ - Page Title: Fast and reliable end-to-end testing for modern web apps | Playwright ### Paused - Expect "toHaveTitle" at output/tests/example.spec.ts:7"><pre>$ npx playwright <span class="pl-c1">test</span> --debug=cli <span class="pl-c"><span class="pl-c">#</span>## Debugging Instructions</span> - Run <span class="pl-s"><span class="pl-pds">"</span>playwright-cli attach tw-87b59e<span class="pl-pds">"</span></span> to attach to this <span class="pl-c1">test</span> $ playwright-cli attach tw-87b59e <span class="pl-c"><span class="pl-c">#</span>## Session `tw-87b59e` created, attached to `tw-87b59e`.</span> Run commands with: playwright-cli --session=tw-87b59e <span class="pl-k"><</span>command<span class="pl-k">></span> <span class="pl-c"><span class="pl-c">#</span>## Paused</span> - Navigate to <span class="pl-s"><span class="pl-pds">"</span>/<span class="pl-pds">"</span></span> at output/tests/example.spec.ts:4 $ playwright-cli --session tw-87b59e step-over <span class="pl-c"><span class="pl-c">#</span>## Page</span> - Page URL: https://playwright.dev/ - Page Title: Fast and reliable end-to-end testing <span class="pl-k">for</span> modern web apps <span class="pl-k">|</span> Playwright <span class="pl-c"><span class="pl-c">#</span>## Paused</span> - Expect <span class="pl-s"><span class="pl-pds">"</span>toHaveTitle<span class="pl-pds">"</span></span> at output/tests/example.spec.ts:7</pre></div> <h2>📋 CLI trace analysis for agents</h2> <p>Coding agents can run <code>npx playwright trace</code> to explore <a href="https://playwright.dev/docs/trace-viewer" rel="nofollow">Playwright Trace</a> and understand failing or flaky tests from the command line:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ npx playwright trace open test-results/example-has-title-chromium/trace.zip Title: example.spec.ts:3 › has title $ npx playwright trace actions --grep="expect" # Time Action Duration ──── ───────── ─────────────────────────────────────────────────────── ──────── 9. 0:00.859 Expect "toHaveTitle" 5.1s ✗ $ npx playwright trace action 9 Expect "toHaveTitle" Error: expect(page).toHaveTitle(expected) failed Expected pattern: /Wrong Title/ Received string: "Fast and reliable end-to-end testing for modern web apps | Playwright" Timeout: 5000ms Snapshots available: before, after usage: npx playwright trace snapshot 9 --name <before|after> $ npx playwright trace snapshot 9 --name after ### Page - Page Title: Fast and reliable end-to-end testing for modern web apps | Playwright $ npx playwright trace close"><pre>$ npx playwright trace open test-results/example-has-title-chromium/trace.zip Title: example.spec.ts:3 › has title $ npx playwright trace actions --grep=<span class="pl-s"><span class="pl-pds">"</span>expect<span class="pl-pds">"</span></span> <span class="pl-c"><span class="pl-c">#</span> Time Action Duration</span> ──── ───────── ─────────────────────────────────────────────────────── ──────── 9. 0:00.859 Expect <span class="pl-s"><span class="pl-pds">"</span>toHaveTitle<span class="pl-pds">"</span></span> 5.1s ✗ $ npx playwright trace action 9 Expect <span class="pl-s"><span class="pl-pds">"</span>toHaveTitle<span class="pl-pds">"</span></span> Error: expect(page).toHaveTitle(expected) failed Expected pattern: /Wrong Title/ Received string: <span class="pl-s"><span class="pl-pds">"</span>Fast and reliable end-to-end testing for modern web apps | Playwright<span class="pl-pds">"</span></span> Timeout: 5000ms Snapshots available: before, after usage: npx playwright trace snapshot 9 --name <span class="pl-k"><</span>before<span class="pl-k">|</span>after<span class="pl-k">></span> $ npx playwright trace snapshot 9 --name after <span class="pl-c"><span class="pl-c">#</span>## Page</span> - Page Title: Fast and reliable end-to-end testing <span class="pl-k">for</span> modern web apps <span class="pl-k">|</span> Playwright $ npx playwright trace close</pre></div> <h2>♻️ <code>await using</code></h2> <p>Many APIs now return <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncDispose" rel="nofollow">async disposables</a>, enabling the <code>await using</code> syntax for automatic cleanup:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await using page = await context.newPage(); { await using route = await page.route('**/*', route => route.continue()); await using script = await page.addInitScript('console.log("init script here")'); await page.goto('https://playwright.dev'); // do something } // route and init script have been removed at this point"><pre><span class="pl-k">await</span> <span class="pl-s1">using</span> <span class="pl-s1">page</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">newPage</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">{</span> <span class="pl-k">await</span> <span class="pl-s1">using</span> <span class="pl-s1">route</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">route</span><span class="pl-kos">(</span><span class="pl-s">'**/*'</span><span class="pl-kos">,</span> <span class="pl-s1">route</span> <span class="pl-c1">=></span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">continue</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">using</span> <span class="pl-s1">script</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">addInitScript</span><span class="pl-kos">(</span><span class="pl-s">'console.log("init script here")'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-s">'https://playwright.dev'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// do something</span> <span class="pl-kos">}</span> <span class="pl-c">// route and init script have been removed at this point</span></pre></div> <h2>🔍 Snapshots and Locators</h2> <ul> <li>Method <a href="https://playwright.dev/docs/api/class-page#page-aria-snapshot" rel="nofollow">page.ariaSnapshot()</a> to capture the aria snapshot of the page — equivalent to <code>page.locator('body').ariaSnapshot()</code>.</li> <li>Options <code>depth</code> and <code>mode</code> in <a href="https://playwright.dev/docs/api/class-locator#locator-aria-snapshot" rel="nofollow">locator.ariaSnapshot()</a>.</li> <li>Method <a href="https://playwright.dev/docs/api/class-locator#locator-normalize" rel="nofollow">locator.normalize()</a> converts a locator to follow best practices like test ids and aria roles.</li> <li>Method <a href="https://playwright.dev/docs/api/class-page#page-pick-locator" rel="nofollow">page.pickLocator()</a> enters an interactive mode where hovering over elements highlights them and shows the corresponding locator. Click an element to get its <a href="https://playwright.dev/docs/api/class-locator" rel="nofollow">Locator</a> back. Use <a href="https://playwright.dev/docs/api/class-page#page-cancel-pick-locator" rel="nofollow">page.cancelPickLocator()</a> to cancel.</li> </ul> <h2>New APIs</h2> <h3>Screencast</h3> <ul> <li><a href="https://playwright.dev/docs/api/class-page#page-screencast" rel="nofollow">page.screencast</a> provides video recording, real-time frame streaming, and overlay management.</li> <li>Methods <a href="https://playwright.dev/docs/api/class-screencast#screencast-start" rel="nofollow">screencast.start()</a> and <a href="https://playwright.dev/docs/api/class-screencast#screencast-stop" rel="nofollow">screencast.stop()</a> for recording and frame capture.</li> <li>Methods <a href="https://playwright.dev/docs/api/class-screencast#screencast-show-actions" rel="nofollow">screencast.showActions()</a> and <a href="https://playwright.dev/docs/api/class-screencast#screencast-hide-actions" rel="nofollow">screencast.hideActions()</a> for action annotations.</li> <li>Methods <a href="https://playwright.dev/docs/api/class-screencast#screencast-show-chapter" rel="nofollow">screencast.showChapter()</a> and <a href="https://playwright.dev/docs/api/class-screencast#screencast-show-overlay" rel="nofollow">screencast.showOverlay()</a> for visual overlays.</li> <li>Methods <a href="https://playwright.dev/docs/api/class-screencast#screencast-show-overlays" rel="nofollow">screencast.showOverlays()</a> and <a href="https://playwright.dev/docs/api/class-screencast#screencast-hide-overlays" rel="nofollow">screencast.hideOverlays()</a> for overlay visibility control.</li> </ul> <h3>Storage, Console and Errors</h3> <ul> <li>Method <a href="https://playwright.dev/docs/api/class-browsercontext#browser-context-set-storage-state" rel="nofollow">browserContext.setStorageState()</a> clears existing cookies, local storage, and IndexedDB for all origins and sets a new storage state — no need to create a new context.</li> <li>Methods <a href="https://playwright.dev/docs/api/class-page#page-clear-console-messages" rel="nofollow">page.clearConsoleMessages()</a> and <a href="https://playwright.dev/docs/api/class-page#page-clear-page-errors" rel="nofollow">page.clearPageErrors()</a> to clear stored messages and errors.</li> <li>Option <code>filter</code> in <a href="https://playwright.dev/docs/api/class-page#page-console-messages" rel="nofollow">page.consoleMessages()</a> and <a href="https://playwright.dev/docs/api/class-page#page-page-errors" rel="nofollow">page.pageErrors()</a> controls which messages are returned.</li> <li>Method <a href="https://playwright.dev/docs/api/class-consolemessage#console-message-timestamp" rel="nofollow">consoleMessage.timestamp()</a>.</li> </ul> <h3>Miscellaneous</h3> <ul> <li><a href="https://playwright.dev/docs/api/class-browsercontext#browser-context-debugger" rel="nofollow">browserContext.debugger</a> provides programmatic control over the Playwright debugger.</li> <li>Method <a href="https://playwright.dev/docs/api/class-browsercontext#browser-context-is-closed" rel="nofollow">browserContext.isClosed()</a>.</li> <li>Method <a href="https://playwright.dev/docs/api/class-request#request-existing-response" rel="nofollow">request.existingResponse()</a> returns the response without waiting.</li> <li>Method <a href="https://playwright.dev/docs/api/class-response#response-http-version" rel="nofollow">response.httpVersion()</a> returns the HTTP version used by the response.</li> <li>Events <a href="https://playwright.dev/docs/api/class-cdpsession#cdp-session-event-event" rel="nofollow">cdpSession.on('event')</a> and <a href="https://playwright.dev/docs/api/class-cdpsession#cdp-session-event-close" rel="nofollow">cdpSession.on('close')</a> for CDP sessions.</li> <li>Option <code>live</code> in <a href="https://playwright.dev/docs/api/class-tracing#tracing-start" rel="nofollow">tracing.start()</a> for real-time trace updates.</li> <li>Option <code>artifactsDir</code> in <a href="https://playwright.dev/docs/api/class-browsertype#browser-type-launch" rel="nofollow">browserType.launch()</a> to configure the artifacts directory.</li> </ul> <h2>🛠️ Other improvements</h2> <ul> <li>UI Mode has an option to only show tests affected by source changes.</li> <li>UI Mode and Trace Viewer have improved action filtering.</li> <li>HTML Reporter shows the list of runs from the same worker.</li> <li>HTML Reporter allows filtering test steps for quick search.</li> <li>New trace mode <code>'retain-on-failure-and-retries'</code> records a trace for each test run and retains all traces when an attempt fails — great for comparing a passing trace with a failing one from a flaky test.</li> </ul> <h2>Known Issues <g-emoji class="g-emoji" alias="warning">⚠️</g-emoji><g-emoji class="g-emoji" alias="warning">⚠️</g-emoji></h2> <ul> <li><code>navigator.platform</code> emulation can cause Ctrl or Meta dispatching errors (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="4188854024" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/40009" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/40009/hovercard" href="https://github.com/microsoft/playwright/issues/40009">#40009</a>). Pass <code>PLAYWRIGHT_NO_UA_PLATFORM = '1'</code> environment variable while we are issuing a patch release. Let us know in the issue how it affected you.</li> </ul> <h2>Breaking Changes <g-emoji class="g-emoji" alias="warning">⚠️</g-emoji></h2> <ul> <li>Removed macOS 14 support for WebKit. We recommend upgrading your macOS version, or keeping an older Playwright version.</li> <li>Removed <code>@playwright/experimental-ct-svelte</code> package.</li> <li><code>junit</code> test reporter now differentiates between types of errors, so some of the previous <code><failure></code>s are now reported as <code><error></code>s.</li> </ul> <h2>Browser Versions</h2> <ul> <li>Chromium 147.0.7727.15</li> <li>Mozilla Firefox 148.0.2</li> <li>WebKit 26.4</li> </ul> <p>This version was also tested against the following stable channels:</p> <ul> <li>Google Chrome 146</li> <li>Microsoft Edge 146</li> </ul>

Open SourceTestingDeveloper Tools

News Radar provides aggregated summaries. Full content and copyright remain with the original publisher.