diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 0cf0e3fa348c8..2d621a0fe078a 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -832,8 +832,8 @@ export class Page extends ChannelOwner implements api.Page return result.pdf; } - async _snapshotForAI(): Promise { - const result = await this._channel.snapshotForAI(); + async _snapshotForAI(options: TimeoutOptions = {}): Promise { + const result = await this._channel.snapshotForAI({ timeout: this._timeoutSettings.timeout(options) }); return result.snapshot; } } diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index ce42269fcddc3..1845533bf0bbc 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -1454,7 +1454,9 @@ scheme.PagePdfParams = tObject({ scheme.PagePdfResult = tObject({ pdf: tBinary, }); -scheme.PageSnapshotForAIParams = tOptional(tObject({})); +scheme.PageSnapshotForAIParams = tObject({ + timeout: tNumber, +}); scheme.PageSnapshotForAIResult = tObject({ snapshot: tString, }); diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index 697bdf1d6cb11..a882f015b4f69 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -2111,7 +2111,7 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel { touchscreenTap(params: PageTouchscreenTapParams, progress?: Progress): Promise; accessibilitySnapshot(params: PageAccessibilitySnapshotParams, progress?: Progress): Promise; pdf(params: PagePdfParams, progress?: Progress): Promise; - snapshotForAI(params?: PageSnapshotForAIParams, progress?: Progress): Promise; + snapshotForAI(params: PageSnapshotForAIParams, progress?: Progress): Promise; startJSCoverage(params: PageStartJSCoverageParams, progress?: Progress): Promise; stopJSCoverage(params?: PageStopJSCoverageParams, progress?: Progress): Promise; startCSSCoverage(params: PageStartCSSCoverageParams, progress?: Progress): Promise; @@ -2540,8 +2540,12 @@ export type PagePdfOptions = { export type PagePdfResult = { pdf: Binary, }; -export type PageSnapshotForAIParams = {}; -export type PageSnapshotForAIOptions = {}; +export type PageSnapshotForAIParams = { + timeout: number, +}; +export type PageSnapshotForAIOptions = { + +}; export type PageSnapshotForAIResult = { snapshot: string, }; diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 4b7cfe79fa7ce..2b37940a4f717 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -1918,6 +1918,8 @@ Page: snapshotForAI: internal: true + parameters: + timeout: number returns: snapshot: string flags: diff --git a/tests/page/page-aria-snapshot-ai.spec.ts b/tests/page/page-aria-snapshot-ai.spec.ts index 10372c72c2830..ec044cb828f01 100644 --- a/tests/page/page-aria-snapshot-ai.spec.ts +++ b/tests/page/page-aria-snapshot-ai.spec.ts @@ -19,8 +19,8 @@ import { asLocator } from 'playwright-core/lib/utils'; import { test as it, expect, unshift } from './pageTest'; -function snapshotForAI(page: any): Promise { - return page._snapshotForAI(); +function snapshotForAI(page: any, options?: { timeout?: number }): Promise { + return page._snapshotForAI(options); } it('should generate refs', async ({ page }) => { @@ -354,3 +354,23 @@ it('should mark iframe as active when it contains focused element', async ({ pag - textbox "Input in iframe" [active] [ref=f1e2] `); }); + +it('return empty snapshot when iframe is not loaded', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/pull/36710' } }, async ({ page, server }) => { + await page.setContent(` +
Test
+ + `); + + // Wait for the iframe to load + await page.waitForSelector('iframe'); + + // Get the snapshot of the page + const snapshot = await snapshotForAI(page, { timeout: 100 }); + + // The iframe should be present but empty + expect(snapshot).toContainYaml(` + - generic [active] [ref=e1]: + - generic [ref=e2]: Test + - iframe [ref=e3] + `); +});