From a715c0f5550ff6874a7ce4a895db2faa3d004eb8 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 20 Mar 2026 22:13:20 +0000 Subject: [PATCH] chore: update APIs for ports --- docs/src/api/class-apiresponseassertions.md | 26 +++++++++++++++++++ docs/src/api/class-browsercontext.md | 9 ------- docs/src/api/class-cdpsession.md | 2 +- docs/src/api/class-debugger.md | 1 - docs/src/api/class-page.md | 23 +++++++++++++--- docs/src/api/class-screencast.md | 4 +++ packages/playwright-client/types/types.d.ts | 17 +++++------- .../src/client/browserContext.ts | 24 +---------------- .../playwright-core/src/client/cdpSession.ts | 2 +- packages/playwright-core/types/types.d.ts | 17 +++++------- tests/library/browsercontext-basic.spec.ts | 14 ---------- tests/library/chromium/session.spec.ts | 11 ++++---- utils/doclint/generateDotnetApi.js | 8 +++++- utils/generate_types/index.js | 2 +- utils/generate_types/overrides.d.ts | 1 - 15 files changed, 79 insertions(+), 82 deletions(-) diff --git a/docs/src/api/class-apiresponseassertions.md b/docs/src/api/class-apiresponseassertions.md index a9913fe812274..720b3dcd40554 100644 --- a/docs/src/api/class-apiresponseassertions.md +++ b/docs/src/api/class-apiresponseassertions.md @@ -46,6 +46,24 @@ def test_navigates_to_login_page(page: Page) -> None: expect(response).to_be_ok() ``` +```csharp +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; + +namespace PlaywrightTests; + +[TestClass] +public class ExampleTests : PageTest +{ + [TestMethod] + public async Task NavigatesToLoginPage() + { + var response = await Page.APIRequest.GetAsync("https://playwright.dev"); + await Expect(response).ToBeOKAsync(); + } +} +``` + ## property: APIResponseAssertions.not * since: v1.20 * langs: java, js, csharp @@ -65,6 +83,10 @@ await expect(response).not.toBeOK(); assertThat(response).not().isOK(); ``` +```csharp +await Expect(response).Not.ToBeOKAsync(); +``` + ## async method: APIResponseAssertions.NotToBeOK * since: v1.19 * langs: python @@ -102,3 +124,7 @@ from playwright.sync_api import expect # ... expect(response).to_be_ok() ``` + +```csharp +await Expect(response).ToBeOKAsync(); +``` diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index e45950fe1bcec..8e9b75ac05c48 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -76,7 +76,6 @@ Playwright has ability to mock clock and passage of time. ## property: BrowserContext.debugger * since: v1.59 -* langs: js - type: <[Debugger]> Debugger allows to pause and resume the execution. @@ -1004,14 +1003,6 @@ named `page`, but it can be a `Page` or `Frame` type. Creates a new page in the browser context. -## method: BrowserContext.contextOptions -* since: v1.59 -* langs: js -- returns: <[Object]> - -Returns the context options that were used to create this browser context. The return type matches the options -accepted by [`method: Browser.newContext`]. - ## method: BrowserContext.pages * since: v1.8 - returns: <[Array]<[Page]>> diff --git a/docs/src/api/class-cdpsession.md b/docs/src/api/class-cdpsession.md index 6573d6386095c..d14b51a86299e 100644 --- a/docs/src/api/class-cdpsession.md +++ b/docs/src/api/class-cdpsession.md @@ -69,7 +69,7 @@ client.send("Animation.setPlaybackRate", params); ## event: CDPSession.close * since: v1.59 -* langs: js +- argument: <[CDPSession]> Emitted when the session is closed, either because the target was closed or `session.detach()` was called. diff --git a/docs/src/api/class-debugger.md b/docs/src/api/class-debugger.md index 044d1acfa9fd8..f7d66d4d17cbb 100644 --- a/docs/src/api/class-debugger.md +++ b/docs/src/api/class-debugger.md @@ -1,6 +1,5 @@ # class: Debugger * since: v1.59 -* langs: js API for controlling the Playwright debugger. The debugger allows pausing script execution and inspecting the page. Obtain the debugger instance via [`property: BrowserContext.debugger`]. diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index 82eded0f08949..2043bf80fbdf0 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -717,7 +717,6 @@ Brings page to front (activates tab). ## async method: Page.cancelPickLocator * since: v1.59 -* langs: js Cancels an ongoing [`method: Page.pickLocator`] call by deactivating pick locator mode. If no pick locator mode is active, this method is a no-op. @@ -2725,7 +2724,6 @@ Returns up to (currently) 200 last page errors from this page. See [`event: Page ### option: Page.pageErrors.filter * since: v1.59 -* langs: js - `filter` <[PageErrorsFilter]<"all"|"sinceNavigation">> Controls which errors are returned: @@ -3036,7 +3034,6 @@ Whether or not to embed the document outline into the PDF. Defaults to `false`. ## async method: Page.pickLocator * since: v1.59 -* langs: js - returns: <[Locator]> Enters pick locator mode where hovering over page elements highlights them and shows the corresponding locator. @@ -3049,6 +3046,26 @@ const locator = await page.pickLocator(); console.log(locator); ``` +```java +Locator locator = page.pickLocator(); +System.out.println(locator); +``` + +```python async +locator = await page.pick_locator() +print(locator) +``` + +```python sync +locator = page.pick_locator() +print(locator) +``` + +```csharp +var locator = await page.PickLocatorAsync(); +Console.WriteLine(locator); +``` + ## async method: Page.press * since: v1.8 * discouraged: Use locator-based [`method: Locator.press`] instead. Read more about [locators](../locators.md). diff --git a/docs/src/api/class-screencast.md b/docs/src/api/class-screencast.md index 63798eda9ace6..b1205845d8b00 100644 --- a/docs/src/api/class-screencast.md +++ b/docs/src/api/class-screencast.md @@ -6,6 +6,7 @@ Interface for capturing screencast frames from a page. ## async method: Screencast.start * since: v1.59 +* langs: js - returns: <[Disposable]> Starts capturing screencast frames. @@ -30,6 +31,7 @@ Callback that receives JPEG-encoded frame data. ### option: Screencast.start.preferredSize * since: v1.59 +* langs: js - `preferredSize` ?<[Object]> - `width` <[int]> Max frame width in pixels. - `height` <[int]> Max frame height in pixels. @@ -42,6 +44,7 @@ Defaults to 800×800. ### option: Screencast.start.annotate * since: v1.59 +* langs: js - `annotate` ?<[Object]> - `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`. @@ -49,5 +52,6 @@ If specified, enables visual annotations on interacted elements during screencas ## async method: Screencast.stop * since: v1.59 +* langs: js Stops the screencast started with [`method: Screencast.start`]. diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index b45d468d5f167..e1ef6201787b0 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -8318,11 +8318,6 @@ export interface BrowserContext { behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; - /** - * Returns the context options that were used to create this browser context. The return type matches the options - * accepted by [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). - */ - contextOptions(): BrowserContextOptions; /** * This event is not emitted. */ @@ -15830,7 +15825,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - on(event: 'close', listener: () => any): this; + on(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing @@ -15860,7 +15855,7 @@ export interface CDPSession { /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. */ - once(event: 'close', listener: () => any): this; + once(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. @@ -15880,7 +15875,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - addListener(event: 'close', listener: () => any): this; + addListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing @@ -15910,7 +15905,7 @@ export interface CDPSession { /** * Removes an event listener added by `on` or `addListener`. */ - removeListener(event: 'close', listener: () => any): this; + removeListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Removes an event listener added by `on` or `addListener`. @@ -15930,7 +15925,7 @@ export interface CDPSession { /** * Removes an event listener added by `on` or `addListener`. */ - off(event: 'close', listener: () => any): this; + off(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Removes an event listener added by `on` or `addListener`. @@ -15950,7 +15945,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - prependListener(event: 'close', listener: () => any): this; + prependListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index fc12a9e69b3bb..21f8cd349ee0d 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -38,7 +38,7 @@ import { WebError } from './webError'; import { Worker } from './worker'; import { TimeoutSettings } from './timeoutSettings'; import { mkdirIfNeeded } from './fileUtils'; -import { headersArrayToObject, headersObjectToArray } from '../utils/isomorphic/headers'; +import { headersObjectToArray } from '../utils/isomorphic/headers'; import { urlMatchesEqual } from '../utils/isomorphic/urlMatch'; import { isRegExp, isString } from '../utils/isomorphic/rtti'; import { rewriteErrorMessage } from '../utils/isomorphic/stackTrace'; @@ -290,10 +290,6 @@ export class BrowserContext extends ChannelOwner return this._browser; } - contextOptions() { - return contextParamsToPublicOptions(this._options); - } - pages(): Page[] { return [...this._pages]; } @@ -607,24 +603,6 @@ export async function prepareBrowserContextParams(platform: Platform, options: B return contextParams; } -function contextParamsToPublicOptions(params: channels.BrowserNewContextParams): api.BrowserContextOptions { - const result = { - ...params, - viewport: params.noDefaultViewport ? null : params.viewport, - extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders, false) : undefined, - colorScheme: params.colorScheme === 'no-override' ? null : params.colorScheme, - reducedMotion: params.reducedMotion === 'no-override' ? null : params.reducedMotion, - forcedColors: params.forcedColors === 'no-override' ? null : params.forcedColors, - contrast: params.contrast === 'no-override' ? null : params.contrast, - acceptDownloads: params.acceptDownloads === 'accept' ? true : params.acceptDownloads === 'deny' ? false : undefined, - storageState: undefined, - }; - delete result.clientCertificates; - delete result.noDefaultViewport; - delete result.selectorEngines; - return result; -} - function toAcceptDownloadsProtocol(acceptDownloads?: boolean) { if (acceptDownloads === undefined) return undefined; diff --git a/packages/playwright-core/src/client/cdpSession.ts b/packages/playwright-core/src/client/cdpSession.ts index cb0553a3ad000..d27b2aaeb29e0 100644 --- a/packages/playwright-core/src/client/cdpSession.ts +++ b/packages/playwright-core/src/client/cdpSession.ts @@ -34,7 +34,7 @@ export class CDPSession extends ChannelOwner impleme }); this._channel.on('close', () => { - this.emit('close'); + this.emit('close', this); }); this.on = super.on; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index b45d468d5f167..e1ef6201787b0 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -8318,11 +8318,6 @@ export interface BrowserContext { behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; - /** - * Returns the context options that were used to create this browser context. The return type matches the options - * accepted by [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). - */ - contextOptions(): BrowserContextOptions; /** * This event is not emitted. */ @@ -15830,7 +15825,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - on(event: 'close', listener: () => any): this; + on(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing @@ -15860,7 +15855,7 @@ export interface CDPSession { /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. */ - once(event: 'close', listener: () => any): this; + once(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. @@ -15880,7 +15875,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - addListener(event: 'close', listener: () => any): this; + addListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing @@ -15910,7 +15905,7 @@ export interface CDPSession { /** * Removes an event listener added by `on` or `addListener`. */ - removeListener(event: 'close', listener: () => any): this; + removeListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Removes an event listener added by `on` or `addListener`. @@ -15930,7 +15925,7 @@ export interface CDPSession { /** * Removes an event listener added by `on` or `addListener`. */ - off(event: 'close', listener: () => any): this; + off(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Removes an event listener added by `on` or `addListener`. @@ -15950,7 +15945,7 @@ export interface CDPSession { /** * Emitted when the session is closed, either because the target was closed or `session.detach()` was called. */ - prependListener(event: 'close', listener: () => any): this; + prependListener(event: 'close', listener: (cdpSession: CDPSession) => any): this; /** * Emitted for every CDP event received from the session. Allows subscribing to all CDP events at once without knowing diff --git a/tests/library/browsercontext-basic.spec.ts b/tests/library/browsercontext-basic.spec.ts index 050d7c36ebcbc..795e8d1932dae 100644 --- a/tests/library/browsercontext-basic.spec.ts +++ b/tests/library/browsercontext-basic.spec.ts @@ -33,20 +33,6 @@ it('should create new context @smoke', async function({ browser }) { await context2.close(); }); -it('should return context options', async function({ browser }) { - const context = await browser.newContext({ - userAgent: 'custom-ua', - locale: 'fr-FR', - extraHTTPHeaders: { 'foo': 'bar' }, - }); - const options = context.contextOptions(); - expect(options.userAgent).toBe('custom-ua'); - expect(options.locale).toBe('fr-FR'); - expect(options.extraHTTPHeaders).toEqual({ 'foo': 'bar' }); - expect((options as any).noDefaultViewport).toBeUndefined(); // internal option should not leak - await context.close(); -}); - it('should be able to click across browser contexts', async function({ browser }) { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29096' }); expect(browser.contexts().length).toBe(0); diff --git a/tests/library/chromium/session.spec.ts b/tests/library/chromium/session.spec.ts index 830a057514cd8..aaf3ff5869c9f 100644 --- a/tests/library/chromium/session.spec.ts +++ b/tests/library/chromium/session.spec.ts @@ -160,19 +160,20 @@ it('should emit event for each CDP event', async function({ page, server }) { it('should emit close event when session is detached', async function({ page }) { const client = await page.context().newCDPSession(page); - let closeFired = false; - client.on('close', () => closeFired = true); + let closedSession: any = null; + client.on('close', session => closedSession = session); await client.detach(); - expect(closeFired).toBe(true); + expect(closedSession).toBe(client); }); browserTest('should emit close event when page closes', async function({ browser }) { const context = await browser.newContext(); const page = await context.newPage(); const session = await context.newCDPSession(page); - const closePromise = new Promise(f => session.on('close', f)); + const closePromise = new Promise(f => session.on('close', f)); await page.close(); - await closePromise; + const closedSession = await closePromise; + expect(closedSession).toBe(session); await context.close(); }); diff --git a/utils/doclint/generateDotnetApi.js b/utils/doclint/generateDotnetApi.js index d46cd62ffd755..5f4182ea4f1ef 100644 --- a/utils/doclint/generateDotnetApi.js +++ b/utils/doclint/generateDotnetApi.js @@ -86,6 +86,7 @@ classNameMap.set('Date', 'DateTime'); classNameMap.set('URL', 'string'); classNameMap.set('RegExp', 'Regex'); classNameMap.set('Readable', 'Stream'); +classNameMap.set('Disposable', 'IAsyncDisposable'); /** * @@ -133,6 +134,8 @@ function renderClass(clazz) { const name = classNameMap.get(clazz.name); if (name === 'TimeoutException') return; + if (name === 'IAsyncDisposable') + return; const body = []; for (const member of clazz.membersArray) { @@ -323,7 +326,10 @@ function renderMember(member, parent, options, out) { renderMemberDoc(member, out); if (member.deprecated) out.push(`[System.Obsolete]`); - out.push(`event EventHandler<${type}> ${name};`); + if (type === 'void') + out.push(`event EventHandler ${name};`); + else + out.push(`event EventHandler<${type}> ${name};`); return; } diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index a34e6f7941634..ad0531180884f 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -217,7 +217,7 @@ class TypesGenerator { return null; if (type.includes('{')) return 'data'; - return (type[0].toLowerCase() + type.slice(1)).replace(/\|/g, 'Or'); + return type.replace(/^[A-Z]+/, match => match.length === 1 ? match.toLowerCase() : match.slice(0, -1).toLowerCase() + match.slice(-1)).replace(/\|/g, 'Or'); } /** diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 2c4b2a0cfa23c..6f7f23037c16b 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -134,7 +134,6 @@ export interface BrowserContext { behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; - contextOptions(): BrowserContextOptions; } export interface Browser {