From f4ef4c0e38f8b192bc9f3c221337ac8fcc49abb8 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Tue, 14 Apr 2026 19:20:48 +0300 Subject: [PATCH 01/29] fix: remove duplicate screenshot delay --- src/browser/existing-browser.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/browser/existing-browser.ts b/src/browser/existing-browser.ts index 1212cb562..1be113579 100644 --- a/src/browser/existing-browser.ts +++ b/src/browser/existing-browser.ts @@ -179,11 +179,7 @@ export class ExistingBrowser extends Browser { return this._calibration ? this._calibration.needsCompatLib : false; } - async captureViewportImage(opts?: CaptureViewportImageOpts, screenshotDelay?: number): Promise { - if (screenshotDelay) { - await new Promise(resolve => setTimeout(resolve, screenshotDelay)); - } - + async captureViewportImage(opts?: CaptureViewportImageOpts): Promise { return this._camera.captureViewportImage(opts); } From 7369319d2e78fdce8ca9d83a988112194386a4b7 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Tue, 14 Apr 2026 19:21:27 +0300 Subject: [PATCH 02/29] fix: correctly handle absence of capture rects in safe area computation --- src/browser/client-scripts/screen-shooter/operations.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/browser/client-scripts/screen-shooter/operations.ts b/src/browser/client-scripts/screen-shooter/operations.ts index b24b919a5..2b8239ddf 100644 --- a/src/browser/client-scripts/screen-shooter/operations.ts +++ b/src/browser/client-scripts/screen-shooter/operations.ts @@ -196,14 +196,15 @@ export function computeSafeArea( const captureElements = selectorsToCapture .map(s => document.querySelector(parseCaptureSelector(s).elementSelector)) .filter((e): e is NonNullable => e !== null); + const captureSpecs = computeCaptureSpecs(selectorsToCapture).captureSpecs.map(s => s.full); - if (captureElements.length === 0) { + if (captureSpecs.length === 0) { return { safeArea: { top: viewportRect.top, height: viewportRect.height } }; } - const captureArea = getCoveringRect(computeCaptureSpecs(selectorsToCapture).captureSpecs.map(s => s.full)); + const captureArea = getCoveringRect(captureSpecs); const scrollEl = scrollElement ?? document.documentElement; // 1. Base safe area equals the visible rectangle of the scroll container From 55720b97663040822b547b492976a4873237647c Mon Sep 17 00:00:00 2001 From: shadowusr Date: Tue, 14 Apr 2026 19:23:49 +0300 Subject: [PATCH 03/29] fix: remove delay in screen-shooter and wait for settle when capturing checkpoints --- src/browser/screen-shooter/elements-screen-shooter.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index 6d6d7a9ae..ba2dfce00 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -135,8 +135,6 @@ export class ElementsScreenShooter { try { perfDebug(`Starting capture attempt.`); - await new Promise(resolve => setTimeout(resolve, 1000)); - const page = await this._prepareScreenshot(selectorsToCapture, { ignoreSelectors: selectorsToIgnore, allowViewportOverflow: opts.allowViewportOverflow, @@ -165,11 +163,13 @@ export class ElementsScreenShooter { prepareScreenshotTime = performance.now() - captureScreenshotStartTime; perfDebug(`Prepare screenshot finished. Time spent on prepare screenshot: ${prepareScreenshotTime}ms`); + const isLastAttempt = retriesCount === retriesLimit; + // For the first attempt, we take optimistic approach and don't verify if the whole area is stable in size, // because in majority of cases, it is stable and it's better to not spend time on scrolling. // If it's not stable on first try, it will throw and we will pre-load the whole area & verify it here, // optimising the "unstable" case - it's faster to discard early during scrolling than during actual capturing. - if (retriesCount > 1) { + if (retriesCount > 1 && !isLastAttempt) { const validateCaptureAreaStabilityStartTime = performance.now(); await this._validateCaptureAreaStability(selectorsToCapture, selectorsToIgnore, page, opts); // await this._preloadCaptureArea(selectorsToCapture, selectorsToIgnore, page, opts); @@ -179,7 +179,7 @@ export class ElementsScreenShooter { ); } - const shouldThrowOnCaptureAreaSizeChange = retriesCount === 1; + const shouldThrowOnCaptureAreaSizeChange = !isLastAttempt; const captureAttemptStartTime = performance.now(); const compositeImage = await this._performCaptureAttempt( @@ -634,6 +634,8 @@ export class ElementsScreenShooter { ); } + await this._waitForCaptureAreaToSettle(selectorsToCapture); + const currentCheckpoint = await this._browserSideScreenshooter.call("getCaptureState", [ selectorsToCapture, selectorsToIgnore, From c56b6d1a595cf7455bed8e6c6a00c23d57d715a5 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Wed, 15 Apr 2026 01:05:01 +0300 Subject: [PATCH 04/29] fix: fix safe area computation and failing e2e tests --- .../screen-shooter/operations.ts | 11 ++- .../e2e/screens/7e93836/chrome/test-block.png | Bin 0 -> 5651 bytes test/e2e/screens/89919a4/chrome/viewport.png | Bin 0 -> 42420 bytes .../chrome/basic-report-page-screenshot.png | Bin 32448 -> 32434 bytes .../e2e/screens/a2b6a7e/chrome/test-block.png | Bin 0 -> 5265 bytes .../e2e/screens/c1dabd5/chrome/text-block.png | Bin 0 -> 25208 bytes .../e2e/screens/e065453/chrome/test-block.png | Bin 25185 -> 25198 bytes test/e2e/static/just-sticky-element.html | 37 ++++++++++ .../static/overlapping-blocks-at-y2000.html | 4 +- ...at-the-bottom-of-scrollable-container.html | 50 ++++++++++++++ test/e2e/static/viewport-sized-block.html | 65 ++++++++++++++++++ test/e2e/tests/assert-view.testplane.js | 61 +++++++++++++--- 12 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 test/e2e/screens/7e93836/chrome/test-block.png create mode 100644 test/e2e/screens/89919a4/chrome/viewport.png create mode 100644 test/e2e/screens/a2b6a7e/chrome/test-block.png create mode 100644 test/e2e/screens/c1dabd5/chrome/text-block.png create mode 100644 test/e2e/static/just-sticky-element.html create mode 100644 test/e2e/static/small-block-at-the-bottom-of-scrollable-container.html create mode 100644 test/e2e/static/viewport-sized-block.html diff --git a/src/browser/client-scripts/screen-shooter/operations.ts b/src/browser/client-scripts/screen-shooter/operations.ts index 2b8239ddf..bcb9257e0 100644 --- a/src/browser/client-scripts/screen-shooter/operations.ts +++ b/src/browser/client-scripts/screen-shooter/operations.ts @@ -359,18 +359,18 @@ export function computeSafeArea( const br = interference.rect; const safeBottom = getBottom({ top: safeTop, height: safeHeight }); const brBottom = getBottom(br); - const shrinkTop = brBottom > safeTop ? brBottom - safeTop : null; - const shrinkBottom = safeBottom > br.top ? safeBottom - br.top : null; + const shrinkTop = brBottom - safeTop; + const shrinkBottom = safeBottom - br.top; let resultingTop = safeTop; let resultingHeight = safeHeight; - if (shrinkTop && shrinkBottom && shrinkTop < shrinkBottom) { - resultingTop = brBottom; + if (shrinkTop < shrinkBottom) { + resultingTop = Math.max(brBottom, safeTop) as Coord<"viewport", "css", "y">; resultingHeight = getHeight(safeBottom, resultingTop); logger?.("decided to shrink top"); } else if (shrinkBottom) { - resultingHeight = getHeight(safeTop, br.top); + resultingHeight = Math.min(safeHeight, br.top - safeTop) as Length<"css", "y">; logger?.("decided to shrink bottom"); } @@ -460,7 +460,6 @@ export function scrollToCaptureAreaIfNeeded( if (!captureSpecsResult) return {}; const captureArea = getCoveringRect(captureSpecsResult.captureSpecs.map(s => s.full)); - // const captureElements = selectorsToCapture.flatMap(s => Array.from(document.querySelectorAll(s))); const safeArea = computeSafeArea(selectorsToCapture).safeArea; const captureAndSafeAreasIntersection = getIntersection(captureArea, safeArea); diff --git a/test/e2e/screens/7e93836/chrome/test-block.png b/test/e2e/screens/7e93836/chrome/test-block.png new file mode 100644 index 0000000000000000000000000000000000000000..c5fbd338800587dcba35130bebe8ffcdc4811f3f GIT binary patch literal 5651 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 literal 0 HcmV?d00001 diff --git a/test/e2e/screens/89919a4/chrome/viewport.png b/test/e2e/screens/89919a4/chrome/viewport.png new file mode 100644 index 0000000000000000000000000000000000000000..3a36818297f0a186403d74cfd045e920e0d0e9ac GIT binary patch literal 42420 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

4C+tY4!EXYFL2>8?y@DemZ1>row3; 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 literal 32448 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 diff --git a/test/e2e/screens/a2b6a7e/chrome/test-block.png b/test/e2e/screens/a2b6a7e/chrome/test-block.png new file mode 100644 index 0000000000000000000000000000000000000000..a948264821f2289b7b934237a173ac50541f6fb7 GIT binary patch literal 5265 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 ezC!IS^_DLm(-Ih@!vLv~;rcZrZK9?__(> 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 literal 0 HcmV?d00001 diff --git a/test/e2e/screens/e065453/chrome/test-block.png b/test/e2e/screens/e065453/chrome/test-block.png index 35c4d3ba20ebd1e3eda782a2a4ad298c7a2ed6c7..387008db8df1f48f0e05767a3804efefb1a11d77 100644 GIT binary patch literal 25198 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 + + + + + Sticky Element Test + + + +

Sticky Element Demo

+ +
+
I'm a sticky element (red border) - I'll stick to the top when you scroll!
+
+ + diff --git a/test/e2e/static/overlapping-blocks-at-y2000.html b/test/e2e/static/overlapping-blocks-at-y2000.html index aa34d3076..f331d4fe5 100644 --- a/test/e2e/static/overlapping-blocks-at-y2000.html +++ b/test/e2e/static/overlapping-blocks-at-y2000.html @@ -106,7 +106,9 @@

Test Block Content

// After page loads, scroll to position the text block perfectly under the fixed overlay // Scroll to the calculated position setTimeout(() => { - window.scrollTo(0, 1197); + const overlayBlock = document.querySelector(".overlay-block"); + const targetBlock = document.querySelector(".text-block"); + window.scrollTo(0, targetBlock.getBoundingClientRect().y - overlayBlock.getBoundingClientRect().y); }, 10); diff --git a/test/e2e/static/small-block-at-the-bottom-of-scrollable-container.html b/test/e2e/static/small-block-at-the-bottom-of-scrollable-container.html new file mode 100644 index 000000000..218b2835d --- /dev/null +++ b/test/e2e/static/small-block-at-the-bottom-of-scrollable-container.html @@ -0,0 +1,50 @@ + + + + + + Small Block at Bottom + + + +

Scrollable Container with Bottom Block

+ +
+
+

This is very long content. Scroll down to see the block at the bottom.

+

Keep scrolling...

+
+ +
+ I'm a block at the bottom of the scrollable container (red border) +
+
+ + diff --git a/test/e2e/static/viewport-sized-block.html b/test/e2e/static/viewport-sized-block.html new file mode 100644 index 000000000..6e1817ed9 --- /dev/null +++ b/test/e2e/static/viewport-sized-block.html @@ -0,0 +1,65 @@ + + + + + + Viewport-sized Block + + + +
This is before the viewport-sized block
+ +
Some header
+ + +
This block is of viewport size
+ +
This is after the viewport-sized block
+ + diff --git a/test/e2e/tests/assert-view.testplane.js b/test/e2e/tests/assert-view.testplane.js index eddf18cf7..7ed20db4a 100644 --- a/test/e2e/tests/assert-view.testplane.js +++ b/test/e2e/tests/assert-view.testplane.js @@ -300,13 +300,20 @@ describe("assertView", () => { it("should resume animations after assertView failure", async ({ browser }) => { await browser.url("animation-cleanup.html"); - await expect(() => - browser.assertView("animation-cleanup-fail", "[data-testid=too-tall]", { - disableAnimation: true, - compositeImage: false, - captureElementFromTop: true, - }), - ).rejects.toThrow(); + const originalTakeScreenshot = browser.takeScreenshot.bind(browser); + browser.overwriteCommand("takeScreenshot", async () => { + throw new Error("Forced screenshot failure"); + }); + + try { + await expect( + browser.assertView("animation-cleanup-fail", "[data-testid=animated-block]", { + disableAnimation: true, + }), + ).rejects.toThrow("Forced screenshot failure"); + } finally { + browser.overwriteCommand("takeScreenshot", async () => originalTakeScreenshot()); + } const state = await browser.execute(() => { const targetElement = document.querySelector("[data-testid=animated-block]"); @@ -318,9 +325,13 @@ describe("assertView", () => { return { animationDuration, someElementHasAnimationStoppedStyle: hasStyle, + animationStyleInserted: window.__animationStyleInserted, + animationStyleRemoved: window.__animationStyleRemoved, }; }); + expect(state.animationStyleInserted).toBe(true); + expect(state.animationStyleRemoved).toBe(true); expect(state.someElementHasAnimationStoppedStyle).toBe(false); expect(state.animationDuration).toBe("0.2s"); }); @@ -329,8 +340,38 @@ describe("assertView", () => { it("should work fine when capturing elements that are overlapping", async ({ browser }) => { await browser.url("overlapping-blocks-at-y2000.html"); - await expect(() => - browser.assertView("text-block", "[data-testid=text-block]", { captureElementFromTop: false }), - ).rejects.toThrow("The element is completely obscured by fixed or sticky elements"); + await browser.assertView("text-block", "[data-testid=text-block]", { captureElementFromTop: false }); + }); + + it("should work fine when capturing elements that contain only sticky element", async ({ browser }) => { + await browser.url("just-sticky-element.html"); + + await browser.assertView("test-block", "[data-testid=parent-block]"); + }); + + it("should be able to scroll to a block inside a scrollable container", async ({ browser }) => { + await browser.url("small-block-at-the-bottom-of-scrollable-container.html"); + + await browser.execute(() => { + document.querySelector("[data-testid=bottom-block]").scrollIntoView(); + }); + + await browser.assertView("test-block", "[data-testid=bottom-block]"); + }); + + it("should screenshot exactly the viewport when compositeImage=false and allowViewportOverflow=true", async ({ + browser, + }) => { + await browser.url("viewport-sized-block.html"); + + await browser.execute(() => { + document.querySelector("[data-testid=viewport-block]").scrollIntoView(); + }); + + await browser.assertView("viewport", "body", { + captureElementFromTop: false, + compositeImage: false, + allowViewportOverflow: true, + }); }); }); From 7e2bd63f7976412dfb8bd0096c1490f994971e8c Mon Sep 17 00:00:00 2001 From: shadowusr Date: Thu, 16 Apr 2026 01:45:09 +0300 Subject: [PATCH 05/29] test: fix unit tests and formatting issues --- .eslintrc.js | 17 +- .mocharc.js | 3 +- .prettierignore | 1 + package.json | 2 +- src/browser/camera/index.ts | 1 - src/browser/client-scripts/calibrate.js | 2 + .../shared/polyfills/getComputedStyle.ts | 6 +- src/browser/isomorphic/tsconfig.json | 4 +- src/config/defaults.js | 1 - .../prepareViewportScreenshot.testplane.ts | 2 +- test/browser-env/types.d.ts | 2 + .../screen-shooter/screen-shooter.test.ts | 24 +- .../non-deterministic-changing-dimensions.png | Bin 25539 -> 0 bytes test/src/browser/client-bridge/index.ts | 3 +- test/src/browser/client-scripts/build.ts | 23 +- test/src/browser/commands/switchToRepl.ts | 77 +- test/src/browser/existing-browser.js | 29 +- test/src/browser/isomorphic/geometry.ts | 2 +- .../composite-image/fixtures/generate.ts | 883 +++++++++--------- test/src/browser/screen-shooter/index.js | 29 +- test/src/browser/screen-shooter/validation.js | 100 +- test/src/cli/commands/install-deps/index.ts | 2 +- test/src/dev-server/index.ts | 4 +- test/src/utils/logger.js | 12 +- test/src/utils/promise.ts | 4 +- test/src/utils/typescript.ts | 3 +- .../browser-env/runner/test-runner/index.ts | 60 +- test/src/worker/runner/index.js | 30 +- test/src/worker/testplane.js | 1 + test/tsconfig.json | 18 +- test/utils.js | 6 + tsconfig.json | 23 +- 32 files changed, 748 insertions(+), 626 deletions(-) delete mode 100644 test/integration/screen-shooter/screens/non-deterministic-changing-dimensions.png diff --git a/.eslintrc.js b/.eslintrc.js index 64f949094..e694a78f8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -45,7 +45,14 @@ module.exports = { { patterns: [ { - group: ["../../**", "!../../isomorphic", "!../../isomorphic/**", "!../../..", "!../../../isomorphic", "!../../../isomorphic/**"], + group: [ + "../../**", + "!../../isomorphic", + "!../../isomorphic/**", + "!../../..", + "!../../../isomorphic", + "!../../../isomorphic/**", + ], message: "Client-scripts cannot import server-side code, except isomorphic modules.", }, ], @@ -66,5 +73,13 @@ module.exports = { "@typescript-eslint/no-var-requires": "off", }, }, + { + files: ["test/**"], + rules: { + "@typescript-eslint/no-empty-function": "off", + // For convenient casting of test objects + "@typescript-eslint/no-explicit-any": "off", + }, + }, ], }; diff --git a/.mocharc.js b/.mocharc.js index 896c1f327..ef3f672bc 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -3,5 +3,6 @@ module.exports = { recursive: true, extension: [".js", ".ts"], - require: ["./test/setup", "./test/assert-ext", "./test/ts-node"], + ignore: ["./test/browser-env/**", "**/report/**", "**/basic-report/**"], + require: ["./test/setup", "./test/assert-ext", "./test/ts-node", "tsconfig-paths/register"], }; diff --git a/.prettierignore b/.prettierignore index 69bfa5405..995780812 100644 --- a/.prettierignore +++ b/.prettierignore @@ -18,3 +18,4 @@ coverage/** test/browser-env/report/** *.png *.DS_Store +.claude diff --git a/package.json b/package.json index 78ff6259b..e86c88de3 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", "test-unit": "npm run test-unit:generate-fixtures && _mocha \"test/!(integration|e2e|browser-env)/**/*.[jt]s\"", "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|e2e)/**/*.[jt]s\"", - "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts", + "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", "test-integration": "TS_NODE_TRANSPILE_ONLY=1 mocha -r ts-node/register test/integration/*/**", "test-e2e": "npm run test-e2e:generate-fixtures && npm run test-e2e:run-tests", diff --git a/src/browser/camera/index.ts b/src/browser/camera/index.ts index d9fc7e184..67442b353 100644 --- a/src/browser/camera/index.ts +++ b/src/browser/camera/index.ts @@ -1,6 +1,5 @@ import os from "node:os"; import path from "node:path"; -import _ from "lodash"; import makeDebug from "debug"; import { Image } from "../../image"; diff --git a/src/browser/client-scripts/calibrate.js b/src/browser/client-scripts/calibrate.js index 3eb443ff7..eb1ad8d3f 100644 --- a/src/browser/client-scripts/calibrate.js +++ b/src/browser/client-scripts/calibrate.js @@ -1,3 +1,5 @@ +/* global navigator, document, window */ + (function (window) { "use strict"; diff --git a/src/browser/client-scripts/shared/polyfills/getComputedStyle.ts b/src/browser/client-scripts/shared/polyfills/getComputedStyle.ts index 6ea638bb4..e97d7357a 100644 --- a/src/browser/client-scripts/shared/polyfills/getComputedStyle.ts +++ b/src/browser/client-scripts/shared/polyfills/getComputedStyle.ts @@ -3,9 +3,10 @@ */ function getComputedStylePixel(element: Element, property: string, fontSize?: number | null): number { const // Internet Explorer sometimes struggles to read currentStyle until the element's document is accessed. - // eslint-disable-next-line @typescript-eslint/no-explicit-any + /* eslint-disable @typescript-eslint/no-explicit-any */ value = ((element as any).document && (element as any).currentStyle[property].match(/([\d.]+)(%|cm|em|in|mm|pc|pt|)/)) || [0, 0, ""], + /* eslint-enable @typescript-eslint/no-explicit-any */ size = value[1], suffix = value[2]; @@ -139,8 +140,9 @@ export { CSSStyleDeclaration }; // .getComputedStyle export function getComputedStyle(element: Element, pseudoEl: string): CSSStyleDeclaration { // IE9 needs matchMedia support but already support getComputedStyle - // eslint-disable-next-line @typescript-eslint/no-explicit-any + /* eslint-disable @typescript-eslint/no-explicit-any */ return window.getComputedStyle ? window.getComputedStyle(element, pseudoEl) : new (CSSStyleDeclaration as any)(element); + /* eslint-enable @typescript-eslint/no-explicit-any */ } diff --git a/src/browser/isomorphic/tsconfig.json b/src/browser/isomorphic/tsconfig.json index fe7f3e52d..85e2d4ee8 100644 --- a/src/browser/isomorphic/tsconfig.json +++ b/src/browser/isomorphic/tsconfig.json @@ -3,6 +3,6 @@ "include": ["."], "compilerOptions": { "composite": true, - "declaration": true, + "declaration": true } -} \ No newline at end of file +} diff --git a/src/config/defaults.js b/src/config/defaults.js index e831888c1..e0d5f3e60 100644 --- a/src/config/defaults.js +++ b/src/config/defaults.js @@ -4,7 +4,6 @@ const { DisableHoverMode } = require("../browser/isomorphic"); const { WEBDRIVER_PROTOCOL, SAVE_HISTORY_MODE, NODEJS_TEST_RUN_ENV } = require("../constants/config"); const { TimeTravelMode } = require("./types"); - module.exports = { baseUrl: "http://localhost", gridUrl: "http://localhost:4444/wd/hub", diff --git a/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts b/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts index 0ba4b201a..e2970dcfb 100644 --- a/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts +++ b/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts @@ -25,7 +25,7 @@ describe("prepareViewportScreenshot in high pixel ratio mode", () => { window.scrollTo(0, 0); }); - it("returns viewport and document dimensions translated to device pixels", async ({ browser }) => { + it("returns viewport and document dimensions translated to device pixels", async () => { window.scrollTo(0, 245); const cssViewportSize = computeViewportSize().viewportSize; diff --git a/test/browser-env/types.d.ts b/test/browser-env/types.d.ts index c4cbfdc01..d29bb7d59 100644 --- a/test/browser-env/types.d.ts +++ b/test/browser-env/types.d.ts @@ -1,3 +1,5 @@ +/// + declare module "*.html?raw" { const content: string; export default content; diff --git a/test/integration/screen-shooter/screen-shooter.test.ts b/test/integration/screen-shooter/screen-shooter.test.ts index f6d9fc73c..22b1973d1 100644 --- a/test/integration/screen-shooter/screen-shooter.test.ts +++ b/test/integration/screen-shooter/screen-shooter.test.ts @@ -56,7 +56,7 @@ describe("ElementsScreenShooter integration", function () { browser = null; } - if (tempDir) { + if (tempDir && !process.env.KEEP_ACTUAL) { await fs.promises.rm(tempDir, { recursive: true, force: true }); tempDir = null; } @@ -195,22 +195,12 @@ describe("ElementsScreenShooter integration", function () { const screenShooter = await createScreenShooter(browser as WdioBrowser); - const { image } = await screenShooter.capture(".Modal-Content", { - compositeImage: true, - selectorToScroll: ".Modal-Wrapper", - }); - - const actualImagePath = path.join(tempDir!, "non-deterministic-changing-dimensions.png"); - await image.save(actualImagePath); - - const expectedImagePath = path.join(SCREENSHOTS_PATH, "non-deterministic-changing-dimensions.png"); - - if (process.env.UPDATE_REFERENCES) { - await fs.promises.copyFile(actualImagePath, expectedImagePath); - } - - const comparison = await looksSame(actualImagePath, expectedImagePath); - assert(comparison.equal, "Expected screenshot to match reference image"); + await assert.doesNotReject(() => + screenShooter.capture(".Modal-Content", { + compositeImage: true, + selectorToScroll: ".Modal-Wrapper", + }), + ); }); it("keeps fractional checkpoint offsets stable during replay", async () => { diff --git a/test/integration/screen-shooter/screens/non-deterministic-changing-dimensions.png b/test/integration/screen-shooter/screens/non-deterministic-changing-dimensions.png deleted file mode 100644 index 21c97e9bb110695915480850377045d56070a589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25539 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%0A8gzAAo$=_j?%MjRG!( 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 { const modulePath = require.resolve("src/browser/client-bridge"); // This is needed to clear the cache of the client-bridge module delete require.cache[modulePath]; - // eslint-disable-next-line @typescript-eslint/no-var-requires + /* eslint-disable @typescript-eslint/no-var-requires */ const { ClientBridge: IsolatedClientBridge } = require("src/browser/client-bridge") as typeof import("src/browser/client-bridge"); + /* eslint-enable @typescript-eslint/no-var-requires */ const readFileStub = fs.promises.readFile as unknown as SinonStub; readFileStub.callsFake(async (filePath: fs.PathOrFileDescriptor) => { diff --git a/test/src/browser/client-scripts/build.ts b/test/src/browser/client-scripts/build.ts index 0166b6462..7cb60edd5 100644 --- a/test/src/browser/client-scripts/build.ts +++ b/test/src/browser/client-scripts/build.ts @@ -5,7 +5,8 @@ import fs from "fs-extra"; describe("client-scripts/build", () => { const sandbox = sinon.createSandbox(); - const targetDir = "build/src/browser/client-scripts"; + const targetDir = path.resolve(process.cwd(), "src", "browser", "client-scripts", "browser-utils"); + const buildDir = path.join(targetDir, "build"); let ensureDirStub: SinonStub; let writeFileStub: SinonStub; @@ -22,32 +23,38 @@ describe("client-scripts/build", () => { const buildClientScripts_ = async (): Promise => { const clearRequire = require("clear-require"); // eslint-disable-line @typescript-eslint/no-var-requires const scriptPath = path.resolve(process.cwd(), "src", "browser", "client-scripts", "build"); + const originalArgv = process.argv; clearRequire(scriptPath); + process.argv = [...process.argv.slice(0, 2), targetDir]; - await require("../../../../src/browser/client-scripts/build"); + try { + await require("../../../../src/browser/client-scripts/build"); + } finally { + process.argv = originalArgv; + } }; const assertForNativeLibrary_ = (): void => { assert.calledWithMatch(transformSpy, { aliases: { - "./lib": { relative: "./lib.native.js" }, + "@lib": "./src/browser/client-scripts/browser-utils/tsc-out/client-scripts/shared/lib.native.js", }, verbose: false, }); - assert.calledWith(ensureDirStub, targetDir); - assert.calledWith(writeFileStub, path.join(targetDir, "bundle.native.js"), sinon.match(Buffer)); + assert.calledWith(ensureDirStub, buildDir); + assert.calledWith(writeFileStub, path.join(buildDir, "bundle.native.js"), sinon.match.string); }; const assertForCompatLibrary_ = (): void => { assert.calledWithMatch(transformSpy, { aliases: { - "./lib": { relative: "./lib.compat.js" }, + "@lib": "./src/browser/client-scripts/browser-utils/tsc-out/client-scripts/shared/lib.compat.js", }, verbose: false, }); - assert.calledWith(ensureDirStub, targetDir); - assert.calledWith(writeFileStub, path.join(targetDir, "bundle.compat.js"), sinon.match(Buffer)); + assert.calledWith(ensureDirStub, buildDir); + assert.calledWith(writeFileStub, path.join(buildDir, "bundle.compat.js"), sinon.match.string); }; it("should build bundles for compat and native library", async function () { diff --git a/test/src/browser/commands/switchToRepl.ts b/test/src/browser/commands/switchToRepl.ts index e95118516..66b8c8608 100644 --- a/test/src/browser/commands/switchToRepl.ts +++ b/test/src/browser/commands/switchToRepl.ts @@ -1,4 +1,4 @@ -import repl, { type REPLServer } from "node:repl"; +import { type REPLServer } from "node:repl"; import net from "node:net"; import { PassThrough } from "node:stream"; import { EventEmitter } from "node:events"; @@ -19,10 +19,14 @@ describe('"switchToRepl" command', () => { const originalStdout = process.stdout; let ExistingBrowser: typeof ExistingBrowserOriginal; + let replStart: SinonStub; + let netCreateServerStub: SinonStub; let logStub: SinonStub; let warnStub: SinonStub; let webdriverioAttachStub: SinonStub; let clientBridgeBuildStub; + let replServer: REPLServer; + let netServer: net.Server; let netCreateServerCb: (socket: net.Socket) => void; const initBrowser_ = ({ @@ -41,8 +45,6 @@ describe('"switchToRepl" command', () => { const replServer = new EventEmitter() as REPLServer; (replServer.context as unknown) = {}; - sandbox.stub(repl, "start").returns(replServer); - return replServer; }; @@ -51,11 +53,6 @@ describe('"switchToRepl" command', () => { netServer.listen = sandbox.stub().named("listen").returnsThis(); netServer.close = sandbox.stub().named("close").returnsThis(); - (sandbox.stub(net, "createServer") as SinonStub).callsFake(cb => { - netCreateServerCb = cb; - return netServer; - }); - return netServer; }; @@ -68,13 +65,11 @@ describe('"switchToRepl" command', () => { return socket; }; - const switchToRepl_ = async ({ - session = mkSessionStub_(), - replServer = mkReplServer_(), - ctx = {}, - }): Promise => { + const switchToRepl_ = async ({ session = mkSessionStub_(), ctx = {} }): Promise => { const promise = session.switchToRepl(ctx); + await new Promise(resolve => setImmediate(resolve)); + replServer.emit("exit"); await promise; }; @@ -82,7 +77,11 @@ describe('"switchToRepl" command', () => { beforeEach(() => { logStub = sandbox.stub(); warnStub = sandbox.stub(); + replStart = sandbox.stub(); + replServer = mkReplServer_(); + netServer = mkNetServer_(); + netCreateServerStub = sandbox.stub(); webdriverioAttachStub = sandbox.stub(); clientBridgeBuildStub = sandbox.stub().resolves(); @@ -95,6 +94,15 @@ describe('"switchToRepl" command', () => { }, "../utils/logger": { warn: warnStub, log: logStub }, "./commands/switchToRepl": proxyquire("src/browser/commands/switchToRepl", { + "node:repl": { + start: replStart.returns(replServer), + }, + "node:net": { + createServer: netCreateServerStub.callsFake(cb => { + netCreateServerCb = cb; + return netServer; + }), + }, "../../utils/logger": { warn: warnStub, log: logStub }, }), }).ExistingBrowser; @@ -117,7 +125,7 @@ describe('"switchToRepl" command', () => { sandbox.restore(); Object.defineProperty(process, "stdin", { value: originalStdin }); - Object.defineProperty(process, "sdout", { value: originalStdout }); + Object.defineProperty(process, "stdout", { value: originalStdout }); }); it("should add command", async () => { @@ -141,10 +149,7 @@ describe('"switchToRepl" command', () => { }); describe("in REPL mode", async () => { - let netServer!: net.Server; - beforeEach(() => { - netServer = mkNetServer_(); (RuntimeConfig.getInstance as SinonStub).returns({ replMode: { enabled: true, port: 12345 }, extend: sinon.stub(), @@ -163,7 +168,7 @@ describe('"switchToRepl" command', () => { "You have entered to REPL mode via terminal (test execution timeout is disabled). Port to connect to REPL from other terminals: 12345", ), ); - assert.callOrder(logStub as SinonStub, repl.start as SinonStub); + assert.callOrder(logStub as SinonStub, replStart); }); it("should change cwd to test directory before run repl server", async () => { @@ -173,7 +178,7 @@ describe('"switchToRepl" command', () => { await initBrowser_({ session }); await switchToRepl_({ session }); - assert.callOrder((process.chdir as SinonStub).withArgs("/root/project/dir"), repl.start as SinonStub); + assert.callOrder((process.chdir as SinonStub).withArgs("/root/project/dir"), replStart); }); it("should change cwd to its original value on close repl server", async () => { @@ -182,12 +187,13 @@ describe('"switchToRepl" command', () => { const currCwd = process.cwd(); const onExit = sandbox.spy(); - const replServer = mkReplServer_(); replServer.on("exit", onExit); await initBrowser_({ session }); const promise = session.switchToRepl(); + await new Promise(resolve => setImmediate(resolve)); + replServer.emit("exit"); await promise; @@ -198,31 +204,28 @@ describe('"switchToRepl" command', () => { const runtimeCfg = { replMode: { enabled: true }, extend: sinon.stub() }; (RuntimeConfig.getInstance as SinonStub).returns(runtimeCfg); - const replServer = mkReplServer_(); const session = mkSessionStub_(); await initBrowser_({ session }); - await switchToRepl_({ session, replServer }); + await switchToRepl_({ session }); assert.calledOnceWith(runtimeCfg.extend, { replServer }); }); it("should add browser instance to repl context by default", async () => { const session = mkSessionStub_(); - const replServer = mkReplServer_(); await initBrowser_({ session }); - await switchToRepl_({ session, replServer }); + await switchToRepl_({ session }); assert.deepEqual(replServer.context.browser, session); }); it("should not be able to overwrite browser instance in repl context", async () => { const session = mkSessionStub_(); - const replServer = mkReplServer_(); await initBrowser_({ session }); - await switchToRepl_({ session, replServer }); + await switchToRepl_({ session }); try { replServer.context.browser = "foo"; @@ -233,43 +236,43 @@ describe('"switchToRepl" command', () => { it("should add passed user context to repl server", async () => { const session = mkSessionStub_(); - const replServer = mkReplServer_(); await initBrowser_({ session }); - await switchToRepl_({ session, replServer, ctx: { foo: "bar" } }); + await switchToRepl_({ session, ctx: { foo: "bar" } }); assert.equal(replServer.context.foo, "bar"); }); it("should not create new repl server if old one is already used", async () => { - const replServer = mkReplServer_(); const session = mkSessionStub_(); await initBrowser_({ session }); const promise1 = session.switchToRepl(); + await new Promise(resolve => setImmediate(resolve)); + const promise2 = session.switchToRepl(); + await new Promise(resolve => setImmediate(resolve)); replServer.emit("exit"); await Promise.all([promise1, promise2]); - assert.calledOnce(repl.start as SinonStub); + assert.calledOnce(replStart); assert.calledOnceWith(warnStub, chalk.yellow("Testplane is already in REPL mode")); }); ["const", "let"].forEach(decl => { describe(`"${decl}" declaration to var in order to reassign`, () => { - let replServer: REPLServer; let onLine: SinonSpy; beforeEach(async () => { - replServer = mkReplServer_(); onLine = sandbox.spy(); replServer.on("line", onLine); const session = mkSessionStub_(); await initBrowser_({ session }); - await switchToRepl_({ session, replServer }); + await switchToRepl_({ session }); + await new Promise(resolve => setImmediate(resolve)); }); describe("should modify", () => { @@ -345,6 +348,8 @@ describe('"switchToRepl" command', () => { await initBrowser_({ session }); await switchToRepl_({ session }); + await new Promise(resolve => setImmediate(resolve)); + netCreateServerCb(socket1); netCreateServerCb(socket2); socket1.emit("data", Buffer.from("o.O")); @@ -374,10 +379,10 @@ describe('"switchToRepl" command', () => { it("should close net server on exit from repl", async () => { const session = mkSessionStub_(); - const replServer = mkReplServer_(); await initBrowser_({ session }); const promise = session.switchToRepl(); + await new Promise(resolve => setImmediate(resolve)); replServer.emit("exit"); await promise; @@ -388,15 +393,17 @@ describe('"switchToRepl" command', () => { const socket1 = mkSocket_(); const socket2 = mkSocket_(); const session = mkSessionStub_(); - const replServer = mkReplServer_(); await initBrowser_({ session }); const promise = session.switchToRepl(); + await new Promise(resolve => setImmediate(resolve)); + netCreateServerCb(socket1); netCreateServerCb(socket2); replServer.emit("exit"); + await new Promise(resolve => setImmediate(resolve)); await promise; assert.calledOnceWith(socket1.end, "The server was closed after the REPL was exited"); diff --git a/test/src/browser/existing-browser.js b/test/src/browser/existing-browser.js index b581138d8..7937c633b 100644 --- a/test/src/browser/existing-browser.js +++ b/test/src/browser/existing-browser.js @@ -64,7 +64,9 @@ describe("ExistingBrowser", () => { attach: webdriverioAttachStub, }, "./client-bridge": { - build: clientBridgeBuildStub, + ClientBridge: { + create: clientBridgeBuildStub, + }, }, "../utils/logger": { warn: loggerWarnStub, @@ -727,7 +729,9 @@ describe("ExistingBrowser", () => { }); it("should perform calibration if `calibrate` is turn on", async () => { - calibrator.calibrate.withArgs(sinon.match.instanceOf(ExistingBrowser)).resolves({ foo: "bar" }); + calibrator.calibrate + .withArgs(sinon.match.instanceOf(ExistingBrowser)) + .resolves({ viewportArea: { foo: "bar" } }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); @@ -744,6 +748,9 @@ describe("ExistingBrowser", () => { }); it("should perform calibration after attaching of a session", async () => { + calibrator.calibrate + .withArgs(sinon.match.instanceOf(ExistingBrowser)) + .resolves({ viewportArea: { foo: "bar" } }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); @@ -753,14 +760,14 @@ describe("ExistingBrowser", () => { }); }); - it("should build client scripts", async () => { + it("should initialize browser side utils", async () => { const calibrator = sinon.createStubInstance(Calibrator); - calibrator.calibrate.resolves({ foo: "bar" }); + calibrator.calibrate.resolves({ needsCompatLib: true, viewportArea: { foo: "bar" } }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); - assert.calledOnceWith(clientBridgeBuildStub, browser, { calibration: { foo: "bar" } }); + assert.calledOnceWith(clientBridgeBuildStub, session, "browser-utils", { needsCompatLib: true }); }); }); @@ -796,17 +803,17 @@ describe("ExistingBrowser", () => { describe("captureViewportImage", () => { beforeEach(() => { sandbox.stub(Camera.prototype, "captureViewportImage"); - sandbox.stub(global, "setTimeout").callsFake(fn => fn()); }); - it("should delay capturing on the passed time", () => { - Camera.prototype.captureViewportImage.withArgs({ foo: "bar" }).resolves({ some: "image" }); + it("should pass screenshotDelay to camera object", () => { + Camera.prototype.captureViewportImage + .withArgs({ foo: "bar", screenshotDelay: 2000 }) + .resolves({ some: "image" }); return mkBrowser_({ screenshotDelay: 100500 }) - .captureViewportImage({ foo: "bar" }, 2000) + .captureViewportImage({ foo: "bar", screenshotDelay: 2000 }) .then(() => { - assert.calledOnceWith(global.setTimeout, sinon.match.any, 2000); - assert.callOrder(global.setTimeout, Camera.prototype.captureViewportImage); + assert.calledOnceWith(Camera.prototype.captureViewportImage, { foo: "bar", screenshotDelay: 2000 }); }); }); diff --git a/test/src/browser/isomorphic/geometry.ts b/test/src/browser/isomorphic/geometry.ts index 1a400b0fe..28a7f23db 100644 --- a/test/src/browser/isomorphic/geometry.ts +++ b/test/src/browser/isomorphic/geometry.ts @@ -74,7 +74,7 @@ describe("browser/isomorphic/geometry", () => { it("should format size as text", () => { const size = { width: 10 as Length<"device", "x">, height: 20 as Length<"device", "y"> } as Size<"device">; - assert.equal(prettySize(size), "10 x 20 (width x height)"); + assert.equal(prettySize(size), "{ width: 10, height: 20 }"); }); }); diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/generate.ts b/test/src/browser/screen-shooter/composite-image/fixtures/generate.ts index f4af877d0..9cd5e7cbc 100644 --- a/test/src/browser/screen-shooter/composite-image/fixtures/generate.ts +++ b/test/src/browser/screen-shooter/composite-image/fixtures/generate.ts @@ -457,472 +457,475 @@ export const createScenario = async ( return result; }; -const scenarios = [ - createScenario({ - id: "single-chunk-in-view", - pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "single-chunk-slightly-out-of-view", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 800 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "single-chunk-completely-out-of-view", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 1100 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "single-chunk-safe-area-expansion-top", - pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - top: 0, - height: 300, - }, - ], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "single-chunk-safe-area-expansion-bottom", - pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - bottom: 0, - height: 600, - }, - ], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "single-chunk-safe-area-expansion-top-and-bottom", - pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - top: 0, - height: 300, - }, - { - bottom: 0, - height: 400, - }, - ], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "two-chunks-with-gap", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [], - chunks: [ - { - height: 400 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - { - height: 800 as Length<"device", "y">, - offsetTop: 500 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "two-chunks-relax-upper-bottom", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - bottom: 0, - height: 100, - }, - ], - chunks: [ - { +// This is to prevent the script from running when it's imported by another script +if (process.argv.includes("generate")) { + const scenarios = [ + createScenario({ + id: "single-chunk-in-view", + pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, height: 500 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, }, - { + ignoreAreas: [], + unsafeAreas: [], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "single-chunk-slightly-out-of-view", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 800 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, height: 500 as Length<"device", "y">, - offsetTop: 500 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "two-chunks-relax-lower-top", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - top: 0, - height: 100, }, - ], - chunks: [ - { + ignoreAreas: [], + unsafeAreas: [], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "single-chunk-completely-out-of-view", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 1100 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, height: 500 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, }, - { + ignoreAreas: [], + unsafeAreas: [], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "single-chunk-safe-area-expansion-top", + pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, height: 500 as Length<"device", "y">, - offsetTop: 500 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "two-equal-chunks", - pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - { - height: 1024 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "multiple-overlapping-chunks-with-safe-areas", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - bottom: 0, - height: 100, - }, - ], - chunks: [ - { - height: 400 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 100 as Coord<"page", "device", "y">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 200 as Coord<"page", "device", "y">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 300 as Coord<"page", "device", "y">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 400 as Coord<"page", "device", "y">, - }, - ], - }), - createScenario({ - id: "multiple-chunks-with-horizontal-shifts", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [], - unsafeAreas: [ - { - bottom: 0, - height: 100, - }, - ], - chunks: [ - { - height: 400 as Length<"device", "y">, - offsetTop: 0 as Coord<"page", "device", "y">, - width: 1000 as Length<"device", "x">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 100 as Coord<"page", "device", "y">, - width: 800 as Length<"device", "x">, - offsetLeft: 100 as Coord<"page", "device", "x">, }, - { - height: 400 as Length<"device", "y">, - offsetTop: 200 as Coord<"page", "device", "y">, - width: 600 as Length<"device", "x">, - offsetLeft: 150 as Coord<"page", "device", "x">, - }, - { - height: 400 as Length<"device", "y">, - offsetTop: 300 as Coord<"page", "device", "y">, - offsetLeft: 10 as Coord<"page", "device", "x">, + ignoreAreas: [], + unsafeAreas: [ + { + top: 0, + height: 300, + }, + ], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "single-chunk-safe-area-expansion-bottom", + pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - { - height: 400 as Length<"device", "y">, - offsetTop: 400 as Coord<"page", "device", "y">, + ignoreAreas: [], + unsafeAreas: [ + { + bottom: 0, + height: 600, + }, + ], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "single-chunk-safe-area-expansion-top-and-bottom", + pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - ], - }), - createScenario({ - id: "multiple-chunks-with-safe-areas-and-ignore-areas", - pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, - captureArea: { - left: 200 as Coord<"page", "device", "x">, - top: 200 as Coord<"page", "device", "y">, - width: 500 as Length<"device", "x">, - height: 500 as Length<"device", "y">, - }, - ignoreAreas: [ - { - left: 300 as Coord<"page", "device", "x">, - top: 100 as Coord<"page", "device", "y">, - width: 100 as Length<"device", "x">, - height: 400 as Length<"device", "y">, + ignoreAreas: [], + unsafeAreas: [ + { + top: 0, + height: 300, + }, + { + bottom: 0, + height: 400, + }, + ], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "two-chunks-with-gap", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - ], - unsafeAreas: [ - { - top: 0, - height: 100, + ignoreAreas: [], + unsafeAreas: [], + chunks: [ + { + height: 400 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + { + height: 800 as Length<"device", "y">, + offsetTop: 500 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "two-chunks-relax-upper-bottom", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - { - bottom: 0, - height: 700, + ignoreAreas: [], + unsafeAreas: [ + { + bottom: 0, + height: 100, + }, + ], + chunks: [ + { + height: 500 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + { + height: 500 as Length<"device", "y">, + offsetTop: 500 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "two-chunks-relax-lower-top", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - ], - chunks: [ - { - height: 1024 as Length<"device", "y">, - offsetTop: 100 as Coord<"page", "device", "y">, + ignoreAreas: [], + unsafeAreas: [ + { + top: 0, + height: 100, + }, + ], + chunks: [ + { + height: 500 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + { + height: 500 as Length<"device", "y">, + offsetTop: 500 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "two-equal-chunks", + pageSize: { width: 1024 as Length<"device", "x">, height: 1024 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - { - height: 1024 as Length<"device", "y">, - offsetTop: 200 as Coord<"page", "device", "y">, + ignoreAreas: [], + unsafeAreas: [], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + { + height: 1024 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "multiple-overlapping-chunks-with-safe-areas", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - { - height: 1024 as Length<"device", "y">, - offsetTop: 300 as Coord<"page", "device", "y">, + ignoreAreas: [], + unsafeAreas: [ + { + bottom: 0, + height: 100, + }, + ], + chunks: [ + { + height: 400 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 100 as Coord<"page", "device", "y">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 200 as Coord<"page", "device", "y">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 300 as Coord<"page", "device", "y">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 400 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "multiple-chunks-with-horizontal-shifts", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - { - height: 1024 as Length<"device", "y">, - offsetTop: 400 as Coord<"page", "device", "y">, + ignoreAreas: [], + unsafeAreas: [ + { + bottom: 0, + height: 100, + }, + ], + chunks: [ + { + height: 400 as Length<"device", "y">, + offsetTop: 0 as Coord<"page", "device", "y">, + width: 1000 as Length<"device", "x">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 100 as Coord<"page", "device", "y">, + width: 800 as Length<"device", "x">, + offsetLeft: 100 as Coord<"page", "device", "x">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 200 as Coord<"page", "device", "y">, + width: 600 as Length<"device", "x">, + offsetLeft: 150 as Coord<"page", "device", "x">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 300 as Coord<"page", "device", "y">, + offsetLeft: 10 as Coord<"page", "device", "x">, + }, + { + height: 400 as Length<"device", "y">, + offsetTop: 400 as Coord<"page", "device", "y">, + }, + ], + }), + createScenario({ + id: "multiple-chunks-with-safe-areas-and-ignore-areas", + pageSize: { width: 1024 as Length<"device", "x">, height: 1800 as Length<"device", "y"> }, + captureArea: { + left: 200 as Coord<"page", "device", "x">, + top: 200 as Coord<"page", "device", "y">, + width: 500 as Length<"device", "x">, + height: 500 as Length<"device", "y">, }, - ], - }), - (async (): Promise => { - const id = "duplicate-chunks-with-offscreen-zero-visible-spec"; - const scenarioDir = path.join(__dirname, id); - const chunksDir = path.join(scenarioDir, "chunks"); - await fs.promises.mkdir(chunksDir, { recursive: true }); - - const viewportWidth = 1024 as Length<"device", "x">; - const viewportHeight = 1024 as Length<"device", "y">; - const safeArea = toViewportYBand(0, viewportHeight as number); - const fixedRect = toViewportRect({ left: 200, top: 620, width: 500, height: 260 }); - const ignoreBoundingRects: Rect<"viewport", "device">[] = []; - const weirdChunkDefs = [120, -500, -800, -800]; - const chunkResults: ScenarioGenerationResult["chunks"] = []; - let firstChunkRgba: Buffer | null = null; - - const drawVisibleSpec = (rgba: Buffer, visibleRect: Rect<"viewport", "device">): void => { - if ((visibleRect.width as number) <= 0 || (visibleRect.height as number) <= 0) { - return; - } - - drawCaptureArea( - rgba, - { width: viewportWidth, height: viewportHeight }, + ignoreAreas: [ { - left: toPageX(visibleRect.left as number), - top: toPageY(visibleRect.top as number), - width: visibleRect.width as Length<"device", "x">, - height: visibleRect.height as Length<"device", "y">, + left: 300 as Coord<"page", "device", "x">, + top: 100 as Coord<"page", "device", "y">, + width: 100 as Length<"device", "x">, + height: 400 as Length<"device", "y">, }, - ); - }; - - for (let chunkIndex = 0; chunkIndex < weirdChunkDefs.length; chunkIndex++) { - const chunkRgba = Buffer.alloc((viewportWidth as number) * (viewportHeight as number) * 4); - fillRect( - chunkRgba, - viewportWidth, - viewportHeight, + ], + unsafeAreas: [ { - left: toPageX(0), - top: toPageY(0), - width: viewportWidth, - height: viewportHeight, + top: 0, + height: 100, }, - WHITE, - ); - - const movingTop = weirdChunkDefs[chunkIndex]; - const movingVisibleHeight = movingTop >= 0 ? 420 : 0; - const chunkPath = path.posix.join(chunksDir, `${chunkIndex}.png`); - const movingSpec = { - full: toViewportRect({ left: 200, top: movingTop, width: 500, height: 420 }), - visible: toViewportRect({ - left: 200, - top: movingTop, - width: 500, - height: movingVisibleHeight, - }), + { + bottom: 0, + height: 700, + }, + ], + chunks: [ + { + height: 1024 as Length<"device", "y">, + offsetTop: 100 as Coord<"page", "device", "y">, + }, + { + height: 1024 as Length<"device", "y">, + offsetTop: 200 as Coord<"page", "device", "y">, + }, + { + height: 1024 as Length<"device", "y">, + offsetTop: 300 as Coord<"page", "device", "y">, + }, + { + height: 1024 as Length<"device", "y">, + offsetTop: 400 as Coord<"page", "device", "y">, + }, + ], + }), + (async (): Promise => { + const id = "duplicate-chunks-with-offscreen-zero-visible-spec"; + const scenarioDir = path.join(__dirname, id); + const chunksDir = path.join(scenarioDir, "chunks"); + await fs.promises.mkdir(chunksDir, { recursive: true }); + + const viewportWidth = 1024 as Length<"device", "x">; + const viewportHeight = 1024 as Length<"device", "y">; + const safeArea = toViewportYBand(0, viewportHeight as number); + const fixedRect = toViewportRect({ left: 200, top: 620, width: 500, height: 260 }); + const ignoreBoundingRects: Rect<"viewport", "device">[] = []; + const weirdChunkDefs = [120, -500, -800, -800]; + const chunkResults: ScenarioGenerationResult["chunks"] = []; + let firstChunkRgba: Buffer | null = null; + + const drawVisibleSpec = (rgba: Buffer, visibleRect: Rect<"viewport", "device">): void => { + if ((visibleRect.width as number) <= 0 || (visibleRect.height as number) <= 0) { + return; + } + + drawCaptureArea( + rgba, + { width: viewportWidth, height: viewportHeight }, + { + left: toPageX(visibleRect.left as number), + top: toPageY(visibleRect.top as number), + width: visibleRect.width as Length<"device", "x">, + height: visibleRect.height as Length<"device", "y">, + }, + ); }; - const captureSpecs = [movingSpec, { full: fixedRect, visible: fixedRect }]; - for (const spec of captureSpecs) { - drawVisibleSpec(chunkRgba, spec.visible); + for (let chunkIndex = 0; chunkIndex < weirdChunkDefs.length; chunkIndex++) { + const chunkRgba = Buffer.alloc((viewportWidth as number) * (viewportHeight as number) * 4); + fillRect( + chunkRgba, + viewportWidth, + viewportHeight, + { + left: toPageX(0), + top: toPageY(0), + width: viewportWidth, + height: viewportHeight, + }, + WHITE, + ); + + const movingTop = weirdChunkDefs[chunkIndex]; + const movingVisibleHeight = movingTop >= 0 ? 420 : 0; + const chunkPath = path.posix.join(chunksDir, `${chunkIndex}.png`); + const movingSpec = { + full: toViewportRect({ left: 200, top: movingTop, width: 500, height: 420 }), + visible: toViewportRect({ + left: 200, + top: movingTop, + width: 500, + height: movingVisibleHeight, + }), + }; + const captureSpecs = [movingSpec, { full: fixedRect, visible: fixedRect }]; + + for (const spec of captureSpecs) { + drawVisibleSpec(chunkRgba, spec.visible); + } + + await saveRgbaAsPng(chunkPath, chunkRgba, viewportWidth, viewportHeight); + + if (chunkIndex === 0) { + firstChunkRgba = chunkRgba; + } + + chunkResults.push({ + file: path.relative(__dirname, chunkPath), + safeArea, + captureSpecs, + ignoreBoundingRects, + }); } - await saveRgbaAsPng(chunkPath, chunkRgba, viewportWidth, viewportHeight); - - if (chunkIndex === 0) { - firstChunkRgba = chunkRgba; + if (!firstChunkRgba) { + throw new Error( + "Failed to build first chunk for duplicate-chunks-with-offscreen-zero-visible-spec scenario", + ); } - chunkResults.push({ - file: path.relative(__dirname, chunkPath), - safeArea, - captureSpecs, - ignoreBoundingRects, - }); - } - - if (!firstChunkRgba) { - throw new Error( - "Failed to build first chunk for duplicate-chunks-with-offscreen-zero-visible-spec scenario", + const expectedRgba = crop( + firstChunkRgba, + viewportWidth, + viewportHeight, + toPageX(200), + toPageY(120), + 500 as Length<"device", "x">, + 760 as Length<"device", "y">, ); - } + const expectedPath = path.posix.join(scenarioDir, "expected.png"); + await saveRgbaAsPng(expectedPath, expectedRgba, 500 as Length<"device", "x">, 760 as Length<"device", "y">); - const expectedRgba = crop( - firstChunkRgba, - viewportWidth, - viewportHeight, - toPageX(200), - toPageY(120), - 500 as Length<"device", "x">, - 760 as Length<"device", "y">, - ); - const expectedPath = path.posix.join(scenarioDir, "expected.png"); - await saveRgbaAsPng(expectedPath, expectedRgba, 500 as Length<"device", "x">, 760 as Length<"device", "y">); - - const fullPagePath = path.posix.join(scenarioDir, "full-page.png"); - await saveRgbaAsPng(fullPagePath, expectedRgba, 500 as Length<"device", "x">, 760 as Length<"device", "y">); - - return { - id, - fullPage: path.relative(__dirname, fullPagePath), - expected: path.relative(__dirname, expectedPath), - chunks: chunkResults, - }; - })(), -] satisfies Promise[]; - -Promise.all(scenarios).then(async results => { - await fs.promises.writeFile(path.join(__dirname, "data.json"), JSON.stringify(results, null, 4) + "\n"); - console.log("Generation completed."); -}); + const fullPagePath = path.posix.join(scenarioDir, "full-page.png"); + await saveRgbaAsPng(fullPagePath, expectedRgba, 500 as Length<"device", "x">, 760 as Length<"device", "y">); + + return { + id, + fullPage: path.relative(__dirname, fullPagePath), + expected: path.relative(__dirname, expectedPath), + chunks: chunkResults, + }; + })(), + ] satisfies Promise[]; + + Promise.all(scenarios).then(async results => { + await fs.promises.writeFile(path.join(__dirname, "data.json"), JSON.stringify(results, null, 4) + "\n"); + console.log("Generation of composite image fixtures completed."); + }); +} diff --git a/test/src/browser/screen-shooter/index.js b/test/src/browser/screen-shooter/index.js index dab6d6b2a..3a803680c 100644 --- a/test/src/browser/screen-shooter/index.js +++ b/test/src/browser/screen-shooter/index.js @@ -1,7 +1,6 @@ "use strict"; const proxyquire = require("proxyquire").noCallThru(); -const { CaptureAreaMovedError } = require("src/browser/screen-shooter/errors/capture-area-moved-error"); const validationStubs = { assertCorrectCaptureAreaBounds: sinon.stub(), @@ -467,19 +466,39 @@ describe("ElementsScreenShooter", () => { ]); }); - it("should reject with CaptureAreaMovedError when capture area size changes and retries are disabled", async () => { + it("should continue capture on the last allowed attempt when capture area size changes", async () => { const page = createMockPage({ captureSpecs: [captureSpec(rect(0, 0, 100, 80))], }); const changedState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 0, 100, 120))], }); + const settledState = createCaptureState({ + captureSpecs: [captureSpec(rect(0, 100, 100, 20))], + safeArea: band(100, 100), + scrollOffset: 100, + }); - browserSideScreenshooter.call.onCall(0).resolves(page).onCall(1).resolves(changedState); + browserSideScreenshooter.call + .onCall(0) + .resolves(page) + .onCall(1) + .resolves(changedState) + .onCall(2) + .resolves({ debugLog: "scroll debug" }) + .onCall(3) + .resolves(settledState) + .onCall(4) + .resolves({ debugLog: "restore debug" }); - const error = await screenShooter.capture(".element", { compositeImage: true }, 1).catch(e => e); + const result = await screenShooter.capture(".element", { compositeImage: true }, 1); - assert.instanceOf(error, CaptureAreaMovedError); + assert.calledOnce(validationStubs.assertCorrectCaptureAreaBounds); + assert.calledTwice(camera.captureViewportImage); + assert.deepEqual(result, { + image: renderedImage, + meta: page, + }); }); it("should warn when the captured area still overflows the viewport and allowViewportOverflow is false", async () => { diff --git a/test/src/browser/screen-shooter/validation.js b/test/src/browser/screen-shooter/validation.js index 9a5d452c8..1ea22fa82 100644 --- a/test/src/browser/screen-shooter/validation.js +++ b/test/src/browser/screen-shooter/validation.js @@ -1,12 +1,23 @@ "use strict"; const _ = require("lodash"); - -const { assertCorrectCaptureAreaBounds } = require("src/browser/screen-shooter/validation"); -const { VerticalOverflowError } = require("src/browser/screen-shooter/errors/vertical-overflow-error"); -const { HorizontalOverflowError } = require("src/browser/screen-shooter/errors/horizontal-overflow-error"); +const proxyquire = require("proxyquire"); describe("assertCorrectCaptureAreaBounds", () => { + const loggerWarnStub = sinon.stub(); + let assertCorrectCaptureAreaBounds; + + beforeEach(() => { + loggerWarnStub.resetHistory(); + loggerWarnStub.resetBehavior(); + + ({ assertCorrectCaptureAreaBounds } = proxyquire("src/browser/screen-shooter/validation", { + "../../../utils/logger": { + warn: loggerWarnStub, + }, + })); + }); + function validate_(areaModification, opts = {}) { const viewport = { left: 0, @@ -31,84 +42,97 @@ describe("assertCorrectCaptureAreaBounds", () => { const viewportOffset = { top: 0, left: 0 }; - return assertCorrectCaptureAreaBounds("test browser", viewport, viewportOffset, captureArea, opts); + return assertCorrectCaptureAreaBounds("test browser", viewport, viewportOffset, [captureArea], opts); } - describe("validation failed", () => { - it("if crop area left boundary is outside of viewport", () => { - assert.throws(() => validate_({ left: -1 }), HorizontalOverflowError); + describe("validation warnings", () => { + it("should warn if crop area left boundary is outside of viewport", () => { + validate_({ left: -1 }); + + assert.calledOnceWithMatch(loggerWarnStub, sinon.match("outside of horizontal viewport bounds")); }); - it("if crop area top boundary is outside of viewport", () => { - // Note: The current implementation checks top < 0 in the horizontal overflow check - assert.throws(() => validate_({ top: -1 }), HorizontalOverflowError); + it("should not warn if crop area top boundary is outside of viewport", () => { + validate_({ top: -1 }); + + assert.notCalled(loggerWarnStub); }); - it("if crop area right boundary is outside of viewport", () => { - assert.throws(() => validate_({ width: +1 }), HorizontalOverflowError); + it("should warn if crop area right boundary is outside of viewport", () => { + validate_({ width: +1 }); + + assert.calledOnceWithMatch(loggerWarnStub, sinon.match("outside of horizontal viewport bounds")); }); - it("if crop area height bigger than viewport height", () => { - assert.throws(() => validate_({ height: +1 }), VerticalOverflowError); + it("should warn if crop area height bigger than viewport height", () => { + validate_({ height: +1 }); + + assert.calledOnceWithMatch(loggerWarnStub, sinon.match("larger than viewport height")); }); }); it('should not throw any errors if option "allowViewportOverflow" is set and "compositeImage" is not', () => { const opts = { allowViewportOverflow: true, compositeImage: false }; - assert.doesNotThrow(() => validate_({ left: -1, height: +1 }, opts)); + validate_({ left: -1, height: +1 }, opts); + + assert.notCalled(loggerWarnStub); }); it("should not throw OffsetViewportError if option allowViewportOverflow is set", () => { const opts = { allowViewportOverflow: true }; - assert.doesNotThrow(() => validate_({ left: -1 }, opts)); + validate_({ left: -1 }, opts); + + assert.notCalled(loggerWarnStub); }); it('should not throw if crop area height bigger than viewport height and "compositeImage" is set', () => { const opts = { compositeImage: true }; - assert.doesNotThrow(() => validate_({ height: +1 }, opts)); + validate_({ height: +1 }, opts); + + assert.notCalled(loggerWarnStub); }); it("should not throw on passed validation", () => { - const fn = () => validate_({ left: 0 }); + validate_({ left: 0 }); - return assert.doesNotThrow(fn); + assert.notCalled(loggerWarnStub); }); describe("comprehensive validation tests", () => { - it("should not throw for valid bounds", () => { + it("should not warn for valid bounds", () => { const viewportSize = { width: 100, height: 100 }; const viewportOffset = { left: 0, top: 0 }; const captureArea = { left: 10, top: 10, width: 50, height: 50 }; const opts = {}; - assert.doesNotThrow(() => { - assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, captureArea, opts); - }); + assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, [captureArea], opts); + + assert.notCalled(loggerWarnStub); }); - it("should throw HorizontalOverflowError when capture area overflows horizontally", () => { + it("should warn when capture area overflows horizontally", () => { const viewportSize = { width: 100, height: 100 }; const viewportOffset = { left: 0, top: 0 }; const captureArea = { left: 90, top: 10, width: 50, height: 50 }; // overflows right const opts = {}; - assert.throws(() => { - assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, captureArea, opts); - }, HorizontalOverflowError); + assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, [captureArea], opts); + + assert.calledOnceWithMatch(loggerWarnStub, sinon.match("outside of horizontal viewport bounds")); }); - it("should throw VerticalOverflowError when capture area overflows vertically", () => { + it("should warn when capture area overflows vertically", () => { const viewportSize = { width: 100, height: 100 }; const viewportOffset = { left: 0, top: 0 }; const captureArea = { left: 10, top: 90, width: 50, height: 50 }; // overflows bottom const opts = {}; - assert.throws(() => { - assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, captureArea, opts); - }, VerticalOverflowError); + assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, [captureArea], opts); + + assert.calledOnceWithMatch(loggerWarnStub, sinon.match("larger than viewport height")); }); it("should not throw when allowViewportOverflow is set and compositeImage is false", () => { @@ -117,9 +141,9 @@ describe("assertCorrectCaptureAreaBounds", () => { const captureArea = { left: 90, top: 10, width: 50, height: 50 }; // would overflow const opts = { allowViewportOverflow: true, compositeImage: false }; - assert.doesNotThrow(() => { - assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, captureArea, opts); - }); + assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, [captureArea], opts); + + assert.notCalled(loggerWarnStub); }); it("should not throw when compositeImage is true", () => { @@ -128,9 +152,9 @@ describe("assertCorrectCaptureAreaBounds", () => { const captureArea = { left: 10, top: 90, width: 50, height: 50 }; // would overflow vertically const opts = { compositeImage: true }; - assert.doesNotThrow(() => { - assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, captureArea, opts); - }); + assertCorrectCaptureAreaBounds("test capture area", viewportSize, viewportOffset, [captureArea], opts); + + assert.notCalled(loggerWarnStub); }); }); }); diff --git a/test/src/cli/commands/install-deps/index.ts b/test/src/cli/commands/install-deps/index.ts index c5f1425de..62a2ab08e 100644 --- a/test/src/cli/commands/install-deps/index.ts +++ b/test/src/cli/commands/install-deps/index.ts @@ -18,7 +18,7 @@ describe("cli/commands/install-deps", () => { process.argv = ["foo/bar/node", "foo/bar/script", "install-deps", ...argv.split(" ")].filter(Boolean); cli.run(); - await (Command.prototype.action as SinonStub).lastCall.returnValue; + await new Promise(resolve => setImmediate(resolve)); }; const mkBrowser_ = (browserName: string, browserVersion: string): Config["browsers"][string] => diff --git a/test/src/dev-server/index.ts b/test/src/dev-server/index.ts index f3c9d794f..e4cf649b7 100644 --- a/test/src/dev-server/index.ts +++ b/test/src/dev-server/index.ts @@ -197,7 +197,7 @@ describe("dev-server", () => { } catch (error) { assert.match( (error as Error).message, - /When 'reuseExisting' is set to 'true' in 'devServer' config, it is required to set 'devServer.readinessProbe.url'/, + /When 'reuseExisting' option is set in 'devServer' config, it is required to set 'devServer\.readinessProbe\.url' option/, ); } @@ -219,7 +219,7 @@ describe("dev-server", () => { } catch (error) { assert.match( (error as Error).message, - /When 'reuseExisting' is set to 'true' in 'devServer' config, it is required to set 'devServer.readinessProbe.url'/, + /When 'reuseExisting' option is set in 'devServer' config, it is required to set 'devServer\.readinessProbe\.url' option/, ); } diff --git a/test/src/utils/logger.js b/test/src/utils/logger.js index fa338c021..e77f6b474 100644 --- a/test/src/utils/logger.js +++ b/test/src/utils/logger.js @@ -5,28 +5,22 @@ const logger = require("src/utils/logger"); describe("utils/logger", () => { ["log", "warn", "error"].forEach(logFnName => { describe(logFnName, () => { - let clock; const sandbox = sinon.createSandbox(); - const originalTZ = process.env.TZ; beforeEach(() => { sandbox.spy(console, logFnName); - clock = sinon.useFakeTimers({ - now: new Date("2023-03-02T14:21:04.000+03:00"), - }); - process.env.TZ = "Europe/Moscow"; }); afterEach(() => { - clock.restore(); sandbox.restore(); - process.env.TZ = originalTZ; }); it("should start with timestamp message", () => { logger[logFnName]("message", "another message"); - assert.calledOnceWith(console[logFnName], "[14:21:04 +0300]", "message", "another message"); + assert.calledOnce(console[logFnName]); + assert.match(console[logFnName].firstCall.args[0], /^\[\d{2}:\d{2}:\d{2} [+-]\d{4}\]$/); + assert.deepEqual(console[logFnName].firstCall.args.slice(1), ["message", "another message"]); }); }); }); diff --git a/test/src/utils/promise.ts b/test/src/utils/promise.ts index e97a57d0b..aebb9da16 100644 --- a/test/src/utils/promise.ts +++ b/test/src/utils/promise.ts @@ -10,8 +10,8 @@ describe("utils/promise", () => { }); afterEach(() => { - clock.restore(); sandbox.restore(); + clock.restore(); }); describe("promiseMethod", () => { @@ -118,8 +118,8 @@ describe("utils/promise", () => { }); it("should work with await syntax", async () => { - const beforeTime = Date.now(); clock.tick(1000); + const beforeTime = Date.now(); const delayPromise = promiseDelay(500); clock.tick(500); diff --git a/test/src/utils/typescript.ts b/test/src/utils/typescript.ts index 1355b3002..7b02ed30b 100644 --- a/test/src/utils/typescript.ts +++ b/test/src/utils/typescript.ts @@ -11,6 +11,7 @@ describe("utils/typescript", () => { const TESTPLANE_TRANSFORM_HOOK = Symbol.for("testplane.transform.hook"); beforeEach(() => { + delete (process as any)[TESTPLANE_TRANSFORM_HOOK]; revertHookStub = sinon.stub(); addHookStub = sinon.stub().returns(revertHookStub); ts = proxyquire.noCallThru().load("src/utils/typescript", { @@ -21,7 +22,7 @@ describe("utils/typescript", () => { }); afterEach(() => { - _.set(process, TESTPLANE_TRANSFORM_HOOK, undefined); + delete (process as any)[TESTPLANE_TRANSFORM_HOOK]; _.set(process, "env", processEnvBackup); }); diff --git a/test/src/worker/browser-env/runner/test-runner/index.ts b/test/src/worker/browser-env/runner/test-runner/index.ts index 2f8d5b72d..1cd01e818 100644 --- a/test/src/worker/browser-env/runner/test-runner/index.ts +++ b/test/src/worker/browser-env/runner/test-runner/index.ts @@ -1,5 +1,6 @@ import process from "node:process"; import crypto from "node:crypto"; +import clearRequire from "clear-require"; import { EventEmitter } from "node:stream"; import _ from "lodash"; import sinon, { SinonStub, SinonFakeTimers } from "sinon"; @@ -22,10 +23,7 @@ import RuntimeConfig from "../../../../../../src/config/runtime-config"; import ExpectWebdriverIO from "expect-webdriverio"; import { BrowserEventNames } from "../../../../../../src/runner/browser-env/vite/types"; import { BrowserViteSocket } from "../../../../../../src/runner/browser-env/vite/browser-modules/types"; -import { - WorkerEventNames, - type WorkerViteSocket, -} from "../../../../../../src/worker/browser-env/runner/test-runner/types"; +import { WorkerEventNames } from "../../../../../../src/worker/browser-env/runner/test-runner/types"; import type { Socket } from "socket.io-client"; import type { MatcherState } from "expect"; import type { ChainablePromiseElement } from "@testplane/webdriverio"; @@ -125,22 +123,24 @@ describe("worker/browser-env/runner/test-runner", () => { return promise; }; - const mkBrowser_ = (opts: Partial = {}): ExistingBrowser => - ({ - publicAPI: { - url: sandbox.stub().resolves(), - $: sandbox.stub().resolves({ - scrollIntoView: sandbox.stub().resolves(), - elementId: "body-id", - }), - execute: sandbox.stub().resolves({ x: 0, y: 0 }), - action: sandbox.stub().returns({ - move: sandbox.stub().returnsThis(), - perform: sandbox.stub().resolves(), - }), - moveToElement: sandbox.stub().resolves(), - isW3C: true, - } as unknown as Browser["publicAPI"], + const mkBrowser_ = (opts: Partial = {}): ExistingBrowser => { + const publicAPI = Object.assign(Object.create({}), { + url: sandbox.stub().resolves(), + $: sandbox.stub().resolves({ + scrollIntoView: sandbox.stub().resolves(), + elementId: "body-id", + }), + execute: sandbox.stub().resolves({ x: 0, y: 0 }), + action: sandbox.stub().returns({ + move: sandbox.stub().returnsThis(), + perform: sandbox.stub().resolves(), + }), + moveToElement: sandbox.stub().resolves(), + isW3C: true, + }) as unknown as Browser["publicAPI"]; + + return { + publicAPI, config: makeBrowserConfigStub({ saveHistoryMode: "none" }) as BrowserConfig, state: { isBroken: false, @@ -162,7 +162,8 @@ describe("worker/browser-env/runner/test-runner", () => { release: sandbox.stub(), } as unknown as ExistingBrowser["callstackHistory"], ...opts, - } as unknown as ExistingBrowser); + } as unknown as ExistingBrowser; + }; const mkElement_ = (opts: Partial = {}): WebdriverIO.Element => { return { @@ -172,8 +173,8 @@ describe("worker/browser-env/runner/test-runner", () => { } as unknown as WebdriverIO.Element; }; - const mkSocket_ = (): WorkerViteSocket => { - const socket = new EventEmitter() as unknown as WorkerViteSocket; + const mkSocket_ = (): BrowserViteSocket => { + const socket = new EventEmitter() as unknown as BrowserViteSocket; socket.emitWithAck = sandbox.stub().onFirstCall().resolves(null).onSecondCall().resolves([null]); socket.timeout = sandbox.stub().returnsThis(); @@ -187,7 +188,9 @@ describe("worker/browser-env/runner/test-runner", () => { const initBrowserEnvRunner_ = ( opts: { expectMatchers: Record } = { expectMatchers: {} }, ): BrowserEnvRunnerClass => { - const strictProxyquire = proxyquire.noCallThru().noPreserveCache(); + const strictProxyquire = proxyquire.noCallThru(); + clearRequire(require.resolve("../../../../../../src/worker/runner/test-runner")); + clearRequire(require.resolve("../../../../../../src/worker/browser-env/runner/test-runner")); loggerWarnStub = sandbox.stub(); socketClientStub = sandbox.stub().returns(mkSocket_()); @@ -237,7 +240,10 @@ describe("worker/browser-env/runner/test-runner", () => { BrowserEnvRunnerStub = initBrowserEnvRunner_(); }); - afterEach(() => sandbox.restore()); + afterEach(() => { + proxyquire.callThru(); + sandbox.restore(); + }); describe("constructor", () => { describe("socket", () => { @@ -292,7 +298,7 @@ describe("worker/browser-env/runner/test-runner", () => { sandbox.stub(process, "pid").value(pid); (crypto.randomUUID as SinonStub).returns(runUuid); - const socket = mkSocket_() as Socket; + const socket = mkSocket_() as unknown as Socket; (socket as any).active = false; socketClientStub.returns(socket); @@ -455,7 +461,7 @@ describe("worker/browser-env/runner/test-runner", () => { let clock: SinonFakeTimers; beforeEach(() => { - clock = sinon.useFakeTimers({ toFake: ["setInterval", "setTimeout", "clearInterval"] }); + clock = sinon.useFakeTimers({ toFake: ["setInterval", "setTimeout", "clearInterval", "clearTimeout"] }); }); afterEach(() => clock.restore()); diff --git a/test/src/worker/runner/index.js b/test/src/worker/runner/index.js index e49fdf31a..696768ebe 100644 --- a/test/src/worker/runner/index.js +++ b/test/src/worker/runner/index.js @@ -1,17 +1,17 @@ "use strict"; +const clearRequire = require("clear-require"); const proxyquire = require("proxyquire"); const BrowserPool = require("src/worker/runner/browser-pool"); const { CachingTestParser } = require("src/worker/runner/caching-test-parser"); const { BrowserAgent } = require("src/worker/runner/browser-agent"); const { WorkerEvents: RunnerEvents } = require("src/events"); -const NodejsEnvTestRunner = require("src/worker/runner/test-runner"); -const { TestRunner: BrowserEnvTestRunner } = require("src/worker/browser-env/runner/test-runner"); const { NODEJS_TEST_RUN_ENV, BROWSER_TEST_RUN_ENV } = require("src/constants/config"); const { makeConfigStub, makeTest } = require("../../../utils"); describe("worker/runner", () => { const sandbox = sinon.createSandbox(); + let NodejsEnvTestRunner, BrowserEnvTestRunner; let nodejsTestRunner, browserTestRunner, Runner; let runWithTestplaneDependenciesCollecting, readTestFileWithTestplaneDependenciesCollecting; let processSendBackup; @@ -22,6 +22,13 @@ describe("worker/runner", () => { }; beforeEach(() => { + clearRequire(require.resolve("src/worker/runner")); + clearRequire(require.resolve("src/worker/runner/test-runner")); + clearRequire(require.resolve("src/worker/browser-env/runner/test-runner")); + + NodejsEnvTestRunner = require("src/worker/runner/test-runner"); + ({ TestRunner: BrowserEnvTestRunner } = require("src/worker/browser-env/runner/test-runner")); + sandbox.stub(BrowserPool, "create").returns({ browser: "pool" }); sandbox.stub(CachingTestParser, "create").returns(Object.create(CachingTestParser.prototype)); @@ -44,12 +51,13 @@ describe("worker/runner", () => { sandbox.stub(BrowserAgent, "create").returns(Object.create(BrowserAgent.prototype)); Runner = proxyquire("src/worker/runner", { - "./test-runner": { default: { create: () => nodejsTestRunner } }, - "../browser-env/runner/test-runner": { TestRunner: { create: () => browserTestRunner } }, "../../browser/cdp/selectivity/testplane-selectivity": { runWithTestplaneDependenciesCollecting, readTestFileWithTestplaneDependenciesCollecting, }, + "../../constants/process-messages": { + TEST_ASSIGNED_TO_WORKER: "worker.testAssignedToWorker", + }, }); processSendBackup = process.send; @@ -92,11 +100,13 @@ describe("worker/runner", () => { }); [ - { name: "NodejsEnvTestRunner", TestRunner: NodejsEnvTestRunner, testRunEnv: NODEJS_TEST_RUN_ENV }, - { name: "BrowserEnvTestRunner", TestRunner: BrowserEnvTestRunner, testRunEnv: BROWSER_TEST_RUN_ENV }, - ].forEach(({ name, TestRunner, testRunEnv }) => { + { name: "NodejsEnvTestRunner", testRunEnv: NODEJS_TEST_RUN_ENV }, + { name: "BrowserEnvTestRunner", testRunEnv: BROWSER_TEST_RUN_ENV }, + ].forEach(({ name, testRunEnv }) => { describe(name, () => { let runner; + const getTestRunner = () => + testRunEnv === NODEJS_TEST_RUN_ENV ? NodejsEnvTestRunner : BrowserEnvTestRunner; beforeEach(() => { runner = mkRunner_({ @@ -124,6 +134,7 @@ describe("worker/runner", () => { CachingTestParser.prototype.parse.resolves([test]); await runner.runTest("some test", {}); + const TestRunner = getTestRunner(); // Note: BrowserEnvTestRunner assertions are skipped due to dynamic import mocking limitations // The core functionality is still tested via NodejsEnvTestRunner which uses the same API @@ -143,6 +154,7 @@ describe("worker/runner", () => { CachingTestParser.prototype.parse.resolves([test]); await runner.runTest("some test", { browserId: "bro" }); + const TestRunner = getTestRunner(); // Note: BrowserEnvTestRunner assertions are skipped due to dynamic import mocking limitations if (TestRunner === NodejsEnvTestRunner) { @@ -157,6 +169,7 @@ describe("worker/runner", () => { CachingTestParser.prototype.parse.resolves([test]); await runner.runTest("some test", { file: "/path/to/file" }); + const TestRunner = getTestRunner(); assert.calledOnceWith(TestRunner.create, sinon.match({ file: "/path/to/file" })); }); @@ -173,6 +186,7 @@ describe("worker/runner", () => { BrowserAgent.create.withArgs({ id: "bro", version: "1.0", pool }).returns(browserAgent); await runner.runTest("some test", { browserId: "bro", browserVersion: "1.0" }); + const TestRunner = getTestRunner(); assert.calledOnceWith(TestRunner.create, sinon.match({ browserAgent })); }); @@ -191,6 +205,7 @@ describe("worker/runner", () => { CachingTestParser.prototype.parse.resolves([test1, test2]); await runner.runTest("other test", {}); + const TestRunner = getTestRunner(); const testRunner = TestRunner === NodejsEnvTestRunner ? nodejsTestRunner : browserTestRunner; @@ -215,6 +230,7 @@ describe("worker/runner", () => { sessionOpts: "some-opts", state: {}, }); + const TestRunner = getTestRunner(); const testRunner = TestRunner === NodejsEnvTestRunner ? nodejsTestRunner : browserTestRunner; diff --git a/test/src/worker/testplane.js b/test/src/worker/testplane.js index 12f417ade..0ba5ff673 100644 --- a/test/src/worker/testplane.js +++ b/test/src/worker/testplane.js @@ -24,6 +24,7 @@ describe("worker/testplane", () => { Testplane = proxyquire("src/worker/testplane", { "expect-webdriverio": ExpectWebdriverio, + "./runner": Runner, }).Testplane; sandbox.stub(Config, "create").returns(makeConfigStub()); diff --git a/test/tsconfig.json b/test/tsconfig.json index 3ccc84cf3..40493864d 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "../tsconfig.common.json", - "include": ["../typings", "../src/index.ts", "."], + "include": ["../typings", "../src/index.ts", "./types.ts", "src", "integration"], "exclude": ["../src/runner/browser-env/vite/browser-modules"], "compilerOptions": { "baseUrl": "..", @@ -9,5 +9,19 @@ "src/*": ["src/*"], "@isomorphic": ["src/browser/isomorphic/index.ts"] } - } + }, + "references": [ + { + "path": "../src/runner/browser-env/vite/browser-modules/tsconfig.json" + }, + { + "path": "../src/browser/client-scripts/screen-shooter/tsconfig.json" + }, + { + "path": "../src/browser/client-scripts/browser-utils/tsconfig.json" + }, + { + "path": "../src/browser/isomorphic/tsconfig.json" + } + ] } diff --git a/test/utils.js b/test/utils.js index cf3be2951..81d0ee04d 100644 --- a/test/utils.js +++ b/test/utils.js @@ -35,6 +35,10 @@ function makeConfigStub(opts = {}) { input: "some-path", output: "some-other-path", }, + takeScreenshotOnFails: { + testFail: true, + assertViewFail: true, + }, timeTravel: { mode: "off" }, selectivity: { enabled: false }, }); @@ -49,6 +53,7 @@ function makeConfigStub(opts = {}) { lastFailed: opts.lastFailed, timeTravel: opts.timeTravel, selectivity: opts.selectivity, + takeScreenshotOnFails: opts.takeScreenshotOnFails, }; opts.browsers.forEach(browserId => { @@ -79,6 +84,7 @@ function makeBrowserConfigStub(opts = {}, browserId) { system: opts.system, urlHttpTimeout: opts.urlHttpTimeout, httpTimeout: opts.httpTimeout, + takeScreenshotOnFails: opts.takeScreenshotOnFails || { testFail: true, assertViewFail: true }, timeTravel: { mode: "off" }, selectivity: opts.selectivity, }; diff --git a/tsconfig.json b/tsconfig.json index 0fdad425e..48a6dcbb5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,13 +12,18 @@ "compilerOptions": { "outDir": "build" }, - "references": [{ - "path": "./src/runner/browser-env/vite/browser-modules/tsconfig.json" - }, { - "path": "./src/browser/client-scripts/screen-shooter/tsconfig.json" - }, { - "path": "./src/browser/client-scripts/browser-utils/tsconfig.json" - }, { - "path": "./src/browser/isomorphic/tsconfig.json" - }] + "references": [ + { + "path": "./src/runner/browser-env/vite/browser-modules/tsconfig.json" + }, + { + "path": "./src/browser/client-scripts/screen-shooter/tsconfig.json" + }, + { + "path": "./src/browser/client-scripts/browser-utils/tsconfig.json" + }, + { + "path": "./src/browser/isomorphic/tsconfig.json" + } + ] } From 0605b6215a115f6275e49da6eda0fc8f6e4e3ab4 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 00:32:53 +0300 Subject: [PATCH 06/29] fix: simplify return types in client-scripts and use correct logging topics --- .../screen-shooter/implementation.ts | 60 +++++------ .../screen-shooter/operations.ts | 88 ++++++--------- .../client-scripts/screen-shooter/types.ts | 36 ------- .../screen-shooter/elements-screen-shooter.ts | 31 +++--- .../computeCaptureSpecs.testplane.ts | 102 +++++++++--------- .../computePixelRatio.testplane.ts | 4 +- .../computeSafeArea.testplane.ts | 72 ++++++------- .../computeViewportSize.testplane.ts | 4 +- .../scrollToCaptureAreaIfNeeded.testplane.ts | 4 +- .../prepareViewportScreenshot.testplane.ts | 6 +- 10 files changed, 177 insertions(+), 230 deletions(-) diff --git a/src/browser/client-scripts/screen-shooter/implementation.ts b/src/browser/client-scripts/screen-shooter/implementation.ts index 26f85042f..6e9fb0f4f 100644 --- a/src/browser/client-scripts/screen-shooter/implementation.ts +++ b/src/browser/client-scripts/screen-shooter/implementation.ts @@ -86,8 +86,8 @@ export function scrollBy( debug?: string[] ): ScrollResult { return safeCall((): ScrollResult => { - const logger = createDebugLogger({ debug }, "scrollAndRecomputeAreas:scroll"); - const pixelRatio = computePixelRatio().pixelRatio; + const logger = createDebugLogger({ debug }, "scrollBy"); + const pixelRatio = computePixelRatio(); const scrollTarget = selectorToScroll ? document.querySelector(selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); @@ -117,8 +117,8 @@ export function scrollTo( debug?: string[] ): ScrollResult { return safeCall((): ScrollResult => { - const logger = createDebugLogger({ debug }, "scrollAndRecomputeAreas:scroll"); - const pixelRatio = computePixelRatio().pixelRatio; + const logger = createDebugLogger({ debug }, "scrollTo"); + const pixelRatio = computePixelRatio(); const scrollTarget = selectorToScroll ? document.querySelector(selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); @@ -150,8 +150,8 @@ export function getCaptureState( debug?: string[] ): GetCaptureStateResult { return safeCall((): GetCaptureStateResult => { - const logger = createDebugLogger({ debug }, "scrollAndRecomputeAreas:scroll"); - const pixelRatio = computePixelRatio().pixelRatio; + const logger = createDebugLogger({ debug }, "getCaptureState"); + const pixelRatio = computePixelRatio(); const scrollTarget = selectorToScroll ? document.querySelector(selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); const readableAutoScrollElementDescr = getReadableElementDescriptor(scrollElement); @@ -160,9 +160,9 @@ export function getCaptureState( ? `${selectorToScroll} (${readableAutoScrollElementDescr})` : `${selectorToScroll} (not found, auto-detected ${readableAutoScrollElementDescr})` : `auto-detected ${readableAutoScrollElementDescr}`; - const ignoreAreas = computeIgnoreAreas(selectorsToIgnore).ignoreAreas; - const safeArea = computeSafeArea(selectorsToCapture, scrollElement, logger).safeArea; - const captureSpecsAfterCss = computeCaptureSpecs(selectorsToCapture, logger).captureSpecs; + const ignoreAreas = computeIgnoreAreas(selectorsToIgnore); + const safeArea = computeSafeArea(selectorsToCapture, scrollElement, logger); + const captureSpecsAfterCss = computeCaptureSpecs(selectorsToCapture, logger); const captureSpecs = captureSpecsAfterCss.map(spec => ({ full: fromCssToDevice(roundCoords(spec.full), pixelRatio), visible: fromCssToDevice(roundCoords(spec.visible), pixelRatio) @@ -188,14 +188,14 @@ export function prepareFullPageScreenshot( return safeCall((): PrepareFullPageScreenshotResult => { prepareFullPageScrollCleanup(); - const pixelRatio = computePixelRatio(opts.usePixelRatio).pixelRatio; + const pixelRatio = computePixelRatio(opts.usePixelRatio); window.scrollTo(0, 0); - const documentSize = computeDocumentSize().documentSize; - const viewportSize = computeViewportSize().viewportSize; - const viewportOffset = computeViewportOffset().viewportOffset; - const safeArea = computeSafeArea(["body"], document.documentElement).safeArea; + const documentSize = computeDocumentSize(); + const viewportSize = computeViewportSize(); + const viewportOffset = computeViewportOffset(); + const safeArea = computeSafeArea(["body"], document.documentElement); if (opts.disableAnimation) { disableAnimations(); @@ -235,13 +235,13 @@ export function scrollFullPage( opts: { usePixelRatio?: boolean } = {} ): ScrollFullPageResult { return safeCall((): ScrollFullPageResult => { - const pixelRatio = computePixelRatio(opts.usePixelRatio).pixelRatio; + const pixelRatio = computePixelRatio(opts.usePixelRatio); const scrollHeightCss = (fromDeviceToCssNumber(scrollHeight as Coord<"page", "device", "y">, pixelRatio) - 1) as Coord<"page", "css", "y">; scrollElementBy(document.documentElement, scrollHeightCss); - const viewportOffset = computeViewportOffset().viewportOffset; + const viewportOffset = computeViewportOffset(); const elementPositionsProbe = computeElementPositionsProbe().map(rect => rect ? fromCssToDevice(roundCoords(rect), pixelRatio) : null ); @@ -257,11 +257,11 @@ export function prepareViewportScreenshot( opts: { usePixelRatio?: boolean; disableAnimation?: boolean; disableHover?: DisableHoverMode } = {} ): PrepareViewportScreenshotResult { return safeCall((): PrepareViewportScreenshotResult => { - const pixelRatio = computePixelRatio(opts.usePixelRatio).pixelRatio; - const viewportSize = computeViewportSize().viewportSize; - const viewportOffset = computeViewportOffset().viewportOffset; - const documentSize = computeDocumentSize().documentSize; - const canHaveCaret = computeCanHaveCaret().canHaveCaret; + const pixelRatio = computePixelRatio(opts.usePixelRatio); + const viewportSize = computeViewportSize(); + const viewportOffset = computeViewportOffset(); + const documentSize = computeDocumentSize(); + const canHaveCaret = computeCanHaveCaret(); if (opts.disableAnimation) { disableAnimations(); @@ -313,7 +313,7 @@ function prepareElementsScreenshotUnsafe( selectorsToCapture: string[], opts: PrepareScreenshotOptions ): PrepareScreenshotResult { - const logger = createDebugLogger(opts, "prepareScreenshot:areas-computation"); + const logger = createDebugLogger(opts, "prepareElementsScreenshot"); saveScrollPositions(selectorsToCapture, opts.selectorToScroll); @@ -329,19 +329,19 @@ function prepareElementsScreenshotUnsafe( disableAnimations(); } - const pixelRatio = computePixelRatio(opts.usePixelRatio).pixelRatio; + const pixelRatio = computePixelRatio(opts.usePixelRatio); const scrollTarget = opts.selectorToScroll ? document.querySelector(opts.selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); - const ignoreAreas = computeIgnoreAreas(opts.ignoreSelectors).ignoreAreas; - const captureSpecs = computeCaptureSpecs(selectorsToCapture, logger).captureSpecs; - const viewportSize = computeViewportSize().viewportSize; - const viewportOffset = computeViewportOffset().viewportOffset; - const safeArea = computeSafeArea(selectorsToCapture, scrollElement, logger).safeArea; + const ignoreAreas = computeIgnoreAreas(opts.ignoreSelectors); + const captureSpecs = computeCaptureSpecs(selectorsToCapture, logger); + const viewportSize = computeViewportSize(); + const viewportOffset = computeViewportOffset(); + const safeArea = computeSafeArea(selectorsToCapture, scrollElement, logger); const scrollOffset = computeScrollOffset(scrollElement); - const documentSize = computeDocumentSize().documentSize; - const canHaveCaret = computeCanHaveCaret().canHaveCaret; + const documentSize = computeDocumentSize(); + const canHaveCaret = computeCanHaveCaret(); let pointerEventsDisabled = false; if (opts.disableHover === DisableHoverMode.Always) { diff --git a/src/browser/client-scripts/screen-shooter/operations.ts b/src/browser/client-scripts/screen-shooter/operations.ts index bcb9257e0..3218ae7ab 100644 --- a/src/browser/client-scripts/screen-shooter/operations.ts +++ b/src/browser/client-scripts/screen-shooter/operations.ts @@ -1,7 +1,10 @@ import { Coord, Length, + Point, Rect, + Size, + YBand, fromBcrToRect, getBottom, getCoveringRect, @@ -9,18 +12,7 @@ import { getIntersection } from "@isomorphic"; import { OutsideOfViewportError } from "./errors/outside-of-viewport"; -import { - ComputeCanHaveCaretResult, - ComputeDocumentSizeResult, - ComputeCaptureSpecsResult, - ComputeIgnoreAreasResult, - ComputePixelRatioResult, - ComputeSafeAreaResult, - ComputeViewportOffsetResult, - ComputeViewportSizeResult, - SavedScrollPosition as ElementScrollPosition, - ScrollToCaptureSpecResult -} from "./types"; +import { CaptureSpec, SavedScrollPosition as ElementScrollPosition, ScrollToCaptureSpecResult } from "./types"; import { getReadableElementDescriptor } from "./utils/descriptions"; import { findContainingBlock, @@ -55,21 +47,17 @@ export function computeScrollOffset(element: Element): Coord<"page", "css", "y"> return (isRootLikeElement(element) ? window.scrollY : element.scrollTop) as Coord<"page", "css", "y">; } -export function computeViewportSize(): ComputeViewportSizeResult { +export function computeViewportSize(): Size<"css"> { return { - viewportSize: { - width: window.innerWidth as Length<"css", "x">, - height: window.innerHeight as Length<"css", "y"> - } + width: window.innerWidth as Length<"css", "x">, + height: window.innerHeight as Length<"css", "y"> }; } -export function computeViewportOffset(): ComputeViewportOffsetResult { +export function computeViewportOffset(): Point<"page", "css"> { return { - viewportOffset: { - left: window.scrollX as Coord<"page", "css", "x">, - top: window.scrollY as Coord<"page", "css", "y"> - } + left: window.scrollX as Coord<"page", "css", "x">, + top: window.scrollY as Coord<"page", "css", "y"> }; } @@ -95,7 +83,7 @@ function getProbeAxisCoordinates(length: number, gridSize: number): number[] { export function computeElementPositionsProbe( gridSize = ELEMENT_POSITIONS_PROBE_GRID_SIZE ): Array | null> { - const viewportSize = computeViewportSize().viewportSize; + const viewportSize = computeViewportSize(); const xCoordinates = getProbeAxisCoordinates(viewportSize.width as number, gridSize); const yCoordinates = getProbeAxisCoordinates(viewportSize.height as number, gridSize); const probe: Array | null> = []; @@ -115,7 +103,7 @@ export function computeElementPositionsProbe( export function computeCaptureSpecs( selectors: string[], logger?: (...args: unknown[]) => unknown -): ComputeCaptureSpecsResult { +): CaptureSpec<"viewport", "css">[] { if (selectors.length === 0) { throw new Error("No selectors to compute capture area"); } @@ -156,10 +144,10 @@ export function computeCaptureSpecs( logger?.("computeCaptureSpecs time taken:", (performance.now() - startTime).toFixed(1) + "ms"); logger?.("========== =========="); - return { captureSpecs }; + return captureSpecs; } -export function computeIgnoreAreas(selectors: string[] = []): ComputeIgnoreAreasResult { +export function computeIgnoreAreas(selectors: string[] = []): Rect<"viewport", "css">[] { const ignoreAreas: Rect<"viewport", "css">[] = []; for (let s = 0; s < selectors.length; s++) { @@ -175,18 +163,18 @@ export function computeIgnoreAreas(selectors: string[] = []): ComputeIgnoreAreas } } - return { ignoreAreas }; + return ignoreAreas; } export function computeSafeArea( selectorsToCapture: string[], scrollElement?: Element, logger?: (...args: unknown[]) => unknown -): ComputeSafeAreaResult { +): YBand<"viewport", "css"> { logger?.("========== =========="); const startTime = performance.now(); - const viewportSize = computeViewportSize().viewportSize; + const viewportSize = computeViewportSize(); const viewportRect: Rect<"viewport", "css"> = { left: 0 as Coord<"viewport", "css", "x">, top: 0 as Coord<"viewport", "css", "y">, @@ -196,12 +184,10 @@ export function computeSafeArea( const captureElements = selectorsToCapture .map(s => document.querySelector(parseCaptureSelector(s).elementSelector)) .filter((e): e is NonNullable => e !== null); - const captureSpecs = computeCaptureSpecs(selectorsToCapture).captureSpecs.map(s => s.full); + const captureSpecs = computeCaptureSpecs(selectorsToCapture).map(s => s.full); if (captureSpecs.length === 0) { - return { - safeArea: { top: viewportRect.top, height: viewportRect.height } - }; + return { top: viewportRect.top, height: viewportRect.height }; } const captureArea = getCoveringRect(captureSpecs); @@ -406,40 +392,36 @@ export function computeSafeArea( logger?.("computeSafeArea time taken:", (performance.now() - startTime).toFixed(1) + "ms"); logger?.("========== =========="); - return { - safeArea: finalSafeArea - }; + return finalSafeArea; } -export function computeDocumentSize(): ComputeDocumentSizeResult { +export function computeDocumentSize(): Size<"css"> { const mainDocumentElem = getMainDocumentElem(); return { - documentSize: { - width: mainDocumentElem.scrollWidth as Length<"css", "x">, - height: mainDocumentElem.scrollHeight as Length<"css", "y"> - } + width: mainDocumentElem.scrollWidth as Length<"css", "x">, + height: mainDocumentElem.scrollHeight as Length<"css", "y"> }; } -export function computeCanHaveCaret(): ComputeCanHaveCaretResult { +export function computeCanHaveCaret(): boolean { const el = document.activeElement; const canHaveCaret = el instanceof HTMLElement && (/^(input|textarea)$/i.test(el.tagName) || el.isContentEditable); - return { canHaveCaret }; + return canHaveCaret; } -export function computePixelRatio(usePixelRatio: boolean = true): ComputePixelRatioResult { +export function computePixelRatio(usePixelRatio: boolean = true): number { if (usePixelRatio === false) { - return { pixelRatio: 1 }; + return 1; } if (window.devicePixelRatio) { - return { pixelRatio: window.devicePixelRatio }; + return window.devicePixelRatio; } // for ie6-ie10 (https://developer.mozilla.org/ru/docs/Web/API/Window/devicePixelRatio) // @ts-expect-error - IE hack - return { pixelRatio: window.screen.deviceXDPI / window.screen.logicalXDPI || 1 }; + return window.screen.deviceXDPI / window.screen.logicalXDPI || 1; } export function scrollToCaptureAreaIfNeeded( @@ -449,7 +431,7 @@ export function scrollToCaptureAreaIfNeeded( selectorToScroll?: string, logger?: (...args: unknown[]) => unknown ): ScrollToCaptureSpecResult { - const viewportSize = computeViewportSize().viewportSize; + const viewportSize = computeViewportSize(); const viewport = { top: 0 as Coord<"viewport", "css", "y">, left: 0 as Coord<"viewport", "css", "x">, @@ -459,8 +441,8 @@ export function scrollToCaptureAreaIfNeeded( const captureSpecsResult = computeCaptureSpecs(selectorsToCapture); if (!captureSpecsResult) return {}; - const captureArea = getCoveringRect(captureSpecsResult.captureSpecs.map(s => s.full)); - const safeArea = computeSafeArea(selectorsToCapture).safeArea; + const captureArea = getCoveringRect(captureSpecsResult.map(s => s.full)); + const safeArea = computeSafeArea(selectorsToCapture); const captureAndSafeAreasIntersection = getIntersection(captureArea, safeArea); const captureAndViewportIntersection = getIntersection(captureArea, viewport); @@ -518,7 +500,7 @@ export function scrollToCaptureAreaIfNeeded( } for (let i = 1; i < scrollChain.length; i++) { - const currentSafeArea = computeSafeArea(selectorsToCapture, scrollChain[i - 1]).safeArea; + const currentSafeArea = computeSafeArea(selectorsToCapture, scrollChain[i - 1]); const childTop = scrollChain[i].getBoundingClientRect().top; const scrollDelta = childTop - currentSafeArea.top; logger?.("scrollToCaptureAreaIfNeeded: scrolling chain element", { @@ -529,10 +511,10 @@ export function scrollToCaptureAreaIfNeeded( scrollElementBy(scrollChain[i - 1], scrollDelta as Coord<"page", "css", "y">, logger); } - const finalCaptureArea = getCoveringRect(computeCaptureSpecs(selectorsToCapture).captureSpecs.map(s => s.full)); + const finalCaptureArea = getCoveringRect(computeCaptureSpecs(selectorsToCapture).map(s => s.full)); if (!finalCaptureArea) return {}; - const finalSafeArea = computeSafeArea(selectorsToCapture, initialScrollElem).safeArea; + const finalSafeArea = computeSafeArea(selectorsToCapture, initialScrollElem); const finalScrollDelta = finalCaptureArea.top - finalSafeArea.top; logger?.("scrollToCaptureAreaIfNeeded: final alignment scroll", { scrollElement: readableSelectorToScrollDescr, diff --git a/src/browser/client-scripts/screen-shooter/types.ts b/src/browser/client-scripts/screen-shooter/types.ts index 9cc9c74fa..e797b3972 100644 --- a/src/browser/client-scripts/screen-shooter/types.ts +++ b/src/browser/client-scripts/screen-shooter/types.ts @@ -73,42 +73,6 @@ export interface ScrollToCaptureSpecResult { readableSelectorToScrollDescr?: string; } -export interface ComputeCaptureSpecsResult { - captureSpecs: CaptureSpec<"viewport", "css">[]; -} - -export interface ComputeCaptureSpecResult { - captureArea: Rect<"viewport", "css">; -} - -export interface ComputeIgnoreAreasResult { - ignoreAreas: Rect<"viewport", "css">[]; -} - -export interface ComputeSafeAreaResult { - safeArea: YBand<"viewport", "css">; -} - -export interface ComputeDocumentSizeResult { - documentSize: Size<"css">; -} - -export interface ComputeCanHaveCaretResult { - canHaveCaret: boolean; -} - -export interface ComputePixelRatioResult { - pixelRatio: number; -} - -export interface ComputeViewportSizeResult { - viewportSize: Size<"css">; -} - -export interface ComputeViewportOffsetResult { - viewportOffset: Point<"page", "css">; -} - export type ElementPositionsProbe = Array | null>; export interface PrepareFullPageScreenshotSuccess { diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index ba2dfce00..8a2422192 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -260,7 +260,7 @@ export class ElementsScreenShooter { const enabledDebugTopics: string[] = []; const browserPrepareScreenshotDebug = makeDebug("testplane:screenshots:browser:prepareScreenshot"); if (browserPrepareScreenshotDebug.enabled) { - enabledDebugTopics.push("prepareScreenshot:areas-computation"); + enabledDebugTopics.push("prepareElementsScreenshot"); } const extendedOpts = { @@ -382,12 +382,6 @@ export class ElementsScreenShooter { scrollTime = 0, callbackTime = 0; - const enabledScrollDebugTopics: string[] = []; - const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollAndRecomputeAreas"); - if (browserScrollDebug.enabled) { - enabledScrollDebugTopics.push("scrollAndRecomputeAreas:scroll"); - } - try { while (iterations < COMPOSITING_ITERATIONS_LIMIT && !hasCapturedTheWholeArea && !hasReachedScrollLimit) { debug(`========== Starting compositing iteration #${iterations} ==========`); @@ -397,6 +391,13 @@ export class ElementsScreenShooter { waitForSettleTime += performance.now() - waitForSettleStartTime; const recomputeStartTime = performance.now(); + + const enabledScrollDebugTopics: string[] = []; + const browserScrollDebug = makeDebug("testplane:screenshots:browser:getCaptureState"); + if (browserScrollDebug.enabled) { + enabledScrollDebugTopics.push("getCaptureState"); + } + const currentStateOrError = await this._browserSideScreenshooter.call("getCaptureState", [ selectorsToCapture, selectorsToIgnore, @@ -547,9 +548,9 @@ export class ElementsScreenShooter { const startedAt = performance.now(); const enabledScrollDebugTopics: string[] = []; - const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollAndRecomputeAreas"); + const browserScrollDebug = makeDebug("testplane:screenshots:browser:getCaptureState"); if (browserScrollDebug.enabled) { - enabledScrollDebugTopics.push("scrollAndRecomputeAreas:scroll"); + enabledScrollDebugTopics.push("getCaptureState"); } const beforeCheckpointsValidationState = await this._browserSideScreenshooter.call("getCaptureState", [ @@ -756,12 +757,6 @@ export class ElementsScreenShooter { let shouldRestoreScrollPosition = false; - const enabledScrollDebugTopics: string[] = []; - const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollAndRecomputeAreas"); - if (browserScrollDebug.enabled) { - enabledScrollDebugTopics.push("scrollAndRecomputeAreas:scroll"); - } - try { await this._scrollThroughCaptureArea( selectorsToCapture, @@ -826,6 +821,12 @@ export class ElementsScreenShooter { } finally { perfDebug(`Done capturing composite image. Time spent on raw viewport captures: ${timeSpentOnCapture}ms`); if (shouldRestoreScrollPosition) { + const enabledScrollDebugTopics: string[] = []; + const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollTo"); + if (browserScrollDebug.enabled) { + enabledScrollDebugTopics.push("scrollTo"); + } + const restoreScrollResult = await this._browserSideScreenshooter.call("scrollTo", [ selectorsToCapture, page.scrollOffset, diff --git a/test/browser-env/tests/desktop/screenshooter/computeCaptureSpecs.testplane.ts b/test/browser-env/tests/desktop/screenshooter/computeCaptureSpecs.testplane.ts index 7ff539de8..cc23bc3f2 100644 --- a/test/browser-env/tests/desktop/screenshooter/computeCaptureSpecs.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/computeCaptureSpecs.testplane.ts @@ -21,7 +21,7 @@ describe("computeCaptureSpecs", () => { describe("empty results", () => { it("should return empty array when selector matches nothing", () => { const result = computeCaptureSpecs([".nonexistent"]); - expect(result.captureSpecs).toEqual([]); + expect(result).toEqual([]); }); it("should return empty array when all matched elements are hidden", async () => { @@ -34,7 +34,7 @@ describe("computeCaptureSpecs", () => { ".hidden-opacity", ".hidden-zero-size", ]); - expect(result.captureSpecs).toEqual([]); + expect(result).toEqual([]); }); }); @@ -44,9 +44,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("single-element"); }); @@ -55,9 +55,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".shadow-target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("box-shadow"); }); @@ -66,9 +66,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".inset-shadow-target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("inset-box-shadow"); }); @@ -77,9 +77,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".outline-target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("outline"); }); @@ -89,7 +89,7 @@ describe("computeCaptureSpecs", () => { const elementResult = computeCaptureSpecs([".pseudo-target"]); - visualizeCaptureSpecs(elementResult.captureSpecs); + visualizeCaptureSpecs(elementResult); await browser.assertView("pseudo-elements"); }); @@ -98,9 +98,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".pseudo-target::before", ".pseudo-target::after"]); - expect(result.captureSpecs).toHaveLength(2); + expect(result).toHaveLength(2); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("pseudo-elements"); }); @@ -111,9 +111,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".parent::before", ".parent::after"]); - expect(result.captureSpecs).toHaveLength(2); + expect(result).toHaveLength(2); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("pseudo-elements-ancestor-cb"); }); @@ -124,9 +124,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target::before", ".target::after"]); - expect(result.captureSpecs).toHaveLength(2); + expect(result).toHaveLength(2); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("transformed-pseudo-elements"); }); @@ -137,9 +137,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".rotated", ".scaled", ".translated", ".skewed", ".combined"]); - expect(result.captureSpecs).toHaveLength(5); + expect(result).toHaveLength(5); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("transformed-elements"); }); }); @@ -150,9 +150,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".a", ".b", ".c"]); - expect(result.captureSpecs).toHaveLength(3); + expect(result).toHaveLength(3); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("multiple-selectors"); }); @@ -161,9 +161,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".item"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("multiple-matches"); }); @@ -173,10 +173,10 @@ describe("computeCaptureSpecs", () => { // Both selectors match the same .target element const result = computeCaptureSpecs([".target", "div.target"]); - expect(result.captureSpecs).toHaveLength(2); + expect(result).toHaveLength(2); // Both rects should be identical - expect(result.captureSpecs[0]).toEqual(result.captureSpecs[1]); + expect(result[0]).toEqual(result[1]); }); it("should only return visible elements from a mix of visible and hidden", async ({ browser }) => { @@ -190,9 +190,9 @@ describe("computeCaptureSpecs", () => { ".hidden-opacity", ".hidden-zero-size", ]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("mixed-visibility"); }); }); @@ -206,9 +206,9 @@ describe("computeCaptureSpecs", () => { container.scrollTop = 200; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("scrollable-container-scrolled"); }); }); @@ -219,9 +219,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".box-model-target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("margin-padding-border"); }); @@ -230,9 +230,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".offscreen"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("offscreen"); }); @@ -243,9 +243,9 @@ describe("computeCaptureSpecs", () => { window.scrollTo(0, 560); const result = computeCaptureSpecs([".long-target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("partially-visible-after-scroll"); }); @@ -254,9 +254,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".fractional", ".transformed"]); - expect(result.captureSpecs).toHaveLength(2); + expect(result).toHaveLength(2); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("fractional-positions"); }); }); @@ -268,7 +268,7 @@ describe("computeCaptureSpecs", () => { const result = computeCaptureSpecs([".parent", ".child"]); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("nested-elements"); }); }); @@ -281,9 +281,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("overflow-hidden"); }); @@ -293,9 +293,9 @@ describe("computeCaptureSpecs", () => { const logger = createDebugLogger({ debug: ["screen-shooter"] }, "screen-shooter"); const result = computeCaptureSpecs([".target"], logger); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("overflow-scroll"); }); @@ -304,14 +304,14 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - const spec = result.captureSpecs[0]; + const spec = result[0]; // Fixed element escapes overflow clipping — full and visible should be the same expect(spec.full.width).toBe(spec.visible.width); expect(spec.full.height).toBe(spec.visible.height); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("fixed-in-overflow"); }); @@ -320,9 +320,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("fixed-parent-in-overflow-hidden-external-containing-block"); }); @@ -335,9 +335,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("target"); }); @@ -348,9 +348,9 @@ describe("computeCaptureSpecs", () => { document.body.innerHTML = html; const result = computeCaptureSpecs([".target"]); - expect(result.captureSpecs).toHaveLength(1); + expect(result).toHaveLength(1); - visualizeCaptureSpecs(result.captureSpecs); + visualizeCaptureSpecs(result); await browser.assertView("target"); }); }); diff --git a/test/browser-env/tests/desktop/screenshooter/computePixelRatio.testplane.ts b/test/browser-env/tests/desktop/screenshooter/computePixelRatio.testplane.ts index 92ba9e049..d2c479068 100644 --- a/test/browser-env/tests/desktop/screenshooter/computePixelRatio.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/computePixelRatio.testplane.ts @@ -3,13 +3,13 @@ import { computePixelRatio } from "../../../../../src/browser/client-scripts/scr describe("computePixelRatio", () => { testplane.only.in("chrome-mobile-dpr3"); it("returns emulated mobile pixel ratio from window.devicePixelRatio", () => { - const pixelRatio = computePixelRatio().pixelRatio; + const pixelRatio = computePixelRatio(); expect(pixelRatio).toBe(3); }); testplane.only.in("chrome-mobile-dpr3"); it("returns 1 when usePixelRatio is disabled", () => { - const pixelRatio = computePixelRatio(false).pixelRatio; + const pixelRatio = computePixelRatio(false); expect(pixelRatio).toBe(1); }); }); diff --git a/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts b/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts index fbdd46730..12eed8543 100644 --- a/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts @@ -17,8 +17,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); expect(captureSpecs).toHaveLength(1); expect(safeArea.top).toBeGreaterThan(0); @@ -33,8 +33,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); expect(captureSpecs).toHaveLength(1); @@ -48,8 +48,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target-modal"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -61,8 +61,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -79,8 +79,8 @@ describe("computeSafeArea", () => { } const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, panel).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, panel); + const captureSpecs = computeCaptureSpecs(selectors); expect(captureSpecs).toHaveLength(1); @@ -101,8 +101,8 @@ describe("computeSafeArea", () => { } const selectors = [".content"]; - const safeArea = computeSafeArea(selectors, panel).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, panel); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -119,8 +119,8 @@ describe("computeSafeArea", () => { ); const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, undefined, logger).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, undefined, logger); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -134,7 +134,7 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; + const safeArea = computeSafeArea(selectors); visualizeSafeArea(safeArea.top, safeArea.height); await browser.assertView("compute-safe-area-sticky-header-with-shadow"); @@ -150,8 +150,8 @@ describe("computeSafeArea", () => { ); const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, undefined, logger).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, undefined, logger); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -163,8 +163,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -174,8 +174,8 @@ describe("computeSafeArea", () => { it("should return full viewport when no selectors match", () => { document.body.innerHTML = "
some content
"; - const { viewportSize } = computeViewportSize(); - const safeArea = computeSafeArea([".does-not-exist"]).safeArea; + const viewportSize = computeViewportSize(); + const safeArea = computeSafeArea([".does-not-exist"]); expect(safeArea.top).toBe(0); expect(safeArea.height).toBe(viewportSize.height); @@ -191,8 +191,8 @@ describe("computeSafeArea", () => { } const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, panel).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, panel); + const captureSpecs = computeCaptureSpecs(selectors); expect(captureSpecs).toHaveLength(1); @@ -211,8 +211,8 @@ describe("computeSafeArea", () => { } const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, panel).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, panel); + const captureSpecs = computeCaptureSpecs(selectors); visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); @@ -224,8 +224,8 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors); + const captureSpecs = computeCaptureSpecs(selectors); const headerBcr = document.querySelector(".header")!.getBoundingClientRect(); const footerBcr = document.querySelector(".footer")!.getBoundingClientRect(); @@ -249,8 +249,8 @@ describe("computeSafeArea", () => { } const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, panel).safeArea; - const captureSpecs = computeCaptureSpecs(selectors).captureSpecs; + const safeArea = computeSafeArea(selectors, panel); + const captureSpecs = computeCaptureSpecs(selectors); expect(captureSpecs).toHaveLength(1); @@ -267,10 +267,10 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; + const safeArea = computeSafeArea(selectors); // overlay: z:5 / target's container: z:10 -> isChainBehind returns true -> no shrink - const { viewportSize } = computeViewportSize(); + const viewportSize = computeViewportSize(); expect(safeArea.top).toBe(0); expect(safeArea.height).toBe(viewportSize.height); @@ -290,7 +290,7 @@ describe("computeSafeArea", () => { window.scrollTo(0, document.documentElement.scrollHeight - document.documentElement.clientHeight - 200); const selectors = [".target"]; - const safeArea = computeSafeArea(selectors, undefined, logger).safeArea; + const safeArea = computeSafeArea(selectors, undefined, logger); visualizeSafeArea(safeArea.top, safeArea.height); await browser.assertView("compute-safe-area-stacking-context-filter-in-front"); @@ -305,7 +305,7 @@ describe("computeSafeArea", () => { window.scrollTo(0, 5000); const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; + const safeArea = computeSafeArea(selectors); // header: z:10 / target: z:0 -> isChainBehind returns false -> does shrink const headerBcr = document.querySelector(".header")!.getBoundingClientRect(); @@ -322,10 +322,10 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; + const safeArea = computeSafeArea(selectors); // overlay: z:50 / app-shell: z:100 -> common ctx = documentElement -> 50 < 100 -> behind -> no shrink - const { viewportSize } = computeViewportSize(); + const viewportSize = computeViewportSize(); expect(safeArea.top).toBe(0); expect(safeArea.height).toBe(viewportSize.height); @@ -340,7 +340,7 @@ describe("computeSafeArea", () => { document.body.innerHTML = html; const selectors = [".target"]; - const safeArea = computeSafeArea(selectors).safeArea; + const safeArea = computeSafeArea(selectors); // overlay: z:50 / app-shell: z:10 -> common ctx = documentElement -> 50 < 10 is false -> in front -> does shrink const overlayBcr = document.querySelector(".fixed-overlay")!.getBoundingClientRect(); diff --git a/test/browser-env/tests/desktop/screenshooter/computeViewportSize.testplane.ts b/test/browser-env/tests/desktop/screenshooter/computeViewportSize.testplane.ts index fa836217b..9c07085a9 100644 --- a/test/browser-env/tests/desktop/screenshooter/computeViewportSize.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/computeViewportSize.testplane.ts @@ -4,7 +4,7 @@ describe("computeViewportSize", () => { it("should return the viewport size", () => { const viewportSize = computeViewportSize(); - expect(viewportSize.viewportSize.width).toBe(1280); - expect(viewportSize.viewportSize.height).toBe(1000); + expect(viewportSize.width).toBe(1280); + expect(viewportSize.height).toBe(1000); }); }); diff --git a/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts b/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts index 42b5e0ce6..b02b6256f 100644 --- a/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts @@ -23,14 +23,14 @@ function expectClientRectClose( } function coveringFullTop(selectors: string[]): number { - const specs = computeCaptureSpecs(selectors).captureSpecs; + const specs = computeCaptureSpecs(selectors); const area = getCoveringRect(specs.map(s => s.full)); return area.top as number; } function expectCaptureAlignedToSafeArea(selectors: string[], scrollElement: Element | undefined): void { const top = coveringFullTop(selectors); - const safe = computeSafeArea(selectors, scrollElement).safeArea; + const safe = computeSafeArea(selectors, scrollElement); expect(top).toBeCloseTo(safe.top as number, 0); } diff --git a/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts b/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts index e2970dcfb..0c0593abf 100644 --- a/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts +++ b/test/browser-env/tests/high-pixel-ratio/prepareViewportScreenshot.testplane.ts @@ -28,9 +28,9 @@ describe("prepareViewportScreenshot in high pixel ratio mode", () => { it("returns viewport and document dimensions translated to device pixels", async () => { window.scrollTo(0, 245); - const cssViewportSize = computeViewportSize().viewportSize; - const cssViewportOffset = computeViewportOffset().viewportOffset; - const cssDocumentSize = computeDocumentSize().documentSize; + const cssViewportSize = computeViewportSize(); + const cssViewportOffset = computeViewportOffset(); + const cssDocumentSize = computeDocumentSize(); const result = getPrepareResult({ usePixelRatio: true }); From 2c63a70964d7e5caa9199d1b7f206af5a3601f9d Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 00:43:13 +0300 Subject: [PATCH 07/29] chore: use better variable names when computing pseudo element coords and strip unnecessary comments --- .../errors/outside-of-viewport.ts | 2 +- .../client-scripts/screen-shooter/types.ts | 2 -- .../utils/pseudo-element-rect.ts | 34 +++++++++---------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/browser/client-scripts/screen-shooter/errors/outside-of-viewport.ts b/src/browser/client-scripts/screen-shooter/errors/outside-of-viewport.ts index 234a4e0ff..d7c7a37d6 100644 --- a/src/browser/client-scripts/screen-shooter/errors/outside-of-viewport.ts +++ b/src/browser/client-scripts/screen-shooter/errors/outside-of-viewport.ts @@ -7,7 +7,7 @@ export class OutsideOfViewportError extends Error { constructor(debugLog?: string) { super( "Can not capture element, because it is completely outside of viewport with no intersection. " + - 'Try to set "captureElementFromTop=true" to scroll to it before capture.' + 'Try to set "captureElementFromTop=true" assertView option to scroll to it before capture.' ); this.name = "OutsideOfViewportError"; this.errorCode = BrowserSideErrorCode.OUTSIDE_OF_VIEWPORT; diff --git a/src/browser/client-scripts/screen-shooter/types.ts b/src/browser/client-scripts/screen-shooter/types.ts index e797b3972..b966b6179 100644 --- a/src/browser/client-scripts/screen-shooter/types.ts +++ b/src/browser/client-scripts/screen-shooter/types.ts @@ -41,8 +41,6 @@ export interface PrepareScreenshotSuccess { // Area free of sticky elements, inside which it's safe to capture element that's interesting to us // Measured relative to browser viewport (not the whole page!) safeArea: YBand<"viewport", "device">; - // Current scroll position of the scroll element, if window is being used, this will always be 0 - // scrollElementOffset: Point; // Boundaries of elements that we should ignore when comparing screenshots (these areas will be painted in black) ignoreAreas: Rect<"viewport", "device">[]; // Element capture areas with full (unconstrained) and visible (clipped by ancestor overflow) rects diff --git a/src/browser/client-scripts/screen-shooter/utils/pseudo-element-rect.ts b/src/browser/client-scripts/screen-shooter/utils/pseudo-element-rect.ts index 7a7f2bc89..8b47463ea 100644 --- a/src/browser/client-scripts/screen-shooter/utils/pseudo-element-rect.ts +++ b/src/browser/client-scripts/screen-shooter/utils/pseudo-element-rect.ts @@ -136,32 +136,30 @@ function applyTransformToRect(rect: Rect<"viewport", "css">, css: CSSStyleDeclar const matrix = parseTransformMatrix(css.transform); if (!matrix) return rect; - const w = rect.width as number; - const h = rect.height as number; - const origin = resolveTransformOrigin(css.transformOrigin, w, h); - const ox = (rect.left as number) + origin.x; - const oy = (rect.top as number) + origin.y; + const transformOrigin = resolveTransformOrigin(css.transformOrigin, rect.width, rect.height); + const originX = rect.left + transformOrigin.x; + const originY = rect.top + transformOrigin.y; const corners = [ - [rect.left as number, rect.top as number], - [(rect.left as number) + w, rect.top as number], - [rect.left as number, (rect.top as number) + h], - [(rect.left as number) + w, (rect.top as number) + h] + [rect.left, rect.top], + [rect.left + rect.width, rect.top], + [rect.left, rect.top + rect.height], + [rect.left + rect.width, rect.top + rect.height] ]; let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - for (const [cx, cy] of corners) { - const dx = cx - ox, - dy = cy - oy; - const nx = matrix.a * dx + matrix.c * dy + matrix.tx + ox; - const ny = matrix.b * dx + matrix.d * dy + matrix.ty + oy; - minX = Math.min(minX, nx); - maxX = Math.max(maxX, nx); - minY = Math.min(minY, ny); - maxY = Math.max(maxY, ny); + for (const [cornerX, cornerY] of corners) { + const relativeX = cornerX - originX, + relativeY = cornerY - originY; + const transformedX = matrix.a * relativeX + matrix.c * relativeY + matrix.tx + originX; + const transformedY = matrix.b * relativeX + matrix.d * relativeY + matrix.ty + originY; + minX = Math.min(minX, transformedX); + maxX = Math.max(maxX, transformedX); + minY = Math.min(minY, transformedY); + maxY = Math.max(maxY, transformedY); } return { From f04fdfc9c87bc8e612879c93f2de88a999346548 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 00:52:11 +0300 Subject: [PATCH 08/29] ci: use separate comment tag for browser-env tests --- .github/workflows/browser-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/browser-env.yml b/.github/workflows/browser-env.yml index 22090b80b..05f7324b0 100644 --- a/.github/workflows/browser-env.yml +++ b/.github/workflows/browser-env.yml @@ -91,7 +91,7 @@ jobs: uses: thollander/actions-comment-pull-request@v3 with: message: ${{ env.PR_COMMENT }} - comment-tag: testplane_results + comment-tag: testplane_browser_env_results - name: Fail the job if any Testplane job is failed if: ${{ steps.testplane.outcome != 'success' }} From 3fd262bbb67617b265d407bc06629acbba5d83fe Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 00:52:31 +0300 Subject: [PATCH 09/29] chore: do not collect coverage for browser-env tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e86c88de3..9829688c0 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "reformat": "eslint --fix . && prettier --write .", "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", "test-unit": "npm run test-unit:generate-fixtures && _mocha \"test/!(integration|e2e|browser-env)/**/*.[jt]s\"", - "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|e2e)/**/*.[jt]s\"", + "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", "test-integration": "TS_NODE_TRANSPILE_ONLY=1 mocha -r ts-node/register test/integration/*/**", From 36411e9c4d6736019edde241502892bf6b2f2ee9 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 01:01:47 +0300 Subject: [PATCH 10/29] test: tiny fixes of browser-env tests and removing unnecessary console log --- package-lock.json | 71 +++++++++++++------ package.json | 6 +- test/browser-env/testplane.config.ts | 6 +- .../computeSafeArea.testplane.ts | 2 - .../scrollToCaptureAreaIfNeeded.testplane.ts | 19 +++-- 5 files changed, 68 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6baeb68f4..ec6ef0c91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -114,7 +114,7 @@ "eslint-config-prettier": "8.7.0", "execa": "5.1.1", "glob-extra": "5.0.2", - "html-reporter": "11.8.3", + "html-reporter": "11.9.3", "husky": "0.11.4", "js-levenshtein": "1.1.6", "jsdom": "^24.0.0", @@ -6830,6 +6830,16 @@ "node": ">=10" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/defined": { "version": "1.0.0", "dev": true, @@ -9377,9 +9387,9 @@ "license": "MIT" }, "node_modules/html-reporter": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/html-reporter/-/html-reporter-11.8.3.tgz", - "integrity": "sha512-wJh7JxRuT+xvgLRUZ+iIXSFhwoSK1KVbsIkscaetB4eVZN0+PDpUzQhrFLGgRT2VXGrJmNZJDPZJ4AClxydBfg==", + "version": "11.9.3", + "resolved": "https://registry.npmjs.org/html-reporter/-/html-reporter-11.9.3.tgz", + "integrity": "sha512-PGqkeCwJg5m8byPt2Y5o/QjjrT//6V75c6GfbwtkT3NjqLIedKOCB6t5J/0AE2n46xLBXVMQSK2aSdaH4KCr0A==", "dev": true, "license": "MIT", "workspaces": [ @@ -9412,7 +9422,7 @@ "looks-same": "^10.0.1", "nested-error-stacks": "^2.1.0", "npm-which": "^3.0.1", - "opener": "^1.4.3", + "open": "^8.4.2", "ora": "^5.4.1", "p-queue": "^5.0.0", "qs": "^6.9.1", @@ -11984,14 +11994,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ora": { @@ -20738,6 +20756,12 @@ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, "defined": { "version": "1.0.0", "dev": true @@ -22394,9 +22418,9 @@ "dev": true }, "html-reporter": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/html-reporter/-/html-reporter-11.8.3.tgz", - "integrity": "sha512-wJh7JxRuT+xvgLRUZ+iIXSFhwoSK1KVbsIkscaetB4eVZN0+PDpUzQhrFLGgRT2VXGrJmNZJDPZJ4AClxydBfg==", + "version": "11.9.3", + "resolved": "https://registry.npmjs.org/html-reporter/-/html-reporter-11.9.3.tgz", + "integrity": "sha512-PGqkeCwJg5m8byPt2Y5o/QjjrT//6V75c6GfbwtkT3NjqLIedKOCB6t5J/0AE2n46xLBXVMQSK2aSdaH4KCr0A==", "dev": true, "requires": { "@gemini-testing/commander": "^2.15.3", @@ -22422,7 +22446,7 @@ "looks-same": "^10.0.1", "nested-error-stacks": "^2.1.0", "npm-which": "^3.0.1", - "opener": "^1.4.3", + "open": "^8.4.2", "ora": "^5.4.1", "p-queue": "^5.0.0", "qs": "^6.9.1", @@ -24083,11 +24107,16 @@ "mimic-fn": "^2.1.0" } }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } }, "ora": { "version": "5.4.1", diff --git a/package.json b/package.json index 9829688c0..969feadf6 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,8 @@ "test-e2e:run-tests": "node bin/testplane --config test/e2e/testplane.config.ts", "test-e2e:generate-fixtures": "node bin/testplane --config test/e2e/fixtures/basic-report/testplane.config.ts || true", "test-e2e:gui": "node bin/testplane --config test/e2e/testplane.config.ts gui", - "test-browser-env": "NODE_OPTIONS='-r tsconfig-paths/register' TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane --config test/browser-env/testplane.config.ts", - "test-browser-env:gui": "NODE_OPTIONS='-r tsconfig-paths/register' TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane gui --config test/browser-env/testplane.config.ts", + "test-browser-env": "TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane -r tsconfig-paths/register --config test/browser-env/testplane.config.ts", + "test-browser-env:gui": "TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane gui -r tsconfig-paths/register --config test/browser-env/testplane.config.ts", "toc": "doctoc docs --title '### Contents'", "precommit": "npm run lint", "prepack": "npm run clean && npm run build", @@ -173,7 +173,7 @@ "eslint-config-prettier": "8.7.0", "execa": "5.1.1", "glob-extra": "5.0.2", - "html-reporter": "11.8.3", + "html-reporter": "11.9.3", "husky": "0.11.4", "js-levenshtein": "1.1.6", "jsdom": "^24.0.0", diff --git a/test/browser-env/testplane.config.ts b/test/browser-env/testplane.config.ts index c3990b2e1..2cc562027 100644 --- a/test/browser-env/testplane.config.ts +++ b/test/browser-env/testplane.config.ts @@ -8,7 +8,7 @@ export default { gridUrl: shouldUseLocalBrowser ? "local" : "http://127.0.0.1:4444/", baseUrl: shouldUseLocalBrowser ? "http://localhost:5173" : "http://host.docker.internal:5173", sessionsPerBrowser: 1, - testsPerSession: 10, + testsPerSession: 50, screenshotsDir: "test/browser-env/screens", @@ -33,10 +33,11 @@ export default { }, }, + headless: !shouldUseLocalBrowser, + browsers: { chrome: { windowSize: { width: 1280, height: 1000 }, - headless: !shouldUseLocalBrowser, desiredCapabilities: { browserName: "chrome", "goog:chromeOptions": { @@ -47,7 +48,6 @@ export default { waitTimeout: 3000, }, "chrome-mobile-dpr3": { - headless: !shouldUseLocalBrowser, desiredCapabilities: { browserName: "chrome", "goog:chromeOptions": { diff --git a/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts b/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts index 12eed8543..39e4f4c58 100644 --- a/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/computeSafeArea.testplane.ts @@ -125,8 +125,6 @@ describe("computeSafeArea", () => { visualizeCaptureSpecs(captureSpecs); visualizeSafeArea(safeArea.top, safeArea.height); await browser.assertView("compute-safe-area-target-element-inside-fixed"); - - console.log(logger.log); }); it("should handle sticky header with shadow", async ({ browser }) => { diff --git a/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts b/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts index b02b6256f..078c892b8 100644 --- a/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts +++ b/test/browser-env/tests/desktop/screenshooter/scrollToCaptureAreaIfNeeded.testplane.ts @@ -14,12 +14,12 @@ function clientRectSnapshot(el: Element): { top: number; left: number; width: nu function expectClientRectClose( a: { top: number; left: number; width: number; height: number }, b: { top: number; left: number; width: number; height: number }, - tol = 1, + tolerance = 1, ): void { - expect(a.top).toBeCloseTo(b.top, tol); - expect(a.left).toBeCloseTo(b.left, tol); - expect(a.width).toBeCloseTo(b.width, tol); - expect(a.height).toBeCloseTo(b.height, tol); + expect(a.top).toBeCloseTo(b.top, tolerance); + expect(a.left).toBeCloseTo(b.left, tolerance); + expect(a.width).toBeCloseTo(b.width, tolerance); + expect(a.height).toBeCloseTo(b.height, tolerance); } function coveringFullTop(selectors: string[]): number { @@ -45,11 +45,16 @@ describe("scrollToCaptureAreaIfNeeded", () => { const { default: html } = await import("./fixtures/scroll-to-capture/below-fold-window.html?raw"); document.body.innerHTML = html; + expect(() => scrollToCaptureAreaIfNeeded([".target"], false)).toThrow(OutsideOfViewportError); + }); + + it("should not try to scroll when the target is outside the viewport and captureElementFromTop is false", async () => { + const { default: html } = await import("./fixtures/scroll-to-capture/below-fold-window.html?raw"); + document.body.innerHTML = html; + const target = document.querySelector(".target")!; const before = clientRectSnapshot(target); - expect(() => scrollToCaptureAreaIfNeeded([".target"], false)).toThrow(OutsideOfViewportError); - expectClientRectClose(clientRectSnapshot(target), before); expect(window.scrollY).toBe(0); }); From 199e206ec1a2e1de2c9fd3a3d02395e3a2e1b2ce Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 01:24:43 +0300 Subject: [PATCH 11/29] fix: add a few explanatory comments and fix a typo in image class --- .../screen-shooter/composite-image/debug-utils.ts | 11 +++++++---- src/browser/screen-shooter/composite-image/index.ts | 4 +--- src/image.ts | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/browser/screen-shooter/composite-image/debug-utils.ts b/src/browser/screen-shooter/composite-image/debug-utils.ts index b5c6f8040..cef6593f7 100644 --- a/src/browser/screen-shooter/composite-image/debug-utils.ts +++ b/src/browser/screen-shooter/composite-image/debug-utils.ts @@ -13,12 +13,15 @@ export type ViewportDebugRect = { color: DebugRectColor; }; -/* This file is used for debugging purposes only, to produce images with capture areas, safe areas, etc. visible when TESTPLANE_DEBUG_SCREENSHOTS is set */ +/* +This file is used for debugging purposes only, to produce images with capture areas, safe areas, etc. visible when TESTPLANE_DEBUG_SCREENSHOTS is set +Green frame means safe area, red means area we want to capture. +*/ export const COMPOSITE_IMAGE_DEBUG_COLORS = { - safeArea: { r: 0, g: 255, b: 0, a: 255 }, - captureSpecVisible: { r: 255, g: 0, b: 0, a: 255 }, - visibleCoveringRect: { r: 255, g: 105, b: 180, a: 255 }, + safeArea: { r: 0, g: 255, b: 0, a: 255 }, // green + captureSpecVisible: { r: 255, g: 0, b: 0, a: 255 }, // red + visibleCoveringRect: { r: 255, g: 105, b: 180, a: 255 }, // pink } as const; const initJsquashPromise = new Promise(resolve => { diff --git a/src/browser/screen-shooter/composite-image/index.ts b/src/browser/screen-shooter/composite-image/index.ts index 68efe9a87..7d7e13511 100644 --- a/src/browser/screen-shooter/composite-image/index.ts +++ b/src/browser/screen-shooter/composite-image/index.ts @@ -313,9 +313,7 @@ export class CompositeImage { } private _shouldTreatHeightChangeAsStartShift(heightDelta: number | null): heightDelta is number { - const shouldShiftFromStart = true; - - return shouldShiftFromStart && typeof heightDelta === "number" && heightDelta > 0; + return typeof heightDelta === "number" && heightDelta > 0; } private _isRenderableCaptureSpec(spec: CaptureSpec<"viewport", "device">): boolean { diff --git a/src/image.ts b/src/image.ts index 8ec419633..2b951847c 100644 --- a/src/image.ts +++ b/src/image.ts @@ -139,10 +139,10 @@ export class Image { let bufferPointer = 0; let sourceOffset = (rect.top * this._width + rect.left) * RGBA_CHANNELS; - const actualWIdth = Math.min(rect.width, this._width - rect.left); + const actualWidth = Math.min(rect.width, this._width - rect.left); const actualHeight = Math.min(rect.height, this._height - rect.top); - const bytesToCopy = actualWIdth * RGBA_CHANNELS; + const bytesToCopy = actualWidth * RGBA_CHANNELS; const bytesToIterate = this._width * RGBA_CHANNELS; for (let i = 0; i < actualHeight; i++) { @@ -153,7 +153,7 @@ export class Image { } this._imgData = imgData.subarray(0, bufferPointer); - this._width = actualWIdth; + this._width = actualWidth; this._height = actualHeight; } From 0a0d5b332b6ae08a875cd0be4ccaea1dd96d9e29 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 17 Apr 2026 01:27:37 +0300 Subject: [PATCH 12/29] test: commit composite-image fixtures instead of generating them on the fly each time --- .gitignore | 2 - package.json | 2 +- .../composite-image/fixtures/data.json | 952 ++++++++++++++++++ .../chunks/0.png | Bin 0 -> 15200 bytes .../chunks/1.png | Bin 0 -> 9970 bytes .../chunks/2.png | Bin 0 -> 9970 bytes .../chunks/3.png | Bin 0 -> 9970 bytes .../expected.png | Bin 0 -> 7655 bytes .../full-page.png | Bin 0 -> 7655 bytes .../chunks/0.png | Bin 0 -> 4160 bytes .../chunks/1.png | Bin 0 -> 4873 bytes .../chunks/2.png | Bin 0 -> 4668 bytes .../chunks/3.png | Bin 0 -> 7362 bytes .../chunks/4.png | Bin 0 -> 6364 bytes .../expected.png | Bin 0 -> 5056 bytes .../full-page.png | Bin 0 -> 17563 bytes .../chunks/0.png | Bin 0 -> 10951 bytes .../chunks/1.png | Bin 0 -> 10653 bytes .../chunks/2.png | Bin 0 -> 10248 bytes .../chunks/3.png | Bin 0 -> 9222 bytes .../expected.png | Bin 0 -> 6700 bytes .../full-page.png | Bin 0 -> 20040 bytes .../chunks/0.png | Bin 0 -> 4193 bytes .../chunks/1.png | Bin 0 -> 5350 bytes .../chunks/2.png | Bin 0 -> 6427 bytes .../chunks/3.png | Bin 0 -> 6251 bytes .../chunks/4.png | Bin 0 -> 6364 bytes .../expected.png | Bin 0 -> 5056 bytes .../full-page.png | Bin 0 -> 17563 bytes .../chunks/0.png | Bin 0 -> 6491 bytes .../expected.png | Bin 0 -> 1960 bytes .../full-page.png | Bin 0 -> 17613 bytes .../single-chunk-in-view/chunks/0.png | Bin 0 -> 12810 bytes .../single-chunk-in-view/expected.png | Bin 0 -> 5056 bytes .../single-chunk-in-view/full-page.png | Bin 0 -> 12810 bytes .../chunks/0.png | Bin 0 -> 9913 bytes .../expected.png | Bin 0 -> 3499 bytes .../full-page.png | Bin 0 -> 12810 bytes .../chunks/0.png | Bin 0 -> 10645 bytes .../expected.png | Bin 0 -> 3959 bytes .../full-page.png | Bin 0 -> 12810 bytes .../chunks/0.png | Bin 0 -> 12072 bytes .../expected.png | Bin 0 -> 4419 bytes .../full-page.png | Bin 0 -> 12810 bytes .../chunks/0.png | Bin 0 -> 9488 bytes .../expected.png | Bin 0 -> 2340 bytes .../full-page.png | Bin 0 -> 17899 bytes .../two-chunks-relax-lower-top/chunks/0.png | Bin 0 -> 7240 bytes .../two-chunks-relax-lower-top/chunks/1.png | Bin 0 -> 4768 bytes .../two-chunks-relax-lower-top/expected.png | Bin 0 -> 4560 bytes .../two-chunks-relax-lower-top/full-page.png | Bin 0 -> 17563 bytes .../chunks/0.png | Bin 0 -> 6010 bytes .../chunks/1.png | Bin 0 -> 5944 bytes .../expected.png | Bin 0 -> 4493 bytes .../full-page.png | Bin 0 -> 17563 bytes .../fixtures/two-chunks-with-gap/chunks/0.png | Bin 0 -> 5151 bytes .../fixtures/two-chunks-with-gap/chunks/1.png | Bin 0 -> 7684 bytes .../fixtures/two-chunks-with-gap/expected.png | Bin 0 -> 4553 bytes .../two-chunks-with-gap/full-page.png | Bin 0 -> 17563 bytes .../fixtures/two-equal-chunks/chunks/0.png | Bin 0 -> 12810 bytes .../fixtures/two-equal-chunks/chunks/1.png | Bin 0 -> 12810 bytes .../fixtures/two-equal-chunks/expected.png | Bin 0 -> 5056 bytes .../fixtures/two-equal-chunks/full-page.png | Bin 0 -> 12810 bytes 63 files changed, 953 insertions(+), 3 deletions(-) create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/data.json create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/2.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/3.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/2.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/3.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/4.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/2.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/3.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/2.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/3.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/4.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-in-view/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-in-view/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-in-view/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-bottom/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-bottom/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-bottom/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top-and-bottom/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top-and-bottom/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top-and-bottom/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/full-page.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/chunks/0.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/chunks/1.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/expected.png create mode 100644 test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/full-page.png diff --git a/.gitignore b/.gitignore index 0c27a1d03..83d2c85da 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,3 @@ testplane/** testplane-report/** *.tsbuildinfo test/browser-env/report/** -test/src/browser/screen-shooter/composite-image/fixtures/** -!test/src/browser/screen-shooter/composite-image/fixtures/generate.ts diff --git a/package.json b/package.json index 969feadf6..5510b0f16 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "lint": "eslint --cache . && prettier --check .", "reformat": "eslint --fix . && prettier --write .", "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", - "test-unit": "npm run test-unit:generate-fixtures && _mocha \"test/!(integration|e2e|browser-env)/**/*.[jt]s\"", + "test-unit": "_mocha \"test/!(integration|e2e|browser-env)/**/*.[jt]s\"", "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/data.json b/test/src/browser/screen-shooter/composite-image/fixtures/data.json new file mode 100644 index 000000000..d6dca3460 --- /dev/null +++ b/test/src/browser/screen-shooter/composite-image/fixtures/data.json @@ -0,0 +1,952 @@ +[ + { + "id": "single-chunk-in-view", + "fullPage": "single-chunk-in-view/full-page.png", + "expected": "single-chunk-in-view/expected.png", + "chunks": [ + { + "file": "single-chunk-in-view/chunks/0.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "single-chunk-slightly-out-of-view", + "fullPage": "single-chunk-slightly-out-of-view/full-page.png", + "expected": "single-chunk-slightly-out-of-view/expected.png", + "chunks": [ + { + "file": "single-chunk-slightly-out-of-view/chunks/0.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 800, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 800, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "single-chunk-completely-out-of-view", + "fullPage": "single-chunk-completely-out-of-view/full-page.png", + "expected": "single-chunk-completely-out-of-view/expected.png", + "chunks": [ + { + "file": "single-chunk-completely-out-of-view/chunks/0.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 1100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 1100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "single-chunk-safe-area-expansion-top", + "fullPage": "single-chunk-safe-area-expansion-top/full-page.png", + "expected": "single-chunk-safe-area-expansion-top/expected.png", + "chunks": [ + { + "file": "single-chunk-safe-area-expansion-top/chunks/0.png", + "safeArea": { + "top": 300, + "height": 724 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "single-chunk-safe-area-expansion-bottom", + "fullPage": "single-chunk-safe-area-expansion-bottom/full-page.png", + "expected": "single-chunk-safe-area-expansion-bottom/expected.png", + "chunks": [ + { + "file": "single-chunk-safe-area-expansion-bottom/chunks/0.png", + "safeArea": { + "top": 0, + "height": 424 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "single-chunk-safe-area-expansion-top-and-bottom", + "fullPage": "single-chunk-safe-area-expansion-top-and-bottom/full-page.png", + "expected": "single-chunk-safe-area-expansion-top-and-bottom/expected.png", + "chunks": [ + { + "file": "single-chunk-safe-area-expansion-top-and-bottom/chunks/0.png", + "safeArea": { + "top": 300, + "height": 324 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "two-chunks-with-gap", + "fullPage": "two-chunks-with-gap/full-page.png", + "expected": "two-chunks-with-gap/expected.png", + "chunks": [ + { + "file": "two-chunks-with-gap/chunks/0.png", + "safeArea": { + "top": 0, + "height": 400 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "two-chunks-with-gap/chunks/1.png", + "safeArea": { + "top": 0, + "height": 800 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "two-chunks-relax-upper-bottom", + "fullPage": "two-chunks-relax-upper-bottom/full-page.png", + "expected": "two-chunks-relax-upper-bottom/expected.png", + "chunks": [ + { + "file": "two-chunks-relax-upper-bottom/chunks/0.png", + "safeArea": { + "top": 0, + "height": 400 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "two-chunks-relax-upper-bottom/chunks/1.png", + "safeArea": { + "top": 0, + "height": 400 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "two-chunks-relax-lower-top", + "fullPage": "two-chunks-relax-lower-top/full-page.png", + "expected": "two-chunks-relax-lower-top/expected.png", + "chunks": [ + { + "file": "two-chunks-relax-lower-top/chunks/0.png", + "safeArea": { + "top": 100, + "height": 400 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "two-chunks-relax-lower-top/chunks/1.png", + "safeArea": { + "top": 100, + "height": 400 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -300, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "two-equal-chunks", + "fullPage": "two-equal-chunks/full-page.png", + "expected": "two-equal-chunks/expected.png", + "chunks": [ + { + "file": "two-equal-chunks/chunks/0.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "two-equal-chunks/chunks/1.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "multiple-overlapping-chunks-with-safe-areas", + "fullPage": "multiple-overlapping-chunks-with-safe-areas/full-page.png", + "expected": "multiple-overlapping-chunks-with-safe-areas/expected.png", + "chunks": [ + { + "file": "multiple-overlapping-chunks-with-safe-areas/chunks/0.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-overlapping-chunks-with-safe-areas/chunks/1.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-overlapping-chunks-with-safe-areas/chunks/2.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 0, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 0, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-overlapping-chunks-with-safe-areas/chunks/3.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-overlapping-chunks-with-safe-areas/chunks/4.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "multiple-chunks-with-horizontal-shifts", + "fullPage": "multiple-chunks-with-horizontal-shifts/full-page.png", + "expected": "multiple-chunks-with-horizontal-shifts/expected.png", + "chunks": [ + { + "file": "multiple-chunks-with-horizontal-shifts/chunks/0.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-chunks-with-horizontal-shifts/chunks/1.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 100, + "top": 100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 100, + "top": 100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-chunks-with-horizontal-shifts/chunks/2.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 50, + "top": 0, + "width": 500, + "height": 500 + }, + "visible": { + "left": 50, + "top": 0, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-chunks-with-horizontal-shifts/chunks/3.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 190, + "top": -100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 190, + "top": -100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "multiple-chunks-with-horizontal-shifts/chunks/4.png", + "safeArea": { + "top": 0, + "height": 300 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [] + } + ] + }, + { + "id": "multiple-chunks-with-safe-areas-and-ignore-areas", + "fullPage": "multiple-chunks-with-safe-areas-and-ignore-areas/full-page.png", + "expected": "multiple-chunks-with-safe-areas-and-ignore-areas/expected.png", + "chunks": [ + { + "file": "multiple-chunks-with-safe-areas-and-ignore-areas/chunks/0.png", + "safeArea": { + "top": 100, + "height": 224 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [ + { + "left": 300, + "top": 0, + "width": 100, + "height": 400 + } + ] + }, + { + "file": "multiple-chunks-with-safe-areas-and-ignore-areas/chunks/1.png", + "safeArea": { + "top": 100, + "height": 224 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 0, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": 0, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [ + { + "left": 300, + "top": -100, + "width": 100, + "height": 400 + } + ] + }, + { + "file": "multiple-chunks-with-safe-areas-and-ignore-areas/chunks/2.png", + "safeArea": { + "top": 100, + "height": 224 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -100, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -100, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [ + { + "left": 300, + "top": -200, + "width": 100, + "height": 400 + } + ] + }, + { + "file": "multiple-chunks-with-safe-areas-and-ignore-areas/chunks/3.png", + "safeArea": { + "top": 100, + "height": 224 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + }, + "visible": { + "left": 200, + "top": -200, + "width": 500, + "height": 500 + } + } + ], + "ignoreBoundingRects": [ + { + "left": 300, + "top": -300, + "width": 100, + "height": 400 + } + ] + } + ] + }, + { + "id": "duplicate-chunks-with-offscreen-zero-visible-spec", + "fullPage": "duplicate-chunks-with-offscreen-zero-visible-spec/full-page.png", + "expected": "duplicate-chunks-with-offscreen-zero-visible-spec/expected.png", + "chunks": [ + { + "file": "duplicate-chunks-with-offscreen-zero-visible-spec/chunks/0.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": 120, + "width": 500, + "height": 420 + }, + "visible": { + "left": 200, + "top": 120, + "width": 500, + "height": 420 + } + }, + { + "full": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + }, + "visible": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "duplicate-chunks-with-offscreen-zero-visible-spec/chunks/1.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -500, + "width": 500, + "height": 420 + }, + "visible": { + "left": 200, + "top": -500, + "width": 500, + "height": 0 + } + }, + { + "full": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + }, + "visible": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "duplicate-chunks-with-offscreen-zero-visible-spec/chunks/2.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -800, + "width": 500, + "height": 420 + }, + "visible": { + "left": 200, + "top": -800, + "width": 500, + "height": 0 + } + }, + { + "full": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + }, + "visible": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + } + } + ], + "ignoreBoundingRects": [] + }, + { + "file": "duplicate-chunks-with-offscreen-zero-visible-spec/chunks/3.png", + "safeArea": { + "top": 0, + "height": 1024 + }, + "captureSpecs": [ + { + "full": { + "left": 200, + "top": -800, + "width": 500, + "height": 420 + }, + "visible": { + "left": 200, + "top": -800, + "width": 500, + "height": 0 + } + }, + { + "full": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + }, + "visible": { + "left": 200, + "top": 620, + "width": 500, + "height": 260 + } + } + ], + "ignoreBoundingRects": [] + } + ] + } +] diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..d61353c6a9ad7d084e538e92968f17c395e5122c GIT binary patch literal 15200 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 c_C9LN%9h%kJ`zsKpGOol<)_rIGH`{*W00000 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0ac7161ae49ad2dfb6a7221cfafe3e54262e21 GIT binary patch literal 9970 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/2.png b/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/2.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0ac7161ae49ad2dfb6a7221cfafe3e54262e21 GIT binary patch literal 9970 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/3.png b/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/chunks/3.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0ac7161ae49ad2dfb6a7221cfafe3e54262e21 GIT binary patch literal 9970 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/duplicate-chunks-with-offscreen-zero-visible-spec/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f99467f3c2304641e5497d043b80c5ec379f436e GIT binary patch literal 7655 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..2e39a934cb4fa6acfa3b86194945730777021441 GIT binary patch literal 4873 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 G&-@2UUgnhm literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/2.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/2.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0aaab5504fa4ddcc510d93274a14b56f9d88d7 GIT binary patch literal 4668 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 Kv#nqYGxom-SqpOj literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/3.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/3.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd453a9b8342c905c6e6193ab2387eb03d96970 GIT binary patch literal 7362 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/4.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/chunks/4.png new file mode 100644 index 0000000000000000000000000000000000000000..8a030c988b4efc716cc871e8b21c5bd2bacc4d4c GIT binary patch literal 6364 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 WRr)HU^1&-XhJ|k5T>c5|@P7eh(*#if literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-horizontal-shifts/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..a6693004501203727cea31c9d479deb83a744ef0 GIT binary patch literal 5056 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..e125f26a5cc14ca2f2d1eeb42ed8a30bc30cdba5 GIT binary patch literal 10951 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 FzX4rt-KPKm literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/2.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/2.png new file mode 100644 index 0000000000000000000000000000000000000000..9e0de5d349955967d3d659ddb263abb305c08b27 GIT binary patch literal 10248 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/3.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/chunks/3.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2d273b547912a99736e71b1479da2383339583 GIT binary patch literal 9222 zcmeHNYgki98lD711;J{oDRR+Oyi^3lh$Wf??P?>%TIh|YV${-lv{DQSm_#rHty)bB z3MxiJ=oYoDT6~l$P(cvU$StSZN{m7huBUaCgkT8-lI%&#%>LhB`|Kt^=A3-bJMVet z`@Wg^&LoH8*K>TmXLthud}G(Hej5N!^41ef@FFkSL81Eqn9~xwdeysP-qVLWQUi3; zUQd`j`&NT-_ty%!$F0S=Kb*+pWxe}=7w|z$e){97+^VYK8+KES)9yzSBt0%KbdDo$ z_$(J6n6TK@u9Q(+7wRNe`@&{dD+3;`i|5O(c2=#c1r&D|x5xhDgsCkzYp6VMjyhxd6og_t=uWve!GU=wEmqEzy*1$ve z^PA`yY!8B9ozZ|=JubEccLwyqUXtd&BLMp#xb1ax5p54##-7av{DfLNc#nAq4F|8EQ!ycva?Shau;==2a4iO5gL z`xsI^6)aP6`&#ICbV$`t%0t9)PXEQUd59_;>)`g>V+xf>)!rt5@p{R0JQzc&+63vU z1XTKA1$hhK&>Y`XS2-W2jdqvSvJm&#HaX_w=%(MS zMou`>wvX`U5oI@7$W+pH3iIB@p3`;;K5uqom_%jVll6YZT$qk?kCCZyQ$5to4}}_h z7L*$qd+~l<$88|T0vzWh$ot$+H3j3ykBjy<+vs#BHAYlb$`qw58H}~_9uz98qMh;=t zb+M4JIDMyo4q@@{4udH9+yH!h;68kI0HivbU(=sbdwFP`0iR(bw2F1AKYQ)rXrdd*Q>1jF!nDS5leD`HK?=!yWRjvxKI04x2_Ios{gw&RQWdogH%IBr>&DK#$gSWD82R&J=Gqm4GO`( z!*5_n46;oAHDv*$x*}rh=|+_@l0d3{E0SA%#GY77B~m3JI;yF`4GLi}Ql)2zi)9#p zP>ECtL|OVdMul>f8mW31blN&Tnu^`Kj8tW)d#Wk9^@{W)MAaTC*(94ISQdm-EfF#G zFB$9Ik`0LJ;WKd$9i0{YbcBWchiZ&iz{K_AW?iG-%O))C1MAXu#!kwTMC>xj4r1mn69 zHZ(OocwF^5z`G_%PeUJnbalW6n8jsc~bGYzq zr)g4r0<#NZ9`lg8JayGjxDkJg^hn$sm6g)TRYr~ zH})?{zipT(dtA{e`h3jg=~v}HKakD@sisd2(-2|!szlpHP;n`A4~7UU!NwjdFs7AS z+To(QvBM(VZ=lGCiaOC3kZ@3r>$0UlWqN9W721781PgQMDA6bA+22A!tlF&ngYYs| zXl(5tjjeV?{a1u{iv4B6=q?f5BGRwPH99E|XowU8%+~vga0X`MQliW0dk92WX;k(Q zp2p=GOFLX$iaG?s1I1HhJC@%P9f1m;%UkYcvq7opH^Uk@hBOLCFD#><9ufZ3TKW{cI zg+MOt1ZJ-W{0Q8JHc(X>S8~TN5#*V_G(|(;J=$@Oa}O|Y%X5@M#$ZXTq}wnK;Lq=x zm=KsiJI1lI0RN>tTOR_ZF(mZ{3gA5d!n6_s^|XRa=P=->TOHv`$I`w}@=7I9>x7tz>FwMVGO}a6WpJ!SNfvvQo8=Mlrk1BVRLSU+7Vr5V9IFPuj z$+Qjv-=`hfU}u2%v&( zdCKFe@W_w*7>IO&`xMNT3hqNd(h2S}P**CrkAO)hxDU-qC%AtzaLotzPbQ=j+@%8P z1b3<6nh)+$fpmhqRB)w&yHp^Z;4T$NC%8)m*L?WDE)^Vx+#ny97baQCgYPcSp8z(m zbbYOrxmp?J&;OrzP+ecVJYDUi39k0#7hLV)S+4efwFBi1zqTaX)a0wKLB_6Gzq<6b H&3pd^%t?AV literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-chunks-with-safe-areas-and-ignore-areas/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ab8de02da76af4e6cde8ff4104421df9efd188d9 GIT binary patch literal 6700 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 J^3CpJ{{>!~7$X1x literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..7012fc60081cdf68fd8433d6001449d089a2ca27 GIT binary patch literal 4193 zcmeHK{Z|uL8XnuO>k;WzPLFP=9JCDeBN#k{iYy8&(#Q>zgII$IA#AZEo^`PZ5&{J1 zhuw7(Fx(;(jY;$48LYwt@J+zE_-O?a#dNJ<{}V{`98_bzSwdnm@gjvopKmNMP#W-M3Vuqda_awkXgMgOA9= z9PhOf@iHQ7vc1=phZPT2`e0=*{LapU%8t%|qM)q=DLaM6jTYt4+b8Ss=Oe3;%9u#M z|Kz)r6+x9K=zHc6?m?8B&i*>@u2`%>Aj)lYIU<%Ltsdo)%TtGfg3})LZUlM#z?aY$A2K>-K(#TJHs6*#vI1MsnMFD&NBdu$gyGSL%x(w`g+X(~e2#)4`*ZC>g0^@L=4%BOPZC7iN9foQlK8x&!}{Ga@odR8 zT?R><7WzhuPvXki2_6Q6TTY44N74s*V?c$wI3*?^@G#5od4r{Ky+ z5J+Wbv`3M&O^m?CofWv}^p>%xd&KnqnU}%_oen&)qZxWS1q|KNxUc-bIIy`h%1i=B z-wYd^bg*IJgSnCje+2n=(0cz;E{j#Vln0>tz5S z)$?ya)X={kizSo)m*md)SNb4e4hgVNF$rLGn_ODGm;upC12x!Q64>Q)cYIvG6_|Si z+-eG_Q%Q~U7a7#~vov>p9bO>wI&2pK%=t{xEvPeX0p>=-%v2bmF;{a_n(GXK=xM{Ok&3n5 zlIFVhLUcG{NPCyC>U&-(qxK&N`y4 z=~;!WG`9t+MA~QC+e9j@&pzN6j+q$X!WFvy5C!BFv(h|^P-W9PwZD)+=VgBLPeK`b z>E2rGHPXa05|iLOwgvn}efUuTzTF=ueA=<2UfIhYc?UM1q_;Ck!t;#S#s|7{=y4aP zG>y#V3io3cy&SLo?xy+bT|@ymH`i2g+*wf7mth~qKdHQ_TrHvbH!TjM!1Vo0)Q^Oi zBMWiiN8K&}%k%8Qj|juAJ1+}rUjzgLUj2(#Nj^UYtFac_4!%h>mJ^bL#!iK^ooZN{ zWo|f0EP!%ltm7kT&@VA+lH4cFiRNw7QHiPSv;3O`drk2{|I6hk!BNfq8^eT%g!Ygs zsMn%RoSB9^l8W~QYhr{4IosSJ5kyMn(07AOu~2=HX+e+|QTVx*DUY^o!mAajjUgK} zQ?bJo2i2c5wPZtNe!0|Rlc^R8IGzS#{onlTLd99saFOZ62vdDGetpfBi5}O<4LtmF z)@xO3l32+P0=EApEkzUQ{(R;eldVQ&E7;&5`;T!r<|z%BMUkIW7>PVSyj~Jw0t6axOlcd&q zJ{_EA=IbfUcVb&v@SXHlA-PuKz>=r~!h+RPN|N~fq9nx))h}{!C&eNUsORt8zMcOl zpUOhe`9ze+?n)P)plAlCMNc5dNE4Qk5y@brXbN(A28xoYv<5|@Imo%&P?SYRe12uMKrW`p+#1BS)Ok5N(}UPMq)f{ zhytkko{1!QZ(f(Jid_y=uESrx0HS|5hT!i=h;HBfGX8$XL#t@W^0>AO+3bBzja`j+ mNBC0M3dM>S;P==Uvw`9#d*16FI+Wu5wFB=Y$E)MAKmI>t?$e_H literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..28767a16a5e6eb72e159843d3dc1e58010f2ad04 GIT binary patch literal 5350 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 OgnskgI?0-!5Bvx8t@D%s literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/2.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/2.png new file mode 100644 index 0000000000000000000000000000000000000000..62d1c4dc0738d1d772c272d53f93ffb29619f8ff GIT binary patch literal 6427 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 QEhOabu)W(Wx5b_MUwb4ukN^Mx literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/3.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/chunks/3.png new file mode 100644 index 0000000000000000000000000000000000000000..17038de7a9724920ad95ba8297c98b20b19b450e GIT binary patch literal 6251 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 WRr)HU^1&-XhJ|k5T>c5|@P7eh(*#if literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/multiple-overlapping-chunks-with-safe-areas/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..a6693004501203727cea31c9d479deb83a744ef0 GIT binary patch literal 5056 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..1a91781d4b595c4eea4dd57092444c6b65ece9bd GIT binary patch literal 6491 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&zE~RK2WrGXsO9lBbJfNJZS68-|Pw20RTL zewpw6J2haEFy|R&prUiLWr1WvH4l(v;4lD@3I{-B0|Q8!foW6%7z(37GMX5G$zU{p zfQp3Cl3}z=94!+^v%zT708|=|HVsCb2Eb%6+B5)VhS8?MXwzV{OdQPyqfG-)X*k+6 z7;PE=lfh`y0F)UjUqKtU9C-3a{)!#tnl&7no J%Q~loCIHpj#Y_MI literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-completely-out-of-view/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..fdfa109d65caa6424f063371a966067c1b736ccc GIT binary patch literal 1960 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-bottom/full-page.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-bottom/full-page.png new file mode 100644 index 0000000000000000000000000000000000000000..def4242c924857fd5ba85d9f47221eac3fca6405 GIT binary patch literal 12810 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 Zu;-^&)L6~dI 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..150135cc070722a7b4e96354cc1c963fdb04e495 GIT binary patch literal 4419 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 M&zWIO8{?3F1B)r_qW}N^ literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/full-page.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-safe-area-expansion-top/full-page.png new file mode 100644 index 0000000000000000000000000000000000000000..def4242c924857fd5ba85d9f47221eac3fca6405 GIT binary patch literal 12810 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 GKmP+ac_Fm` literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..835d31b86f4c6a460b2c96d7dc40fce714652f3b GIT binary patch literal 2340 zcmW;OSzJ?R8o=Q%a3BjyfXF5Uk+rTYDZ7YA84wYu6{y%^K_IaMB_NR{76_ph5Znf< zL`XQTT{T0&R0J^)*vAI2)%ia%{UjtttS4SYdJ?#h9o+%xl+{jpa!~mk%Z8ckVls$- zexILQKB?Z=4+ew`S_fYIMpq23$1EnA6WO$1LU7LImRB5Y)byWM3?xkv4|C69^*5%> zK#0ApcLrugl!k%ufXA0kawk!(8K^uLVfd|)n714PEc%3+7&A6)=@Cfznm1DKq^4^Y zagr?2`;XidBbTQjj(y_W*-2P^LYE1+EBxo{7f8UKQU}03E&K5|n3=eB5Xc`s&e+MF z3@7Z-;N+B{$~Cq5}WcS2~6{kj*x8C9

wiLaS z&Z+$DAq~vTFD(IMuf^`WxRdFHcrZ4AU4I*9K6ru$OX(j)-a`U-lSZ5tUq4s<;H*W% zL#49QH+&T_{RIZdwVEqO9n>Dmi@2QRG5@d3*|n<^AkZ_9@&Yd&+$;f~+!7nPb0^~q zBZ1&P#_@%j_nvryu7vjWXe06W>L&0q;qlV2J~f@dI-x@uZ7lv?D+LMhPiBYpxi$%S z3F6n$c=7ie3qTg%`O~mIH#dQOeAlp%&NdS?dlj@HrD;^4nO)etjf6GZfb|^4mWLwl z6q%!yznmhjnT$cs`wP@lkj_kLU~#QuH3;64yaK&5u_ZAWx%nVawpUM4)a61;N$|q- zD5QgwkauIpiX9v_cp8V!N<(8YujVsgwmoyyQe7>ymjo`1FF`tEr7_mnvAiAb8hnLQ z&&G;lv5@8xu+kpAXsM1B?vz|uz}6wLtCEl-=n#?NMf9|RrB3|heWi|4TGYM;F$D9Uw`K?zGe2T8j zRGyJZWLs#!I4>kC6ejl`1R>`O`kWO{$4yc^7leUOsPj5bB}ulfM(`PNoB{cXzXzdM&AL6Q$xb0o8mx*hqFK9W+Yb{J!f$Cynj&yRy3S-Xs^`m2SV@; z9=Y;q(yvr_-hyV38C3p>i^7o}n_|Ye<_hsoq9pV;H1{Twcc-W>>jwHzQw}UbJp{%C`Qs^!rxQFMZy)BX) zc$lw-5O>DEk)YUd7ndk3)H!T)+6*#e41)5`&{O30DEo|4P>KxPY{A<>LT+~ z6RW~8;^1*BzPmO8wDY z_v=FQofTPqLf?8`nk`qFkM0rG`Q^JPvIbG#JN9V-Txl!1?{3|`d^bhbi0VZ>@9cYA zsRs2D*SY6=D85ShtbN$DB?R^~%R>|B6{ZkB9`$AL>>pULUigeUW+V=TV^M?0m#XY{ zI>4U$@<#U1%WEM1=36iOlnzu_@E>x_IUtYhA@b+`u<){yu71=+>j7OZ1F%H{FA zdlsxApT!H~nY%4n$9$JoWoh>;Swp@nMY8vITd|JO)>p?*-m_v2(YA`lqjytS+Fg+S z_>p`1=nERZEjENJm<^Y7<23DUq{nbRb%%yjLSYql^D0N3o)&P;y#j4>We(bUq{l%T zaXgsc$u-9Zx+-Ocg>l%7^L#orliWxQZkQILjFA~TxT3bZ0XpxCQDY^;Od)ar@Jq3&8dM$R+5giMPgr2<`u!2 z_!VL>>({+}#t1@&E2ItI&I+y7t_p7sZJFoC?S!btxlLz8{#YZ@b4WTiB_!7DRCw1d zE!RKfO`syTv4@K@bL1Y=^jGx@x(Vz64>vZiosILNQ|cL zki%|V^Xl}21-vOU{T-ZoYgRU_jcqQ^*KFc@-D;+FhUGK*-w%lTM{Ic0;S}zF0XvFj ATL1t6 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/full-page.png b/test/src/browser/screen-shooter/composite-image/fixtures/single-chunk-slightly-out-of-view/full-page.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3be3c1adb2970d37dafa08c3e34e8e5f7a2d82 GIT binary patch literal 17899 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..51ee672b1c184425fcdb74abbc42b9322ea1e702 GIT binary patch literal 7240 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

-fy-SZiU2x=CF{1uHw3uxQtLaqi^(wkf^aV<`lzni34`y!wMm*8j!=gy z0y|+IIs_*eH?w6KBs=)9T+PapFb8;sATPM(u5mSQl#}KMu;v=bsCE5hw(P+uQ^z;J zh%2!S${wBC=jyAAe}Pt|o?p*01gFEz0o&SAEM{aX4ryv2P~BvvteeS95U3&0?-+wZ zR;zu?lL&6Uv^hp(r6gnP80&^rcxa`*91{tMo^Giv|< literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..afd2c20718a0c29b5ac2573d980c61dad0592ee9 GIT binary patch literal 4768 zcmeHJ{Z|uL8opG^v8-}h`(deIw=k$}H0V;rY(hXwg$pfhQz*-p1X^|HxGsJ`wgEyC zvF)}R570qOsUc|(K`UU;x{8L6D6Lf&nptC!B1>>(X^a>GB;hL`>}2Q8ulpAyKjhBb z^WNuupXWaJoqPE0%+zIJFN6UAmcg_X0RW4s#}L<&P-AiTfwpQ8LcTz1Nk$N_xzv7AHT8cYlGK2KdkV3-X}0fU_ym>3K^=mA2y=}kOq|X)$`|}2RY~GQ zUSXO+U}|x?tiz9keUXPZ?62Ua`d4AXjd(xjcL1!bOnLrNN0ipM29 z_my3R3%p_|F-5c~7@!L>XGiR_MR)8cP)uy0k+%mns!Kf#&ep*-WUgQ%KFnuwnM7KA z-D!3FgqxY^6`ioMps70tN6BB73N>f2GwQ>wJpi2DviyU4+or$b<-mD~>Bs(^C@5l( zPi7H(GUBp~spnjwlNW0nQ`Zju2?aed$R-6umo~n*eJKFSn5RP71%v8&ep0Cl_i%#;ji0!9imw5^BE*~E&W`ZuR zBI9dx{i8=^yhY&3{j^Uily`QNiU`-d`a%_>$<2AWrWUiS;%7X}y0cv>D+WE*M?MiE zqiSw-9>r{z)K~KvSTAVJOcUw+3ufbSYLZAsDE9%46048Ho!1%clm2=< z8d`sf@HrR_1Pi^+YMs;C;>Q`NZ)@?FVE@g!PR2ONouiyIv%BacBU5*2QN=MG%epiH z0B=1drCa%~&y!(}YSNCu1=hpE}mU z`Agm0D>U={Gs;^-MlEI=8~3v}&{6-I6Ns&j)v&CEYkV4UmvlZk-(HSoaG4#w-WA=Wb zB?_s)&6AH$L}Bo{_%q4pH0yg0S7@6Ra%i3u`h*|SG%rmxTK}OH5@NmHo4Jv$IM3Z( z+()j5zu%W5YeOmYB?Fi5!1FLHXVv*DSAkXehC-nV&mQ5%vOIW0L<;KGP@pMNd zVwTO`k~60!bRKc7qzaW1raHkY-ww@*?cLlPi0!oUr-39&Jb%4Uhz{5mXXCHE+Bb=x zAND#h1eY84D(=f8bbE1G0q>eL!6PS%O%~m4ssO{0k7s(iC_L!#i%$#j`@kufo znt!gdy{SISi=uCn9r zk#p^_@a}gp!@Ch)1AASnPXq~3-#d=YsN|H+EW3kNG%}y+-N{hlJ^uRgPqoqB(ALtACD) z>&!9!2AR6G<5g67MuP{)kGBQ5{Y7w_vcWE7fut)#4Cs=<-l) z&AeGQGqi^WoHdQ!=PI@nSmCh5auo%(vY*TMEl?i1Aak=f(^bErI$~R>p?cz`&Kjht zR=Ae$u~K1Q@}&tYX(D{X8|5yN$}uT(RidRG#{PM#kif^cECDmd* zD-R}6J;eLhiisDgtiooa@%xaHk+e^)YE_{NlX1|z$upK1eq|-~Y4jVmq!GHY(7+3I z^Ic4xNdSIJ^&ILK61WS4B~*6+Ao*ZOV0etO4ggOU1pW_#MS&r>gc2dBSilNF!%!jw v&kH3&uw4YsL$F&?A_PAclnDRlTREGQQkQLTPW(GOU>W#&W{Q4W!J+>GWG~&@ literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ce1c9cd9459c75d6745ded55a0d9fabe09177412 GIT binary patch literal 4560 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/full-page.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-lower-top/full-page.png new file mode 100644 index 0000000000000000000000000000000000000000..c4346ecbc19bef800264e79f1787838ffc9b218f GIT binary patch literal 17563 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..6499a5420e85b5018f5b74af6e8581d669c3543b GIT binary patch literal 6010 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�kJEUS&5iVC1ow(nE1`0^f1e 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≫y$|K4vQcEKcLsR?FMipR-SWX;wlGx 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 RFe|B}hpfM=IC%Qv{{hOnKXw2B literal 106543 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 O!DOUwu2-+?8vkE7R+P8^ diff --git a/test/integration/screen-shooter/screens/partially-offscreen.png b/test/integration/screen-shooter/screens/partially-offscreen.png index b2ffe725cf083326c8fb1be866ad7d378e0fc615..037ec9f1e310224ccb471da902c67413bbaa0e6f 100644 GIT binary patch literal 3724 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 literal 4005 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 BrP%-g diff --git a/test/integration/screen-shooter/screens/visible-top-long-block-overflow.png b/test/integration/screen-shooter/screens/visible-top-long-block-overflow.png index b99c2320a62ed7342b3a4679e62026172000e237..8e7aa9d2be24827f58342395ccb6b1fb34f777e5 100644 GIT binary patch literal 5699 zcmeAS@N?(olHy`uVBq!ia0y~yVB%z8V7|b?1{B$&@?tdugBX{mi(^Pd+}mphIS&{x z9NF+@e+k!jlbZ{KD%j^&zqfUtq@p>K#dFe^Gb$dFmZYmWPExV0_GM!DVE>nKG6RE8 z{Q(sQhRgB>oD2uPu=_AE7>o*!hRJAx7|ji%MZswCI9fN1R*a*qg3%_?XftuNjXc^x z80{U6_83RI%cEljqXQ+QqeP=4XQRW0gKf;z&g+@KQ2WwNZ-9ft44$rjF6*2UngHvw BbGHBh literal 3718 zcmeAS@N?(olHy`uVBq!ia0y~yVB%n4U>4wD1By8D%~fPz;Pdr#aSW-5dwXpo?*Rjb z!yEqmFR?mqwNT~3QSldZir3GaIrHXjnKU4FVdQ&MBb@0Af+FPyhe` diff --git a/test/integration/screen-shooter/utils.ts b/test/integration/screen-shooter/utils.ts index d9a7e3cbe..f1513ac88 100644 --- a/test/integration/screen-shooter/utils.ts +++ b/test/integration/screen-shooter/utils.ts @@ -3,6 +3,7 @@ import getPort from "get-port"; import path from "node:path"; import fs from "node:fs"; const FIXTURES_DIR = path.join(__dirname, "fixtures"); +const shouldUseLocalBrowser = Boolean(process.env.USE_LOCAL_BROWSER); export const closeServer = (server: http.Server): Promise => new Promise((resolve, reject) => { @@ -37,11 +38,14 @@ export const startFixtureServer = async (): Promise<{ server: http.Server; pageU await new Promise((resolve, reject) => { const onError = (error: Error): void => reject(error); server.once("error", onError); - server.listen(port, "127.0.0.1", () => { + server.listen(port, shouldUseLocalBrowser ? "127.0.0.1" : "0.0.0.0", () => { server.off("error", onError); resolve(); }); }); - return { server, pageUrl: `http://127.0.0.1:${port}` }; + return { + server, + pageUrl: `http://${shouldUseLocalBrowser ? "127.0.0.1" : "host.docker.internal"}:${port}`, + }; }; From 2c35a3c82190458fe851a43df8d6d32c9e31d951 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 15:44:26 +0300 Subject: [PATCH 27/29] test: build browser bundle before test --- .github/workflows/node.js.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index ec5237ccc..f46dbdd09 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,6 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} cache: "npm" - run: npm ci + - run: npm run build-browser-bundle - run: npm test - name: Build From a10119b0c6b623db2c3c574572d0f389c160dbca Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 15:46:55 +0300 Subject: [PATCH 28/29] test: build project before test --- .github/workflows/node.js.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index f46dbdd09..fe3d0c1b4 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,13 +26,9 @@ jobs: node-version: ${{ matrix.node-version }} cache: "npm" - run: npm ci - - run: npm run build-browser-bundle + - run: npm run build - run: npm test - - name: Build - if: ${{ startsWith(matrix.node-version, '20') }} - run: npm run build - - name: Publish if: ${{ startsWith(matrix.node-version, '20') }} run: npx pkg-pr-new publish From 6c2281e56f667c8be3d412666090530ab5611699 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 16:02:38 +0300 Subject: [PATCH 29/29] test: do not run screenshot integration tests in firefox --- .github/workflows/standalone-e2e.yml | 5 ++++- test/integration/screen-shooter/screen-shooter.test.ts | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/standalone-e2e.yml b/.github/workflows/standalone-e2e.yml index 4059a3857..1cd6e20b5 100644 --- a/.github/workflows/standalone-e2e.yml +++ b/.github/workflows/standalone-e2e.yml @@ -40,12 +40,14 @@ jobs: run: npm run build - name: "Prepare screenshot tests: Cache browser docker image" + if: ${{ matrix.browser == 'chrome' }} uses: actions/cache@v3 with: path: ~/.docker/cache key: docker-browser-image-testplane - name: "Prepare screenshot tests: Pull browser docker image" + if: ${{ matrix.browser == 'chrome' }} run: | mkdir -p ~/.docker/cache if [ -f ~/.docker/cache/image.tar ]; then @@ -56,6 +58,7 @@ jobs: fi - name: "Prepare screenshot tests: Run browser docker image" + if: ${{ matrix.browser == 'chrome' }} run: docker run -d --name ${{ env.DOCKER_IMAGE_NAME }} -it --rm --network=host $(which colima >/dev/null || echo --add-host=host.docker.internal:0.0.0.0) yinfra/html-reporter-browsers - name: Run integration tests for ${{ matrix.browser }} @@ -64,7 +67,7 @@ jobs: run: npm run test-integration - name: "Screenshot tests: Stop browser docker image" - if: always() + if: ${{ always() && matrix.browser == 'chrome' }} run: | docker kill ${{ env.DOCKER_IMAGE_NAME }} || true docker rm ${{ env.DOCKER_IMAGE_NAME }} || true diff --git a/test/integration/screen-shooter/screen-shooter.test.ts b/test/integration/screen-shooter/screen-shooter.test.ts index 9d28084da..287857a6b 100644 --- a/test/integration/screen-shooter/screen-shooter.test.ts +++ b/test/integration/screen-shooter/screen-shooter.test.ts @@ -46,6 +46,13 @@ describe("ElementsScreenShooter integration", function () { let pageUrl = ""; let warningSpy: sinon.SinonSpy | null = null; + before(function () { + // Our docker image has chrome only + if (!shouldUseLocalBrowser && BROWSER_CONFIG.desiredCapabilities.browserName !== "chrome") { + this.skip(); + } + }); + beforeEach(async () => { tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), TEMP_DIR_PREFIX)); browser = await launchBrowser({

@m2n41{P`z2S}X;L=FvB3(7GdI?<4=+KG-~ z>d7$R)H#f3Ay%WHs0@hW8u+T+XfGBz83CMBM#R=>@TH(Y2SjJIS*ie3gsE$G11A+5 zad8?P5#$(;TW+BGyf#m@7iD9iHL<|ykqO!9G^i19jKJx#LzZekYEr1r>;O)WP9xDy zMe)m*@`-$JO*|EG5RPBGR7h+DCMHK5gRTZ$z74~2Z#W#wngo*H5dtY&F6Zv4u4MYVyLbK&i!EyJr>O@e3@@R2b1stBc@ z`@>RV9K{{3`>L!_yeK}Kkw@?-6H|JvVT#74&dV~~?l(oJ)h|FJWokDc5LWj_WDO+e zQcemiqtcdKU9M--b3bEtgaDw^&-!T`*LcN^5dhuSEHi%2`c1I&Xe5zVS$f{MkCN`5 z)hxHvbzH#`PhF^LeS{CJ~5CHvJrDyw{g_uoY0O;St z{WM;Ce_F^IBCzdo^7=CLPOJKtND$bcwMeW}iX!Ki7-HxBCtXOYQ?&d0oeCmlE5kSG z%DF4Fw)Ct2Tr==j+9-OBoBNIBLAR5&-S;QkT5}kLj(OZey4&-onu)? z(bZK(dUfXjlkaN~-SsMcjsm3SuuNfGBjsT6i3FQ}A=O&>c)|u$*Xj0b&E{N6J|h}< zWY+eFULE+I8FU-4(o+;>A$d&mpB;F{=FSPMFW)1HK^7Oyj?+mnD%*5pd; zqHB$Uf+ z8(`Y2>zm+=wJ>2F=)r`c9_lvbxe1%W9*~0FT8@T()+OITJ2$3_8uY7Rte;ZY0B&q^ z6;rfgusk`ak_obXV@yGDdO4AHLI<1z95@=kNw0ic2jH~6xKMuzK4{4KBLHBEJ=SCV zQ4aQPh743tM;p@26=CNyKuxXdutOBwT;@S0;1&!?s3-keDP%%I{D zgH6;J^?t1fX!-q)eeUfNB++dv=!_DdmWmr{y)23gq7O;uY62?yLObXn)N*?lOzeYE zirWD6F}EWk|MXnuUPsXKvZ!`y-mDH>Z9&Ha#LLZ3v^`w_hIC1rA#G@g`kg%u00mL{ z+&lIoW3Jl(kTkNTqPW5!V`T%Na5-1ApV=S!a0dXY$#uab84AizY575O!6t$Vm=>lqG6|&9J$Wa_4}8o%`H7OOV9MxeS#BwNyx$ z2H6Q706HY)YC;OO)s*Z?GPH~yroB@!{$qs6FEk-HW53coc zRlF#+N5ASsKjF+jA{8;iMOIP~k+CC^3sjAHVDPSjK9g{%!w7=$K;wNY5mR;Mxy0iV z3RF@_H4JNLLEszx`i})7vpY6z9<{u=#7IVy-yOit z-53QiGh3!ND+J@a%<&};&@WtUtuWXAy<`LvX9CHIB0X|#g^srmoYSUMB`c^lHq3cYiTbaiH3xy<_f%nDoCk!IKT9*~yJybs*`#^Oyb{+V@QTG01_%yi@^ St8V6BKY05t@6xS@zWqPu&Goqe literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..49b20e6fbed290279f56aa4ba8ead7cac6a0e0bd GIT binary patch literal 5944 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/expected.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-relax-upper-bottom/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..6175be932d070ade04db02a75605fc115d40f411 GIT binary patch literal 4493 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..de64376a810cd808adcae1148ddf489fd52dfd3f GIT binary patch literal 5151 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 SWIrn?6f|J_=CV!y`ucx}#^XBx literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/1.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/chunks/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7904ea06e05020ece2f1ea20f5b25ba94d7e4bee GIT binary patch literal 7684 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 TG;YyZG$3kKOvH_qI|cs*$K5Lg literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/full-page.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-chunks-with-gap/full-page.png new file mode 100644 index 0000000000000000000000000000000000000000..c4346ecbc19bef800264e79f1787838ffc9b218f GIT binary patch literal 17563 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 literal 0 HcmV?d00001 diff --git a/test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/chunks/0.png b/test/src/browser/screen-shooter/composite-image/fixtures/two-equal-chunks/chunks/0.png new file mode 100644 index 0000000000000000000000000000000000000000..def4242c924857fd5ba85d9f47221eac3fca6405 GIT binary patch literal 12810 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 Date: Sun, 19 Apr 2026 16:11:31 +0300 Subject: [PATCH 13/29] docs: add info about generating debug images to dev docs --- src/browser/screen-shooter/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/browser/screen-shooter/README.md b/src/browser/screen-shooter/README.md index 05027043e..5efd9e260 100644 --- a/src/browser/screen-shooter/README.md +++ b/src/browser/screen-shooter/README.md @@ -7,6 +7,12 @@ ![](./terminology.svg) +### Debugging + +Screenshots logic is heavily covered by debug logs. You can turn them on by setting `DEBUG` environment variable to `testplane:screenshots*`, various namespaces are available. + +You can also use `TESTPLANE_DEBUG_SCREENSHOTS` environment variable to save viewport images with debug rectangles to a directory (the directory will be created and logged to console). + ### Algorithm overview Overall, we have two stages: coordinates computation and screenshot capturing itself. From d5290d02a1ef05dc33e91c73b1c38c654b1d9159 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sun, 19 Apr 2026 16:12:30 +0300 Subject: [PATCH 14/29] fix: use correct viewport offset for a case when driver returns full-page screenshot --- src/browser/client-scripts/screen-shooter/implementation.ts | 2 ++ src/browser/client-scripts/screen-shooter/types.ts | 1 + src/browser/screen-shooter/elements-screen-shooter.ts | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/browser/client-scripts/screen-shooter/implementation.ts b/src/browser/client-scripts/screen-shooter/implementation.ts index 6e9fb0f4f..f10aa6a61 100644 --- a/src/browser/client-scripts/screen-shooter/implementation.ts +++ b/src/browser/client-scripts/screen-shooter/implementation.ts @@ -168,6 +168,7 @@ export function getCaptureState( visible: fromCssToDevice(roundCoords(spec.visible), pixelRatio) })); const scrollOffset = computeScrollOffset(scrollElement); + const viewportOffset = computeViewportOffset(); logger("scrollOffset:", scrollOffset); @@ -176,6 +177,7 @@ export function getCaptureState( ignoreAreas: ignoreAreas.map(area => fromCssToDevice(roundCoords(area), pixelRatio)), safeArea: fromCssToDevice(roundCoords(safeArea), pixelRatio), scrollOffset: fromCssToDeviceNumber(scrollOffset, pixelRatio), + viewportOffset: fromCssToDevice(floorCoords(viewportOffset), pixelRatio), readableSelectorToScrollDescr, debugLog: logger() }; diff --git a/src/browser/client-scripts/screen-shooter/types.ts b/src/browser/client-scripts/screen-shooter/types.ts index b966b6179..d55580a11 100644 --- a/src/browser/client-scripts/screen-shooter/types.ts +++ b/src/browser/client-scripts/screen-shooter/types.ts @@ -9,6 +9,7 @@ export interface CaptureSpec { export interface CaptureState { scrollOffset: Coord<"page", "device", "y">; + viewportOffset: Point<"page", "device">; captureSpecs: CaptureSpec<"viewport", "device">[]; ignoreAreas: Rect<"viewport", "device">[]; safeArea: YBand<"viewport", "device">; diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index 8a2422192..74e983067 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -369,6 +369,7 @@ export class ElementsScreenShooter { let iterations = 0; let lastState: CaptureState = { captureSpecs: page.captureSpecs, + viewportOffset: page.viewportOffset, scrollOffset: page.scrollOffset, safeArea: page.safeArea, ignoreAreas: page.ignoreAreas, @@ -749,6 +750,7 @@ export class ElementsScreenShooter { let restoreScrollPositionError: Error | null = null; let lastState: CaptureState = { + viewportOffset: page.viewportOffset, captureSpecs: page.captureSpecs, scrollOffset: page.scrollOffset, safeArea: page.safeArea, @@ -789,7 +791,7 @@ export class ElementsScreenShooter { // const viewport = { ...page.viewportSize, ...page.viewportOffset }; const viewportImage = await this._camera.captureViewportImage({ viewportSize: page.viewportSize, - viewportOffset: page.viewportOffset, + viewportOffset: currentState.viewportOffset, screenshotDelay: opts.screenshotDelay, }); From ba977a5a7cb4621fd6b1b914e08d0c8d11ca901f Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sun, 19 Apr 2026 16:13:13 +0300 Subject: [PATCH 15/29] refactor: move composite iterations limit to constants, minor review fixes --- src/browser/commands/assert-view/index.js | 11 ++++------- src/browser/screen-shooter/constants.ts | 1 + src/browser/screen-shooter/elements-screen-shooter.ts | 4 +--- .../screen-shooter/full-page-screen-shooter.ts | 3 +-- 4 files changed, 7 insertions(+), 12 deletions(-) create mode 100644 src/browser/screen-shooter/constants.ts diff --git a/src/browser/commands/assert-view/index.js b/src/browser/commands/assert-view/index.js index 55e29f157..27a5612fa 100644 --- a/src/browser/commands/assert-view/index.js +++ b/src/browser/commands/assert-view/index.js @@ -32,12 +32,9 @@ const getIgnoreDiffPixelCountRatio = value => { }; module.exports.default = browser => { - const browserProperties = { - isWebdriverProtocol: browser.isWebdriverProtocol, - shouldUsePixelRatio: browser.shouldUsePixelRatio, - needsCompatLib: browser.needsCompatLib, - }; - const screenShooterPromise = ElementsScreenShooter.create({ + const { isWebdriverProtocol, shouldUsePixelRatio, needsCompatLib } = browser; + const browserProperties = { isWebdriverProtocol, shouldUsePixelRatio, needsCompatLib }; + const elementsScreenShooterPromise = ElementsScreenShooter.create({ camera: browser.camera, browser: browser.publicAPI, browserProperties, @@ -173,7 +170,7 @@ module.exports.default = browser => { debug(`[${debugId}] assertView selectors: %O`, selectors); debug(`[${debugId}] assertView opts: %O`, opts); - const screenShooter = await screenShooterPromise; + const screenShooter = await elementsScreenShooterPromise; const { image, meta } = await screenShooter.capture(selectors, opts); return compareScreenshot(state, image, meta, opts); diff --git a/src/browser/screen-shooter/constants.ts b/src/browser/screen-shooter/constants.ts new file mode 100644 index 000000000..0235a67d1 --- /dev/null +++ b/src/browser/screen-shooter/constants.ts @@ -0,0 +1 @@ +export const COMPOSITING_ITERATIONS_LIMIT = 50; diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index 74e983067..6aad990b1 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -25,11 +25,10 @@ import type { } from "../client-scripts/screen-shooter/types"; import { isBrowserSideError } from "../isomorphic/types"; import { CaptureAreaMovedError } from "./errors/capture-area-moved-error"; +import { COMPOSITING_ITERATIONS_LIMIT } from "./constants"; const debug = makeDebug("testplane:screenshots:screen-shooter"); -const COMPOSITING_ITERATIONS_LIMIT = 50; - interface ScreenShooterOpts extends AssertViewOpts { debugId?: string; } @@ -788,7 +787,6 @@ export class ElementsScreenShooter { const captureStartTime = performance.now(); - // const viewport = { ...page.viewportSize, ...page.viewportOffset }; const viewportImage = await this._camera.captureViewportImage({ viewportSize: page.viewportSize, viewportOffset: currentState.viewportOffset, diff --git a/src/browser/screen-shooter/full-page-screen-shooter.ts b/src/browser/screen-shooter/full-page-screen-shooter.ts index 46e8b3e55..2f163152c 100644 --- a/src/browser/screen-shooter/full-page-screen-shooter.ts +++ b/src/browser/screen-shooter/full-page-screen-shooter.ts @@ -17,6 +17,7 @@ import { preparePointerForScreenshot, } from "./operations"; import { runWithoutHistory } from "../history"; +import { COMPOSITING_ITERATIONS_LIMIT } from "./constants"; const debug = makeDebug("testplane:screenshots:full-page-screen-shooter"); @@ -81,8 +82,6 @@ export class FullPageScreenShooter { } private async _captureImpl(opts: FullPageCaptureOpts): Promise { - const COMPOSITING_ITERATIONS_LIMIT = 50; - const prepareResult = await this._browserSideScreenshooter.call("prepareFullPageScreenshot", [ { usePixelRatio: this._browserProperties.shouldUsePixelRatio, From 3d0a92d3cd87ebc4f88a8c3b2f8dcd2d31492873 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sun, 19 Apr 2026 16:13:59 +0300 Subject: [PATCH 16/29] fix: fix off-by-one errors in calibrator and leave a comment clearing why coord helpers use specific height/width convention --- src/browser/calibrator.ts | 4 ++-- src/browser/isomorphic/geometry.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/browser/calibrator.ts b/src/browser/calibrator.ts index bed954cdf..c70034c17 100644 --- a/src/browser/calibrator.ts +++ b/src/browser/calibrator.ts @@ -93,7 +93,7 @@ export class Calibrator { top: 0, left: result.left, width: result.width, - height: getHeight(0 as Coord<"image", "device", "y">, y), + height: getHeight(0 as Coord<"image", "device", "y">, (y + 1) as Coord<"image", "device", "y">), }; return getIntersection(topPart, bottomPart); @@ -122,7 +122,7 @@ async function findMarkerXBandInRow( return { left: markerStart, - width: getWidth(markerStart, markerEnd), + width: getWidth(markerStart, (markerEnd + 1) as Coord<"image", "device", "x">), }; } diff --git a/src/browser/isomorphic/geometry.ts b/src/browser/isomorphic/geometry.ts index fc6b9a216..2ea4f8f60 100644 --- a/src/browser/isomorphic/geometry.ts +++ b/src/browser/isomorphic/geometry.ts @@ -117,6 +117,12 @@ export const getIntersection = < type GetUnit = T extends Coord ? Unit : never; type GetAxis = T extends Coord ? Axis : never; +/* +Note: width and height between a and b is computed inclusive of a, but exclusive of b. Width between 1 and 2 is 1. + bottom of rect with top=0 and height=1 is 1. + These conventions are very useful when dealing with 0-sized areas. +*/ + export const getHeight = >(a: T, b: T): Length, GetAxis> => { return Math.abs(a - b) as Length, GetAxis>; }; From a194b5073966d44a04d1ee10e6b5615b2c2c4b4c Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sun, 19 Apr 2026 16:29:17 +0300 Subject: [PATCH 17/29] test: fix a couple of ever-green tests on screen-shooter --- .../screen-shooter/screen-shooter.test.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/integration/screen-shooter/screen-shooter.test.ts b/test/integration/screen-shooter/screen-shooter.test.ts index 22b1973d1..5126bc00b 100644 --- a/test/integration/screen-shooter/screen-shooter.test.ts +++ b/test/integration/screen-shooter/screen-shooter.test.ts @@ -79,6 +79,7 @@ describe("ElementsScreenShooter integration", function () { }); it("prints horizontal overflow warning and captures only visible part", async () => { + assert.ok(tempDir); await browser!.url(`${pageUrl}/partially-offscreen.html`); warningSpy = sinon.spy(console, "warn"); @@ -103,7 +104,7 @@ describe("ElementsScreenShooter integration", function () { "Expected warning to contain partially offscreen element selector", ); - const actualImagePath = path.join(tempDir!, "actual.png"); + const actualImagePath = path.join(tempDir, "partially-offscreen.actual.png"); await image.save(actualImagePath); const expectedImagePath = path.join(SCREENSHOTS_PATH, "partially-offscreen.png"); @@ -117,6 +118,7 @@ describe("ElementsScreenShooter integration", function () { }); it("captures long screenshot with deterministic geometry changes", async () => { + assert.ok(tempDir); await browser!.url(`${pageUrl}/deterministic-changing-dimensions.html`); const screenShooter = await createScreenShooter(browser as WdioBrowser); @@ -125,7 +127,7 @@ describe("ElementsScreenShooter integration", function () { selectorToScroll: ".Modal-Wrapper", }); - const actualImagePath = path.join(tempDir!, "deterministic-changing-dimensions.png"); + const actualImagePath = path.join(tempDir, "deterministic-changing-dimensions.png"); await image.save(actualImagePath); const stat = await fs.promises.stat(actualImagePath); @@ -142,6 +144,7 @@ describe("ElementsScreenShooter integration", function () { }); it("captures full page body with dynamic sticky menu fixture", async () => { + assert.ok(tempDir); await browser!.url(`${pageUrl}/dynamic-sticky-menu-safe-area.html`); const screenShooter = await createScreenShooter(browser as WdioBrowser); @@ -152,7 +155,7 @@ describe("ElementsScreenShooter integration", function () { disableAnimation: true, }); - const actualImagePath = path.join(__dirname, "screens", "dynamic-sticky-menu-safe-area.png"); + const actualImagePath = path.join(tempDir, "dynamic-sticky-menu-safe-area.png"); await image.save(actualImagePath); const expectedImagePath = path.join(SCREENSHOTS_PATH, "dynamic-sticky-menu-safe-area.png"); @@ -166,6 +169,7 @@ describe("ElementsScreenShooter integration", function () { }); it("captures only the visible part of a long block when allowViewportOverflow=true and captureElementFromTop=false", async () => { + assert.ok(tempDir); await browser!.url(`${pageUrl}/visible-top-long-block-overflow.html`); const screenShooter = await createScreenShooter(browser as WdioBrowser); @@ -175,7 +179,7 @@ describe("ElementsScreenShooter integration", function () { disableAnimation: true, }); - const actualImagePath = path.join(__dirname, "screens", "visible-top-long-block-overflow.png"); + const actualImagePath = path.join(tempDir, "visible-top-long-block-overflow.png"); await image.save(actualImagePath); const expectedImagePath = path.join(SCREENSHOTS_PATH, "visible-top-long-block-overflow.png"); @@ -252,7 +256,7 @@ describe("ElementsScreenShooter integration", function () { compositeImage: true, }); - const actualImagePath = path.join(__dirname, "screens", "fixed-block-slightly-off-viewport.png"); + const actualImagePath = path.join(tempDir, "fixed-block-slightly-off-viewport.png"); await image.save(actualImagePath); const expectedImagePath = path.join(SCREENSHOTS_PATH, "fixed-block-slightly-off-viewport.png"); From f059162b2746b0aee02cc93dae8ef3eaa9298a12 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sun, 19 Apr 2026 16:31:46 +0300 Subject: [PATCH 18/29] test: run fractional scroll test only in chrome --- test/integration/screen-shooter/screen-shooter.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/screen-shooter/screen-shooter.test.ts b/test/integration/screen-shooter/screen-shooter.test.ts index 5126bc00b..e376cc861 100644 --- a/test/integration/screen-shooter/screen-shooter.test.ts +++ b/test/integration/screen-shooter/screen-shooter.test.ts @@ -210,6 +210,10 @@ describe("ElementsScreenShooter integration", function () { it("keeps fractional checkpoint offsets stable during replay", async () => { assert.ok(browser); const browserConfig = _.cloneDeep(BROWSER_CONFIG); + // This test is only applicable to Chrome, it's hard to replicate the issue in firefox + if (BROWSER_CONFIG.desiredCapabilities.browserName !== "chrome") { + return; + } _.set(browserConfig.desiredCapabilities, "goog:chromeOptions", { args: [ From c49ceeef22b8b38c071126dc993d1c83fcad34bc Mon Sep 17 00:00:00 2001 From: shadowusr Date: Mon, 20 Apr 2026 19:31:14 +0300 Subject: [PATCH 19/29] fix: fix calibration script and add debug logging to calibrator --- src/browser/calibrator.ts | 6 ++++++ src/browser/client-scripts/calibrate.js | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/browser/calibrator.ts b/src/browser/calibrator.ts index c70034c17..8b7f9f082 100644 --- a/src/browser/calibrator.ts +++ b/src/browser/calibrator.ts @@ -7,6 +7,9 @@ import type { Image } from "../image"; import { Coord, Length, Rect, XBand, getHeight, getIntersection, getWidth } from "./isomorphic"; import * as logger from "../utils/logger"; import os from "node:os"; +import makeDebug from "debug"; + +const debug = makeDebug("testplane:screenshots:calibrator"); interface BrowserFeatures { needsCompatLib: boolean; @@ -33,8 +36,11 @@ export class Calibrator { return this._cache[browser.id]; } + debug("calibrating browser %s", browser.id); + await browser.open("about:blank"); const features = await browser.evalScript(this._script); + debug("features: %O", features); const image = await browser.captureViewportImage(); const { innerWidth, pixelRatio } = features; diff --git a/src/browser/client-scripts/calibrate.js b/src/browser/client-scripts/calibrate.js index eb1ad8d3f..2620928c2 100644 --- a/src/browser/client-scripts/calibrate.js +++ b/src/browser/client-scripts/calibrate.js @@ -1,8 +1,6 @@ -/* global navigator, document, window */ - (function (window) { "use strict"; - + // HACK: ie8 does not need to reset the body border, // while any other browser does. // This hack is obsolete in standards mode, but @@ -10,10 +8,11 @@ // which is in quirks mode. // Needs to find a proper way to open calibration // page in standards mode. + /* global navigator, document, window */ function needsResetBorder() { return !/MSIE 8\.0/.test(navigator.userAgent); } - + function resetZoom() { var meta = document.createElement("meta"); meta.name = "viewport"; From 495385b8d362dbee76f8abbdde3cc535613d568d Mon Sep 17 00:00:00 2001 From: shadowusr Date: Mon, 20 Apr 2026 19:33:18 +0300 Subject: [PATCH 20/29] chore: enhance logging in elements screenshooter and fix tests --- .../screen-shooter/implementation.ts | 1 + .../screen-shooter/elements-screen-shooter.ts | 21 ++++++++++++------- test/src/browser/screen-shooter/index.js | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/browser/client-scripts/screen-shooter/implementation.ts b/src/browser/client-scripts/screen-shooter/implementation.ts index f10aa6a61..0d2415173 100644 --- a/src/browser/client-scripts/screen-shooter/implementation.ts +++ b/src/browser/client-scripts/screen-shooter/implementation.ts @@ -118,6 +118,7 @@ export function scrollTo( ): ScrollResult { return safeCall((): ScrollResult => { const logger = createDebugLogger({ debug }, "scrollTo"); + logger("Asked to scroll to with params: selectorsToCapture:", selectorsToCapture, "scrollOffset:", scrollOffset, "selectorToScroll:", selectorToScroll); const pixelRatio = computePixelRatio(); const scrollTarget = selectorToScroll ? document.querySelector(selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index 6aad990b1..aebb7bd4f 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -27,7 +27,7 @@ import { isBrowserSideError } from "../isomorphic/types"; import { CaptureAreaMovedError } from "./errors/capture-area-moved-error"; import { COMPOSITING_ITERATIONS_LIMIT } from "./constants"; -const debug = makeDebug("testplane:screenshots:screen-shooter"); +const debug = makeDebug("testplane:screenshots:elements-screen-shooter"); interface ScreenShooterOpts extends AssertViewOpts { debugId?: string; @@ -547,21 +547,27 @@ export class ElementsScreenShooter { perfDebug(`Starting capture area stability validation.`); const startedAt = performance.now(); + const enabledCaptureStateDebugTopics: string[] = []; + const browserCaptureStateDebug = makeDebug("testplane:screenshots:browser:getCaptureState"); + if (browserCaptureStateDebug.enabled) { + enabledCaptureStateDebugTopics.push("getCaptureState"); + } + const enabledScrollDebugTopics: string[] = []; - const browserScrollDebug = makeDebug("testplane:screenshots:browser:getCaptureState"); + const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollTo"); if (browserScrollDebug.enabled) { - enabledScrollDebugTopics.push("getCaptureState"); + enabledScrollDebugTopics.push("scrollTo"); } const beforeCheckpointsValidationState = await this._browserSideScreenshooter.call("getCaptureState", [ selectorsToCapture, selectorsToIgnore, opts.selectorToScroll, - enabledScrollDebugTopics, + enabledCaptureStateDebugTopics, ]); const beforeValidationDebugLog = beforeCheckpointsValidationState.debugLog; delete beforeCheckpointsValidationState.debugLog; - browserScrollDebug(beforeValidationDebugLog); + browserCaptureStateDebug(beforeValidationDebugLog); if (isBrowserSideError(beforeCheckpointsValidationState)) { throw new Error( @@ -600,6 +606,7 @@ export class ElementsScreenShooter { selectorsToCapture, page.scrollOffset, opts.selectorToScroll, + enabledScrollDebugTopics, ]); if (isBrowserSideError(restoreToInitialScrollOffsetResult)) { @@ -701,11 +708,11 @@ export class ElementsScreenShooter { selectorsToCapture, beforeCheckpointsValidationState.scrollOffset, opts.selectorToScroll, - enabledScrollDebugTopics, + enabledCaptureStateDebugTopics, ]); const restoreScrollDebugLog = restoreScrollResult.debugLog; delete restoreScrollResult.debugLog; - browserScrollDebug(restoreScrollDebugLog); + browserCaptureStateDebug(restoreScrollDebugLog); if (isBrowserSideError(restoreScrollResult)) { restoreScrollPositionError = new Error( diff --git a/test/src/browser/screen-shooter/index.js b/test/src/browser/screen-shooter/index.js index 3a803680c..2b0844199 100644 --- a/test/src/browser/screen-shooter/index.js +++ b/test/src/browser/screen-shooter/index.js @@ -371,6 +371,7 @@ describe("ElementsScreenShooter", () => { const page = createMockPage(); const state = createCaptureState({ captureSpecs: page.captureSpecs, + viewportOffset: page.viewportOffset, ignoreAreas: page.ignoreAreas, safeArea: page.safeArea, }); From b5bccc25127b0506a998e1abdc733abfc26f4298 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Mon, 20 Apr 2026 19:33:42 +0300 Subject: [PATCH 21/29] ci: add tsc-out to prettierignore --- .prettierignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.prettierignore b/.prettierignore index 995780812..4a7e938d9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -19,3 +19,4 @@ test/browser-env/report/** *.png *.DS_Store .claude +tsc-out From 26391320af437e62345e01d41799d74838094a2b Mon Sep 17 00:00:00 2001 From: shadowusr Date: Wed, 22 Apr 2026 02:03:39 +0300 Subject: [PATCH 22/29] fix: do not apply calibration if viewport size changed --- src/browser/calibrator.ts | 5 ++- src/browser/camera/index.ts | 34 ++++++++++++------- src/browser/client-scripts/calibrate.js | 4 +-- src/browser/existing-browser.ts | 2 +- test/e2e/testplane.config.ts | 21 ++++++++++++ .../e2e/tests/calibration-resize.testplane.js | 11 ++++++ test/src/browser/calibrator.js | 2 ++ test/src/browser/camera/index.js | 12 ++++++- test/src/browser/existing-browser.js | 12 ++++--- 9 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 test/e2e/tests/calibration-resize.testplane.js diff --git a/src/browser/calibrator.ts b/src/browser/calibrator.ts index 8b7f9f082..abbfecb6f 100644 --- a/src/browser/calibrator.ts +++ b/src/browser/calibrator.ts @@ -4,7 +4,7 @@ import looksSame from "looks-same"; import { CoreError } from "./core-error"; import { ExistingBrowser } from "./existing-browser"; import type { Image } from "../image"; -import { Coord, Length, Rect, XBand, getHeight, getIntersection, getWidth } from "./isomorphic"; +import { Coord, Length, Rect, Size, XBand, getHeight, getIntersection, getWidth } from "./isomorphic"; import * as logger from "../utils/logger"; import os from "node:os"; import makeDebug from "debug"; @@ -19,6 +19,7 @@ interface BrowserFeatures { export interface CalibrationResult extends BrowserFeatures { viewportArea: Rect<"image", "device">; + screenshotSize: Size<"device">; usePixelRatio: boolean; } @@ -45,6 +46,7 @@ export class Calibrator { const { innerWidth, pixelRatio } = features; const hasPixelRatio = Boolean(pixelRatio && pixelRatio > 1.0); + const screenshotSize = (await image.getSize()) as Size<"device">; const imageFeatures = await this._findMarkerAreaInImage(image); if (!imageFeatures) { @@ -63,6 +65,7 @@ export class Calibrator { const calibratedFeatures: CalibrationResult = { ...features, viewportArea: imageFeatures, + screenshotSize, usePixelRatio: hasPixelRatio && imageFeatures.width > innerWidth, }; diff --git a/src/browser/camera/index.ts b/src/browser/camera/index.ts index 67442b353..d12c454e2 100644 --- a/src/browser/camera/index.ts +++ b/src/browser/camera/index.ts @@ -32,6 +32,7 @@ export class Camera { private _screenshotMode: ScreenshotMode; private _takeScreenshot: () => Promise; private _calibratedArea: Rect<"image", "device"> | null; + private _calibrationScreenshotSize: Size<"device"> | null; private _debugTmpDir: string | null = null; static create(screenshotMode: ScreenshotMode, takeScreenshot: () => Promise): Camera { @@ -42,6 +43,7 @@ export class Camera { this._screenshotMode = screenshotMode; this._takeScreenshot = takeScreenshot; this._calibratedArea = null; + this._calibrationScreenshotSize = null; if (process.env.TESTPLANE_DEBUG_SCREENSHOTS) { this._debugTmpDir = path.join( @@ -52,9 +54,10 @@ export class Camera { } } - calibrate(calibratedArea: Rect<"image", "device">): void { - debug("Setting calibrated area: %O", calibratedArea); + calibrate(calibratedArea: Rect<"image", "device">, screenshotSize: Size<"device">): void { + debug("Setting calibrated area: %O for screenshot size: %O", calibratedArea, screenshotSize ?? null); this._calibratedArea = calibratedArea; + this._calibrationScreenshotSize = screenshotSize; } async captureViewportImage(opts?: CaptureViewportImageOpts): Promise { @@ -73,10 +76,15 @@ export class Camera { height, }; - const calibratedArea = this._cropAreaToCalibratedArea(imageArea); + const shouldApplyCalibration = + this._calibrationScreenshotSize !== null && + (this._calibrationScreenshotSize.width === width && this._calibrationScreenshotSize.height === height); + const calibrationArea = shouldApplyCalibration ? this._calibratedArea : null; - const viewportCroppedArea = this._cropAreaToViewport(calibratedArea, { width, height }, opts); - await utils.saveViewportImageForDebugIfNeeded(image, calibratedArea, this._debugTmpDir); + const calibratedImageArea = this._cropAreaToCalibratedArea(imageArea, calibrationArea); + + const viewportCroppedArea = this._cropAreaToViewport(calibratedImageArea, { width, height }, calibrationArea, opts); + await utils.saveViewportImageForDebugIfNeeded(image, calibratedImageArea, this._debugTmpDir); if (viewportCroppedArea.width !== width || viewportCroppedArea.height !== height) { await image.crop(viewportCroppedArea); @@ -85,18 +93,19 @@ export class Camera { return image; } - private _cropAreaToCalibratedArea(imageArea: Rect<"image", "device">): Rect<"image", "device"> { - if (!this._calibratedArea) { + private _cropAreaToCalibratedArea( + imageArea: Rect<"image", "device">, + calibrationArea: Rect<"image", "device"> | null, + ): Rect<"image", "device"> { + if (!calibrationArea) { return imageArea; } - const intersection = getIntersection(imageArea, this._calibratedArea); + const intersection = getIntersection(imageArea, calibrationArea); if (intersection === null) { logger.warn( `No intersection found between image area and calibrated viewport area, falling back to original image area.\n` + - `imageArea: ${prettyRect(imageArea)}, calibratedViewportArea: ${prettyRect( - this._calibratedArea, - )}\n` + + `imageArea: ${prettyRect(imageArea)}, calibratedViewportArea: ${prettyRect(calibrationArea)}\n` + `This likely means Testplane incorrectly determined area free of system UI elements. You can let us know at ${NEW_ISSUE_LINK}, providing this log and browser used.`, ); @@ -112,6 +121,7 @@ export class Camera { private _cropAreaToViewport( imageAreaToCrop: Rect<"image", "device">, originalImageSize: Size<"device">, + calibrationArea: Rect<"image", "device"> | null, opts?: CaptureViewportImageOpts, ): Rect<"image", "device"> { if (!opts?.viewportSize || !opts?.viewportOffset) { @@ -121,7 +131,7 @@ export class Camera { const isFullPage = utils.isFullPage( imageAreaToCrop, originalImageSize, - this._calibratedArea ?? imageAreaToCrop, + calibrationArea ?? imageAreaToCrop, this._screenshotMode, ); const cropArea = { ...opts.viewportSize, ...opts.viewportOffset }; diff --git a/src/browser/client-scripts/calibrate.js b/src/browser/client-scripts/calibrate.js index 2620928c2..23ddef3c2 100644 --- a/src/browser/client-scripts/calibrate.js +++ b/src/browser/client-scripts/calibrate.js @@ -1,6 +1,6 @@ (function (window) { "use strict"; - + // HACK: ie8 does not need to reset the body border, // while any other browser does. // This hack is obsolete in standards mode, but @@ -12,7 +12,7 @@ function needsResetBorder() { return !/MSIE 8\.0/.test(navigator.userAgent); } - + function resetZoom() { var meta = document.createElement("meta"); meta.name = "viewport"; diff --git a/src/browser/existing-browser.ts b/src/browser/existing-browser.ts index 1be113579..47a888f8a 100644 --- a/src/browser/existing-browser.ts +++ b/src/browser/existing-browser.ts @@ -464,7 +464,7 @@ export class ExistingBrowser extends Browser { return calibrator.calibrate(this).then(calibration => { this._calibration = calibration; - this._camera.calibrate(calibration.viewportArea); + this._camera.calibrate(calibration.viewportArea, calibration.screenshotSize); }); } diff --git a/test/e2e/testplane.config.ts b/test/e2e/testplane.config.ts index 53002c7d8..c7ce8558f 100644 --- a/test/e2e/testplane.config.ts +++ b/test/e2e/testplane.config.ts @@ -15,9 +15,15 @@ export default { sets: { assertView: { files: path.join(__dirname, "tests/assert-view.testplane.js"), + browsers: ["chrome"], }, reportPageScreenshot: { files: path.join(__dirname, "tests/report-page-screenshot.testplane.js"), + browsers: ["chrome"], + }, + calibrationResize: { + files: path.join(__dirname, "tests/calibration-resize.testplane.js"), + browsers: ["calibrated-chrome"], }, }, @@ -41,6 +47,21 @@ export default { }, waitTimeout: 3000, }, + "calibrated-chrome": { + assertViewOpts: { + ignoreDiffPixelCount: 4, + }, + calibrate: true, + windowSize: "360x640", + desiredCapabilities: { + browserName: "chrome", + "goog:chromeOptions": { + args: ["headless", "no-sandbox", "hide-scrollbars", "disable-dev-shm-usage"], + binary: "/usr/bin/chromium", + }, + }, + waitTimeout: 3000, + }, }, devServer: { diff --git a/test/e2e/tests/calibration-resize.testplane.js b/test/e2e/tests/calibration-resize.testplane.js new file mode 100644 index 000000000..1064202ed --- /dev/null +++ b/test/e2e/tests/calibration-resize.testplane.js @@ -0,0 +1,11 @@ +describe("calibration", () => { + it("should work correctly when window size changes", async ({ browser }) => { + await browser.url("viewport-sized-block.html"); + + await browser.assertView("before", '[data-testid="viewport-block"]', { compositeImage: false }); + + await browser.setWindowSize(900, 900); + + await browser.assertView("after", '[data-testid="viewport-block"]', { compositeImage: false }); + }); +}); diff --git a/test/src/browser/calibrator.js b/test/src/browser/calibrator.js index 42ed97d45..04182b104 100644 --- a/test/src/browser/calibrator.js +++ b/test/src/browser/calibrator.js @@ -56,6 +56,8 @@ describe("calibrator", () => { const result = await calibrator.calibrate(browser); assert.match(result.feature, "value"); + assert.isAbove(result.screenshotSize.width, 0); + assert.isAbove(result.screenshotSize.height, 0); }); it("should not perform the calibration process two times", async () => { diff --git a/test/src/browser/camera/index.js b/test/src/browser/camera/index.js index ce39ed118..bee833dc8 100644 --- a/test/src/browser/camera/index.js +++ b/test/src/browser/camera/index.js @@ -45,7 +45,7 @@ describe("browser/camera", () => { const camera = Camera.create(null, sinon.stub().resolves()); image.getSize.resolves({ width: 10, height: 10 }); - camera.calibrate({ top: 6, left: 4, width: 10, height: 10 }); + camera.calibrate({ top: 6, left: 4, width: 10, height: 10 }, { width: 10, height: 10 }); await camera.captureViewportImage(); assert.calledOnceWith(image.crop, { @@ -55,6 +55,16 @@ describe("browser/camera", () => { height: 10 - 6, }); }); + + it("should not apply calibration when screenshot size differs from calibration screenshot size", async () => { + const camera = Camera.create(null, sinon.stub().resolves()); + image.getSize.resolves({ width: 20, height: 20 }); + + camera.calibrate({ top: 6, left: 4, width: 10, height: 10 }, { width: 10, height: 10 }); + await camera.captureViewportImage(); + + assert.notCalled(image.crop); + }); }); describe("crop to viewport", () => { diff --git a/test/src/browser/existing-browser.js b/test/src/browser/existing-browser.js index 7937c633b..4709068ec 100644 --- a/test/src/browser/existing-browser.js +++ b/test/src/browser/existing-browser.js @@ -731,12 +731,12 @@ describe("ExistingBrowser", () => { it("should perform calibration if `calibrate` is turn on", async () => { calibrator.calibrate .withArgs(sinon.match.instanceOf(ExistingBrowser)) - .resolves({ viewportArea: { foo: "bar" } }); + .resolves({ viewportArea: { foo: "bar" }, screenshotSize: { width: 100, height: 200 } }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); - assert.calledOnceWith(Camera.prototype.calibrate, { foo: "bar" }); + assert.calledOnceWith(Camera.prototype.calibrate, { foo: "bar" }, { width: 100, height: 200 }); }); it("should not perform calibration if `calibrate` is turn off", async () => { @@ -750,7 +750,7 @@ describe("ExistingBrowser", () => { it("should perform calibration after attaching of a session", async () => { calibrator.calibrate .withArgs(sinon.match.instanceOf(ExistingBrowser)) - .resolves({ viewportArea: { foo: "bar" } }); + .resolves({ viewportArea: { foo: "bar" }, screenshotSize: { width: 100, height: 200 } }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); @@ -762,7 +762,11 @@ describe("ExistingBrowser", () => { it("should initialize browser side utils", async () => { const calibrator = sinon.createStubInstance(Calibrator); - calibrator.calibrate.resolves({ needsCompatLib: true, viewportArea: { foo: "bar" } }); + calibrator.calibrate.resolves({ + needsCompatLib: true, + viewportArea: { foo: "bar" }, + screenshotSize: { width: 100, height: 200 }, + }); const browser = mkBrowser_({ calibrate: true }); await initBrowser_(browser, {}, calibrator); From dc44163ea19aff95f5382ad46aa00bcc10fe37c6 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 14:17:38 +0300 Subject: [PATCH 23/29] fix: add more robust logic for computing layout shifts and fix tests --- package-lock.json | 4 +- package.json | 2 +- src/browser/camera/index.ts | 10 +- .../screen-shooter/implementation.ts | 158 +++++- .../client-scripts/screen-shooter/types.ts | 9 + .../screen-shooter/composite-image/index.ts | 90 +--- .../screen-shooter/elements-screen-shooter.ts | 474 +++++------------- .../errors/capture-area-moved-error.ts | 25 - .../788fe47/calibrated-chrome/after.png | Bin 0 -> 28141 bytes .../788fe47/calibrated-chrome/before.png | Bin 0 -> 15420 bytes .../deterministic-changing-dimensions.png | Bin 34675 -> 34595 bytes test/src/browser/screen-shooter/index.js | 125 +++-- 12 files changed, 415 insertions(+), 482 deletions(-) delete mode 100644 src/browser/screen-shooter/errors/capture-area-moved-error.ts create mode 100644 test/e2e/screens/788fe47/calibrated-chrome/after.png create mode 100644 test/e2e/screens/788fe47/calibrated-chrome/before.png diff --git a/package-lock.json b/package-lock.json index ec6ef0c91..17f40ac7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "testplane", - "version": "9.0.0-rc.3", + "version": "9.0.0-rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "testplane", - "version": "9.0.0-rc.3", + "version": "9.0.0-rc.4", "license": "MIT", "dependencies": { "@babel/code-frame": "7.24.2", diff --git a/package.json b/package.json index 5510b0f16..eae91dbfa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "testplane", - "version": "9.0.0-rc.3", + "version": "9.0.0-rc.4", "description": "Tests framework based on mocha and wdio", "main": "build/src/index.js", "files": [ diff --git a/src/browser/camera/index.ts b/src/browser/camera/index.ts index d12c454e2..74df153dd 100644 --- a/src/browser/camera/index.ts +++ b/src/browser/camera/index.ts @@ -78,12 +78,18 @@ export class Camera { const shouldApplyCalibration = this._calibrationScreenshotSize !== null && - (this._calibrationScreenshotSize.width === width && this._calibrationScreenshotSize.height === height); + this._calibrationScreenshotSize.width === width && + this._calibrationScreenshotSize.height === height; const calibrationArea = shouldApplyCalibration ? this._calibratedArea : null; const calibratedImageArea = this._cropAreaToCalibratedArea(imageArea, calibrationArea); - const viewportCroppedArea = this._cropAreaToViewport(calibratedImageArea, { width, height }, calibrationArea, opts); + const viewportCroppedArea = this._cropAreaToViewport( + calibratedImageArea, + { width, height }, + calibrationArea, + opts, + ); await utils.saveViewportImageForDebugIfNeeded(image, calibratedImageArea, this._debugTmpDir); if (viewportCroppedArea.width !== width || viewportCroppedArea.height !== height) { diff --git a/src/browser/client-scripts/screen-shooter/implementation.ts b/src/browser/client-scripts/screen-shooter/implementation.ts index 0d2415173..e5b4c3f62 100644 --- a/src/browser/client-scripts/screen-shooter/implementation.ts +++ b/src/browser/client-scripts/screen-shooter/implementation.ts @@ -6,11 +6,13 @@ import { Length, ceilCoords, floorCoords, + fromBcrToRect, fromCssToDevice, fromCssToDeviceNumber, fromDeviceToCssNumber, getBottom, getCoveringRect, + getIntersection, roundCoords } from "@isomorphic"; import { @@ -21,7 +23,8 @@ import { PrepareViewportScreenshotResult, ScrollFullPageResult, ScrollResult, - GetCaptureStateResult + GetCaptureStateResult, + TrackedElementData } from "./types"; import { createDebugLogger } from "../shared/logger"; import { @@ -51,6 +54,101 @@ declare global { var __cleanupAnimation: undefined | (() => void); } +const MIN_ANCHOR_SAMPLE_SIZE = 3; +const MAX_ANCHOR_TRACKED_ELEMENTS = 500; +/** Tolerance in CSS pixels for binning observed viewport shift deltas */ +const ANCHOR_SHIFT_TOLERANCE_CSS = 1.5; + +function sampleRandom(items: T[], maxCount: number): T[] { + if (items.length <= maxCount) return items.slice(); + const arr = items.slice(); + for (let i = 0; i < maxCount; i++) { + const j = i + Math.floor(Math.random() * (arr.length - i)); + const tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + return arr.slice(0, maxCount); +} + +/** Finds the densest tolerance-wide window and returns its median value. */ +function computeShiftMode(deltas: number[], tolerance: number): number | null { + if (deltas.length === 0) { + return null; + } + + const sortedDeltas = deltas.slice().sort((a, b) => a - b); + let bestWindowStartIndex = 0; + let bestWindowEndIndex = 0; + + for (let startIndex = 0, endIndex = 0; startIndex < sortedDeltas.length; startIndex++) { + while ( + endIndex + 1 < sortedDeltas.length && + sortedDeltas[endIndex + 1] - sortedDeltas[startIndex] <= tolerance + ) { + endIndex++; + } + + const currentWindowSize = endIndex - startIndex + 1; + const bestWindowSize = bestWindowEndIndex - bestWindowStartIndex + 1; + const shouldPreferCurrentWindow = currentWindowSize > bestWindowSize; + + if (shouldPreferCurrentWindow) { + bestWindowStartIndex = startIndex; + bestWindowEndIndex = endIndex; + } + } + + const dominantValues = sortedDeltas.slice(bestWindowStartIndex, bestWindowEndIndex + 1); + const middleIndex = Math.floor(dominantValues.length / 2); + + if (dominantValues.length % 2 === 1) { + return dominantValues[middleIndex]; + } + + return (dominantValues[middleIndex - 1] + dominantValues[middleIndex]) / 2; +} + +/** This function is useful to understand what actually is going on when capture area unexpectedly changes size/top position. + * It returns the actual shift of the capture area compared to the baseline. + * This shift can then be compared to the shift of the whole capture area to compute correction delta. */ +function computeActualShift(): Length<"css", "y"> | null { + const { trackedElementsData } = getScreenshooterNamespaceData(); + if (!trackedElementsData || trackedElementsData.length === 0) { + return null; + } + + const verticalDeltas: number[] = []; + for (const trackedElementData of trackedElementsData) { + if (!trackedElementData.element.isConnected) { + continue; + } + + const currentRect = trackedElementData.element.getBoundingClientRect(); + const baselineRect = trackedElementData.rect; + + if (currentRect.width <= 0 || currentRect.height <= 0) { + continue; + } + + if ( + Math.abs(currentRect.width - baselineRect.width) > 1 || + Math.abs(currentRect.height - baselineRect.height) > 1 + ) { + continue; + } + + verticalDeltas.push(currentRect.top - baselineRect.top); + } + if (verticalDeltas.length < MIN_ANCHOR_SAMPLE_SIZE) { + return null; + } + + const shiftCss = computeShiftMode(verticalDeltas, ANCHOR_SHIFT_TOLERANCE_CSS); + + return shiftCss === null ? null : (shiftCss as Length<"css", "y">); +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any function safeCall any>( callback: T, @@ -118,7 +216,14 @@ export function scrollTo( ): ScrollResult { return safeCall((): ScrollResult => { const logger = createDebugLogger({ debug }, "scrollTo"); - logger("Asked to scroll to with params: selectorsToCapture:", selectorsToCapture, "scrollOffset:", scrollOffset, "selectorToScroll:", selectorToScroll); + logger( + "Asked to scroll to with params: selectorsToCapture:", + selectorsToCapture, + "scrollOffset:", + scrollOffset, + "selectorToScroll:", + selectorToScroll + ); const pixelRatio = computePixelRatio(); const scrollTarget = selectorToScroll ? document.querySelector(selectorToScroll) : null; const scrollElement = scrollTarget ?? getCommonScrollParent(selectorsToCapture); @@ -171,6 +276,9 @@ export function getCaptureState( const scrollOffset = computeScrollOffset(scrollElement); const viewportOffset = computeViewportOffset(); + const anchorShift = computeActualShift(); + const anchorShiftDevice = anchorShift === null ? null : fromCssToDeviceNumber(anchorShift, pixelRatio); + logger("scrollOffset:", scrollOffset); return { @@ -179,6 +287,7 @@ export function getCaptureState( safeArea: fromCssToDevice(roundCoords(safeArea), pixelRatio), scrollOffset: fromCssToDeviceNumber(scrollOffset, pixelRatio), viewportOffset: fromCssToDevice(floorCoords(viewportOffset), pixelRatio), + anchorShift: anchorShiftDevice, readableSelectorToScrollDescr, debugLog: logger() }; @@ -309,9 +418,54 @@ export function cleanupPointerEvents(): void { } export function cleanupScrolls(): void { + getScreenshooterNamespaceData().trackedElementsData = []; cleanupSavedScrolls(); } +/** + * Records up to 500 random non-degenerate descendants of the capture elements as anchor baselines. + * Must be called once before the best-effort capture pass; getCaptureState will then return anchorShift. + */ +export function captureAnchorBaseline(selectorsToCapture: string[]): void | BrowserSideError { + return safeCall((): void => { + const captureSpecs = computeCaptureSpecs(selectorsToCapture); + const captureArea = captureSpecs.length > 0 ? getCoveringRect(captureSpecs.map(spec => spec.full)) : null; + + const allDescendants: Element[] = []; + for (let si = 0; si < selectorsToCapture.length; si++) { + const el = document.querySelector(selectorsToCapture[si]); + if (!el) continue; + allDescendants.push(el); + const nodes = el.querySelectorAll("*"); + for (let ni = 0; ni < nodes.length; ni++) allDescendants.push(nodes[ni]); + } + + const nonDegenerate = allDescendants.filter(el => { + const r = el.getBoundingClientRect(); + if (r.width <= 0 || r.height <= 0) { + return false; + } + + if (!captureArea) { + return true; + } + + const rect = fromBcrToRect(r); + + return Boolean(getIntersection(captureArea, rect)); + }); + + const sampled = sampleRandom(nonDegenerate, MAX_ANCHOR_TRACKED_ELEMENTS); + getScreenshooterNamespaceData().trackedElementsData = sampled.map((el): TrackedElementData => { + const r = el.getBoundingClientRect(); + return { + element: el, + rect: fromBcrToRect(r) + }; + }); + }); +} + function prepareElementsScreenshotUnsafe( selectorsToCapture: string[], opts: PrepareScreenshotOptions diff --git a/src/browser/client-scripts/screen-shooter/types.ts b/src/browser/client-scripts/screen-shooter/types.ts index d55580a11..91520e7c6 100644 --- a/src/browser/client-scripts/screen-shooter/types.ts +++ b/src/browser/client-scripts/screen-shooter/types.ts @@ -7,12 +7,20 @@ export interface CaptureSpec { visible: Rect; } +export interface TrackedElementData { + element: Element; + /** baseline element rect in viewport CSS coordinates */ + rect: Rect<"viewport", "css">; +} + export interface CaptureState { scrollOffset: Coord<"page", "device", "y">; viewportOffset: Point<"page", "device">; captureSpecs: CaptureSpec<"viewport", "device">[]; ignoreAreas: Rect<"viewport", "device">[]; safeArea: YBand<"viewport", "device">; + /** Observed viewport-space vertical movement of tracked elements vs baseline, in device px. */ + anchorShift: number | null; } export interface SavedScrollPosition { @@ -24,6 +32,7 @@ export interface SavedScrollPosition { export interface ScreenshooterNamespaceData { cleanupPointerEventsCb?: () => void; savedScrollPositions?: SavedScrollPosition[]; + trackedElementsData?: TrackedElementData[]; } export interface PrepareScreenshotOptions { diff --git a/src/browser/screen-shooter/composite-image/index.ts b/src/browser/screen-shooter/composite-image/index.ts index 7d7e13511..e8681bd0b 100644 --- a/src/browser/screen-shooter/composite-image/index.ts +++ b/src/browser/screen-shooter/composite-image/index.ts @@ -35,6 +35,8 @@ interface CompositeChunk { safeArea: YBand<"viewport", "device">; captureSpecs: CaptureSpec<"viewport", "device">[]; boundingRectsToIgnore: Rect<"viewport", "device">[]; + /** Anchor correction delta in device px. */ + anchorShift: number | null; } /** Chunk enriched with render-time computed anchor top. */ @@ -91,6 +93,7 @@ export class CompositeImage { safeArea: YBand<"viewport", "device">, captureSpecs: CaptureSpec<"viewport", "device">[], ignoreBoundingRects: Rect<"viewport", "device">[], + anchorShift: number | null = null, ): Promise { const visibleCoveringRect = this._getVisibleCoveringRect({ captureSpecs }) ?? getCoveringRect(captureSpecs.map(s => s.visible)); @@ -129,6 +132,7 @@ export class CompositeImage { safeArea, captureSpecs, boundingRectsToIgnore: ignoreBoundingRects, + anchorShift, }); } @@ -208,10 +212,17 @@ export class CompositeImage { } /** - * Computes anchor tops for all chunks by comparing element rects against a reference chunk - * (the one with the highest covering rect top). Reference chunk gets anchorTop = its covering rect top. - * Other chunks get anchorTop = referenceCoveringRectTop - maxDelta, where maxDelta is the max - * downward movement of any element rect compared to the reference. + * Computes anchor tops for all chunks. + * + * The reference chunk is the one with the highest captureSpec covering-rect top (= the first + * scroll position, which has the most positive viewport-space top). + * + * For each non-reference chunk the base anchorTop is computed from captureSpec deltas (same as + * before). When per-chunk correction data is available, the anchor is additionally corrected. + * + * anchorTop_corrected = anchorTop_from_specs + (chunkAnchorShift - referenceAnchorShift) + * + * In the stable case correction values are 0 for all chunks. */ private _computeAnchoredChunks(): AnchoredChunk[] { let referenceIndex = 0; @@ -225,7 +236,9 @@ export class CompositeImage { } } - const referenceCaptureSpecs = this._compositeChunks[referenceIndex].captureSpecs; + const referenceChunk = this._compositeChunks[referenceIndex]; + const referenceCaptureSpecs = referenceChunk.captureSpecs; + const referenceAnchorShift = referenceChunk.anchorShift; const anchoredChunks = this._compositeChunks.map((chunk, index) => { if (index === referenceIndex) { @@ -248,74 +261,25 @@ export class CompositeImage { } } + const anchorTopFromSpecs = (referenceCoveringRectTop as number) - maxDelta; + + // Apply content-shift correction when anchor tracking data is available (best-effort pass). + const shiftCorrection = + chunk.anchorShift !== null && referenceAnchorShift !== null + ? chunk.anchorShift - referenceAnchorShift + : 0; + return { ...chunk, - anchorTop: ((referenceCoveringRectTop as number) - maxDelta) as Coord<"viewport", "device", "y">, + anchorTop: (anchorTopFromSpecs + shiftCorrection) as Coord<"viewport", "device", "y">, }; }); debug("Anchored chunks: %O", anchoredChunks); - this._applyHeightChangeAnchorFixups(anchoredChunks); - return anchoredChunks; } - private _applyHeightChangeAnchorFixups(chunks: AnchoredChunk[]): void { - if (chunks.length < 2) { - return; - } - - debug("Applying height change anchor fixups"); - - const sortedChunks = chunks.slice().sort((a, b) => subtractCoords(b.anchorTop, a.anchorTop)); - - for (let i = 1; i < sortedChunks.length; i++) { - const previousChunk = sortedChunks[i - 1]; - const currentChunk = sortedChunks[i]; - const heightDelta = this._getHeightDeltaFromDifferingCaptureSpec(previousChunk, currentChunk); - - if (!this._shouldTreatHeightChangeAsStartShift(heightDelta)) { - continue; - } - - debug( - "Shifting anchor top for chunk %d by %d. Old anchor top: %d, new anchor top: %d", - i, - heightDelta, - currentChunk.anchorTop, - currentChunk.anchorTop - heightDelta, - ); - currentChunk.anchorTop = ((currentChunk.anchorTop as number) - heightDelta) as Coord< - "viewport", - "device", - "y" - >; - } - } - - private _getHeightDeltaFromDifferingCaptureSpec( - previousChunk: AnchoredChunk, - currentChunk: AnchoredChunk, - ): number | null { - const minLength = Math.min(previousChunk.captureSpecs.length, currentChunk.captureSpecs.length); - - for (let i = 0; i < minLength; i++) { - const previousSpecHeight = previousChunk.captureSpecs[i].full.height as number; - const currentSpecHeight = currentChunk.captureSpecs[i].full.height as number; - - if (previousSpecHeight !== currentSpecHeight) { - return previousSpecHeight - currentSpecHeight; - } - } - - return null; - } - - private _shouldTreatHeightChangeAsStartShift(heightDelta: number | null): heightDelta is number { - return typeof heightDelta === "number" && heightDelta > 0; - } - private _isRenderableCaptureSpec(spec: CaptureSpec<"viewport", "device">): boolean { return spec.visible.width > 0 && spec.visible.height > 0; } diff --git a/src/browser/screen-shooter/elements-screen-shooter.ts b/src/browser/screen-shooter/elements-screen-shooter.ts index aebb7bd4f..c43f5eb9f 100644 --- a/src/browser/screen-shooter/elements-screen-shooter.ts +++ b/src/browser/screen-shooter/elements-screen-shooter.ts @@ -18,15 +18,20 @@ import { Camera } from "../camera"; import type * as browserSideScreenshooterImplementation from "../client-scripts/screen-shooter/implementation"; import { ClientBridge } from "../client-bridge"; import type { - CaptureSpec, CaptureState, PrepareScreenshotOptions, PrepareScreenshotSuccess, } from "../client-scripts/screen-shooter/types"; import { isBrowserSideError } from "../isomorphic/types"; -import { CaptureAreaMovedError } from "./errors/capture-area-moved-error"; import { COMPOSITING_ITERATIONS_LIMIT } from "./constants"; +class CaptureAreaSizeChangeError extends Error { + constructor() { + super("Capture area size changed unexpectedly during capture"); + this.name = "CaptureAreaSizeChangeError"; + } +} + const debug = makeDebug("testplane:screenshots:elements-screen-shooter"); interface ScreenShooterOpts extends AssertViewOpts { @@ -54,28 +59,40 @@ interface ScreenShooterFullParams extends ScreenShooterInputParams { browserSideScreenshooter: ClientBridge; } -function areCaptureSpecsEqual( - left: CaptureSpec<"viewport", "device">[], - right: CaptureSpec<"viewport", "device">[], -): boolean { - if (left.length !== right.length) { - return false; +function getMedian(values: number[]): number | null { + if (values.length === 0) { + return null; } - return left.every((spec, index) => { - const otherSpec = right[index]; + const sorted = values.slice().sort((a, b) => a - b); + const middleIndex = Math.floor(sorted.length / 2); - if (!otherSpec) { - return false; + if (sorted.length % 2 === 1) { + return sorted[middleIndex]; + } + + return (sorted[middleIndex - 1] + sorted[middleIndex]) / 2; +} + +function getExpectedTotalMoveFromBaseline( + baselineCaptureSpecs: CaptureState["captureSpecs"], + currentCaptureSpecs: CaptureState["captureSpecs"], +): number { + const sharedSpecsCount = Math.min(baselineCaptureSpecs.length, currentCaptureSpecs.length); + const shifts: number[] = []; + + for (let index = 0; index < sharedSpecsCount; index++) { + const baselineSpec = baselineCaptureSpecs[index]; + const currentSpec = currentCaptureSpecs[index]; + + if (!baselineSpec || !currentSpec) { + continue; } - return ( - spec.full.left === otherSpec.full.left && - spec.full.top === otherSpec.full.top && - spec.full.width === otherSpec.full.width && - spec.full.height === otherSpec.full.height - ); - }); + shifts.push((currentSpec.full.top as number) - (baselineSpec.full.top as number)); + } + + return getMedian(shifts) ?? 0; } export class ElementsScreenShooter { @@ -101,19 +118,9 @@ export class ElementsScreenShooter { this._browserSideScreenshooter = browserSideScreenshooter; } - async capture( - selectorOrSelectors: string | string[], - opts: ScreenShooterOpts = {}, - retriesLimit = 3, - ): Promise { + async capture(selectorOrSelectors: string | string[], opts: ScreenShooterOpts = {}): Promise { const globalStartedAt = performance.now(); const perfDebug = makeDebug("testplane:screenshots:perf:" + opts.debugId); - let startedAt, - prepareScreenshotTime = 0, - validateCaptureAreaStabilityTime = 0, - captureAttemptTime = 0, - renderImageTime = 0, - cleanupTime = 0; const selectorsToCapture = ([] as string[]).concat(selectorOrSelectors); const selectorsToIgnore = ([] as string[]).concat(opts.ignoreElements ?? []); @@ -122,133 +129,77 @@ export class ElementsScreenShooter { throw new Error("No selectors to capture passed to ElementsScreenShooter.capture"); } - let retriesCount = 0; - // This error may never be thrown, but just in case. - let originalError: unknown = new Error( - `An unknown error happened while capturing screenshot for selectors: ${JSON.stringify(selectorsToCapture)}`, - ); - - while (retriesCount < retriesLimit) { - retriesCount++; - startedAt = performance.now(); - try { - perfDebug(`Starting capture attempt.`); - - const page = await this._prepareScreenshot(selectorsToCapture, { - ignoreSelectors: selectorsToIgnore, - allowViewportOverflow: opts.allowViewportOverflow, - captureElementFromTop: opts.captureElementFromTop, - selectorToScroll: opts.selectorToScroll, - disableAnimation: opts.disableAnimation, - disableHover: opts.disableHover, - compositeImage: opts.compositeImage, - }); - - assertCorrectCaptureAreaBounds( - JSON.stringify(selectorsToCapture), - page.viewportSize, - page.viewportOffset, - page.captureSpecs.map(s => s.full), - opts, - ); + try { + perfDebug(`Starting capture.`); + + const page = await this._prepareScreenshot(selectorsToCapture, { + ignoreSelectors: selectorsToIgnore, + allowViewportOverflow: opts.allowViewportOverflow, + captureElementFromTop: opts.captureElementFromTop, + selectorToScroll: opts.selectorToScroll, + disableAnimation: opts.disableAnimation, + disableHover: opts.disableHover, + compositeImage: opts.compositeImage, + }); - const captureScreenshotStartTime = performance.now(); - - await preparePointerForScreenshot(this._browser, { - disableHover: opts.disableHover, - pointerEventsDisabled: page.pointerEventsDisabled, - }); - - prepareScreenshotTime = performance.now() - captureScreenshotStartTime; - perfDebug(`Prepare screenshot finished. Time spent on prepare screenshot: ${prepareScreenshotTime}ms`); - - const isLastAttempt = retriesCount === retriesLimit; - - // For the first attempt, we take optimistic approach and don't verify if the whole area is stable in size, - // because in majority of cases, it is stable and it's better to not spend time on scrolling. - // If it's not stable on first try, it will throw and we will pre-load the whole area & verify it here, - // optimising the "unstable" case - it's faster to discard early during scrolling than during actual capturing. - if (retriesCount > 1 && !isLastAttempt) { - const validateCaptureAreaStabilityStartTime = performance.now(); - await this._validateCaptureAreaStability(selectorsToCapture, selectorsToIgnore, page, opts); - // await this._preloadCaptureArea(selectorsToCapture, selectorsToIgnore, page, opts); - validateCaptureAreaStabilityTime = performance.now() - validateCaptureAreaStabilityStartTime; - perfDebug( - `Capture area stab>ility validated. Time spent on validate capture area stability: ${validateCaptureAreaStabilityTime}ms`, - ); - } + assertCorrectCaptureAreaBounds( + JSON.stringify(selectorsToCapture), + page.viewportSize, + page.viewportOffset, + page.captureSpecs.map(s => s.full), + opts, + ); - const shouldThrowOnCaptureAreaSizeChange = !isLastAttempt; + await preparePointerForScreenshot(this._browser, { + disableHover: opts.disableHover, + pointerEventsDisabled: page.pointerEventsDisabled, + }); - const captureAttemptStartTime = performance.now(); - const compositeImage = await this._performCaptureAttempt( + let compositeImage: CompositeImage; + try { + compositeImage = await this._performCaptureAttempt( selectorsToCapture, selectorsToIgnore, page, opts, - shouldThrowOnCaptureAreaSizeChange, + true, ); - - captureAttemptTime = performance.now() - captureAttemptStartTime; - perfDebug( - `All areas captured. Proceeding to render image. Time spent on capture attempt: ${captureAttemptTime}ms`, - ); - const renderImageStartTime = performance.now(); - - const renderedImage = await compositeImage.render(); - - renderImageTime = performance.now() - renderImageStartTime; - perfDebug(`Rendering finished. Time spent on rendering: ${renderImageTime}ms`); - - perfDebug(`Total time spent on capture (all attempts): ${performance.now() - globalStartedAt}ms`); - - return { - image: renderedImage, - meta: page, - }; } catch (error) { - originalError = error; - const isRetriable = (error as null | { retriable?: boolean })?.retriable === true; - - if (isRetriable && retriesCount < retriesLimit) { - perfDebug(`Capture attempt failed. Going to retry. Retry # ${retriesCount}`); - continue; + if (!(error instanceof CaptureAreaSizeChangeError)) { + throw error; } - perfDebug(`Total time spent on capture (all attempts): ${performance.now() - globalStartedAt}ms`); + perfDebug(`Capture area size changed. Preloading area and switching to best-effort pass.`); + await this._preloadCaptureArea(selectorsToCapture, selectorsToIgnore, page, opts); + compositeImage = await this._performCaptureAttempt( + selectorsToCapture, + selectorsToIgnore, + page, + opts, + false, + ); + } - throw error; - } finally { - const cleanupStartTime = performance.now(); - try { - await this._cleanupScreenshot(opts); + const renderedImage = await compositeImage.render(); - cleanupTime = performance.now() - cleanupStartTime; - perfDebug(`[${opts.debugId}] Cleanup finished. Time spent on cleanup: ${cleanupTime}ms`); - } catch (cleanupError) { - const cleanupMessage = cleanupError instanceof Error ? cleanupError.message : String(cleanupError); - console.warn( - `Warning: failed to cleanup after screenshot for selectors: ${JSON.stringify( - selectorsToCapture, - )}\n` + `Cleanup error: ${cleanupMessage}`, - ); - } + perfDebug(`Total time spent on capture: ${performance.now() - globalStartedAt}ms`); - const totalTimeSpent = performance.now() - startedAt; - const timeSpentOnKnownOperations = - prepareScreenshotTime + - validateCaptureAreaStabilityTime + - captureAttemptTime + - renderImageTime + - cleanupTime; - perfDebug(`Other time during capture attempt: ${totalTimeSpent - timeSpentOnKnownOperations}ms`); - perfDebug(`Attempt finished. Starting cleanup. Time spent on this attempt: ${totalTimeSpent}ms\n\n`); + return { + image: renderedImage, + meta: page, + }; + } finally { + try { + await this._cleanupScreenshot(opts); + } catch (cleanupError) { + const cleanupMessage = cleanupError instanceof Error ? cleanupError.message : String(cleanupError); + console.warn( + `Warning: failed to cleanup after screenshot for selectors: ${JSON.stringify( + selectorsToCapture, + )}\n` + `Cleanup error: ${cleanupMessage}`, + ); } } - - perfDebug(`Total time spent on capture (all attempts): ${performance.now() - globalStartedAt}ms`); - - throw originalError; } private async _prepareScreenshot( @@ -357,6 +308,24 @@ export class ElementsScreenShooter { }, selectorsToCapture); } + /** Scrolls through the entire capture area to trigger lazy loading, then restores scroll and records anchor baselines. */ + private async _preloadCaptureArea( + selectorsToCapture: string[], + selectorsToIgnore: string[], + page: PrepareScreenshotSuccess, + opts: ScreenShooterOpts, + ): Promise { + await this._scrollThroughCaptureArea(selectorsToCapture, selectorsToIgnore, page, opts, async () => {}); + + await this._browserSideScreenshooter.call("scrollTo", [ + selectorsToCapture, + page.scrollOffset, + opts.selectorToScroll ?? null, + ]); + + await this._browserSideScreenshooter.call("captureAnchorBaseline", [selectorsToCapture]); + } + private async _scrollThroughCaptureArea( selectorsToCapture: string[], selectorsToIgnore: string[], @@ -372,6 +341,7 @@ export class ElementsScreenShooter { scrollOffset: page.scrollOffset, safeArea: page.safeArea, ignoreAreas: page.ignoreAreas, + anchorShift: null, }; let hasReachedScrollLimit = false; let hasCapturedTheWholeArea = false; @@ -536,207 +506,6 @@ export class ElementsScreenShooter { } } - /** Scrolls through the capture area twice and validates if these two passes resulted in the same capture areas, thus checking if the area is stable. */ - private async _validateCaptureAreaStability( - selectorsToCapture: string[], - selectorsToIgnore: string[], - page: PrepareScreenshotSuccess, - opts: ScreenShooterOpts, - ): Promise { - const perfDebug = makeDebug("testplane:screenshots:perf:" + opts.debugId); - perfDebug(`Starting capture area stability validation.`); - const startedAt = performance.now(); - - const enabledCaptureStateDebugTopics: string[] = []; - const browserCaptureStateDebug = makeDebug("testplane:screenshots:browser:getCaptureState"); - if (browserCaptureStateDebug.enabled) { - enabledCaptureStateDebugTopics.push("getCaptureState"); - } - - const enabledScrollDebugTopics: string[] = []; - const browserScrollDebug = makeDebug("testplane:screenshots:browser:scrollTo"); - if (browserScrollDebug.enabled) { - enabledScrollDebugTopics.push("scrollTo"); - } - - const beforeCheckpointsValidationState = await this._browserSideScreenshooter.call("getCaptureState", [ - selectorsToCapture, - selectorsToIgnore, - opts.selectorToScroll, - enabledCaptureStateDebugTopics, - ]); - const beforeValidationDebugLog = beforeCheckpointsValidationState.debugLog; - delete beforeCheckpointsValidationState.debugLog; - browserCaptureStateDebug(beforeValidationDebugLog); - - if (isBrowserSideError(beforeCheckpointsValidationState)) { - throw new Error( - `Failed to recompute areas before checkpoints validation while compositing image of selectors: ${selectorsToCapture.join( - ", ", - )}, error type '${beforeCheckpointsValidationState.errorCode}' and error message: ${ - beforeCheckpointsValidationState.message - }`, - ); - } - - const baselineCheckpoints: CaptureState[] = []; - const currentCheckpoints: CaptureState[] = []; - let shouldRestoreScrollPosition = false; - let restoreScrollPositionError: Error | null = null; - - try { - await this._scrollThroughCaptureArea( - selectorsToCapture, - selectorsToIgnore, - page, - opts, - async currentState => { - baselineCheckpoints.push(currentState); - }, - ); - - // If the whole area fits viewport there is no scrolling and no point in a second pass. - if (baselineCheckpoints.length <= 1) { - return; - } - - shouldRestoreScrollPosition = true; - - const restoreToInitialScrollOffsetResult = await this._browserSideScreenshooter.call("scrollTo", [ - selectorsToCapture, - page.scrollOffset, - opts.selectorToScroll, - enabledScrollDebugTopics, - ]); - - if (isBrowserSideError(restoreToInitialScrollOffsetResult)) { - throw new Error( - `Failed to restore the initial state before checkpoints validation while compositing image of selectors: ${selectorsToCapture.join( - ", ", - )}, error type '${restoreToInitialScrollOffsetResult.errorCode}' and error message: ${ - restoreToInitialScrollOffsetResult.message - }`, - ); - } - - const collectCurrentCheckpointsStartTime = performance.now(); - - for (const checkpoint of baselineCheckpoints) { - const scrollToCheckpointResult = await this._browserSideScreenshooter.call("scrollTo", [ - selectorsToCapture, - checkpoint.scrollOffset, - opts.selectorToScroll, - enabledScrollDebugTopics, - ]); - const scrollToCheckpointDebugLog = scrollToCheckpointResult.debugLog; - delete scrollToCheckpointResult.debugLog; - browserScrollDebug(scrollToCheckpointDebugLog); - - if (isBrowserSideError(scrollToCheckpointResult)) { - throw new Error( - `Failed to scroll to checkpoint offset while compositing image of selectors: ${selectorsToCapture.join( - ", ", - )}, error type '${scrollToCheckpointResult.errorCode}' and error message: ${ - scrollToCheckpointResult.message - }`, - ); - } - - await this._waitForCaptureAreaToSettle(selectorsToCapture); - - const currentCheckpoint = await this._browserSideScreenshooter.call("getCaptureState", [ - selectorsToCapture, - selectorsToIgnore, - opts.selectorToScroll, - enabledScrollDebugTopics, - ]); - const currentCheckpointDebugLog = currentCheckpoint.debugLog; - delete currentCheckpoint.debugLog; - browserScrollDebug(currentCheckpointDebugLog); - - if (isBrowserSideError(currentCheckpoint)) { - throw new Error( - `Failed to recompute checkpoint capture specs for selectors: ${selectorsToCapture.join( - ", ", - )}, error type '${currentCheckpoint.errorCode}' and error message: ${ - currentCheckpoint.message - }`, - ); - } - - currentCheckpoints.push(currentCheckpoint); - } - - perfDebug( - `[${opts.debugId}] Collected current checkpoints. Time spent: ${ - performance.now() - collectCurrentCheckpointsStartTime - }ms`, - ); - - debug("captureCheckpoints: %O", baselineCheckpoints); - debug("currentCheckpoints: %O", currentCheckpoints); - - const mismatchIndex = baselineCheckpoints.findIndex((checkpoint, index) => { - const currentCheckpoint = currentCheckpoints[index]; - - if (!currentCheckpoint || checkpoint.scrollOffset !== currentCheckpoint.scrollOffset) { - return true; - } - - return !areCaptureSpecsEqual(checkpoint.captureSpecs, currentCheckpoint.captureSpecs); - }); - - if (mismatchIndex !== -1 || baselineCheckpoints.length !== currentCheckpoints.length) { - const safeIndex = mismatchIndex === -1 ? baselineCheckpoints.length - 1 : mismatchIndex; - const expectedCheckpoint = baselineCheckpoints[safeIndex]; - const currentCheckpoint = currentCheckpoints[safeIndex]; - - const lastFullRects = expectedCheckpoint.captureSpecs.map(s => s.full); - const newFullRects = currentCheckpoint ? currentCheckpoint.captureSpecs.map(s => s.full) : []; - - debug( - `Checkpoints mismatch, mismatchIndex: ${mismatchIndex}, expected checkpoint: %O, current checkpoint: %O, interrupting and starting over.`, - expectedCheckpoint, - currentCheckpoint, - ); - - throw new CaptureAreaMovedError(selectorsToCapture, lastFullRects, newFullRects); - } - } finally { - if (shouldRestoreScrollPosition) { - const restoreScrollResult = await this._browserSideScreenshooter.call("scrollTo", [ - selectorsToCapture, - beforeCheckpointsValidationState.scrollOffset, - opts.selectorToScroll, - enabledCaptureStateDebugTopics, - ]); - const restoreScrollDebugLog = restoreScrollResult.debugLog; - delete restoreScrollResult.debugLog; - browserCaptureStateDebug(restoreScrollDebugLog); - - if (isBrowserSideError(restoreScrollResult)) { - restoreScrollPositionError = new Error( - `Failed to restore scroll position after checkpoints validation while compositing image of selectors: ${selectorsToCapture.join( - ", ", - )}, error type '${restoreScrollResult.errorCode}' and error message: ${ - restoreScrollResult.message - }`, - ); - } - } - - perfDebug( - `[${opts.debugId}] Capture area stability validation finished. Time taken: ${ - performance.now() - startedAt - }ms`, - ); - } - - if (restoreScrollPositionError) { - throw restoreScrollPositionError; - } - } - private async _performCaptureAttempt( selectorsToCapture: string[], selectorsToIgnore: string[], @@ -761,6 +530,7 @@ export class ElementsScreenShooter { scrollOffset: page.scrollOffset, safeArea: page.safeArea, ignoreAreas: page.ignoreAreas, + anchorShift: null, }; let shouldRestoreScrollPosition = false; @@ -781,9 +551,7 @@ export class ElementsScreenShooter { ); if (hasCaptureAreaSizeChanged && shouldThrowOnCaptureAreaSizeChange) { - const lastFullRects = lastState.captureSpecs.map(s => s.full); - const newFullRects = currentState.captureSpecs.map(s => s.full); - throw new CaptureAreaMovedError(selectorsToCapture, lastFullRects, newFullRects); + throw new CaptureAreaSizeChangeError(); } const { @@ -802,11 +570,27 @@ export class ElementsScreenShooter { timeSpentOnCapture += performance.now() - captureStartTime; + const expectedTotalMove = getExpectedTotalMoveFromBaseline(page.captureSpecs, newCaptureSpecs); + const observedTotalMove = currentState.anchorShift; + + let correctionDelta = 0; + if (!shouldThrowOnCaptureAreaSizeChange && observedTotalMove !== null) { + correctionDelta = expectedTotalMove - observedTotalMove; + } + + if (correctionDelta !== 0) { + debug("correctionDelta: %d (raw)", correctionDelta); + } + + const correctionDeltaForComposite = Math.round(correctionDelta); + const correctionDeltaToApply = correctionDeltaForComposite === 0 ? 0 : -correctionDeltaForComposite; + await image.registerViewportImageAtOffset( viewportImage, newSafeArea, newCaptureSpecs, newIgnoreAreas, + correctionDeltaToApply, ); hasReachedScrollLimit = iterations > 0 && currentState.scrollOffset <= lastState.scrollOffset; diff --git a/src/browser/screen-shooter/errors/capture-area-moved-error.ts b/src/browser/screen-shooter/errors/capture-area-moved-error.ts deleted file mode 100644 index 8e5913f2d..000000000 --- a/src/browser/screen-shooter/errors/capture-area-moved-error.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Rect, prettyRect } from "../../isomorphic"; - -export class CaptureAreaMovedError extends Error { - retriable: boolean; - - constructor( - selectorsToCapture: string[], - lastCaptureAreas: Rect<"viewport", "device">[], - newCaptureAreas: Rect<"viewport", "device">[], - ) { - const message = `The capture area moved unexpectedly during scrolling while capturing long screenshot. What happened: -- you requested to capture the following selectors: ${selectorsToCapture.join("; ")} -- last capture areas: ${lastCaptureAreas.map(prettyRect).join(", ")} -- new capture areas: ${newCaptureAreas.map(prettyRect).join(", ")} -- we tried multiple times, but still couldn't capture the whole area - -What you can do: -- Check that the page is stable before taking the screenshot -- Check that there's no content that loads dynamically -`; - super(message); - this.name = "CaptureAreaMovedError"; - this.retriable = true; - } -} diff --git a/test/e2e/screens/788fe47/calibrated-chrome/after.png b/test/e2e/screens/788fe47/calibrated-chrome/after.png new file mode 100644 index 0000000000000000000000000000000000000000..1c811bdd5e3f6447593edf0ac04b9bf084c18360 GIT binary patch literal 28141 zcmb__30PCt)^@-4wsLC)I*9`kv5r?uY8?=Pf5D_InfEWWrgb+f=Je+@@lLQUK-tYgPpXX^*lALq)UemkY zwbt&@FE@lvczep*uf6u#gf*Xk_SI{zy^#U_o9^}&_zkJ*O4Vzx?JZvO*@~~zqWe3J zX77#K%A`Plp^x?+J9=IDpX?1AV>0qiT(qd$4epIDb^nQ$9{isjE67s zv=$aX9hb+O3t8Sj%MH6JZTMUnks8g?M#$5cEKz}_Ie`B=iX_?PyV!QCNt6|Ix%MHI!+SEZfQ9-a!odW(^F&LxFJamnB-SKS87isxh++wP3PZCLsYbJ@h z?JpHw*L8PRrV-0Ls>^%|f~(8?>@S@t1`j>4a#Q~4uh!1H2wt|%r~$W>COvDJ3I7xR zT>}fgOJc%F`$y)<8{n(8c$7>ew$5dPwOo4DT5t<86f-P4M!qP#uIpZz);I&-b7B8g zcUpza5Zd8b46-i4RIHXC>6V=t!n*(40)vR{hJ!!z31U9K4q;S2@)LGSK zlbnPz3lUEDm)He%StJ>ej~50O z933pS!RIp^yI%lyABb)0cP#1&LGa=)m~y#hw;&};ZXmuaKm9psKjpe-w9i@l7XxTn zJmo&$NLJOIp+Qa{llI723rRyU%8Cd#lcIW4K2SWFlj6y)>pDKpu?H6l6mG-~N^L5Z6Zu!eNKAR3u~@E?BC4L|FyZ^{i1k1Xs(<5uo+SIxNv#+_t+u$K zJ#@E5t(WX7|cvOYM4j@$@D+Yz7JRt5bTGnH5>`Slw=+njFQ_1_?!)-9qIppo(6V59W?I zg6Z^}-2_tKd{^(?Y07so`AaDG7Jy$&wCTCojJ(cnN|L+vF*T% zupL52R;cP~HTD&q$JTTbIGzsSTv`;PG?l##A_>bl{5_G$>V%`sXiMq?-ii`A z64LIQfjyWG4LV1H3Y^<9M%XQseU}C0YG@$>JWM4U{F$<`1{Ya?%y&5sciz~FV z9h+`pcS31E%zNCW|UwKxCqy!g?>#1z``uz85D^o8Q57HwRED*y})t7Gz}8 zjo%*Y+us&*tS`y-BD1JqSmH{jCBl{(>4x6+nKP|Z z#Sq~SM|)!?j1KhE5KR>5?uSLV56?cj@ao-{ZBKU>_D9!vs@+-ih1G95J-`5>{mh*2 z_WT?(1Og20w6m`v4I{p6=t~y$`rk%ua0A?Dc0uesjzqF}I;n`;G1frwh=F!SJ3iih zACa3WuX#2a{lmhmRZb6o&-MV<90p?m216Jx{j{cPlI({u5(6ro_J{x4WBY?QkdEz- zvcGV#KCoXBmc^Z_TlGnGx6`)zA=~Ol$4~8U8|!RMz?qLSiw<;#P+v?J2)@Guty$~z z46tFCMy%|MUnax4On-|Ql(y$I=N?;0q`n1vdRNii)M|nCJJRo42eiCzH!Dohl6$lR zuodobx|uC*dC=YICfBwSIi)K}KO_5a`3*S&Ms5BcasB22GkmuoZ~ng1@_sLr4uN4W zqbW%yVuF&yFx;LmH9pn!}T) z%mL8Y`Qth{?6ssXdGB1rOr8&3+DJ7H3DCdD4fkFKej`c9c|@oMnV;KbvjB(!fQe=8 z#4o56p?VPvj`c9Kelp5I3vJ-~&MJrdg;NI@r$1Yq%L@3!f!-afwFgV`8U*u)t z%El@o6(}LVj8%C*Auw0#3j@^3kG$Ho6Gti1M!a{4A+P&Au zFTG;y>X?X$ad)5fDvIoHa0RbTDp+iZyHD2TW$prgdkkiRab(=R&bbS#HBL?o4jk7# z{pg#gj7cm&Fn}Qj-)(f10I&(X5rn!a0&(b6^2?#M1BBLr4}csnmKky>k(%nt9^nKD z*dx=~t~s7ph0+~FSNjtTFvni_s-1Jate0SD()KD#-TT2xJJwwI&8~jR)I-<&YsaL2 zc;H-*zd#+eNajs#3o8louYH3>AC>EjsJyGZTUuawgxv~)B{9d9=D~;(Pe!u3OovPRpB4d)CV7)ylMa_!`iC2aMD#kM`3!CT`H z2@I-%M}0UwJEX7vq}*_gszBR-0lt*Ild^dD{1=(Pr!h+Lf(#ZP024~X z{ZX#i!L#6+7%*csl0Ga%BFBTdq@ti$*5B|Pj(~@x4qM#9jt><;y}qL#9!66z!7wm7 z1Jr>G5O}lpxs2BT7HYykr~$H&&JZ1UY*)7p+tR#F6o_lV@!diiam3tn3!Q3EV+SC11h{nw?szrho1E{hPTR?E>0qgb~F{ z*$0_|*g=?AUsF!^n;=Cjf0q8Pv9(PwMUr zyz_UgbH~#ALN^y=QypS*CGZxwf?qecQzurJO&=4}V0d8p>E*2Sx~I=M;CUT>CKjP& z(};fvkJ2-TMv+I3CBkGk@QRC=mez1O{#C)+1LYTF3&G!EWaB%L*vQ8(45F~IO^bN_}yF?J~hF`^m z0K^%IKb`G0%|(LA0GI7pS%#^}yd%XEf}lT~-8!tV1c9gfdiC&zY8QS3pepdTBaY1j zG#E(K(Nnsyysm{r!0%&+Ts{==i6E;ODZ}hSlD&sBS(a8%R`>zfoWvDKjknp{@&mCj z(iILk7ao*I01}L_dQ%WaL*%ZT>|)t0dtOa$NZdF&u?|HNYZ2XHS`AEl)O7q}Ga$VH zkWhSyKgn7&NOXYQ(JlghT=21)*@i_SMXoAFFc_)I{#bn_u+z~eVyd{d9CDNxpVV}6HoCEMxylnAZAyI$-@@iMn0%WOAPsta%swQo5^O$hMf8^>#;Oa2HPu_Df zn9+o;R+In7$#21Ho)Gy#g!)2fvm_yQ6b2C%9P(7 z?qoLt`A3n`k$^DSmI-nln1~a&a+o5-VScjM0cuYtg8~?m*YyGS=6C1iFbaEkV8TLr z`k2BFT=oD6X>2{@f0b+reGdOF8ZfI=4E?OY(7kPK*u(X}=n zvS-Vdu5l!Z$wF9AfZr0nQ=cRiPJN~8a_}9I?~G1|ZPn3>E26!tCxv&tT-bu?B_JWn zyN)c#rWQf|_pH1>y#8x#P79mtHPoJ0ht9EXSSlR}C9v-Zgn5-%B+)qLlxTpQ38uuV zUSTNK{%&aqkf)b(p$_3hMp0oK-LN`o5gj%dr^v4ZdLf=W0&)ICGT;6QNx@ijKM?0g zecD#i^#a~ui<@}rRJ&l{Vg!h1H@9a6EPb#LuF+y^os&-<$b`V=zOr0Rb<|VsEOK35 z9>Da@DKbn~?C>@Bvn*y=9@8?zMUl)#TmvcW9lEhGdJ$l@OmJ~|R8B-*Z+re##ygH= zz(#8&1{_E@$=g2q#&B+)`Q{{{y2<4e+XyuV9V37K^nb%BC;9f*-v|@jJqm>9vNB{tlYqtg z*>b_fMw)gaiYB7Pyis7d+rz_0U?}`)ZMFm@qJe*1`HJnJWE3yK?Bxm;1@MO z`~9k&ydua_5nyu_W-^@HDW=-^Gyi+kcU{yM06==lV0&XD7leaIuf4OU<$v`gB zn!Vvd*GMOV{v=!x2kHK!G3&CCOLB~SXmGEKWKrOOD6hvjd%d9gYfxhYHM`DFu!L^` z`q#TscvyYvUrlLRY{4n+ri4!n$W;4HoHzH|rYm8jhX3H9d~rG&jj zlJ7e&xPziggdg(&rv}~YU#Ra#J%2F(%tFc(X0DvvXc#;>+KAzj6C9l8 zx@uW60U-k85j?Y%;MO?pmc3;3Af@W|r0}ONhg%a8Zh@$m0GfZ{=q~}gYH`=}x^|kE zfzt%QQ69nrF=A}B7+4^+OsKh&#$=B!XS}F4bCBdFjWkj*fT^bAE6bL?g7vqv+Gw)g zJQe`LY}3+_Zn2-?((e{G(m{s^wti&iIvi#3`@x7nA50fKld4%_*R?57YOBkWNyqTv zHjnB8z(%@Hc%kh!<_s{VnT*jXu8lDTv2KjBhU=JsW*xZ-l4Sa2C?4$Qr#;z^q(D!b z5^`lAZNp}U6{TbeI#lKbnEK`bYpOrkQMlR~?8A=(v`D&B%@TfQK%RN%0#t?zuhPM8 zP&ff`Ys5g$f}{sHgSPIp6PE$mMgHelP!6|wS$~l3m?T^7bU%0@k#1r1n!~N2K;XK} za{)=ncq<&R87@x(5aaBO0A`8%2^X|@Ol{d8N!bcQ#y~O~73xPfj`X87+0qLT9vANt zw795;U9}ZuQR(f5r>?8Lrm<=OFLAW25UZK&0A+v|26l-e1QmCJ-V2<>MfwW!%F$QG z(0R6)M{ck38h&LV5`5L&>x`X_2uJ}9WuW}DjNCX^kO;!i9G7iia6{KCIc|i952G_+ zp8ZEB_-l*w(*L~NS^-kH^+WsVRpUBu8Dg!xK+_UJ`B zD4-ia2)nS|VG1x|44$R;OO&hd?g#u5RlnZ@w|MYpxQvF{>1>!75KDkzE~%|SdBhxB z=TzphVfg;_NeQQ2p-!alEfTtLC!KJ49mGJA0fy7g z6=YkLNvZ;TAm(*L4Bl{*9@eG$5N&zhZ4R_{=_Xpk*aq}v5v~rECiC!%?HnA3kJQi} zn>+o%XTH zsDn}d>R6gJw$3X}3Eef}BXbIP`uS(oO8sBgJ*^Kp>}cA@v?s@*_<*7hDnEq6>y?x$ z5AX5K>_TIS`Oj=>eNxYtZg|U_Mc5Mz|861FiCzGn3~#sxKN(xk3-?2bSk(S76tz2; zO-iedV3inCS#i{QA;pqp3Gpr0kc3{=hD;yKaHB^@KXmh<8V#QBQeXzi)0QH!z(myh zLwe3x^dNP(9$Wf6kS+1OkCzN(vUDv~??(@I(QB~K^>3i??&Mp~3GD*{N={#32FH5p z9_wyRj$S3CJsoNs5hJS8g3kRS~VjhFfssu+lff($gx{EN{ykR+AOa6bs}R zJ>P;vw-oAuK{K0lEIz4C29r)p-JM-ph&TcpBURd}DbrEJa0GOM;AFoSK- zf+gR&3?6_>k+F^CQg>;!7)lwMGo)&$rVUE5k=A1n_zd-N_>*ENr$>wWXIpMXh%Z+& zNfvg#$wvu%FQD@>S2h-z_{DhyQmAlCYjM%7n`o7HrY*^0(;At7dPuu-6Y zRz<=LkMqE)BZQL&+OF^p4}KCxY0M4|GI6L{DFHi}MQ4}|p=Z%MB2L7K%*{A+>0_N> zsbvWfZ>+*m()!;F+lo0%pgrrT(_jW;QEB=+1k1xJ5zjo8-Ec*4crZv}F)E|p7PHK) ztRQkf8dGYXEUtkhwC;+1ouw=&Trh~w7S;1~VNhB?)6hkM=>{E5>kW5DDOZ6oCFx;7 zX3hf1u2#%dWtxJ}so#GU7n0UVv&`oc4W;#1{UB;sM2l2){I*0Z|Q72C!P3vY`8go$mLRyaI4(l?c)W~%cF0=61!QWBaIz>Xu zK%Ec2XD3b&S;1q;1&TujLb_^ySw7Y}`6`RUfF!c_56huzrfk6=yM|C% zE+v>lQwBlzK%=m-5pkh#b0@KJZn%xlroKnJ8KUn&MQAK!bOv_#GDMm;84vxX#BiVI zvZMKP6^w9erx2GbNS`3x4|RD_?^P*b8Cn_EVcxnEX?Fsn4TF73N?#Su8)EZ1_md%i zlt}F(;6@3kre$rpCq#Tx_}Llyni{kot8etckQH@&>4AYEcWIghw~V^6BRahGYAb(m zU+Y>tiQA<>^9;-QI*mjSd708KP}K+wgLO)(qF1PsGN^j#)M#tHKT4VRS}sH`{7uWy znI!symxYj?O0(w5MV?v<$6P6h=KqRkNQjU)8yiL{lq#nQju!=cNzAo0)&3|*M#W^w z1$`+J^($ z+-K{&MAiw#fk`-$Ijt?(bc};hOJis%d7bD1hkV0lWV`Hb==6)UtXV@Wa@ zeWYlJSI4*H?1uJ9bSHGdT$M-X@SqHD5O_ec6p3Z<27yafDav<4`+p0DaHb)AnL!8^X?ok*EX& zS9LC}Q+xZJrNe1J{y>v;qfV#vWEOZ;dQgW$Jg~+dlpu+xFG2USj28+z`o&)577L`r znHqQMda&trRWc@YyGguMGEi0=UtIBz?5m(N3OLI)uSWt4UlKiV;DGM7S5S(fk{i5j zMZa8x3(;p>JOcJ#x}5$xF;y~LOS}HTf3$in&YIQ4r|dVMz(PgcVq zi-PZhb1>hZR_|B1pw}vA2b0z6ceUZJxx^o3(FjxjJ6jE#?I7 zQK&u=Xla`z5;fH{xSzv1-)boWyL~pQV(O=S3W=tO*e%X|q{X1Ioz^LpHB6|B&f)4r z*&WF=6VV?91!F9y8*wz_J%Pd^DC*~1vZ20uG1f|Cd@QU97xedSX8VI!MlR-(CrEjH zgnc4x(44|gB2AlL7w3QYtJRRW^>aUomD8yc*IDT_MQFGLCunNn^KPiJ`OoUIE51}T z^mmJO6^Vu4mI`xHYjh8>&|dTwa>b_3GU!p8Htr&cEC@@#wJ8jHj}r`auvijVO<)jO z7|3Vgh&q*lH7(c`7(l&#~p zn^tQ0P*xLlLB?JQUvs4+rI(?t3T}({faFv8w0ZxKr6_lTjf_y53cr!upyZJZ``I17 z3GB;#46Uj#N#~;OgSGwmI$;FnPzL9~Pvx=+9q+-~7zeTvx%5+U6kn^qBq3`nSjDk zP>1@x(Z?c|w0Yf8H1g}0@St@A1UC~$R2n*eQaoW-a|5m?jeboj_W0*+>~~$$P-!*2 zl;Y6&|5Rk(#t!J0UnPmcgf%;_2BY?3CswN3cWQTc=LdJ{={5LJep$$)fu~W-3U0__ zp^l-GQHI}Z7R)O7@YiaEc(*v;@>z4WB_hkjskd@)2Gn>CKDHkf29fvB7&6x7WVEvI zyuVd6Rfx|ik#i)z3D7Q4Lt%$+WSvUZ2Yjs{p9J~T$Z6btby}2vr?Hdchi~F5QieY^ zu^<`c*hQjQU(+ShnQ`?6!GbU(Uk#&Y34WRk_mxv;MDs$*hP2s&pRG*XfTxe8+>_ti zqX@(r4&jW0IGjmx7VnXOJyR4+m0JYK>Gcowz;le3MnHQ1%@i4oyalr*zUJSrZT(hdR!rEhH%#F;xSWh61;Flp2^`qQoKYp6M>`Un&+ky3Vqb87Mhu;+XwWCD&NSi;{jP@!^{ zE|b-W21<)j7bQNB^)V!^W;7|wcpS@v6CctHQ!1@}6Pu$$S_b~qaN-4=Yb*g7lBn7s zzTO)0d0VmQc}XaAYr3rX!lSDl1LqbG9JYfE{)zmSpVqqnOrQQ>Z9-^Y`>QLC~6Ymv$5WXp4UbExgi^w+CBx z(W{e9Gx!%q)ApXjvvPps&~3?W)^>&FUXtERqV2~ht+Cv13Oq?0j_3R<$gcG&I1QznwpMtAbgf~v`uTnSkx6C_7_ZJRh8@( zO4=kMy|oFnrCU!a0Td_zPyo#CttKLs9Me(#pPpCs4M0Pb`l@(050f>s7+f{g|2ImW zDF%-*|M0v-C&Go5aZbP%Mi1uN6i>-#kbT!p&&;WdZv`ftg|%QYqu_#F!yCp9ZCT zz^o~I+0dySdE5;LyM)q%U*#C50qxCsL_ z^@Cbvcc0E!e4)ihktIxwZxcGM!jS591wkJb>(DyLFC*kOB%fYUQ`wMlIa8dl3q4OdQM zgl)0t(oAM-Y5Rl(npUfaDXPR=jZR?ErOdq_0nz3~0R&JE5CGhL018GmnNcv2zicXhbsn0yS(l)n&U*1Jcl<>- znRe4W5Ig+1IGQpdJ1|HQ;SrISrlWTjm2LhHe@M>nIbgl%8I5B@wclecEum-QOZ$o$ zmuVz%uXqs}!`z&1;y@*+6VOc^muj#av@EYv$^!Y8$4XysYY^|>rK}{wX|G^KHG`|2 zQmL(&X{ve1|CRbU5XbwVX7k~6X#zIrJ4JfD`DhSIbZF4338mf>dkA)2p!gIEPc(6M zMRP4FzU3I`2M#ZBzd{y|iZ$uQl2E~-wzVB!)gIPKFnFW7`N!IeO2LdgQx(UDCBdV& z7arjRR(~8(PQE9`rQaOi+z@T8cqYd(<+>pS8W*w*gFY^vrq{0P66aHVN+3`5LHr)c z@8?*$Zi(#r@Esb1H+&Mk}2w^Y^A{RQ?B+14W|sSQaTL! zg;pAL_Tj9@>%4wZnokk@aG#Z; z-Nd;kQ?r$WA2T?xDB5`1INV>Qs11$Od#Uqd6a#BbsrA}baTN!XiPoX4hBV$%MZ`F< z$8G(SP;42u-h>&lcBfDkew}S%|9yl5ZQ|mg)`5p53E150mH@N_X0>i{&}5Tj)%=ot z6p-i(PV#39Gc#59`Xx=01(T#e0)(V z{rN+VP_X%Kn|zZgO)L*LG2T>YNa5X2pIQV@r_oX0HvK4WiY8mm-RUu*Phh!BHVgY5 z`trJK&$*}29{Z)iKlpo;#UzZ%03#dVj?@V-N;U|FcskNvWFJBGNBYp4?}H>9lv3i6Y8dEeJG0d<6=|y+Jzxd5TO)Nh z#ss();GxIGUzH_q{)1C74O z!@s)fU4*Q|@?cLDw`{JX8+mkh6x=Mb#SKLxUOxjMY!J4{dD0$*P(Oa-&Ib7KZ8fd2 zou8mX_v&JRD4gd8s#d22#Sk{4M!#^auY|jH?^P-219>RdzJwQ3`%~z^hEuuPgnIq*o4ASW2 z;~u;nF1$foppy`o0&7r2=np#adeBK?RioA;NHH` zb_Q44KrgAkV@pndh`2OA`b*uk@Jwi=8*Z>mmIsT&`B)Q2_bX>9nCh_X@OtGO6@31K zS7np0qe~RN5#epALVDSiv3LPv0q;s5#8iP1^c1JoHrr&si>^*v3&EJPEG}=}ZSVQo zWwcM28@h5<6LVcCayZflbgiVO`@x-WM^z;)NFQY+7=_v?yuLpR9$2z&95sYnkI?^h zFPiqO$hbi`815gva}~&ODJ>pj=Cy4dKKhpN%ug5B7M%A>-SMivfFJF<^pm5)KLvEq zfQF-aH6ilD#HTT!{_XP6Ab3;+v^b#AXAi>^^eB(=9J%WD7ybEf0|fwA)eaI}3>N5m z>_&uD9TIs}jXG`#UJI~Rd6mfJ=_6r?Pt?9;xGe)>c0O#uCe6;JuV|IK1oyc*&8|fu zx}2a;CF+A*HPXOScn*Wwc@&Y$m}W|k2}ASXmSATkC)q^>j(LJdmq5wzrDK+CjSAvC z>PSnJ88H}f9>xof!_FnxYrNe2VJi&+sZyfS^>cH`v^d=H+pg5#xTDO zH2Jw|Fo0C#{fdDJxYZzUBl89h1m`hFzM#RTmwPh(X4|_5?Nh5~s^s2NpSkQzh(;Q1 z$PW`iL~(`{wic7_5vx`sD5Zb>$UfT+w+JKO+T=ku4riVRF0a?6%L7w0NaxmzZG`>K z7Pkmeq=l4#JN~CJjYhEhfQP}uMjo=eAKVGVwt&Tp zYyV5PRyde-h67z>*SdzW!i6VJosXIURz}J$!%OxOLQn@*V@#-#o?l$eY(lcxnOURrw@jPvhtwcYmf&Ms}t zB66SAk3IPWKKctB*)(l!a^tdaM`6#YpZz$3A<@Q%AdHR)2DUKjs?Q%jt;VbJMV~+H zxIkO{i$2;M1ofmnoA;_n$#mD1Ke?QVID(f>WOBe*I2eEljL~?8Ikg8I)R5}ppa!a~ z?JlyvbYw*T{30a1xU^k+Yn1DRQ8vJl-piNV8|&h2=Q5OP(^5_}{I|)fBm`Zv{gRqK zff?elMCe+$~&SzZ@D8)^BgT2j(_9O@p@z21J9KBBEcJAz&P> zPDwV{vF_jtPuy*Dryd^IfixKphwYp&Ira|pq&rQ zx(p$+F8`May?F?B5Y8ul+1l>5kB*Gyq3*x3qZilZAfqD3M~_FS%`=feHQ)3)kUOv% z!w&gqO|wBdaO~gcPEC+(gTNztp~)~f0FyYgi7H;fB-sTg?B~duH;llr(c^(Eha9T}D0HXpSRA}v@R6sp?= zQ+{O64;~Z1sX(qF1dQwaGP1qwDaxcp;516$R?R@7$7YCk8jZZ&Zk znF$WJ1ZPsZ0BP)JNL-XAzDTCv(=z~Du=IYxgyZ0VoFh&I4ag1vODBD>H$NyUA;raH zCm?%3OY6;+F(-+@s1~A;bQ2eBjl%7ZeAD~Gjqe|-O#7c%pa1;pk+(Kp|Lnc@K3aY1 z-7jvtT{s;1uZzDPbNAZ#M%wX7?73bae)+-4Bd`B(?2Y_iFWnBh{q@!Aijphjh-uI|14^chsB2x93S|U@}mw#Sv z;9_bG*A3~qI|mcf<7PAEYQtPP5yNIAfxjB(%0qkmI=nn856wDy1o;Vx<(ZzYSQh*> zy7pouTjarEB=Mp_zn%TnGS`G$Dm6}&uyH7eRUaB4R1+zu)j=##XaIIKPRUR6Or-~^ zf>=W5x7H$WbqeCsC%udOEV|Z7iGOQ*zz4fUKYju3RN=UX?S7Um#&libx)?%fZ3#Gk0YsU8wET7^T{corDdDfQR_WU`1ufiVFJsIz(7E zn=;Hj^c>cWaen7~-u?rZ+ouT`7`4kkf?ZZkPw=owbmPRw75Mt;=NH`NgpUUHh_;azjcv!&ni_gXug!Q2?04mgW#yj}7TPZ6y&UMgd*uzE zidp5iwL9hm-G;xbNvCvB9Oi^r z7WF)$d<*C|t8BZ!jNDv-_Q_}pvHkPsgPMWNank+=cZycEMt#@#YH`E@aR3PnBo;j1 z0Tgxx>bmkgHRY!_VJ#76?OS7lutPj3yEM%pKAjvt!{M_}X~~HUeRS9f+{&7rZ1OkMCBb zu6xg>4D<%%1JNh#TaW;@z&m5-ic_0L|kwUe-K^En#*7^-uIHeX)6Iwr>WP z(mjz&FMJab&Aq%mum>9DW|kx0P91;a{V`@N8%E5S1njE7OGd=7oP~A(>`weRU)$4n zZ{(SlPRXbnpRBq7jN>oY=H3f7VeewQwZ!TFBuLJ!NW1q?x^L@--$Z?jh8-qtGj9|Q zJlm3kiK-bkHC&tk%;g|Z`up<)o6sA85(2mFtc1^jm%BARGNtizWA_(qiNrJ)_&Vaq zE29uGc|yJW`nzLHYMD*#10G$fa2vB1F*cXRnMqhL5S^AAGF(YFu`jWpF!ST||7uzh zr|pXUgWXYfoa~{wJD|T*`+q@aDDlX-;{k5hU(dO>Ng7Q^>!}-+N`#b~Q=jn=;Y0QYT z@6&d7Ytk)0ndT}33xIivLy3}rkquC55R)-WHvl71JKIYGatBHI0oCArkHr-^@Xyr3k-6rsM@){Vd73g zV*q>1lR3N|>xL~rylIc;0b5{e+Ay)Z>%m$i9D$WN>(B+{3w;g%P_+y3mVuAP3dL^o z!H=e`Ml|^LEyO7==(`@AVOz#L);F$T8TjX!>&Wic{r56Q(2gK=OH>a-SS}6 z-o`4C)u(PutxL-4xYOqfP?aH?4j{uO!nu1-KCf%$Sk&qh?_KwqQ5$8)`aGx>0x{pG}Zd zPB&}IP6?OP?l#s|9QhB&YjrqTYpcGlB7P$rX=;v(9Fri#zOT_OVjzGp-tyP zgPy-zpGh^XS{E!-$J<=MM>C%Ov6XSFb-KA3TyEU7#D6DiRW<$p}cH`If1(jjXEhM{6i@k%mDs%g*IM z1M9X+2+?c_G-~e|*V#2s5s3^nDX5 zwSVpD81mpOEigB%I~U?Z`aJo`ig8OrebmK07Z}k&eL}&IS=-z84Tt(0(Re)!&-!Fy zbh0p|KJaSW;~>NCuzfz7XQ4}kftufX=0gX>{p|y+f!z(|Pc-$LveMV82lsm51y>_4 zTTOu$X%0@5Rk~pgGwJDSUHI^IHknK8Q8OPWkZzZ1#p_v?AKpI~*0DcDe8$8S>@$?M zt{+eugIVzc>yN_dR`318@76D@fodNHzmK?G3-@bS4qWYr?6{iylf@i=NuZLu3zR-` zy|?K<+mBBc3Y7bpNsl(=ozle^g1w)Qk=eSLt}`6edMY@9DiD3G|jr?4S}u zo5w&LUwcq2ephq50CSz#dl}c(u3;1WIc8a*B92_o%3V@nz1(?Vb)XM{(siNd_i_9O z=b_H=ZGDmYyxbxI%}V84WfeKOC@RTBkPIqv&WUMh^3^&*6$hU%E~;D*PrykcD@-?g z4hamEslRm&@gj0a)EgD${m%&{v6y7tlKN@bo5}g6`MNI~yeaLC3d)&y5d@`CA)Aku zTr%ATr4F+#6?&)Pt?iBDHUt(1d?zkVeRO*NfrppoEWuMC@wo~rS=aTtNxL)~M_47s zsgK8dMSq=TDv_O&bDxzfSZMQ;LkiJpR!F~b5%lc-(j3~1E!4?h=)P8Fp*mZ$E)V@< zUuqTjdV!#4xMxi$W_OR5^`KUr}saaHdk<`$h;uh zKomT!yY?^1^YTO~@s71M*HEv15?WaVDr>4L=W z<+(qi4eNEZ?Y-FFq z`JM3yfZ_AKnvh=b9K`^JC3srp4Y~C+T++Sf>HX1P{2n&sLu-*m(6k15v1Hp;?Dt~T z;qdi`TiV~RO!eGgYMp-Ns@T19=pO_4Ibl!yDvTZVa$V=OUxf-@o}pUMQ8cJaA&Uy+ zw7O@zbh<02He-Dk2=u?3KRx#}o9VePkv9I|wVPqUVOW0r?6bvdAIDsqmI0L{$0k3i z@@bAtt(}({=B88Z)tdYH+Iy{N=y_uyTCk$%81u5g`pY4&Gec9Cu%JF69^wvXBvL&a zI_}p+7cFtC6FxgLXCI#b^y3Iz5gu<^MDJ*cNPjm%wJ0N}UGj^ZchjPMJTyM;Cf_`i zGgPb$^RqNH6AoT8aVGee3kG7{V#D0R+sCR;1Jjc)>pGP~#|-Dy6NQw0$?|xd*m@<> zu(eDMRgZ7unw#sBzW;Qn7JKQ-w{{p}r|<_ma&n5S<`RX7tgj0%L4TSP; zO+FAuZwtf{w+7y>#X?{5c}3Hb9%pU|z-_@IdYm{P8=Kaa)zl_=C%t2!PmDkMF*Zhj z26X%P*3ZF1Uz0lgan`fsz>NYQ`%6ftE(D{>Vq?s@ySU0Z;yVqfNDmUovzMXMWK2dXv|Qp|C}#ar~q~-*KF< z$FPcH3c6~5zxPeULp$a&vuWe>NEloCN~G`FEsvB zI$IaM#X7BWC?~XzlZ_dA61sE_zl*34eAJ?mn0uM2Gta7pROvsbcHs0GAUWAj1JL&P z2F;|%Ng3+rm^Auwdq$|f+3V3fIyS! z1`@p4Pk)5J`7_Iw^u$TdF2`Y_&g(`}eK_IrTBe(ww+UqSMybw*RYPo$<)YUF@bLGm zKE%K0`R+n207t2wSHB`%|L~;;m-NK{hHDr$<^ci&6^;P4YX}fDEYtP8_U^kiRWMa_ z&3l{b=+iIY`~{Vc5H2`e5VA`k2i|U31LvYW+XwG01b+bN+3da&{9^5&y*Y2pm@y^$ zIh_BPo4?zbiuO@QgQSt`NE$7RX^H2AfJuPqgGm5~EuEAB9{Kc!@%Z z7P*CU)8G%fH{;)1>%%2J=+msgoW|^s1X!MvpV$Cp@2Xud?le#A|CSp69w2-Gp@)J| z*|`;EPw%_|!g=yF(y1@a{q>b^k6?QSjOT^Z0Z($_^d8A1&vzSJzE<*?E0#t5yeRe0 zWLqi&XPMML2jAZbxVAsx9W|Z?H%@;G&VDa`t$XWx5N0l>>oo6F_TD)EA`vK9fOp>p za&8Hr`j!HLGZBzI@0-q<;5N^`R$^efDelU@@a}tF+$tYH>sT0BAKy5?b7sZ}P%Z$P zX8Zj&YWx(>clUpAg}{O@xOnv$|8d}t<&P`a1kZuO=zoKy+Y%zGFBjg4HaXEXOQd4eSrFjlllU6JddWt!7OEh%^q! f=mPX+{PGp4dsP0J;D6)x+L~1xKD)Z|+aLZ9=AFf~ literal 0 HcmV?d00001 diff --git a/test/e2e/screens/788fe47/calibrated-chrome/before.png b/test/e2e/screens/788fe47/calibrated-chrome/before.png new file mode 100644 index 0000000000000000000000000000000000000000..ad67df965364a6cc1c660b15f00e9e5bfa9334db GIT binary patch literal 15420 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�mIA#1#l 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 diff --git a/test/src/browser/screen-shooter/index.js b/test/src/browser/screen-shooter/index.js index 2b0844199..687eb5f05 100644 --- a/test/src/browser/screen-shooter/index.js +++ b/test/src/browser/screen-shooter/index.js @@ -80,6 +80,7 @@ describe("ElementsScreenShooter", () => { captureSpecs: [captureSpec(rect(0, 0, 100, 80))], ignoreAreas: [], safeArea: band(0, 100), + anchorShift: null, debugLog: "state debug", }, overrides, @@ -282,46 +283,44 @@ describe("ElementsScreenShooter", () => { assert.calledOnceWithExactly(operationsStubs.disableIframeAnimations, browser, browserSideScreenshooter); }); - it("should retry retriable errors and validate capture area stability on retry", async () => { - const page = createMockPage(); - const changedState = createCaptureState({ - captureSpecs: [captureSpec(rect(0, 0, 100, 120))], - safeArea: band(0, 100), - }); - const stableState = createCaptureState({ - captureSpecs: page.captureSpecs, - ignoreAreas: page.ignoreAreas, - safeArea: page.safeArea, - }); + it("should preload and do best-effort capture when capture area size changes mid-capture", async () => { + const page = createMockPage({ captureSpecs: [captureSpec(rect(0, 0, 100, 80))] }); + const changedState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 0, 100, 120))] }); + const preloadState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 0, 100, 120))] }); + const settledState = createCaptureState({ captureSpecs: page.captureSpecs, safeArea: page.safeArea }); browserSideScreenshooter.call .onCall(0) - .resolves(page) + .resolves(page) // prepareElementsScreenshot .onCall(1) - .resolves(changedState) + .resolves(changedState) // getCaptureState phase 1 → size change .onCall(2) - .resolves(page) + .resolves(preloadState) // getCaptureState in preload .onCall(3) - .resolves(stableState) + .resolves({}) // scrollTo restore after preload .onCall(4) - .resolves(stableState) + .resolves(undefined) // captureAnchorBaseline .onCall(5) - .resolves(stableState); + .resolves(settledState); // getCaptureState phase 2 - const result = await screenShooter.capture(".element", {}, 2); + const result = await screenShooter.capture(".element", { compositeImage: false }); assert.deepEqual( browserSideScreenshooter.call .getCalls() .map(call => call.args[0]) - .filter(method => method === "prepareElementsScreenshot"), - ["prepareElementsScreenshot", "prepareElementsScreenshot"], + .filter(m => m === "prepareElementsScreenshot"), + ["prepareElementsScreenshot"], + ); + assert.deepEqual( + browserSideScreenshooter.call + .getCalls() + .map(call => call.args[0]) + .filter(m => m === "captureAnchorBaseline"), + ["captureAnchorBaseline"], ); assert.calledOnce(camera.captureViewportImage); - assert.deepEqual(result, { - image: renderedImage, - meta: page, - }); + assert.deepEqual(result, { image: renderedImage, meta: page }); }); it("should return rendered image and page meta", async () => { @@ -394,6 +393,7 @@ describe("ElementsScreenShooter", () => { state.safeArea, state.captureSpecs, state.ignoreAreas, + 0, ); assert.deepEqual(result, { image: renderedImage, @@ -467,17 +467,14 @@ describe("ElementsScreenShooter", () => { ]); }); - it("should continue capture on the last allowed attempt when capture area size changes", async () => { - const page = createMockPage({ - captureSpecs: [captureSpec(rect(0, 0, 100, 80))], - }); - const changedState = createCaptureState({ - captureSpecs: [captureSpec(rect(0, 0, 100, 120))], - }); + it("should pass correction delta to registerViewportImageAtOffset during best-effort pass", async () => { + const page = createMockPage({ captureSpecs: [captureSpec(rect(0, 34, 100, 80))], scrollOffset: 0 }); + const changedState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 34, 100, 120))] }); + const preloadState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 34, 100, 120))] }); const settledState = createCaptureState({ - captureSpecs: [captureSpec(rect(0, 100, 100, 20))], - safeArea: band(100, 100), - scrollOffset: 100, + captureSpecs: [captureSpec(rect(0, -246, 100, 80))], + scrollOffset: 280, + anchorShift: -287, }); browserSideScreenshooter.call @@ -486,20 +483,64 @@ describe("ElementsScreenShooter", () => { .onCall(1) .resolves(changedState) .onCall(2) - .resolves({ debugLog: "scroll debug" }) + .resolves(preloadState) .onCall(3) - .resolves(settledState) + .resolves({}) .onCall(4) + .resolves(undefined) + .onCall(5) + .resolves(settledState) + .onCall(6) .resolves({ debugLog: "restore debug" }); - const result = await screenShooter.capture(".element", { compositeImage: true }, 1); + await screenShooter.capture(".element", { compositeImage: false }); - assert.calledOnce(validationStubs.assertCorrectCaptureAreaBounds); - assert.calledTwice(camera.captureViewportImage); - assert.deepEqual(result, { - image: renderedImage, - meta: page, + assert.calledOnceWithExactly( + compositeImage.registerViewportImageAtOffset, + viewportImage, + settledState.safeArea, + settledState.captureSpecs, + settledState.ignoreAreas, + -7, + ); + }); + + it("should pass zero correction when observed shift is unavailable", async () => { + const page = createMockPage({ captureSpecs: [captureSpec(rect(0, 34, 100, 80))], scrollOffset: 0 }); + const changedState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 34, 100, 120))] }); + const preloadState = createCaptureState({ captureSpecs: [captureSpec(rect(0, 34, 100, 120))] }); + const settledState = createCaptureState({ + captureSpecs: [captureSpec(rect(0, -246, 100, 80))], + scrollOffset: 280, + anchorShift: null, }); + + browserSideScreenshooter.call + .onCall(0) + .resolves(page) + .onCall(1) + .resolves(changedState) + .onCall(2) + .resolves(preloadState) + .onCall(3) + .resolves({}) + .onCall(4) + .resolves(undefined) + .onCall(5) + .resolves(settledState) + .onCall(6) + .resolves({ debugLog: "restore debug" }); + + await screenShooter.capture(".element", { compositeImage: false }); + + assert.calledOnceWithExactly( + compositeImage.registerViewportImageAtOffset, + viewportImage, + settledState.safeArea, + settledState.captureSpecs, + settledState.ignoreAreas, + 0, + ); }); it("should warn when the captured area still overflows the viewport and allowViewportOverflow is false", async () => { From 5fc2c26108ce5c5e3dffe64b20c49cefecf8324b Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 14:19:57 +0300 Subject: [PATCH 24/29] test: exclude fixtures from unit tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eae91dbfa..240daa9f3 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "lint": "eslint --cache . && prettier --check .", "reformat": "eslint --fix . && prettier --write .", "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", - "test-unit": "_mocha \"test/!(integration|e2e|browser-env)/**/*.[jt]s\"", + "test-unit": "_mocha \"test/!(integration|e2e|browser-env|fixtures)/**/*.[jt]s\"", "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", From 6192614ee2b254a626a3e075c0f73466508b9ee0 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 14:42:07 +0300 Subject: [PATCH 25/29] test: fix tests with node types stripping --- package.json | 4 ++-- test/src/browser/cdp/connection.ts | 2 +- test/src/browser/cdp/selectivity/css-selectivity.ts | 2 +- test/src/browser/cdp/selectivity/hash-provider.ts | 2 +- test/src/browser/cdp/selectivity/hash-reader.ts | 2 +- test/src/browser/cdp/selectivity/hash-writer.ts | 2 +- test/src/browser/cdp/selectivity/index.ts | 2 +- test/src/browser/cdp/selectivity/js-selectivity.ts | 2 +- test/src/browser/cdp/selectivity/runner.ts | 2 +- test/src/browser/cdp/selectivity/test-dependencies-reader.ts | 2 +- test/src/browser/cdp/selectivity/test-dependencies-writer.ts | 2 +- test/src/browser/cdp/selectivity/utils.ts | 2 +- test/src/browser/commands/clearSession.ts | 2 +- test/src/browser/commands/openAndWait.ts | 2 +- test/src/browser/commands/waitForStaticToLoad.ts | 2 +- test/src/cli/commands/config/index.ts | 2 +- test/src/cli/commands/list-browsers/index.ts | 2 +- test/src/cli/commands/list-tests/index.ts | 2 +- test/src/runner/browser-env/vite/manual-mock.ts | 2 +- test/src/runner/browser-env/vite/server.ts | 2 +- test/src/test-collection/index.ts | 2 +- test/src/test-reader/controllers/also-controller.ts | 2 +- test/src/utils/fs.ts | 2 +- test/src/utils/module.ts | 2 +- test/src/utils/page-loader.ts | 2 +- test/src/worker/browser-env/runner/test-runner/index.ts | 2 +- 26 files changed, 27 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 240daa9f3..7bf811230 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "lint": "eslint --cache . && prettier --check .", "reformat": "eslint --fix . && prettier --write .", "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", - "test-unit": "_mocha \"test/!(integration|e2e|browser-env|fixtures)/**/*.[jt]s\"", - "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", + "test-unit": "NODE_OPTIONS=\"${NODE_OPTIONS:+$NODE_OPTIONS }--no-experimental-strip-types\" _mocha \"test/!(integration|e2e|browser-env|fixtures)/**/*.[jt]s\"", + "test-unit:coverage": "NODE_OPTIONS=\"${NODE_OPTIONS:+$NODE_OPTIONS }--no-experimental-strip-types\" c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", "test-integration": "TS_NODE_TRANSPILE_ONLY=1 mocha -r ts-node/register test/integration/*/**", diff --git a/test/src/browser/cdp/connection.ts b/test/src/browser/cdp/connection.ts index 9c37aad08..08ac1dcfc 100644 --- a/test/src/browser/cdp/connection.ts +++ b/test/src/browser/cdp/connection.ts @@ -1,5 +1,5 @@ import { WebSocket, WebSocketServer } from "ws"; -import sinon, { SinonStub, SinonFakeTimers } from "sinon"; +import sinon, { type SinonStub, type SinonFakeTimers } from "sinon"; import proxyquire from "proxyquire"; import { CDPConnection } from "src/browser/cdp/connection"; import { CDPError, CDPConnectionTerminatedError } from "src/browser/cdp/error"; diff --git a/test/src/browser/cdp/selectivity/css-selectivity.ts b/test/src/browser/cdp/selectivity/css-selectivity.ts index 0d49292e4..ed4453a98 100644 --- a/test/src/browser/cdp/selectivity/css-selectivity.ts +++ b/test/src/browser/cdp/selectivity/css-selectivity.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; describe("CDP/Selectivity/CSSSelectivity", () => { diff --git a/test/src/browser/cdp/selectivity/hash-provider.ts b/test/src/browser/cdp/selectivity/hash-provider.ts index c77bfea6c..acc552257 100644 --- a/test/src/browser/cdp/selectivity/hash-provider.ts +++ b/test/src/browser/cdp/selectivity/hash-provider.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import { EventEmitter } from "events"; diff --git a/test/src/browser/cdp/selectivity/hash-reader.ts b/test/src/browser/cdp/selectivity/hash-reader.ts index a49023055..f3ef80ee2 100644 --- a/test/src/browser/cdp/selectivity/hash-reader.ts +++ b/test/src/browser/cdp/selectivity/hash-reader.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; describe("CDP/Selectivity/HashReader", () => { diff --git a/test/src/browser/cdp/selectivity/hash-writer.ts b/test/src/browser/cdp/selectivity/hash-writer.ts index da1443bab..dd8a8e249 100644 --- a/test/src/browser/cdp/selectivity/hash-writer.ts +++ b/test/src/browser/cdp/selectivity/hash-writer.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; describe("CDP/Selectivity/HashWriter", () => { diff --git a/test/src/browser/cdp/selectivity/index.ts b/test/src/browser/cdp/selectivity/index.ts index 9aa12a0b5..46facdd55 100644 --- a/test/src/browser/cdp/selectivity/index.ts +++ b/test/src/browser/cdp/selectivity/index.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import type { ExistingBrowser } from "src/browser/existing-browser"; import type { Test } from "src/types"; diff --git a/test/src/browser/cdp/selectivity/js-selectivity.ts b/test/src/browser/cdp/selectivity/js-selectivity.ts index ab6e69cad..e0cd74e45 100644 --- a/test/src/browser/cdp/selectivity/js-selectivity.ts +++ b/test/src/browser/cdp/selectivity/js-selectivity.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub, type SinonStubbedInstance } from "sinon"; +import sinon, { type SinonStub, type SinonStubbedInstance } from "sinon"; import proxyquire from "proxyquire"; import type { CDPTarget } from "src/browser/cdp/domains/target"; import type { CDPDebugger } from "src/browser/cdp/domains/debugger"; diff --git a/test/src/browser/cdp/selectivity/runner.ts b/test/src/browser/cdp/selectivity/runner.ts index 01a228ff7..561cf4ecc 100644 --- a/test/src/browser/cdp/selectivity/runner.ts +++ b/test/src/browser/cdp/selectivity/runner.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import type { SelectivityRunner } from "src/browser/cdp/selectivity/runner"; import type { Test } from "src/types"; diff --git a/test/src/browser/cdp/selectivity/test-dependencies-reader.ts b/test/src/browser/cdp/selectivity/test-dependencies-reader.ts index afedf6e33..814383c56 100644 --- a/test/src/browser/cdp/selectivity/test-dependencies-reader.ts +++ b/test/src/browser/cdp/selectivity/test-dependencies-reader.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; describe("CDP/Selectivity/TestDependenciesReader", () => { diff --git a/test/src/browser/cdp/selectivity/test-dependencies-writer.ts b/test/src/browser/cdp/selectivity/test-dependencies-writer.ts index 6b58f7570..1b947127d 100644 --- a/test/src/browser/cdp/selectivity/test-dependencies-writer.ts +++ b/test/src/browser/cdp/selectivity/test-dependencies-writer.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; describe("CDP/Selectivity/TestDependenciesWriter", () => { diff --git a/test/src/browser/cdp/selectivity/utils.ts b/test/src/browser/cdp/selectivity/utils.ts index 14bfff688..88be96ba8 100644 --- a/test/src/browser/cdp/selectivity/utils.ts +++ b/test/src/browser/cdp/selectivity/utils.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub, type SinonStubbedInstance } from "sinon"; +import sinon, { type SinonStub, type SinonStubbedInstance } from "sinon"; import proxyquire from "proxyquire"; import type { CDPRuntime } from "src/browser/cdp/domains/runtime"; diff --git a/test/src/browser/commands/clearSession.ts b/test/src/browser/commands/clearSession.ts index 19f753d1e..098937987 100644 --- a/test/src/browser/commands/clearSession.ts +++ b/test/src/browser/commands/clearSession.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import { mkExistingBrowser_ as mkBrowser_, mkSessionStub_ } from "../utils"; diff --git a/test/src/browser/commands/openAndWait.ts b/test/src/browser/commands/openAndWait.ts index f691c7ade..7bd475dcb 100644 --- a/test/src/browser/commands/openAndWait.ts +++ b/test/src/browser/commands/openAndWait.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import FakeTimers from "@sinonjs/fake-timers"; import PageLoader from "src/utils/page-loader"; diff --git a/test/src/browser/commands/waitForStaticToLoad.ts b/test/src/browser/commands/waitForStaticToLoad.ts index 08703d7b0..5d4a50ac4 100644 --- a/test/src/browser/commands/waitForStaticToLoad.ts +++ b/test/src/browser/commands/waitForStaticToLoad.ts @@ -1,4 +1,4 @@ -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import FakeTimers from "@sinonjs/fake-timers"; import { mkExistingBrowser_ as mkBrowser_, mkSessionStub_ as mkSessionStubOrigin_ } from "../utils"; diff --git a/test/src/cli/commands/config/index.ts b/test/src/cli/commands/config/index.ts index efa5cf0bd..69bec5700 100644 --- a/test/src/cli/commands/config/index.ts +++ b/test/src/cli/commands/config/index.ts @@ -1,5 +1,5 @@ import { Command } from "@gemini-testing/commander"; -import sinon, { SinonStub, SinonSpy } from "sinon"; +import sinon, { type SinonStub, type SinonSpy } from "sinon"; import { Testplane } from "../../../../../src/testplane"; import * as testplaneCli from "../../../../../src/cli"; diff --git a/test/src/cli/commands/list-browsers/index.ts b/test/src/cli/commands/list-browsers/index.ts index 833eca3ac..65848a396 100644 --- a/test/src/cli/commands/list-browsers/index.ts +++ b/test/src/cli/commands/list-browsers/index.ts @@ -1,5 +1,5 @@ import { Command } from "@gemini-testing/commander"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import { Testplane } from "../../../../../src/testplane"; import * as testplaneCliOriginal from "../../../../../src/cli"; diff --git a/test/src/cli/commands/list-tests/index.ts b/test/src/cli/commands/list-tests/index.ts index 80171e961..7600f7eb4 100644 --- a/test/src/cli/commands/list-tests/index.ts +++ b/test/src/cli/commands/list-tests/index.ts @@ -1,7 +1,7 @@ import path from "node:path"; import { Command } from "@gemini-testing/commander"; import fs from "fs-extra"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import { Formatters } from "../../../../../src/test-collection"; diff --git a/test/src/runner/browser-env/vite/manual-mock.ts b/test/src/runner/browser-env/vite/manual-mock.ts index 8f1b98559..b07af1b51 100644 --- a/test/src/runner/browser-env/vite/manual-mock.ts +++ b/test/src/runner/browser-env/vite/manual-mock.ts @@ -1,6 +1,6 @@ import path from "node:path"; import fs from "node:fs/promises"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import type { Stats } from "node:fs"; import { ManualMock } from "../../../../../src/runner/browser-env/vite/manual-mock"; diff --git a/test/src/runner/browser-env/vite/server.ts b/test/src/runner/browser-env/vite/server.ts index cc93d929a..0962ffc04 100644 --- a/test/src/runner/browser-env/vite/server.ts +++ b/test/src/runner/browser-env/vite/server.ts @@ -1,5 +1,5 @@ import proxyquire from "proxyquire"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import Vite from "vite"; import chalk from "chalk"; diff --git a/test/src/test-collection/index.ts b/test/src/test-collection/index.ts index 689fcfa5e..ec1e7d4a5 100644 --- a/test/src/test-collection/index.ts +++ b/test/src/test-collection/index.ts @@ -1,7 +1,7 @@ import path from "node:path"; import _ from "lodash"; import proxyquire from "proxyquire"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import { TestCollection, Formatters, AVAILABLE_FORMATTERS } from "../../../src/test-collection"; import { Test } from "../../../src/test-reader/test-object"; diff --git a/test/src/test-reader/controllers/also-controller.ts b/test/src/test-reader/controllers/also-controller.ts index 3e14ec8c0..8c0e97eda 100644 --- a/test/src/test-reader/controllers/also-controller.ts +++ b/test/src/test-reader/controllers/also-controller.ts @@ -1,5 +1,5 @@ import { EventEmitter } from "node:events"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import { AlsoController } from "../../../../src/test-reader/controllers/also-controller"; import { TreeBuilder } from "../../../../src/test-reader/tree-builder"; import { ConfigurableTestObject } from "../../../../src/test-reader/test-object/configurable-test-object"; diff --git a/test/src/utils/fs.ts b/test/src/utils/fs.ts index 2bab7f4a4..545c8906e 100644 --- a/test/src/utils/fs.ts +++ b/test/src/utils/fs.ts @@ -1,5 +1,5 @@ import fs from "fs"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import { exists } from "../../../src/utils/fs"; describe("utils/fs", () => { diff --git a/test/src/utils/module.ts b/test/src/utils/module.ts index 5c2a001d4..59f6890ba 100644 --- a/test/src/utils/module.ts +++ b/test/src/utils/module.ts @@ -1,5 +1,5 @@ import path from "path"; -import sinon, { SinonStub } from "sinon"; +import sinon, { type SinonStub } from "sinon"; import proxyquire from "proxyquire"; import { requireModule as realRequireModule } from "../../../src/utils/module"; diff --git a/test/src/utils/page-loader.ts b/test/src/utils/page-loader.ts index 351e2b30b..00f3b06bd 100644 --- a/test/src/utils/page-loader.ts +++ b/test/src/utils/page-loader.ts @@ -1,5 +1,5 @@ import proxyquire from "proxyquire"; -import sinon, { SinonStub, SinonSpy } from "sinon"; +import sinon, { type SinonStub, type SinonSpy } from "sinon"; import FakeTimers from "@sinonjs/fake-timers"; import { mkSessionStub_, mkMockStub_ } from "../browser/utils"; import type PageLoaderType from "../../../src/utils/page-loader"; diff --git a/test/src/worker/browser-env/runner/test-runner/index.ts b/test/src/worker/browser-env/runner/test-runner/index.ts index 1cd01e818..617c8b311 100644 --- a/test/src/worker/browser-env/runner/test-runner/index.ts +++ b/test/src/worker/browser-env/runner/test-runner/index.ts @@ -3,7 +3,7 @@ import crypto from "node:crypto"; import clearRequire from "clear-require"; import { EventEmitter } from "node:stream"; import _ from "lodash"; -import sinon, { SinonStub, SinonFakeTimers } from "sinon"; +import sinon, { type SinonStub, type SinonFakeTimers } from "sinon"; import proxyquire from "proxyquire"; import type NodejsEnvRunnerOriginal from "../../../../../../src/worker/runner/test-runner"; From 4a5c353b36ecf63997e05579188072031c7f8446 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 22 May 2026 15:35:06 +0300 Subject: [PATCH 26/29] test: fix integration screenshot tests --- .github/workflows/standalone-e2e.yml | 28 ++++++++++++++++++ package.json | 6 ++-- scripts/run-node-without-type-stripping.js | 27 +++++++++++++++++ .../screen-shooter/screen-shooter.test.ts | 13 ++++++-- .../deterministic-changing-dimensions.png | Bin 34595 -> 35699 bytes .../screens/dynamic-sticky-menu-safe-area.png | Bin 106543 -> 104064 bytes .../fixed-block-slightly-off-viewport.png | Bin 4285 -> 3971 bytes .../screens/partially-offscreen.png | Bin 4005 -> 3724 bytes .../visible-top-long-block-overflow.png | Bin 3718 -> 5699 bytes test/integration/screen-shooter/utils.ts | 8 +++-- 10 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 scripts/run-node-without-type-stripping.js diff --git a/.github/workflows/standalone-e2e.yml b/.github/workflows/standalone-e2e.yml index 6a87d7582..4059a3857 100644 --- a/.github/workflows/standalone-e2e.yml +++ b/.github/workflows/standalone-e2e.yml @@ -7,6 +7,9 @@ on: jobs: integration-test: runs-on: ubuntu-latest + env: + DOCKER_IMAGE_NAME: html-reporter-browsers + strategy: matrix: node-version: [20.18.1] @@ -36,7 +39,32 @@ jobs: - name: Build project run: npm run build + - name: "Prepare screenshot tests: Cache browser docker image" + uses: actions/cache@v3 + with: + path: ~/.docker/cache + key: docker-browser-image-testplane + + - name: "Prepare screenshot tests: Pull browser docker image" + run: | + mkdir -p ~/.docker/cache + if [ -f ~/.docker/cache/image.tar ]; then + docker load -i ~/.docker/cache/image.tar + else + docker pull yinfra/html-reporter-browsers + docker save yinfra/html-reporter-browsers -o ~/.docker/cache/image.tar + fi + + - name: "Prepare screenshot tests: Run browser docker image" + run: docker run -d --name ${{ env.DOCKER_IMAGE_NAME }} -it --rm --network=host $(which colima >/dev/null || echo --add-host=host.docker.internal:0.0.0.0) yinfra/html-reporter-browsers + - name: Run integration tests for ${{ matrix.browser }} env: BROWSER: ${{ matrix.browser }} run: npm run test-integration + + - name: "Screenshot tests: Stop browser docker image" + if: always() + run: | + docker kill ${{ env.DOCKER_IMAGE_NAME }} || true + docker rm ${{ env.DOCKER_IMAGE_NAME }} || true diff --git a/package.json b/package.json index 7bf811230..5d61e469c 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,11 @@ "lint": "eslint --cache . && prettier --check .", "reformat": "eslint --fix . && prettier --write .", "prettier-watch": "onchange '**' --exclude-path .prettierignore -- prettier --write {{changed}}", - "test-unit": "NODE_OPTIONS=\"${NODE_OPTIONS:+$NODE_OPTIONS }--no-experimental-strip-types\" _mocha \"test/!(integration|e2e|browser-env|fixtures)/**/*.[jt]s\"", - "test-unit:coverage": "NODE_OPTIONS=\"${NODE_OPTIONS:+$NODE_OPTIONS }--no-experimental-strip-types\" c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" _mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", + "test-unit": "node scripts/run-node-without-type-stripping.js ./node_modules/mocha/bin/_mocha \"test/!(integration|e2e|browser-env|fixtures)/**/*.[jt]s\"", + "test-unit:coverage": "c8 --all --src=src --reporter=html --reporter=text-summary --exclude=\"build/**\" --exclude=\"test/**\" --exclude=\"**/*.d.ts\" node scripts/run-node-without-type-stripping.js ./node_modules/mocha/bin/_mocha \"test/!(integration|browser-env|e2e)/**/*.[jt]s\"", "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", - "test-integration": "TS_NODE_TRANSPILE_ONLY=1 mocha -r ts-node/register test/integration/*/**", + "test-integration": "TS_NODE_TRANSPILE_ONLY=1 node scripts/run-node-without-type-stripping.js ./node_modules/mocha/bin/_mocha -r ts-node/register test/integration/*/**", "test-e2e": "npm run test-e2e:generate-fixtures && npm run test-e2e:run-tests", "test-e2e:run-tests": "node bin/testplane --config test/e2e/testplane.config.ts", "test-e2e:generate-fixtures": "node bin/testplane --config test/e2e/fixtures/basic-report/testplane.config.ts || true", diff --git a/scripts/run-node-without-type-stripping.js b/scripts/run-node-without-type-stripping.js new file mode 100644 index 000000000..2c536cf28 --- /dev/null +++ b/scripts/run-node-without-type-stripping.js @@ -0,0 +1,27 @@ +"use strict"; + +const { spawnSync } = require("node:child_process"); + +const DISABLE_TYPE_STRIPPING_FLAG = "--no-experimental-strip-types"; + +const supportsDisableTypeStripping = () => { + const result = spawnSync(process.execPath, [DISABLE_TYPE_STRIPPING_FLAG, "-e", ""], { + stdio: "ignore", + }); + + return result.status === 0; +}; + +const nodeArgs = supportsDisableTypeStripping() ? [DISABLE_TYPE_STRIPPING_FLAG] : []; +const commandArgs = process.argv.slice(2); + +const result = spawnSync(process.execPath, [...nodeArgs, ...commandArgs], { + stdio: "inherit", + env: process.env, +}); + +if (result.error) { + throw result.error; +} + +process.exit(result.status ?? 1); diff --git a/test/integration/screen-shooter/screen-shooter.test.ts b/test/integration/screen-shooter/screen-shooter.test.ts index e376cc861..9d28084da 100644 --- a/test/integration/screen-shooter/screen-shooter.test.ts +++ b/test/integration/screen-shooter/screen-shooter.test.ts @@ -18,6 +18,10 @@ import { closeServer, startFixtureServer } from "./utils"; const SCREENSHOTS_PATH = path.join(__dirname, "screens"); const HORIZONTAL_OVERFLOW_WARNING_PART = "outside of horizontal viewport bounds"; const TEMP_DIR_PREFIX = "testplane-elements-screen-shooter-"; +const shouldUseLocalBrowser = Boolean(process.env.USE_LOCAL_BROWSER); +const SCREENSHOOTER_BROWSER_CONFIG = shouldUseLocalBrowser + ? BROWSER_CONFIG + : { ...BROWSER_CONFIG, gridUrl: "http://127.0.0.1:4444/" }; const createScreenShooter = async (browser: WdioBrowser): Promise => { const camera = Camera.create("auto", () => browser.takeScreenshot()); @@ -45,7 +49,7 @@ describe("ElementsScreenShooter integration", function () { beforeEach(async () => { tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), TEMP_DIR_PREFIX)); browser = await launchBrowser({ - ...BROWSER_CONFIG, + ...SCREENSHOOTER_BROWSER_CONFIG, windowSize: "1280x1000", }); }); @@ -209,14 +213,19 @@ describe("ElementsScreenShooter integration", function () { it("keeps fractional checkpoint offsets stable during replay", async () => { assert.ok(browser); - const browserConfig = _.cloneDeep(BROWSER_CONFIG); + const browserConfig = _.cloneDeep(SCREENSHOOTER_BROWSER_CONFIG); // This test is only applicable to Chrome, it's hard to replicate the issue in firefox if (BROWSER_CONFIG.desiredCapabilities.browserName !== "chrome") { return; } + const chromeOptions = _.get(browserConfig.desiredCapabilities, "goog:chromeOptions", {}); + const chromeArgs = _.get(chromeOptions, "args", []); + _.set(browserConfig.desiredCapabilities, "goog:chromeOptions", { + ...chromeOptions, args: [ + ...chromeArgs, "--force-device-scale-factor=3", "--high-dpi-support=1", "--screen-info={devicePixelRatio=3}", diff --git a/test/integration/screen-shooter/screens/deterministic-changing-dimensions.png b/test/integration/screen-shooter/screens/deterministic-changing-dimensions.png index 31a88f5fdb0f19abebc8687e373e6fb9b8a454c0..44f9fb7beca2bd1f830635279dc787071411b57a 100644 GIT binary patch literal 35699 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 Pzc)hPdF{+AA8q}A?3lKA literal 34595 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�mIA#1#l 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