From f3fac6f4e95f0818a47c88c055854576d98103e0 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 19 Jan 2024 12:35:00 -0800 Subject: [PATCH] feat: `page.handleLocator` that closes any interstitial pages/dialogs (#29029) --- docs/src/api/class-page.md | 196 ++++++++++++++++++ packages/playwright-core/src/client/page.ts | 19 ++ .../playwright-core/src/protocol/validator.ts | 13 ++ .../src/server/dispatchers/pageDispatcher.ts | 10 + packages/playwright-core/src/server/dom.ts | 8 +- packages/playwright-core/src/server/frames.ts | 49 +++-- packages/playwright-core/src/server/page.ts | 40 ++++ packages/playwright-core/types/types.d.ts | 60 ++++++ packages/protocol/src/channels.ts | 23 ++ packages/protocol/src/protocol.yml | 14 ++ tests/assets/input/handle-locator.html | 79 +++++++ tests/page/page-handle-locator.spec.ts | 172 +++++++++++++++ .../screenshot-grid-chromium.png | Bin 0 -> 36296 bytes .../screenshot-grid-firefox.png | Bin 0 -> 26202 bytes .../screenshot-grid-webkit.png | Bin 0 -> 32727 bytes 15 files changed, 663 insertions(+), 20 deletions(-) create mode 100644 tests/assets/input/handle-locator.html create mode 100644 tests/page/page-handle-locator.spec.ts create mode 100644 tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-chromium.png create mode 100644 tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-firefox.png create mode 100644 tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-webkit.png diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index 635f49ebba1ee..3b9a6d42e229b 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -3130,6 +3130,202 @@ return value resolves to `[]`. ### param: Page.querySelectorAll.selector = %%-query-selector-%% * since: v1.9 + +## async method: Page.handleLocator +* since: v1.42 + +Registers a handler for an element that might block certain actions like click. The handler should get rid of the blocking element so that an action may proceed. This is useful for nondeterministic interstitial pages or dialogs, like a cookie consent dialog. + +The handler will be executed before [actionability checks](../actionability.md) for each action, and also before each attempt of the [web assertions](../test-assertions.md). When no actions or assertions are executed, the handler will not be run at all, even if the interstitial element appears on the page. + +Note that execution time of the handler counts towards the timeout of the action/assertion that executed the handler. + +**Usage** + +An example that closes a cookie dialog when it appears: + +```js +// Setup the handler. +await page.handleLocator(page.getByRole('button', { name: 'Accept all cookies' }), async () => { + await page.getByRole('button', { name: 'Reject all cookies' }).click(); +}); + +// Write the test as usual. +await page.goto('https://example.com'); +await page.getByRole('button', { name: 'Start here' }).click(); +``` + +```java +// Setup the handler. +page.handleLocator(page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Accept all cookies")), () => { + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Reject all cookies")).click(); +}); + +// Write the test as usual. +page.goto("https://example.com"); +page.getByRole("button", Page.GetByRoleOptions().setName("Start here")).click(); +``` + +```python sync +# Setup the handler. +def handler(): + page.get_by_role("button", name="Reject all cookies").click() +page.handle_locator(page.get_by_role("button", name="Accept all cookies"), handler) + +# Write the test as usual. +page.goto("https://example.com") +page.get_by_role("button", name="Start here").click() +``` + +```python async +# Setup the handler. +def handler(): + await page.get_by_role("button", name="Reject all cookies").click() +await page.handle_locator(page.get_by_role("button", name="Accept all cookies"), handler) + +# Write the test as usual. +await page.goto("https://example.com") +await page.get_by_role("button", name="Start here").click() +``` + +```csharp +// Setup the handler. +await page.HandleLocatorAsync(page.GetByRole(AriaRole.Button, new() { Name = "Accept all cookies" }), async () => { + await page.GetByRole(AriaRole.Button, new() { Name = "Reject all cookies" }).ClickAsync(); +}); + +// Write the test as usual. +await page.GotoAsync("https://example.com"); +await page.GetByRole("button", new() { Name = "Start here" }).ClickAsync(); +``` + +An example that skips the "Confirm your security details" page when it is shown: + +```js +// Setup the handler. +await page.handleLocator(page.getByText('Confirm your security details'), async () => { + await page.getByRole('button', 'Remind me later').click(); +}); + +// Write the test as usual. +await page.goto('https://example.com'); +await page.getByRole('button', { name: 'Start here' }).click(); +``` + +```java +// Setup the handler. +page.handleLocator(page.getByText("Confirm your security details")), () => { + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Remind me later")).click(); +}); + +// Write the test as usual. +page.goto("https://example.com"); +page.getByRole("button", Page.GetByRoleOptions().setName("Start here")).click(); +``` + +```python sync +# Setup the handler. +def handler(): + page.get_by_role("button", name="Remind me later").click() +page.handle_locator(page.get_by_text("Confirm your security details"), handler) + +# Write the test as usual. +page.goto("https://example.com") +page.get_by_role("button", name="Start here").click() +``` + +```python async +# Setup the handler. +def handler(): + await page.get_by_role("button", name="Remind me later").click() +await page.handle_locator(page.get_by_text("Confirm your security details"), handler) + +# Write the test as usual. +await page.goto("https://example.com") +await page.get_by_role("button", name="Start here").click() +``` + +```csharp +// Setup the handler. +await page.HandleLocatorAsync(page.GetByText("Confirm your security details"), async () => { + await page.GetByRole(AriaRole.Button, new() { Name = "Remind me later" }).ClickAsync(); +}); + +// Write the test as usual. +await page.GotoAsync("https://example.com"); +await page.GetByRole("button", new() { Name = "Start here" }).ClickAsync(); +``` + +An example with a custom callback on every actionability check. It uses a `` locator that is always visible, so the handler is called before every actionability check: + +```js +// Setup the handler. +await page.handleLocator(page.locator('body'), async () => { + await page.evaluate(() => window.removeObstructionsForTestIfNeeded()); +}); + +// Write the test as usual. +await page.goto('https://example.com'); +await page.getByRole('button', { name: 'Start here' }).click(); +``` + +```java +// Setup the handler. +page.handleLocator(page.locator("body")), () => { + page.evaluate("window.removeObstructionsForTestIfNeeded()"); +}); + +// Write the test as usual. +page.goto("https://example.com"); +page.getByRole("button", Page.GetByRoleOptions().setName("Start here")).click(); +``` + +```python sync +# Setup the handler. +def handler(): + page.evaluate("window.removeObstructionsForTestIfNeeded()") +page.handle_locator(page.locator("body"), handler) + +# Write the test as usual. +page.goto("https://example.com") +page.get_by_role("button", name="Start here").click() +``` + +```python async +# Setup the handler. +def handler(): + await page.evaluate("window.removeObstructionsForTestIfNeeded()") +await page.handle_locator(page.locator("body"), handler) + +# Write the test as usual. +await page.goto("https://example.com") +await page.get_by_role("button", name="Start here").click() +``` + +```csharp +// Setup the handler. +await page.HandleLocatorAsync(page.Locator("body"), async () => { + await page.EvaluateAsync("window.removeObstructionsForTestIfNeeded()"); +}); + +// Write the test as usual. +await page.GotoAsync("https://example.com"); +await page.GetByRole("button", new() { Name = "Start here" }).ClickAsync(); +``` + +### param: Page.handleLocator.locator +* since: v1.42 +- `locator` <[Locator]> + +Locator that triggers the handler. + +### param: Page.handleLocator.handler +* since: v1.42 +- `handler` <[function]> + +Function that should be run once [`param: locator`] appears. This function should get rid of the element that blocks actions like click. + + ## async method: Page.reload * since: v1.8 - returns: <[null]|[Response]> diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 570e391cb76f1..df03d2f229414 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -97,6 +97,8 @@ export class Page extends ChannelOwner implements api.Page _closeWasCalled: boolean = false; private _harRouters: HarRouter[] = []; + private _locatorHandlers = new Map(); + static from(page: channels.PageChannel): Page { return (page as any)._object; } @@ -133,6 +135,7 @@ export class Page extends ChannelOwner implements api.Page this._channel.on('fileChooser', ({ element, isMultiple }) => this.emit(Events.Page.FileChooser, new FileChooser(this, ElementHandle.from(element), isMultiple))); this._channel.on('frameAttached', ({ frame }) => this._onFrameAttached(Frame.from(frame))); this._channel.on('frameDetached', ({ frame }) => this._onFrameDetached(Frame.from(frame))); + this._channel.on('locatorHandlerTriggered', ({ uid }) => this._onLocatorHandlerTriggered(uid)); this._channel.on('route', ({ route }) => this._onRoute(Route.from(route))); this._channel.on('video', ({ artifact }) => { const artifactObject = Artifact.from(artifact); @@ -360,6 +363,22 @@ export class Page extends ChannelOwner implements api.Page return Response.fromNullable((await this._channel.reload({ ...options, waitUntil })).response); } + async handleLocator(locator: Locator, handler: Function): Promise { + if (locator._frame !== this._mainFrame) + throw new Error(`Locator must belong to the main frame of this page`); + const { uid } = await this._channel.registerLocatorHandler({ selector: locator._selector }); + this._locatorHandlers.set(uid, handler); + } + + private async _onLocatorHandlerTriggered(uid: number) { + try { + const handler = this._locatorHandlers.get(uid); + await handler?.(); + } finally { + this._channel.resolveLocatorHandlerNoReply({ uid }).catch(() => {}); + } + } + async waitForLoadState(state?: LifecycleEvent, options?: { timeout?: number }): Promise { return await this._mainFrame.waitForLoadState(state, options); } diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 5a6e9363d8edb..fe523bf63d11f 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -983,6 +983,9 @@ scheme.PageFrameAttachedEvent = tObject({ scheme.PageFrameDetachedEvent = tObject({ frame: tChannel(['Frame']), }); +scheme.PageLocatorHandlerTriggeredEvent = tObject({ + uid: tNumber, +}); scheme.PageRouteEvent = tObject({ route: tChannel(['Route']), }); @@ -1038,6 +1041,16 @@ scheme.PageGoForwardParams = tObject({ scheme.PageGoForwardResult = tObject({ response: tOptional(tChannel(['Response'])), }); +scheme.PageRegisterLocatorHandlerParams = tObject({ + selector: tString, +}); +scheme.PageRegisterLocatorHandlerResult = tObject({ + uid: tNumber, +}); +scheme.PageResolveLocatorHandlerNoReplyParams = tObject({ + uid: tNumber, +}); +scheme.PageResolveLocatorHandlerNoReplyResult = tOptional(tObject({})); scheme.PageReloadParams = tObject({ timeout: tOptional(tNumber), waitUntil: tOptional(tType('LifecycleEvent')), diff --git a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts index 70ccf16638795..775fd515f04b1 100644 --- a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts @@ -85,6 +85,7 @@ export class PageDispatcher extends Dispatcher this._onFrameAttached(frame)); this.addObjectListener(Page.Events.FrameDetached, frame => this._onFrameDetached(frame)); + this.addObjectListener(Page.Events.LocatorHandlerTriggered, (uid: number) => this._dispatchEvent('locatorHandlerTriggered', { uid })); this.addObjectListener(Page.Events.WebSocket, webSocket => this._dispatchEvent('webSocket', { webSocket: new WebSocketDispatcher(this, webSocket) })); this.addObjectListener(Page.Events.Worker, worker => this._dispatchEvent('worker', { worker: new WorkerDispatcher(this, worker) })); this.addObjectListener(Page.Events.Video, (artifact: Artifact) => this._dispatchEvent('video', { artifact: ArtifactDispatcher.from(parentScope, artifact) })); @@ -136,6 +137,15 @@ export class PageDispatcher extends Dispatcher { + const uid = this._page.registerLocatorHandler(params.selector); + return { uid }; + } + + async resolveLocatorHandlerNoReply(params: channels.PageResolveLocatorHandlerNoReplyParams, metadata: CallMetadata): Promise { + this._page.resolveLocatorHandler(params.uid); + } + async emulateMedia(params: channels.PageEmulateMediaParams, metadata: CallMetadata): Promise { await this._page.emulateMedia({ media: params.media, diff --git a/packages/playwright-core/src/server/dom.ts b/packages/playwright-core/src/server/dom.ts index 0fb196c4a221f..d2188aab5a179 100644 --- a/packages/playwright-core/src/server/dom.ts +++ b/packages/playwright-core/src/server/dom.ts @@ -288,7 +288,7 @@ export class ElementHandle extends js.JSHandle { }; } - async _retryAction(progress: Progress, actionName: string, action: (retry: number) => Promise, options: { trial?: boolean, force?: boolean }): Promise<'error:notconnected' | 'done'> { + async _retryAction(progress: Progress, actionName: string, action: (retry: number) => Promise, options: { trial?: boolean, force?: boolean, skipLocatorHandlersCheckpoint?: boolean }): Promise<'error:notconnected' | 'done'> { let retry = 0; // We progressively wait longer between retries, up to 500ms. const waitTime = [0, 20, 100, 100, 500]; @@ -306,6 +306,8 @@ export class ElementHandle extends js.JSHandle { } else { progress.log(`attempting ${actionName} action${options.trial ? ' (trial run)' : ''}`); } + if (!options.skipLocatorHandlersCheckpoint) + await this._frame._page.performLocatorHandlersCheckpoint(progress); const result = await action(retry); ++retry; if (result === 'error:notvisible') { @@ -339,6 +341,8 @@ export class ElementHandle extends js.JSHandle { async _retryPointerAction(progress: Progress, actionName: ActionName, waitForEnabled: boolean, action: (point: types.Point) => Promise, options: types.PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { + // Note: do not perform locator handlers checkpoint to avoid moving the mouse in the middle of a drag operation. + const skipLocatorHandlersCheckpoint = actionName === 'move and up'; return await this._retryAction(progress, actionName, async retry => { // By default, we scroll with protocol method to reveal the action point. // However, that might not work to scroll from under position:sticky elements @@ -352,7 +356,7 @@ export class ElementHandle extends js.JSHandle { ]; const forceScrollOptions = scrollOptions[retry % scrollOptions.length]; return await this._performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options); - }, options); + }, { ...options, skipLocatorHandlersCheckpoint }); } async _performPointerAction(progress: Progress, actionName: ActionName, waitForEnabled: boolean, action: (point: types.Point) => Promise, forceScrollOptions: ScrollIntoViewOptions | undefined, options: types.PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise { diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 014ca2243e774..1a7f9d77ec07d 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -1090,9 +1090,13 @@ export class Frame extends SdkObject { progress: Progress, selector: string, strict: boolean | undefined, + performLocatorHandlersCheckpoint: boolean, action: (handle: dom.ElementHandle) => Promise): Promise { progress.log(`waiting for ${this._asLocator(selector)}`); return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => { + if (performLocatorHandlersCheckpoint) + await this._page.performLocatorHandlersCheckpoint(progress); + const resolved = await this.selectors.resolveInjectedForSelector(selector, { strict }); progress.throwIfAborted(); if (!resolved) @@ -1133,7 +1137,7 @@ export class Frame extends SdkObject { } async rafrafTimeoutScreenshotElementWithProgress(progress: Progress, selector: string, timeout: number, options: ScreenshotOptions): Promise { - return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, async handle => { + return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performLocatorHandlersCheckpoint */, async handle => { await handle._frame.rafrafTimeout(timeout); return await this._page._screenshotter.screenshotElement(progress, handle, options); }); @@ -1142,21 +1146,21 @@ export class Frame extends SdkObject { async click(metadata: CallMetadata, selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._click(progress, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._click(progress, options))); }, this._page._timeoutSettings.timeout(options)); } async dblclick(metadata: CallMetadata, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._dblclick(progress, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._dblclick(progress, options))); }, this._page._timeoutSettings.timeout(options)); } async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); await controller.run(async progress => { - dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, async handle => { + dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, true /* performLocatorHandlersCheckpoint */, async handle => { return handle._retryPointerAction(progress, 'move and down', false, async point => { await this._page.mouse.move(point.x, point.y); await this._page.mouse.down(); @@ -1166,7 +1170,8 @@ export class Frame extends SdkObject { timeout: progress.timeUntilDeadline(), }); })); - dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, async handle => { + // Note: do not perform locator handlers checkpoint to avoid moving the mouse in the middle of a drag operation. + dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false /* performLocatorHandlersCheckpoint */, async handle => { return handle._retryPointerAction(progress, 'move and up', false, async point => { await this._page.mouse.move(point.x, point.y); await this._page.mouse.up(); @@ -1184,28 +1189,28 @@ export class Frame extends SdkObject { throw new Error('The page does not support tap. Use hasTouch context option to enable touch support.'); const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._tap(progress, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._tap(progress, options))); }, this._page._timeoutSettings.timeout(options)); } async fill(metadata: CallMetadata, selector: string, value: string, options: types.NavigatingActionWaitOptions & { force?: boolean }) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._fill(progress, value, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._fill(progress, value, options))); }, this._page._timeoutSettings.timeout(options)); } async focus(metadata: CallMetadata, selector: string, options: types.TimeoutOptions & types.StrictOptions = {}) { const controller = new ProgressController(metadata, this); await controller.run(async progress => { - dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._focus(progress))); + dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._focus(progress))); }, this._page._timeoutSettings.timeout(options)); } async blur(metadata: CallMetadata, selector: string, options: types.TimeoutOptions & types.StrictOptions = {}) { const controller = new ProgressController(metadata, this); await controller.run(async progress => { - dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._blur(progress))); + dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._blur(progress))); }, this._page._timeoutSettings.timeout(options)); } @@ -1268,6 +1273,12 @@ export class Frame extends SdkObject { const controller = new ProgressController(metadata, this); return controller.run(async progress => { progress.log(` checking visibility of ${this._asLocator(selector)}`); + return await this.isVisibleInternal(selector, options, scope); + }, this._page._timeoutSettings.timeout({})); + } + + async isVisibleInternal(selector: string, options: types.StrictOptions = {}, scope?: dom.ElementHandle): Promise { + try { const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope); if (!resolved) return false; @@ -1276,11 +1287,11 @@ export class Frame extends SdkObject { const state = element ? injected.elementState(element, 'visible') : false; return state === 'error:notconnected' ? false : state; }, { info: resolved.info, root: resolved.frame === this ? scope : undefined }); - }, this._page._timeoutSettings.timeout({})).catch(e => { + } catch (e) { if (js.isJavaScriptErrorInEvaluate(e) || isInvalidSelectorError(e) || isSessionClosedError(e)) throw e; return false; - }); + } } async isHidden(metadata: CallMetadata, selector: string, options: types.StrictOptions = {}, scope?: dom.ElementHandle): Promise { @@ -1306,14 +1317,14 @@ export class Frame extends SdkObject { async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._hover(progress, options))); }, this._page._timeoutSettings.timeout(options)); } async selectOption(metadata: CallMetadata, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions & types.ForceOptions = {}): Promise { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._selectOption(progress, elements, values, options)); + return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._selectOption(progress, elements, values, options)); }, this._page._timeoutSettings.timeout(options)); } @@ -1321,35 +1332,35 @@ export class Frame extends SdkObject { const inputFileItems = await prepareFilesForUpload(this, params); const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, handle => handle._setInputFiles(progress, inputFileItems, params))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._setInputFiles(progress, inputFileItems, params))); }, this._page._timeoutSettings.timeout(params)); } async type(metadata: CallMetadata, selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._type(progress, text, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._type(progress, text, options))); }, this._page._timeoutSettings.timeout(options)); } async press(metadata: CallMetadata, selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._press(progress, key, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._press(progress, key, options))); }, this._page._timeoutSettings.timeout(options)); } async check(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, true, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._setChecked(progress, true, options))); }, this._page._timeoutSettings.timeout(options)); } async uncheck(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, false, options))); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performLocatorHandlersCheckpoint */, handle => handle._setChecked(progress, false, options))); }, this._page._timeoutSettings.timeout(options)); } @@ -1384,6 +1395,8 @@ export class Frame extends SdkObject { progress.log(`waiting for ${this._asLocator(selector)}`); } return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1000], async continuePolling => { + await this._page.performLocatorHandlersCheckpoint(progress); + const selectorInFrame = await this.selectors.resolveFrameForSelector(selector, { strict: true }); progress.throwIfAborted(); diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index a00d09cfe3fab..0b043d1ff44b4 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -131,6 +131,7 @@ export class Page extends SdkObject { FrameAttached: 'frameattached', FrameDetached: 'framedetached', InternalFrameNavigatedToNewDocument: 'internalframenavigatedtonewdocument', + LocatorHandlerTriggered: 'locatorhandlertriggered', ScreencastFrame: 'screencastframe', Video: 'video', WebSocket: 'websocket', @@ -168,6 +169,9 @@ export class Page extends SdkObject { _video: Artifact | null = null; _opener: Page | undefined; private _isServerSideOnly = false; + private _locatorHandlers = new Map }>(); + private _lastLocatorHandlerUid = 0; + private _locatorHandlerRunningCounter = 0; // Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms. // When throttling for tracing, 200ms between frames, except for 10 frames around the action. @@ -249,6 +253,7 @@ export class Page extends SdkObject { async resetForReuse(metadata: CallMetadata) { this.setDefaultNavigationTimeout(undefined); this.setDefaultTimeout(undefined); + this._locatorHandlers.clear(); await this._removeExposedBindings(); await this._removeInitScripts(); @@ -428,6 +433,40 @@ export class Page extends SdkObject { }), this._timeoutSettings.navigationTimeout(options)); } + registerLocatorHandler(selector: string) { + const uid = ++this._lastLocatorHandlerUid; + this._locatorHandlers.set(uid, { selector }); + return uid; + } + + resolveLocatorHandler(uid: number) { + const handler = this._locatorHandlers.get(uid); + if (handler) { + handler.resolved?.resolve(); + handler.resolved = undefined; + } + } + + async performLocatorHandlersCheckpoint(progress: Progress) { + // Do not run locator handlers from inside locator handler callbacks to avoid deadlocks. + if (this._locatorHandlerRunningCounter) + return; + for (const [uid, handler] of this._locatorHandlers) { + if (!handler.resolved) { + if (await this.mainFrame().isVisibleInternal(handler.selector, { strict: true })) { + handler.resolved = new ManualPromise(); + this.emit(Page.Events.LocatorHandlerTriggered, uid); + } + } + if (handler.resolved) { + ++this._locatorHandlerRunningCounter; + await this.openScope.race(handler.resolved).finally(() => --this._locatorHandlerRunningCounter); + // Avoid side-effects after long-running operation. + progress.throwIfAborted(); + } + } + } + async emulateMedia(options: Partial) { if (options.media !== undefined) this._emulatedMedia.media = options.media; @@ -500,6 +539,7 @@ export class Page extends SdkObject { const rafrafScreenshot = locator ? async (progress: Progress, timeout: number) => { return await locator.frame.rafrafTimeoutScreenshotElementWithProgress(progress, locator.selector, timeout, options.screenshotOptions || {}); } : async (progress: Progress, timeout: number) => { + await this.performLocatorHandlersCheckpoint(progress); await this.mainFrame().rafrafTimeout(timeout); return await this._screenshotter.screenshotPage(progress, options.screenshotOptions || {}); }; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 4ce24d9297b43..7a4e941acd1df 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -2926,6 +2926,66 @@ export interface Page { waitUntil?: "load"|"domcontentloaded"|"networkidle"|"commit"; }): Promise; + /** + * Registers a handler for an element that might block certain actions like click. The handler should get rid of the + * blocking element so that an action may proceed. This is useful for nondeterministic interstitial pages or dialogs, + * like a cookie consent dialog. + * + * The handler will be executed before [actionability checks](https://playwright.dev/docs/actionability) for each action, and also before + * each attempt of the [web assertions](https://playwright.dev/docs/test-assertions). When no actions or assertions are executed, the + * handler will not be run at all, even if the interstitial element appears on the page. + * + * Note that execution time of the handler counts towards the timeout of the action/assertion that executed the + * handler. + * + * **Usage** + * + * An example that closes a cookie dialog when it appears: + * + * ```js + * // Setup the handler. + * await page.handleLocator(page.getByRole('button', { name: 'Accept all cookies' }), async () => { + * await page.getByRole('button', { name: 'Reject all cookies' }).click(); + * }); + * + * // Write the test as usual. + * await page.goto('https://example.com'); + * await page.getByRole('button', { name: 'Start here' }).click(); + * ``` + * + * An example that skips the "Confirm your security details" page when it is shown: + * + * ```js + * // Setup the handler. + * await page.handleLocator(page.getByText('Confirm your security details'), async () => { + * await page.getByRole('button', 'Remind me later').click(); + * }); + * + * // Write the test as usual. + * await page.goto('https://example.com'); + * await page.getByRole('button', { name: 'Start here' }).click(); + * ``` + * + * An example with a custom callback on every actionability check. It uses a `` locator that is always visible, + * so the handler is called before every actionability check: + * + * ```js + * // Setup the handler. + * await page.handleLocator(page.locator('body'), async () => { + * await page.evaluate(() => window.removeObstructionsForTestIfNeeded()); + * }); + * + * // Write the test as usual. + * await page.goto('https://example.com'); + * await page.getByRole('button', { name: 'Start here' }).click(); + * ``` + * + * @param locator Locator that triggers the handler. + * @param handler Function that should be run once `locator` appears. This function should get rid of the element that blocks actions + * like click. + */ + handleLocator(locator: Locator, handler: Function): Promise; + /** * **NOTE** Use locator-based [locator.hover([options])](https://playwright.dev/docs/api/class-locator#locator-hover) instead. * Read more about [locators](https://playwright.dev/docs/locators). diff --git a/packages/protocol/src/channels.ts b/packages/protocol/src/channels.ts index cf2cd36501446..2ff7b258444a1 100644 --- a/packages/protocol/src/channels.ts +++ b/packages/protocol/src/channels.ts @@ -1761,6 +1761,7 @@ export interface PageEventTarget { on(event: 'fileChooser', callback: (params: PageFileChooserEvent) => void): this; on(event: 'frameAttached', callback: (params: PageFrameAttachedEvent) => void): this; on(event: 'frameDetached', callback: (params: PageFrameDetachedEvent) => void): this; + on(event: 'locatorHandlerTriggered', callback: (params: PageLocatorHandlerTriggeredEvent) => void): this; on(event: 'route', callback: (params: PageRouteEvent) => void): this; on(event: 'video', callback: (params: PageVideoEvent) => void): this; on(event: 'webSocket', callback: (params: PageWebSocketEvent) => void): this; @@ -1776,6 +1777,8 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel { exposeBinding(params: PageExposeBindingParams, metadata?: CallMetadata): Promise; goBack(params: PageGoBackParams, metadata?: CallMetadata): Promise; goForward(params: PageGoForwardParams, metadata?: CallMetadata): Promise; + registerLocatorHandler(params: PageRegisterLocatorHandlerParams, metadata?: CallMetadata): Promise; + resolveLocatorHandlerNoReply(params: PageResolveLocatorHandlerNoReplyParams, metadata?: CallMetadata): Promise; reload(params: PageReloadParams, metadata?: CallMetadata): Promise; expectScreenshot(params: PageExpectScreenshotParams, metadata?: CallMetadata): Promise; screenshot(params: PageScreenshotParams, metadata?: CallMetadata): Promise; @@ -1822,6 +1825,9 @@ export type PageFrameAttachedEvent = { export type PageFrameDetachedEvent = { frame: FrameChannel, }; +export type PageLocatorHandlerTriggeredEvent = { + uid: number, +}; export type PageRouteEvent = { route: RouteChannel, }; @@ -1907,6 +1913,22 @@ export type PageGoForwardOptions = { export type PageGoForwardResult = { response?: ResponseChannel, }; +export type PageRegisterLocatorHandlerParams = { + selector: string, +}; +export type PageRegisterLocatorHandlerOptions = { + +}; +export type PageRegisterLocatorHandlerResult = { + uid: number, +}; +export type PageResolveLocatorHandlerNoReplyParams = { + uid: number, +}; +export type PageResolveLocatorHandlerNoReplyOptions = { + +}; +export type PageResolveLocatorHandlerNoReplyResult = void; export type PageReloadParams = { timeout?: number, waitUntil?: LifecycleEvent, @@ -2258,6 +2280,7 @@ export interface PageEvents { 'fileChooser': PageFileChooserEvent; 'frameAttached': PageFrameAttachedEvent; 'frameDetached': PageFrameDetachedEvent; + 'locatorHandlerTriggered': PageLocatorHandlerTriggeredEvent; 'route': PageRouteEvent; 'video': PageVideoEvent; 'webSocket': PageWebSocketEvent; diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 7eb7a96a9be28..eba4e5cc39eaa 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -1349,6 +1349,16 @@ Page: slowMo: true snapshot: true + registerLocatorHandler: + parameters: + selector: string + returns: + uid: number + + resolveLocatorHandlerNoReply: + parameters: + uid: number + reload: parameters: timeout: number? @@ -1668,6 +1678,10 @@ Page: parameters: frame: Frame + locatorHandlerTriggered: + parameters: + uid: number + route: parameters: route: Route diff --git a/tests/assets/input/handle-locator.html b/tests/assets/input/handle-locator.html new file mode 100644 index 0000000000000..abefafd7a2e59 --- /dev/null +++ b/tests/assets/input/handle-locator.html @@ -0,0 +1,79 @@ + + + + Interstitial test + + + +
+
A place on the side to hover
+
+
This interstitial covers the button
+ +
+ + + diff --git a/tests/page/page-handle-locator.spec.ts b/tests/page/page-handle-locator.spec.ts new file mode 100644 index 0000000000000..e7c829218f4c4 --- /dev/null +++ b/tests/page/page-handle-locator.spec.ts @@ -0,0 +1,172 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test, expect } from './pageTest'; +import { kTargetClosedErrorMessage } from '../config/errors'; + +test('should work', async ({ page, server }) => { + await page.goto(server.PREFIX + '/input/handle-locator.html'); + + let beforeCount = 0; + let afterCount = 0; + await page.handleLocator(page.getByText('This interstitial covers the button'), async () => { + ++beforeCount; + await page.locator('#close').click(); + ++afterCount; + }); + + for (const args of [ + ['mouseover', 1], + ['mouseover', 1, 'capture'], + ['mouseover', 2], + ['mouseover', 2, 'capture'], + ['pointerover', 1], + ['pointerover', 1, 'capture'], + ['none', 1], + ['remove', 1], + ['hide', 1], + ]) { + await test.step(`${args[0]}${args[2] === 'capture' ? ' with capture' : ''} ${args[1]} times`, async () => { + await page.locator('#aside').hover(); + beforeCount = 0; + afterCount = 0; + await page.evaluate(args => { + (window as any).clicked = 0; + (window as any).setupAnnoyingInterstitial(...args); + }, args); + expect(beforeCount).toBe(0); + expect(afterCount).toBe(0); + await page.locator('#target').click(); + expect(beforeCount).toBe(args[1]); + expect(afterCount).toBe(args[1]); + expect(await page.evaluate('window.clicked')).toBe(1); + await expect(page.locator('#interstitial')).not.toBeVisible(); + }); + } +}); + +test('should work with a custom check', async ({ page, server }) => { + await page.goto(server.PREFIX + '/input/handle-locator.html'); + + await page.handleLocator(page.locator('body'), async () => { + if (await page.getByText('This interstitial covers the button').isVisible()) + await page.locator('#close').click(); + }); + + for (const args of [ + ['mouseover', 2], + ['none', 1], + ['remove', 1], + ['hide', 1], + ]) { + await test.step(`${args[0]}${args[2] === 'capture' ? ' with capture' : ''} ${args[1]} times`, async () => { + await page.locator('#aside').hover(); + await page.evaluate(args => { + (window as any).clicked = 0; + (window as any).setupAnnoyingInterstitial(...args); + }, args); + await page.locator('#target').click(); + expect(await page.evaluate('window.clicked')).toBe(1); + await expect(page.locator('#interstitial')).not.toBeVisible(); + }); + } +}); + +test('should throw when page closes', async ({ page, server }) => { + await page.goto(server.PREFIX + '/input/handle-locator.html'); + + await page.handleLocator(page.getByText('This interstitial covers the button'), async () => { + await page.close(); + }); + + await page.locator('#aside').hover(); + await page.evaluate(() => { + (window as any).clicked = 0; + (window as any).setupAnnoyingInterstitial('mouseover', 1); + }); + const error = await page.locator('#target').click().catch(e => e); + expect(error.message).toContain(kTargetClosedErrorMessage); +}); + +test('should throw when handler times out', async ({ page, server }) => { + await page.goto(server.PREFIX + '/input/handle-locator.html'); + + let called = 0; + await page.handleLocator(page.getByText('This interstitial covers the button'), async () => { + ++called; + // Deliberately timeout. + await new Promise(() => {}); + }); + + await page.locator('#aside').hover(); + await page.evaluate(() => { + (window as any).clicked = 0; + (window as any).setupAnnoyingInterstitial('mouseover', 1); + }); + const error = await page.locator('#target').click({ timeout: 3000 }).catch(e => e); + expect(error.message).toContain('Timeout 3000ms exceeded'); + + const error2 = await page.locator('#target').click({ timeout: 3000 }).catch(e => e); + expect(error2.message).toContain('Timeout 3000ms exceeded'); + + // Should not enter the same handler while it is still running. + expect(called).toBe(1); +}); + +test('should work with toBeVisible', async ({ page, server }) => { + await page.goto(server.PREFIX + '/input/handle-locator.html'); + + let called = 0; + await page.handleLocator(page.getByText('This interstitial covers the button'), async () => { + ++called; + await page.locator('#close').click(); + }); + + await page.evaluate(() => { + (window as any).clicked = 0; + (window as any).setupAnnoyingInterstitial('remove', 1); + }); + await expect(page.locator('#target')).toBeVisible(); + await expect(page.locator('#interstitial')).not.toBeVisible(); + expect(called).toBe(1); +}); + +test('should work with toHaveScreenshot', async ({ page, server }) => { + await page.setViewportSize({ width: 500, height: 500 }); + await page.goto(server.PREFIX + '/grid.html'); + + await page.evaluate(() => { + const overlay = document.createElement('div'); + document.body.append(overlay); + overlay.style.position = 'absolute'; + overlay.style.left = '0'; + overlay.style.right = '0'; + overlay.style.top = '0'; + overlay.style.bottom = '0'; + overlay.style.backgroundColor = 'red'; + + const closeButton = document.createElement('button'); + overlay.appendChild(closeButton); + closeButton.textContent = 'close'; + closeButton.addEventListener('click', () => overlay.remove()); + }); + + await page.handleLocator(page.getByRole('button', { name: 'close' }), async () => { + await page.getByRole('button', { name: 'close' }).click(); + }); + + await expect(page).toHaveScreenshot('screenshot-grid.png'); +}); diff --git a/tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-chromium.png b/tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-chromium.png new file mode 100644 index 0000000000000000000000000000000000000000..122a4f0ae04d939518343abfbe203d9c719612bb GIT binary patch literal 36296 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 F{~tmaMuz|Z literal 0 HcmV?d00001 diff --git a/tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-webkit.png b/tests/page/page-handle-locator.spec.ts-snapshots/screenshot-grid-webkit.png new file mode 100644 index 0000000000000000000000000000000000000000..af070c52a8cd300ca4c3a8a31608820cf80c22d5 GIT binary patch literal 32727 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

*Xe?TT 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 vu5GIZ`JV