From 62b7feb18856f134e05ab1ac89edf439a26e5678 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 21 Jan 2026 12:25:45 +0100 Subject: [PATCH 1/3] chore: hide stuff --- docs/src/api/class-page.md | 48 --- docs/src/api/class-pageagent.md | 134 ------- docs/src/test-api/class-fixtures.md | 4 - docs/src/test-api/class-fullconfig.md | 9 - docs/src/test-api/class-testconfig.md | 9 - docs/src/test-api/class-testoptions.md | 17 - packages/playwright-client/types/types.d.ts | 327 ------------------ packages/playwright-core/src/client/page.ts | 2 + .../playwright-core/src/client/pageAgent.ts | 1 + packages/playwright-core/types/types.d.ts | 327 ------------------ packages/playwright/src/common/config.ts | 5 +- packages/playwright/src/index.ts | 8 +- .../playwright/src/isomorphic/teleReceiver.ts | 1 + packages/playwright/src/program.ts | 1 - .../playwright/src/transform/transform.ts | 2 +- packages/playwright/types/test.d.ts | 38 +- tests/library/agent-helpers.ts | 4 + tests/library/agent-perform.spec.ts | 2 + utils/doclint/missingDocs.js | 4 + utils/generate_types/overrides-test.d.ts | 22 +- utils/generate_types/overrides.d.ts | 11 - 21 files changed, 27 insertions(+), 949 deletions(-) delete mode 100644 docs/src/api/class-pageagent.md diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index 55399a4d678f8..b438dd045c978 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -709,54 +709,6 @@ current working directory. Raw CSS content to be injected into frame. -## async method: Page.agent -* since: v1.58 -* langs: js -- returns: <[PageAgent]> - -Initialize page agent with the llm provider and cache. - -### option: Page.agent.cache -* since: v1.58 -- `cache` <[Object]> - - `cacheFile` ?<[string]> Cache file to use/generate code for performed actions into. Cache is not used if not specified (default). - - `cacheOutFile` ?<[string]> When specified, generated entries are written into the `cacheOutFile` instead of updating the `cacheFile`. - -### option: Page.agent.expect -* since: v1.58 -- `expect` <[Object]> - - `timeout` ?<[int]> Default timeout for expect calls in milliseconds, defaults to 5000ms. - -### option: Page.agent.limits -* since: v1.58 -- `limits` <[Object]> - - `maxTokens` ?<[int]> Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. Defaults to unlimited. - - `maxActions` ?<[int]> Maximum number of agentic actions to generate, defaults to 10. - - `maxActionRetries` ?<[int]> Maximum number retries per action, defaults to 3. - -Limits to use for the agentic loop. - -### option: Page.agent.provider -* since: v1.58 -- `provider` <[Object]> - - `api` <[PageAgentAPI]<"openai"|"openai-compatible"|"anthropic"|"google">> API to use. - - `apiEndpoint` ?<[string]> Endpoint to use if different from default. - - `apiKey` <[string]> API key for the LLM provider. - - `apiTimeout` ?<[int]> Amount of time to wait for the provider to respond to each request. - - `model` <[string]> Model identifier within the provider. Required in non-cache mode. - -### option: Page.agent.secrets -* since: v1.58 -- `secrets` ?<[Object]<[string], [string]>> - -Secrets to hide from the LLM. - -### option: Page.agent.systemPrompt -* since: v1.58 -- `systemPrompt` <[string]> - -System prompt for the agent's loop. - ## async method: Page.bringToFront * since: v1.8 diff --git a/docs/src/api/class-pageagent.md b/docs/src/api/class-pageagent.md deleted file mode 100644 index 0f04e2b04d851..0000000000000 --- a/docs/src/api/class-pageagent.md +++ /dev/null @@ -1,134 +0,0 @@ -# class: PageAgent -* since: v1.58 -* langs: js - -## event: PageAgent.turn -* since: v1.58 -- argument: <[Object]> - - `role` <[string]> - - `message` <[string]> - - `usage` ?<[Object]> - - `inputTokens` <[int]> - - `outputTokens` <[int]> - -Emitted when the agent makes a turn. - -## async method: PageAgent.dispose -* since: v1.58 - -Dispose this agent. - -## async method: PageAgent.expect -* since: v1.58 - -Expect certain condition to be met. - -**Usage** - -```js -await agent.expect('"0 items" to be reported'); -``` - -### param: PageAgent.expect.expectation -* since: v1.58 -- `expectation` <[string]> - -Expectation to assert. - -### option: PageAgent.expect.timeout -* since: v1.58 -- `timeout` <[float]> - -Expect timeout in milliseconds. Defaults to `5000`. The default value can be changed via `expect.timeout` option in the config, or by specifying the `expect` property of the [`option: Page.agent.expect`] option. Pass `0` to disable timeout. - -### option: PageAgent.expect.-inline- = %%-page-agent-call-options-v1.58-%% -* since: v1.58 - -## async method: PageAgent.extract -* since: v1.58 -- returns: <[Object]> - - `result` <[any]> - - `usage` <[Object]> - - `turns` <[int]> - - `inputTokens` <[int]> - - `outputTokens` <[int]> - -Extract information from the page using the agentic loop, return it in a given Zod format. - -**Usage** - -```js -await agent.extract('List of items in the cart', z.object({ - title: z.string().describe('Item title to extract'), - price: z.string().describe('Item price to extract'), -}).array()); -``` - -### param: PageAgent.extract.query -* since: v1.58 -- `query` <[string]> - -Task to perform using agentic loop. - -### param: PageAgent.extract.schema -* since: v1.58 -- `schema` <[z.ZodSchema]> - -### option: PageAgent.extract.timeout -* since: v1.58 -- `timeout` <[float]> - -Extract timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in the config, or by using the [`method: BrowserContext.setDefaultTimeout`] or -[`method: Page.setDefaultTimeout`] methods. Pass `0` to disable timeout. - -### option: PageAgent.extract.-inline- = %%-page-agent-call-options-v1.58-%% -* since: v1.58 - - -## async method: PageAgent.perform -* since: v1.58 -- returns: <[Object]> - - `usage` <[Object]> - - `turns` <[int]> - - `inputTokens` <[int]> - - `outputTokens` <[int]> - -Perform action using agentic loop. - -**Usage** - -```js -await agent.perform('Click submit button'); -``` - -### param: PageAgent.perform.task -* since: v1.58 -- `task` <[string]> - -Task to perform using agentic loop. - -### option: PageAgent.perform.timeout -* since: v1.58 -- `timeout` <[float]> - -Perform timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in the config, or by using the [`method: BrowserContext.setDefaultTimeout`] or -[`method: Page.setDefaultTimeout`] methods. Pass `0` to disable timeout. - -### option: PageAgent.perform.-inline- = %%-page-agent-call-options-v1.58-%% -* since: v1.58 - -## async method: PageAgent.usage -* since: v1.58 -- returns: <[Object]> - - `turns` <[int]> - - `inputTokens` <[int]> - - `outputTokens` <[int]> - -Returns the current token usage for this agent. - -**Usage** - -```js -const usage = await agent.usage(); -console.log(`Tokens used: ${usage.inputTokens} in, ${usage.outputTokens} out`); -``` diff --git a/docs/src/test-api/class-fixtures.md b/docs/src/test-api/class-fixtures.md index 9ec8e33f92cd3..0c08b19da3b2a 100644 --- a/docs/src/test-api/class-fixtures.md +++ b/docs/src/test-api/class-fixtures.md @@ -18,10 +18,6 @@ Given the test above, Playwright Test will set up the `page` fixture before runn Playwright Test comes with builtin fixtures listed below, and you can add your own fixtures as well. Playwright Test also [provides options][TestOptions] to configure [`property: Fixtures.browser`], [`property: Fixtures.context`] and [`property: Fixtures.page`]. -## property: Fixtures.agent -* since: v1.58 -- type: <[PageAgent]> - ## property: Fixtures.browser * since: v1.10 - type: <[Browser]> diff --git a/docs/src/test-api/class-fullconfig.md b/docs/src/test-api/class-fullconfig.md index 1f3ee92df7750..7ce3da974bb71 100644 --- a/docs/src/test-api/class-fullconfig.md +++ b/docs/src/test-api/class-fullconfig.md @@ -104,15 +104,6 @@ See [`property: TestConfig.reportSlowTests`]. Base directory for all relative paths used in the reporters. -## property: FullConfig.runAgents -* since: v1.58 -- type: <['RunAgentsMode]<"all"|"missing"|"none">> - -Whether to run LLM agent for [PageAgent]: -* "all" disregards existing cache and performs all actions via LLM -* "missing" only performs actions that don't have generated cache actions -* "none" does not talk to LLM at all, relies on the cached actions (default) - ## property: FullConfig.shard * since: v1.10 - type: <[null]|[Object]> diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index a01babad1f23b..ea08d8af46ae4 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -514,15 +514,6 @@ export default defineConfig({ }); ``` -## property: TestConfig.runAgents -* since: v1.58 -- type: ?<['RunAgentsMode]<"all"|"missing"|"none">> - -Whether to run LLM agent for [PageAgent]: -* "all" disregards existing cache and performs all actions via LLM -* "missing" only performs actions that don't have generated cache actions -* "none" does not talk to LLM at all, relies on the cached actions (default) - ## property: TestConfig.shard * since: v1.10 - type: ?<[null]|[Object]> diff --git a/docs/src/test-api/class-testoptions.md b/docs/src/test-api/class-testoptions.md index 4c60a5c89617d..c2854306164ad 100644 --- a/docs/src/test-api/class-testoptions.md +++ b/docs/src/test-api/class-testoptions.md @@ -46,23 +46,6 @@ export default defineConfig({ }); ``` -## property: TestOptions.agentOptions -* since: v1.58 -- type: <[Object]> - - `provider` <[Object]> - - `api` <[PageAgentAPI]<"openai"|"openai-compatible"|"anthropic"|"google">> API to use. - - `apiEndpoint` ?<[string]> Endpoint to use if different from default. - - `apiKey` <[string]> API key for the LLM provider. - - `apiTimeout` ?<[int]> Amount of time to wait for the provider to respond to each request. - - `model` <[string]> Model identifier within the provider. Required in non-cache mode. - - `cachePathTemplate` ?<[string]> Cache file template to use/generate code for performed actions into. - - `limits` <[Object]> - - `maxTokens` ?<[int]> Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. Defaults to unlimited. - - `maxActions` ?<[int]> Maximum number of agentic actions to generate, defaults to 10. - - `maxActionRetries` ?<[int]> Maximum number retries per action, defaults to 3. - - `secrets` ?<[Object]<[string], [string]>> Secrets to hide from the LLM. - - `systemPrompt` <[string]> System prompt for the agent's loop. - ## property: TestOptions.baseURL = %%-context-option-baseURL-%% * since: v1.10 diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index 50dd490708e13..f6e6165885f0a 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -27,13 +27,6 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector state?: 'visible'|'attached'; }; -// @ts-ignore this will be any if zod is not installed -import { ZodTypeAny, z } from 'zod'; -// @ts-ignore this will be any if zod is not installed -import * as z3 from 'zod/v3'; -type ZodSchema = ZodTypeAny | z3.ZodTypeAny; -type InferZodSchema = T extends z3.ZodTypeAny ? z3.infer : T extends ZodTypeAny ? z.infer : never; - /** * Page provides methods to interact with a single tab in a [Browser](https://playwright.dev/docs/api/class-browser), * or an [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One @@ -2095,89 +2088,6 @@ export interface Page { url?: string; }): Promise; - /** - * Initialize page agent with the llm provider and cache. - * @param options - */ - agent(options?: { - cache?: { - /** - * Cache file to use/generate code for performed actions into. Cache is not used if not specified (default). - */ - cacheFile?: string; - - /** - * When specified, generated entries are written into the `cacheOutFile` instead of updating the `cacheFile`. - */ - cacheOutFile?: string; - }; - - expect?: { - /** - * Default timeout for expect calls in milliseconds, defaults to 5000ms. - */ - timeout?: number; - }; - - /** - * Limits to use for the agentic loop. - */ - limits?: { - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to unlimited. - */ - maxTokens?: number; - - /** - * Maximum number of agentic actions to generate, defaults to 10. - */ - maxActions?: number; - - /** - * Maximum number retries per action, defaults to 3. - */ - maxActionRetries?: number; - }; - - provider?: { - /** - * API to use. - */ - api: "openai"|"openai-compatible"|"anthropic"|"google"; - - /** - * Endpoint to use if different from default. - */ - apiEndpoint?: string; - - /** - * API key for the LLM provider. - */ - apiKey: string; - - /** - * Amount of time to wait for the provider to respond to each request. - */ - apiTimeout?: number; - - /** - * Model identifier within the provider. Required in non-cache mode. - */ - model: string; - }; - - /** - * Secrets to hide from the LLM. - */ - secrets?: { [key: string]: string; }; - - /** - * System prompt for the agent's loop. - */ - systemPrompt?: string; - }): Promise; - /** * Brings page to front (activates tab). */ @@ -5294,243 +5204,6 @@ export interface Page { [Symbol.asyncDispose](): Promise; } -/** - * - */ -export interface PageAgent { - /** - * Extract information from the page using the agentic loop, return it in a given Zod format. - * - * **Usage** - * - * ```js - * await agent.extract('List of items in the cart', z.object({ - * title: z.string().describe('Item title to extract'), - * price: z.string().describe('Item price to extract'), - * }).array()); - * ``` - * - * @param query Task to perform using agentic loop. - * @param schema - * @param options - */ - extract(query: string, schema: Schema): Promise<{ result: InferZodSchema, usage: { turns: number, inputTokens: number, outputTokens: number } }>; - /** - * Emitted when the agent makes a turn. - */ - on(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Emitted when the agent makes a turn. - */ - addListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Emitted when the agent makes a turn. - */ - prependListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Dispose this agent. - */ - dispose(): Promise; - - /** - * Expect certain condition to be met. - * - * **Usage** - * - * ```js - * await agent.expect('"0 items" to be reported'); - * ``` - * - * @param expectation Expectation to assert. - * @param options - */ - expect(expectation: string, options?: { - /** - * All the agentic actions are converted to the Playwright calls and are cached. By default, they are cached globally - * with the `task` as a key. This option allows controlling the cache key explicitly. - */ - cacheKey?: string; - - /** - * Maximum number of retries when generating each action, defaults to context-wide value specified in `agent` - * property. - */ - maxActionRetries?: number; - - /** - * Maximum number of agentic actions to generate, defaults to context-wide value specified in `agent` property. - */ - maxActions?: number; - - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to context-wide value specified in `agent` property. - */ - maxTokens?: number; - - /** - * Expect timeout in milliseconds. Defaults to `5000`. The default value can be changed via `expect.timeout` option in - * the config, or by specifying the `expect` property of the - * [`expect`](https://playwright.dev/docs/api/class-page#page-agent-option-expect) option. Pass `0` to disable - * timeout. - */ - timeout?: number; - }): Promise; - - /** - * Perform action using agentic loop. - * - * **Usage** - * - * ```js - * await agent.perform('Click submit button'); - * ``` - * - * @param task Task to perform using agentic loop. - * @param options - */ - perform(task: string, options?: { - /** - * All the agentic actions are converted to the Playwright calls and are cached. By default, they are cached globally - * with the `task` as a key. This option allows controlling the cache key explicitly. - */ - cacheKey?: string; - - /** - * Maximum number of retries when generating each action, defaults to context-wide value specified in `agent` - * property. - */ - maxActionRetries?: number; - - /** - * Maximum number of agentic actions to generate, defaults to context-wide value specified in `agent` property. - */ - maxActions?: number; - - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to context-wide value specified in `agent` property. - */ - maxTokens?: number; - - /** - * Perform timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in - * the config, or by using the - * [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout) - * or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods. - * Pass `0` to disable timeout. - */ - timeout?: number; - }): Promise<{ - usage: { - turns: number; - - inputTokens: number; - - outputTokens: number; - }; - }>; - - /** - * Returns the current token usage for this agent. - * - * **Usage** - * - * ```js - * const usage = await agent.usage(); - * console.log(`Tokens used: ${usage.inputTokens} in, ${usage.outputTokens} out`); - * ``` - * - */ - usage(): Promise<{ - turns: number; - - inputTokens: number; - - outputTokens: number; - }>; - - [Symbol.asyncDispose](): Promise; -} - /** * At every point of time, page exposes its current frame tree via the * [page.mainFrame()](https://playwright.dev/docs/api/class-page#page-main-frame) and diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index adc7654de9599..b8c2651ee9370 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -847,6 +847,7 @@ export class Page extends ChannelOwner implements api.Page return result.pdf; } + // @ts-expect-error agents are hidden async agent(options: Parameters[0] = {}) { const params: channels.PageAgentParams = { api: options.provider?.api, @@ -861,6 +862,7 @@ export class Page extends ChannelOwner implements api.Page maxTokens: options.limits?.maxTokens, maxActions: options.limits?.maxActions, maxActionRetries: options.limits?.maxActionRetries, + // @ts-expect-error runAgents is hidden secrets: options.secrets ? Object.entries(options.secrets).map(([name, value]) => ({ name, value })) : undefined, systemPrompt: options.systemPrompt, }; diff --git a/packages/playwright-core/src/client/pageAgent.ts b/packages/playwright-core/src/client/pageAgent.ts index ec6a16cc9aeab..374c736888060 100644 --- a/packages/playwright-core/src/client/pageAgent.ts +++ b/packages/playwright-core/src/client/pageAgent.ts @@ -22,6 +22,7 @@ import { Page } from './page'; import type * as api from '../../types/types'; import type * as channels from '@protocol/channels'; +// @ts-expect-error runAgents is hidden export class PageAgent extends ChannelOwner implements api.PageAgent { private _page: Page; _expectTimeout?: number; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 50dd490708e13..f6e6165885f0a 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -27,13 +27,6 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector state?: 'visible'|'attached'; }; -// @ts-ignore this will be any if zod is not installed -import { ZodTypeAny, z } from 'zod'; -// @ts-ignore this will be any if zod is not installed -import * as z3 from 'zod/v3'; -type ZodSchema = ZodTypeAny | z3.ZodTypeAny; -type InferZodSchema = T extends z3.ZodTypeAny ? z3.infer : T extends ZodTypeAny ? z.infer : never; - /** * Page provides methods to interact with a single tab in a [Browser](https://playwright.dev/docs/api/class-browser), * or an [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One @@ -2095,89 +2088,6 @@ export interface Page { url?: string; }): Promise; - /** - * Initialize page agent with the llm provider and cache. - * @param options - */ - agent(options?: { - cache?: { - /** - * Cache file to use/generate code for performed actions into. Cache is not used if not specified (default). - */ - cacheFile?: string; - - /** - * When specified, generated entries are written into the `cacheOutFile` instead of updating the `cacheFile`. - */ - cacheOutFile?: string; - }; - - expect?: { - /** - * Default timeout for expect calls in milliseconds, defaults to 5000ms. - */ - timeout?: number; - }; - - /** - * Limits to use for the agentic loop. - */ - limits?: { - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to unlimited. - */ - maxTokens?: number; - - /** - * Maximum number of agentic actions to generate, defaults to 10. - */ - maxActions?: number; - - /** - * Maximum number retries per action, defaults to 3. - */ - maxActionRetries?: number; - }; - - provider?: { - /** - * API to use. - */ - api: "openai"|"openai-compatible"|"anthropic"|"google"; - - /** - * Endpoint to use if different from default. - */ - apiEndpoint?: string; - - /** - * API key for the LLM provider. - */ - apiKey: string; - - /** - * Amount of time to wait for the provider to respond to each request. - */ - apiTimeout?: number; - - /** - * Model identifier within the provider. Required in non-cache mode. - */ - model: string; - }; - - /** - * Secrets to hide from the LLM. - */ - secrets?: { [key: string]: string; }; - - /** - * System prompt for the agent's loop. - */ - systemPrompt?: string; - }): Promise; - /** * Brings page to front (activates tab). */ @@ -5294,243 +5204,6 @@ export interface Page { [Symbol.asyncDispose](): Promise; } -/** - * - */ -export interface PageAgent { - /** - * Extract information from the page using the agentic loop, return it in a given Zod format. - * - * **Usage** - * - * ```js - * await agent.extract('List of items in the cart', z.object({ - * title: z.string().describe('Item title to extract'), - * price: z.string().describe('Item price to extract'), - * }).array()); - * ``` - * - * @param query Task to perform using agentic loop. - * @param schema - * @param options - */ - extract(query: string, schema: Schema): Promise<{ result: InferZodSchema, usage: { turns: number, inputTokens: number, outputTokens: number } }>; - /** - * Emitted when the agent makes a turn. - */ - on(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Emitted when the agent makes a turn. - */ - addListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Emitted when the agent makes a turn. - */ - prependListener(event: 'turn', listener: (data: { - role: string; - - message: string; - - usage?: { - inputTokens: number; - - outputTokens: number; - }; - }) => any): this; - - /** - * Dispose this agent. - */ - dispose(): Promise; - - /** - * Expect certain condition to be met. - * - * **Usage** - * - * ```js - * await agent.expect('"0 items" to be reported'); - * ``` - * - * @param expectation Expectation to assert. - * @param options - */ - expect(expectation: string, options?: { - /** - * All the agentic actions are converted to the Playwright calls and are cached. By default, they are cached globally - * with the `task` as a key. This option allows controlling the cache key explicitly. - */ - cacheKey?: string; - - /** - * Maximum number of retries when generating each action, defaults to context-wide value specified in `agent` - * property. - */ - maxActionRetries?: number; - - /** - * Maximum number of agentic actions to generate, defaults to context-wide value specified in `agent` property. - */ - maxActions?: number; - - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to context-wide value specified in `agent` property. - */ - maxTokens?: number; - - /** - * Expect timeout in milliseconds. Defaults to `5000`. The default value can be changed via `expect.timeout` option in - * the config, or by specifying the `expect` property of the - * [`expect`](https://playwright.dev/docs/api/class-page#page-agent-option-expect) option. Pass `0` to disable - * timeout. - */ - timeout?: number; - }): Promise; - - /** - * Perform action using agentic loop. - * - * **Usage** - * - * ```js - * await agent.perform('Click submit button'); - * ``` - * - * @param task Task to perform using agentic loop. - * @param options - */ - perform(task: string, options?: { - /** - * All the agentic actions are converted to the Playwright calls and are cached. By default, they are cached globally - * with the `task` as a key. This option allows controlling the cache key explicitly. - */ - cacheKey?: string; - - /** - * Maximum number of retries when generating each action, defaults to context-wide value specified in `agent` - * property. - */ - maxActionRetries?: number; - - /** - * Maximum number of agentic actions to generate, defaults to context-wide value specified in `agent` property. - */ - maxActions?: number; - - /** - * Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. - * Defaults to context-wide value specified in `agent` property. - */ - maxTokens?: number; - - /** - * Perform timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in - * the config, or by using the - * [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout) - * or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods. - * Pass `0` to disable timeout. - */ - timeout?: number; - }): Promise<{ - usage: { - turns: number; - - inputTokens: number; - - outputTokens: number; - }; - }>; - - /** - * Returns the current token usage for this agent. - * - * **Usage** - * - * ```js - * const usage = await agent.usage(); - * console.log(`Tokens used: ${usage.inputTokens} in, ${usage.outputTokens} out`); - * ``` - * - */ - usage(): Promise<{ - turns: number; - - inputTokens: number; - - outputTokens: number; - }>; - - [Symbol.asyncDispose](): Promise; -} - /** * At every point of time, page exposes its current frame tree via the * [page.mainFrame()](https://playwright.dev/docs/api/class-page#page-main-frame) and diff --git a/packages/playwright/src/common/config.ts b/packages/playwright/src/common/config.ts index bafd9ecc8de61..4dfb7a1889485 100644 --- a/packages/playwright/src/common/config.ts +++ b/packages/playwright/src/common/config.ts @@ -112,7 +112,8 @@ export class FullConfigInternal { quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false), reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]), reportSlowTests: takeFirst(userConfig.reportSlowTests, { max: 5, threshold: 300_000 /* 5 minutes */ }), - runAgents: takeFirst(configCLIOverrides.runAgents, userConfig.runAgents, 'none'), + // @ts-expect-error runAgents is hidden + runAgents: takeFirst(configCLIOverrides.runAgents, 'none'), shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null), tags: globalTags, updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'), @@ -196,7 +197,7 @@ export class FullProjectInternal { testDir, snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir), testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []), - testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).{md,?(c|m)[jt]s?(x)}'), + testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).?(c|m)[jt]s?(x)'), timeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout), use: mergeObjects(config.use, projectConfig.use, configCLIOverrides.use), dependencies: projectConfig.dependencies || [], diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index 874ba50ef2d00..e986e71b3374b 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -58,6 +58,9 @@ type TestFixtures = PlaywrightTestArgs & PlaywrightTestOptions & { _setupContextOptions: void; _setupArtifacts: void; _contextFactory: (options?: BrowserContextOptions) => Promise<{ context: BrowserContext, close: () => Promise }>; + + agent: {}; + agentOptions?: any; }; type WorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & { @@ -152,7 +155,7 @@ const playwrightFixtures: Fixtures = ({ }, { option: true, box: true }], serviceWorkers: [({ contextOptions }, use) => use(contextOptions.serviceWorkers ?? 'allow'), { option: true, box: true }], contextOptions: [{}, { option: true, box: true }], - agentOptions: [({}, use) => use(undefined), { option: true, box: true }], + agentOptions: [undefined, { option: true, box: true }], _combinedContextOptions: [async ({ acceptDownloads, @@ -459,9 +462,11 @@ const playwrightFixtures: Fixtures = ({ const testInfoImpl = testInfo as TestInfoImpl; const cachePathTemplate = agentOptions?.cachePathTemplate ?? '{testDir}/{testFilePath}-cache.json'; const resolvedCacheFile = testInfoImpl._applyPathTemplate(cachePathTemplate, '', '.json'); + // @ts-expect-error runAgents is hidden const cacheFile = testInfoImpl.config.runAgents === 'all' ? undefined : await testInfoImpl._cloneStorage(resolvedCacheFile); const cacheOutFile = path.join(testInfoImpl.artifactsDir(), 'agent-cache-' + createGuid() + '.json'); + // @ts-expect-error runAgents is hidden const provider = agentOptions?.provider && testInfo.config.runAgents !== 'none' ? agentOptions.provider : undefined; if (provider) testInfo.setTimeout(0); @@ -471,6 +476,7 @@ const playwrightFixtures: Fixtures = ({ cacheOutFile, }; + // @ts-expect-error agent is hidden const agent = await page.agent({ provider, cache, diff --git a/packages/playwright/src/isomorphic/teleReceiver.ts b/packages/playwright/src/isomorphic/teleReceiver.ts index c113c8b9b6623..3829704cadc4f 100644 --- a/packages/playwright/src/isomorphic/teleReceiver.ts +++ b/packages/playwright/src/isomorphic/teleReceiver.ts @@ -792,6 +792,7 @@ export const baseFullConfig: reporterTypes.FullConfig = { tags: [], updateSnapshots: 'missing', updateSourceMethod: 'patch', + // @ts-expect-error runAgents is hidden runAgents: 'none', version: '', workers: 0, diff --git a/packages/playwright/src/program.ts b/packages/playwright/src/program.ts index 0df97a777ca29..81f96336dd1e3 100644 --- a/packages/playwright/src/program.ts +++ b/packages/playwright/src/program.ts @@ -425,7 +425,6 @@ const testOptions: [string, { description: string, choices?: string[], preset?: ['--repeat-each ', { description: `Run each test N times (default: 1)` }], ['--reporter ', { description: `Reporter to use, comma-separated, can be ${builtInReporters.map(name => `"${name}"`).join(', ')} (default: "${defaultReporter}")` }], ['--retries ', { description: `Maximum retry count for flaky tests, zero for no retries (default: no retries)` }], - ['--run-agents ', { description: `Run agents to generate the code for page.perform`, choices: ['missing', 'all', 'none'], preset: 'none' }], ['--shard ', { description: `Shard tests and execute only the selected shard, specify in the form "current/all", 1-based, for example "3/5"` }], ['--shard-weights ', { description: `Weights for each shard, colon-separated, for example "2:1:1" for 3 shards where the first shard should be allocated half of the work` }], ['--test-list ', { description: `Path to a file containing a list of tests to run. See https://playwright.dev/docs/test-cli for more details.` }], diff --git a/packages/playwright/src/transform/transform.ts b/packages/playwright/src/transform/transform.ts index 862023cc5f9b8..3cab05d844399 100644 --- a/packages/playwright/src/transform/transform.ts +++ b/packages/playwright/src/transform/transform.ts @@ -224,7 +224,7 @@ export function transformHook(originalCode: string, filename: string, moduleUrl? // TODO: ideally, we would not transform before checking the cache. However, the source // currently depends on the seed.md, so "originalCode" is not enough to produce a cache key. let inputSourceMap: EncodedSourceMap | undefined; - if (filename.endsWith('.md')) { + if (filename.endsWith('.md') && false) { const transformed = transformMDToTS(originalCode, filename); originalCode = transformed.code; inputSourceMap = transformed.map; diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 4119c6d1b1695..03a07785f17cf 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, PageAgent, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; +import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; export * from 'playwright-core'; // @ts-ignore ReactCSSProperties will be any if react is not installed @@ -1615,14 +1615,6 @@ interface TestConfig { */ retries?: number; - /** - * Whether to run LLM agent for [PageAgent](https://playwright.dev/docs/api/class-pageagent): - * - "all" disregards existing cache and performs all actions via LLM - * - "missing" only performs actions that don't have generated cache actions - * - "none" does not talk to LLM at all, relies on the cached actions (default) - */ - runAgents?: "all"|"missing"|"none"; - /** * Shard tests and execute only the selected shard. Specify in the one-based form like `{ total: 5, current: 2 }`. * @@ -2079,14 +2071,6 @@ export interface FullConfig { */ rootDir: string; - /** - * Whether to run LLM agent for [PageAgent](https://playwright.dev/docs/api/class-pageagent): - * - "all" disregards existing cache and performs all actions via LLM - * - "missing" only performs actions that don't have generated cache actions - * - "none" does not talk to LLM at all, relies on the cached actions (default) - */ - runAgents: "all"|"missing"|"none"; - /** * See [testConfig.shard](https://playwright.dev/docs/api/class-testconfig#test-config-shard). */ @@ -6954,24 +6938,6 @@ export interface PlaywrightWorkerOptions { export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure'; export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure'; export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; -export type AgentOptions = { - provider?: { - api: 'openai' | 'openai-compatible' | 'anthropic' | 'google'; - apiEndpoint?: string; - apiKey: string; - apiTimeout?: number; - model: string; - }, - limits?: { - maxTokens?: number; - maxActions?: number; - maxActionRetries?: number; - }; - cachePathTemplate?: string; - runAgents?: 'all' | 'missing' | 'none'; - secrets?: { [key: string]: string }; - systemPrompt?: string; -}; /** * Playwright Test provides many options to configure test environment, @@ -7012,7 +6978,6 @@ export type AgentOptions = { * */ export interface PlaywrightTestOptions { - agentOptions: AgentOptions | undefined; /** * Whether to automatically download all the attachments. Defaults to `true` where all the downloads are accepted. * @@ -7722,7 +7687,6 @@ export interface PlaywrightTestArgs { * */ request: APIRequestContext; - agent: PageAgent; } type ExcludeProps = { diff --git a/tests/library/agent-helpers.ts b/tests/library/agent-helpers.ts index 5a718082df48d..a68988ed7f6c6 100644 --- a/tests/library/agent-helpers.ts +++ b/tests/library/agent-helpers.ts @@ -18,6 +18,7 @@ import fs from 'fs'; import path from 'path'; import { browserTest as test } from '../config/browserTest'; +// @ts-expect-error import type { BrowserContext, Page, PageAgent } from '@playwright/test'; export function cacheFile() { @@ -32,12 +33,14 @@ export async function setCacheObject(object: any) { await fs.promises.writeFile(cacheFile(), JSON.stringify(object, null, 2), 'utf8'); } +// @ts-expect-error type AgentOptions = Parameters[0]; export async function generateAgent(context: BrowserContext, options: AgentOptions = {}) { const apiCacheFile = path.join(__dirname, '__llm_cache__', sanitizeFileName(test.info().titlePath.join(' ')) + '.json'); const page = await context.newPage(); + // @ts-expect-error const agent = await page.agent({ provider: { api: 'anthropic' as const, @@ -57,6 +60,7 @@ export async function generateAgent(context: BrowserContext, options: AgentOptio export async function runAgent(context: BrowserContext, options: AgentOptions = {}) { const page = await context.newPage(); + // @ts-expect-error const agent = await page.agent({ ...options, cache: { cacheFile: cacheFile() }, diff --git a/tests/library/agent-perform.spec.ts b/tests/library/agent-perform.spec.ts index 9a14b409a20df..4030f1b825ebb 100644 --- a/tests/library/agent-perform.spec.ts +++ b/tests/library/agent-perform.spec.ts @@ -230,12 +230,14 @@ test('empty cache file works', async ({ context }) => { }); test('missing apiKey throws a nice error', async ({ page }) => { + // @ts-expect-error const agent = await page.agent({ provider: { api: 'anthropic', model: 'some model' } as any }); const error = await agent.perform('click the Test button').catch(e => e); expect(error.message).toContain(`This action requires API key to be set on the page agent`); }); test('malformed apiEndpoint throws a nice error', async ({ page }) => { + // @ts-expect-error const agent = await page.agent({ provider: { api: 'anthropic', model: 'some model', apiKey: 'some key', apiEndpoint: 'foobar' } }); const error = await agent.perform('click the Test button').catch(e => e); expect(error.message).toContain(`Agent API endpoint "foobar" is not a valid URL`); diff --git a/utils/doclint/missingDocs.js b/utils/doclint/missingDocs.js index 856c4f02101b6..0eca3a2cbee89 100644 --- a/utils/doclint/missingDocs.js +++ b/utils/doclint/missingDocs.js @@ -29,12 +29,16 @@ module.exports = function lint(documentation, jsSources, apiFileName) { documentation.copyDocsFromSuperclasses(errors); const apiMethods = listMethods(jsSources, apiFileName); for (const [className, methods] of apiMethods) { + if (className === 'PageAgent') + continue; const docClass = documentation.classes.get(className); if (!docClass) { errors.push(`Missing documentation for "${className}"`); continue; } for (const [methodName, params] of methods) { + if (className === 'Page' && methodName === 'agent') + continue; const members = docClass.membersArray.filter(m => m.alias === methodName && m.kind !== 'event'); if (!members.length) { errors.push(`Missing documentation for "${className}.${methodName}"`); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 3a0eb2eb2d004..49b99eb3e452d 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, PageAgent, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; +import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; export * from 'playwright-core'; // @ts-ignore ReactCSSProperties will be any if react is not installed @@ -269,27 +269,8 @@ export interface PlaywrightWorkerOptions { export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure'; export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure'; export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; -export type AgentOptions = { - provider?: { - api: 'openai' | 'openai-compatible' | 'anthropic' | 'google'; - apiEndpoint?: string; - apiKey: string; - apiTimeout?: number; - model: string; - }, - limits?: { - maxTokens?: number; - maxActions?: number; - maxActionRetries?: number; - }; - cachePathTemplate?: string; - runAgents?: 'all' | 'missing' | 'none'; - secrets?: { [key: string]: string }; - systemPrompt?: string; -}; export interface PlaywrightTestOptions { - agentOptions: AgentOptions | undefined; acceptDownloads: boolean; bypassCSP: boolean; colorScheme: ColorScheme; @@ -328,7 +309,6 @@ export interface PlaywrightTestArgs { context: BrowserContext; page: Page; request: APIRequestContext; - agent: PageAgent; } type ExcludeProps = { diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 09b54a6dd7cd9..a88c80ba6ecdf 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -26,13 +26,6 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector state?: 'visible'|'attached'; }; -// @ts-ignore this will be any if zod is not installed -import { ZodTypeAny, z } from 'zod'; -// @ts-ignore this will be any if zod is not installed -import * as z3 from 'zod/v3'; -type ZodSchema = ZodTypeAny | z3.ZodTypeAny; -type InferZodSchema = T extends z3.ZodTypeAny ? z3.infer : T extends ZodTypeAny ? z.infer : never; - export interface Page { evaluate(pageFunction: PageFunction, arg: Arg): Promise; evaluate(pageFunction: PageFunction, arg?: any): Promise; @@ -81,10 +74,6 @@ export interface Page { }): Promise; } -export interface PageAgent { - extract(query: string, schema: Schema): Promise<{ result: InferZodSchema, usage: { turns: number, inputTokens: number, outputTokens: number } }>; -} - export interface Frame { evaluate(pageFunction: PageFunction, arg: Arg): Promise; evaluate(pageFunction: PageFunction, arg?: any): Promise; From 12abeee4fb3e9a1ce429f0fee3d036c11e674030 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 21 Jan 2026 15:09:07 +0100 Subject: [PATCH 2/3] hide instead --- docs/src/api/class-page.md | 54 +++++++++ docs/src/api/class-pageagent.md | 147 +++++++++++++++++++++++++ docs/src/api/params.md | 4 + docs/src/test-api/class-fixtures.md | 5 + docs/src/test-api/class-fullconfig.md | 10 ++ docs/src/test-api/class-testconfig.md | 10 ++ docs/src/test-api/class-testoptions.md | 18 +++ utils/doclint/api_parser.js | 8 +- 8 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 docs/src/api/class-pageagent.md diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index b438dd045c978..ba94676d64e39 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -709,6 +709,60 @@ current working directory. Raw CSS content to be injected into frame. +## async method: Page.agent +* since: v1.58 +* hidden +- returns: <[PageAgent]> + +Initialize page agent with the llm provider and cache. + +### option: Page.agent.cache +* since: v1.58 +* hidden +- `cache` <[Object]> + - `cacheFile` ?<[string]> Cache file to use/generate code for performed actions into. Cache is not used if not specified (default). + - `cacheOutFile` ?<[string]> When specified, generated entries are written into the `cacheOutFile` instead of updating the `cacheFile`. + +### option: Page.agent.expect +* since: v1.58 +* hidden +- `expect` <[Object]> + - `timeout` ?<[int]> Default timeout for expect calls in milliseconds, defaults to 5000ms. + +### option: Page.agent.limits +* since: v1.58 +* hidden +- `limits` <[Object]> + - `maxTokens` ?<[int]> Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. Defaults to unlimited. + - `maxActions` ?<[int]> Maximum number of agentic actions to generate, defaults to 10. + - `maxActionRetries` ?<[int]> Maximum number retries per action, defaults to 3. + +Limits to use for the agentic loop. + +### option: Page.agent.provider +* since: v1.58 +* hidden +- `provider` <[Object]> + - `api` <[PageAgentAPI]<"openai"|"openai-compatible"|"anthropic"|"google">> API to use. + - `apiEndpoint` ?<[string]> Endpoint to use if different from default. + - `apiKey` <[string]> API key for the LLM provider. + - `apiTimeout` ?<[int]> Amount of time to wait for the provider to respond to each request. + - `model` <[string]> Model identifier within the provider. Required in non-cache mode. + +### option: Page.agent.secrets +* since: v1.58 +* hidden +- `secrets` ?<[Object]<[string], [string]>> + +Secrets to hide from the LLM. + +### option: Page.agent.systemPrompt +* since: v1.58 +* hidden +- `systemPrompt` <[string]> + +System prompt for the agent's loop. + ## async method: Page.bringToFront * since: v1.8 diff --git a/docs/src/api/class-pageagent.md b/docs/src/api/class-pageagent.md new file mode 100644 index 0000000000000..6a248c35ed8d5 --- /dev/null +++ b/docs/src/api/class-pageagent.md @@ -0,0 +1,147 @@ +# class: PageAgent +* since: v1.58 +* hidden + +## event: PageAgent.turn +* since: v1.58 +* hidden +- argument: <[Object]> + - `role` <[string]> + - `message` <[string]> + - `usage` ?<[Object]> + - `inputTokens` <[int]> + - `outputTokens` <[int]> + +Emitted when the agent makes a turn. + +## async method: PageAgent.dispose +* hidden +* since: v1.58 + +Dispose this agent. + +## async method: PageAgent.expect +* hidden +* since: v1.58 + +Expect certain condition to be met. + +**Usage** + +```js +await agent.expect('"0 items" to be reported'); +``` + +### param: PageAgent.expect.expectation +* since: v1.58 +* hidden +- `expectation` <[string]> + +Expectation to assert. + +### option: PageAgent.expect.timeout +* since: v1.58 +* hidden +- `timeout` <[float]> + +Expect timeout in milliseconds. Defaults to `5000`. The default value can be changed via `expect.timeout` option in the config, or by specifying the `expect` property of the [`option: Page.agent.expect`] option. Pass `0` to disable timeout. + +### option: PageAgent.expect.-inline- = %%-page-agent-call-options-v1.58-%% +* since: v1.58 + +## async method: PageAgent.extract +* since: v1.58 +* hidden +- returns: <[Object]> + - `result` <[any]> + - `usage` <[Object]> + - `turns` <[int]> + - `inputTokens` <[int]> + - `outputTokens` <[int]> + +Extract information from the page using the agentic loop, return it in a given Zod format. + +**Usage** + +```js +await agent.extract('List of items in the cart', z.object({ + title: z.string().describe('Item title to extract'), + price: z.string().describe('Item price to extract'), +}).array()); +``` + +### param: PageAgent.extract.query +* since: v1.58 +* hidden +- `query` <[string]> + +Task to perform using agentic loop. + +### param: PageAgent.extract.schema +* since: v1.58 +* hidden +- `schema` <[z.ZodSchema]> + +### option: PageAgent.extract.timeout +* since: v1.58 +* hidden +- `timeout` <[float]> + +Extract timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in the config, or by using the [`method: BrowserContext.setDefaultTimeout`] or +[`method: Page.setDefaultTimeout`] methods. Pass `0` to disable timeout. + +### option: PageAgent.extract.-inline- = %%-page-agent-call-options-v1.58-%% +* since: v1.58 + +## async method: PageAgent.perform +* since: v1.58 +* hidden +- returns: <[Object]> + - `usage` <[Object]> + - `turns` <[int]> + - `inputTokens` <[int]> + - `outputTokens` <[int]> + +Perform action using agentic loop. + +**Usage** + +```js +await agent.perform('Click submit button'); +``` + +### param: PageAgent.perform.task +* since: v1.58 +* hidden +- `task` <[string]> + +Task to perform using agentic loop. + +### option: PageAgent.perform.timeout +* since: v1.58 +* hidden +- `timeout` <[float]> + +Perform timeout in milliseconds. Defaults to `5000`. The default value can be changed via `actionTimeout` option in the config, or by using the [`method: BrowserContext.setDefaultTimeout`] or +[`method: Page.setDefaultTimeout`] methods. Pass `0` to disable timeout. + +### option: PageAgent.perform.-inline- = %%-page-agent-call-options-v1.58-%% +* since: v1.58 +* hidden + +## async method: PageAgent.usage +* since: v1.58 +* hidden +- returns: <[Object]> + - `turns` <[int]> + - `inputTokens` <[int]> + - `outputTokens` <[int]> + +Returns the current token usage for this agent. + +**Usage** + +```js +const usage = await agent.usage(); +console.log(`Tokens used: ${usage.inputTokens} in, ${usage.outputTokens} out`); +``` diff --git a/docs/src/api/params.md b/docs/src/api/params.md index 69257b93db23d..90c3b9e3621f4 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -372,6 +372,7 @@ Emulates consistent window screen size available inside web page via `window.scr ## page-agent-cache-key * since: v1.58 +* hidden - `cacheKey` <[string]> All the agentic actions are converted to the Playwright calls and are cached. @@ -379,6 +380,7 @@ By default, they are cached globally with the `task` as a key. This option allow ## page-agent-max-tokens * since: v1.58 +* hidden - `maxTokens` <[int]> Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. @@ -386,12 +388,14 @@ Defaults to context-wide value specified in `agent` property. ## page-agent-max-actions * since: v1.58 +* hidden - `maxActions` <[int]> Maximum number of agentic actions to generate, defaults to context-wide value specified in `agent` property. ## page-agent-max-action-retries * since: v1.58 +* hidden - `maxActionRetries` <[int]> Maximum number of retries when generating each action, defaults to context-wide value specified in `agent` property. diff --git a/docs/src/test-api/class-fixtures.md b/docs/src/test-api/class-fixtures.md index 0c08b19da3b2a..4704ff708a15d 100644 --- a/docs/src/test-api/class-fixtures.md +++ b/docs/src/test-api/class-fixtures.md @@ -18,6 +18,11 @@ Given the test above, Playwright Test will set up the `page` fixture before runn Playwright Test comes with builtin fixtures listed below, and you can add your own fixtures as well. Playwright Test also [provides options][TestOptions] to configure [`property: Fixtures.browser`], [`property: Fixtures.context`] and [`property: Fixtures.page`]. +## property: Fixtures.agent +* since: v1.58 +* hidden +- type: <[PageAgent]> + ## property: Fixtures.browser * since: v1.10 - type: <[Browser]> diff --git a/docs/src/test-api/class-fullconfig.md b/docs/src/test-api/class-fullconfig.md index 7ce3da974bb71..411ba615851fe 100644 --- a/docs/src/test-api/class-fullconfig.md +++ b/docs/src/test-api/class-fullconfig.md @@ -104,6 +104,16 @@ See [`property: TestConfig.reportSlowTests`]. Base directory for all relative paths used in the reporters. +## property: FullConfig.runAgents +* since: v1.58 +* hidden +- type: <['RunAgentsMode]<"all"|"missing"|"none">> + +Whether to run LLM agent for [PageAgent]: +* "all" disregards existing cache and performs all actions via LLM +* "missing" only performs actions that don't have generated cache actions +* "none" does not talk to LLM at all, relies on the cached actions (default) + ## property: FullConfig.shard * since: v1.10 - type: <[null]|[Object]> diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index ea08d8af46ae4..a7b417484e51c 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -514,6 +514,16 @@ export default defineConfig({ }); ``` +## property: TestConfig.runAgents +* since: v1.58 +* hidden +- type: ?<['RunAgentsMode]<"all"|"missing"|"none">> + +Whether to run LLM agent for [PageAgent]: +* "all" disregards existing cache and performs all actions via LLM +* "missing" only performs actions that don't have generated cache actions +* "none" does not talk to LLM at all, relies on the cached actions (default) + ## property: TestConfig.shard * since: v1.10 - type: ?<[null]|[Object]> diff --git a/docs/src/test-api/class-testoptions.md b/docs/src/test-api/class-testoptions.md index c2854306164ad..759fa86e55715 100644 --- a/docs/src/test-api/class-testoptions.md +++ b/docs/src/test-api/class-testoptions.md @@ -46,6 +46,24 @@ export default defineConfig({ }); ``` +## property: TestOptions.agentOptions +* since: v1.58 +* hidden +- type: <[Object]> + - `provider` <[Object]> + - `api` <[PageAgentAPI]<"openai"|"openai-compatible"|"anthropic"|"google">> API to use. + - `apiEndpoint` ?<[string]> Endpoint to use if different from default. + - `apiKey` <[string]> API key for the LLM provider. + - `apiTimeout` ?<[int]> Amount of time to wait for the provider to respond to each request. + - `model` <[string]> Model identifier within the provider. Required in non-cache mode. + - `cachePathTemplate` ?<[string]> Cache file template to use/generate code for performed actions into. + - `limits` <[Object]> + - `maxTokens` ?<[int]> Maximum number of tokens to consume. The agentic loop will stop after input + output tokens exceed this value. Defaults to unlimited. + - `maxActions` ?<[int]> Maximum number of agentic actions to generate, defaults to 10. + - `maxActionRetries` ?<[int]> Maximum number retries per action, defaults to 3. + - `secrets` ?<[Object]<[string], [string]>> Secrets to hide from the LLM. + - `systemPrompt` <[string]> System prompt for the agent's loop. + ## property: TestOptions.baseURL = %%-context-option-baseURL-%% * since: v1.10 diff --git a/utils/doclint/api_parser.js b/utils/doclint/api_parser.js index a4d504ea48d6e..28e67114509e5 100644 --- a/utils/doclint/api_parser.js +++ b/utils/doclint/api_parser.js @@ -93,6 +93,9 @@ class ApiParser { if (!match) throw new Error('Invalid member: ' + spec.text); const metainfo = extractMetainfo(spec); + if (metainfo.hidden) + return; + const name = match[3]; let returnType = null; let optional = false; @@ -125,8 +128,6 @@ class ApiParser { const clazz = /** @type {docs.Class} */(this.classes.get(match[2])); if (!clazz) throw new Error(`Unknown class ${match[2]} for member: ` + spec.text); - if (metainfo.hidden) - return; const existingMember = clazz.membersArray.find(m => m.name === name && m.kind === member.kind); if (existingMember && isTypeOverride(existingMember, member)) { @@ -146,6 +147,9 @@ class ApiParser { const match = spec.text.match(/(param|option): (.*)/); if (!match) throw `Something went wrong with matching ${spec.text}`; + const metainfo = extractMetainfo(spec); + if (metainfo.hidden) + return null; // For "test.describe.only.title": // - className is "test" From 0ea9ba958d225f44f359a234af14b80aa9c29e13 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 21 Jan 2026 15:10:10 +0100 Subject: [PATCH 3/3] add back langs --- docs/src/api/class-page.md | 1 + docs/src/api/class-pageagent.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index ba94676d64e39..13299d4646cf7 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -711,6 +711,7 @@ Raw CSS content to be injected into frame. ## async method: Page.agent * since: v1.58 +* langs: js * hidden - returns: <[PageAgent]> diff --git a/docs/src/api/class-pageagent.md b/docs/src/api/class-pageagent.md index 6a248c35ed8d5..e1a9f4e5201d7 100644 --- a/docs/src/api/class-pageagent.md +++ b/docs/src/api/class-pageagent.md @@ -1,5 +1,6 @@ # class: PageAgent * since: v1.58 +* langs: js * hidden ## event: PageAgent.turn