From 5d2aa079faedd1b853baee83b80436a79c88db43 Mon Sep 17 00:00:00 2001 From: wswebcreation Date: Tue, 13 May 2025 08:27:34 +0200 Subject: [PATCH 1/2] fix: fix capturing non-static positioned elements via bidi interface --- .changeset/hot-carrots-appear.md | 6 ++++ .../src/commands/saveWebElement.ts | 33 ++++++++++++------- 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 .changeset/hot-carrots-appear.md diff --git a/.changeset/hot-carrots-appear.md b/.changeset/hot-carrots-appear.md new file mode 100644 index 00000000..cde037ce --- /dev/null +++ b/.changeset/hot-carrots-appear.md @@ -0,0 +1,6 @@ +--- +"webdriver-image-comparison": patch +"@wdio/visual-service": patch +--- + +Fix capturing element screenshots with BiDi diff --git a/packages/webdriver-image-comparison/src/commands/saveWebElement.ts b/packages/webdriver-image-comparison/src/commands/saveWebElement.ts index cd60738e..61e2cd07 100644 --- a/packages/webdriver-image-comparison/src/commands/saveWebElement.ts +++ b/packages/webdriver-image-comparison/src/commands/saveWebElement.ts @@ -10,6 +10,7 @@ import scrollElementIntoView from '../clientSideScripts/scrollElementIntoView.js import { canUseBidiScreenshot, getBase64ScreenshotSize, getMethodOrWicOption, waitFor } from '../helpers/utils.js' import scrollToPosition from '../clientSideScripts/scrollToPosition.js' import type { InternalSaveElementMethodOptions } from './save.interfaces.js' +import type { BidiScreenshot, GetWindowHandle } from '../methods/methods.interfaces.js' /** * Saves an image of an element @@ -78,17 +79,27 @@ export default async function saveWebElement( // We also need to clip the image to the element size, taking into account the DPR // and also clipt if from the document, not the viewport const rect = await methods.getElementRect!((await element as WebdriverIO.Element).elementId) - base64Image = await takeBase64BiDiScreenshot({ - bidiScreenshot: methods.bidiScreenshot!, - getWindowHandle: methods.getWindowHandle!, - origin: 'document', - clip: { - x: Math.floor(rect.x), - y: Math.floor(rect.y), - width: Math.floor(rect.width), - height: Math.floor(rect.height), - }, - }) + const clip = { x: Math.floor(rect.x), y: Math.floor(rect.y), width: Math.floor(rect.width), height: Math.floor(rect.height) } + const { bidiScreenshot, getWindowHandle } = methods as { bidiScreenshot: BidiScreenshot; getWindowHandle: GetWindowHandle } + const takeBiDiElementScreenshot = (origin: 'document' | 'viewport') => + takeBase64BiDiScreenshot({ bidiScreenshot, getWindowHandle, origin, clip }) + + try { + // By default we take the screenshot from the document + base64Image = await takeBiDiElementScreenshot('viewport') + } catch (err: any) { + // But when we get a zero dimension error (meaning the element might be bigger than the + // viewport or it might not be in the viewport), we need to take the screenshot from the document. + const isZeroDimensionError = typeof err?.message === 'string' && err.message.includes( + 'WebDriver Bidi command "browsingContext.captureScreenshot" failed with error: unable to capture screen - Unable to capture screenshot with zero dimensions' + ) + + if (!isZeroDimensionError) { + throw err + } + + base64Image = await takeBiDiElementScreenshot('document') + } } else { // Scroll the element into top of the viewport and return the current scroll position let currentPosition: number | undefined From e349afd0bd67c3f47791b30db01e1f6141baf4d7 Mon Sep 17 00:00:00 2001 From: wswebcreation Date: Tue, 13 May 2025 08:32:08 +0200 Subject: [PATCH 2/2] chore: update release notes --- .changeset/hot-carrots-appear.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.changeset/hot-carrots-appear.md b/.changeset/hot-carrots-appear.md index cde037ce..a855431e 100644 --- a/.changeset/hot-carrots-appear.md +++ b/.changeset/hot-carrots-appear.md @@ -4,3 +4,10 @@ --- Fix capturing element screenshots with BiDi + +This release fixes #919 where an element screenshot, that was for example from an overlay, dropdown, popover, tooltip, modal, was returning an incorrect screenshot + +## Committers: 1 + +- Wim Selles ([@wswebcreation](https://github.com/wswebcreation)) +