@testivai/witness-playwright 2.0.8 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capture/full-page.d.ts +22 -0
- package/dist/capture/full-page.js +42 -0
- package/dist/snapshot.js +9 -26
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CDPSession, Page } from '@playwright/test';
|
|
2
|
+
import { type CaptureLog } from '@testivai/witness';
|
|
3
|
+
/**
|
|
4
|
+
* Full-page screenshot through CDP: wait for a fresh frame, measure the
|
|
5
|
+
* content, then capture beyond the viewport until two captures in a row match
|
|
6
|
+
* (at most MAX_STABLE_CAPTURES from @testivai/witness).
|
|
7
|
+
*
|
|
8
|
+
* Chrome can hand back a frame painted with styles resolved against the wrong
|
|
9
|
+
* viewport while it sets up a beyond-viewport capture: on testivai-site's CI,
|
|
10
|
+
* em-sized text on the home page was drawn at its `max-width: 480px` size in
|
|
11
|
+
* some captures, so an unchanged page read as 4.13% changed while its measured
|
|
12
|
+
* layout matched the baseline. See capture/stable-capture.ts in
|
|
13
|
+
* @testivai/witness, which the standalone CLI shares.
|
|
14
|
+
*
|
|
15
|
+
* A stable page costs one extra screenshot.
|
|
16
|
+
*
|
|
17
|
+
* @param page The page being captured; used for the in-page frame wait.
|
|
18
|
+
* @param client A CDP session attached to `page`.
|
|
19
|
+
* @param log Optional debug sink.
|
|
20
|
+
* @returns The PNG bytes of the kept capture.
|
|
21
|
+
*/
|
|
22
|
+
export declare function captureFullPageScreenshot(page: Page, client: CDPSession, log?: CaptureLog): Promise<Buffer>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.captureFullPageScreenshot = captureFullPageScreenshot;
|
|
4
|
+
const witness_1 = require("@testivai/witness");
|
|
5
|
+
/**
|
|
6
|
+
* Full-page screenshot through CDP: wait for a fresh frame, measure the
|
|
7
|
+
* content, then capture beyond the viewport until two captures in a row match
|
|
8
|
+
* (at most MAX_STABLE_CAPTURES from @testivai/witness).
|
|
9
|
+
*
|
|
10
|
+
* Chrome can hand back a frame painted with styles resolved against the wrong
|
|
11
|
+
* viewport while it sets up a beyond-viewport capture: on testivai-site's CI,
|
|
12
|
+
* em-sized text on the home page was drawn at its `max-width: 480px` size in
|
|
13
|
+
* some captures, so an unchanged page read as 4.13% changed while its measured
|
|
14
|
+
* layout matched the baseline. See capture/stable-capture.ts in
|
|
15
|
+
* @testivai/witness, which the standalone CLI shares.
|
|
16
|
+
*
|
|
17
|
+
* A stable page costs one extra screenshot.
|
|
18
|
+
*
|
|
19
|
+
* @param page The page being captured; used for the in-page frame wait.
|
|
20
|
+
* @param client A CDP session attached to `page`.
|
|
21
|
+
* @param log Optional debug sink.
|
|
22
|
+
* @returns The PNG bytes of the kept capture.
|
|
23
|
+
*/
|
|
24
|
+
async function captureFullPageScreenshot(page, client, log) {
|
|
25
|
+
const waitOnce = async () => (await page.evaluate(witness_1.FRESH_FRAME_EXPRESSION)) === true;
|
|
26
|
+
const settle = () => (0, witness_1.settleFreshFrame)(waitOnce, log);
|
|
27
|
+
await settle();
|
|
28
|
+
const layoutMetrics = await client.send('Page.getLayoutMetrics');
|
|
29
|
+
const width = Math.ceil(layoutMetrics.contentSize.width);
|
|
30
|
+
const height = Math.ceil(layoutMetrics.contentSize.height);
|
|
31
|
+
log?.(`page ${width}x${height}, viewport ${layoutMetrics.layoutViewport?.clientWidth}x${layoutMetrics.layoutViewport?.clientHeight}`);
|
|
32
|
+
const data = await (0, witness_1.captureUntilStable)({
|
|
33
|
+
capture: async () => (await client.send('Page.captureScreenshot', {
|
|
34
|
+
format: 'png',
|
|
35
|
+
captureBeyondViewport: true,
|
|
36
|
+
clip: { x: 0, y: 0, width, height, scale: 1 },
|
|
37
|
+
})).data,
|
|
38
|
+
settle,
|
|
39
|
+
log,
|
|
40
|
+
});
|
|
41
|
+
return Buffer.from(data, 'base64');
|
|
42
|
+
}
|
package/dist/snapshot.js
CHANGED
|
@@ -46,6 +46,7 @@ const loader_1 = require("./config/loader");
|
|
|
46
46
|
const ignore_selectors_1 = require("./config/ignore-selectors");
|
|
47
47
|
const element_map_1 = require("./capture/element-map");
|
|
48
48
|
const stabilize_1 = require("./config/stabilize");
|
|
49
|
+
const full_page_1 = require("./capture/full-page");
|
|
49
50
|
/**
|
|
50
51
|
* Generates a safe filename from a URL.
|
|
51
52
|
* @param pageUrl The URL of the page.
|
|
@@ -322,33 +323,15 @@ async function snapshot(page, testInfo, name, config) {
|
|
|
322
323
|
});
|
|
323
324
|
// Wait a bit for styles to apply
|
|
324
325
|
await page.waitForTimeout(100);
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
//
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
pageWidth,
|
|
333
|
-
pageHeight,
|
|
334
|
-
viewportWidth: layoutMetrics.layoutViewport.clientWidth,
|
|
335
|
-
viewportHeight: layoutMetrics.layoutViewport.clientHeight
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
// Capture screenshot with captureBeyondViewport: true
|
|
339
|
-
const screenshot = await client.send('Page.captureScreenshot', {
|
|
340
|
-
format: 'png',
|
|
341
|
-
captureBeyondViewport: true,
|
|
342
|
-
clip: {
|
|
343
|
-
x: 0,
|
|
344
|
-
y: 0,
|
|
345
|
-
width: pageWidth,
|
|
346
|
-
height: pageHeight,
|
|
347
|
-
scale: 1
|
|
348
|
-
}
|
|
349
|
-
});
|
|
326
|
+
// Wait for a fresh frame, measure, and capture beyond the viewport until
|
|
327
|
+
// two captures in a row match: Chrome can return a frame painted for the
|
|
328
|
+
// wrong viewport while it sets up the capture (capture/full-page.ts).
|
|
329
|
+
const captureLog = process.env.TESTIVAI_DEBUG === 'true'
|
|
330
|
+
? (message) => console.log(`[TestivAI] Full-page capture: ${message}`)
|
|
331
|
+
: undefined;
|
|
332
|
+
const png = await (0, full_page_1.captureFullPageScreenshot)(page, client, captureLog);
|
|
350
333
|
// Save the screenshot
|
|
351
|
-
await fs.writeFile(screenshotPath,
|
|
334
|
+
await fs.writeFile(screenshotPath, png);
|
|
352
335
|
// Remove the temporary style tag
|
|
353
336
|
await page.evaluate(`
|
|
354
337
|
const styleTags = document.querySelectorAll('style');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testivai/witness-playwright",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "Playwright adapter for TestivAI Witness — local-first visual regression with pixel + DOM comparison",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"fs-extra": "^11.4.0",
|
|
48
48
|
"sharp": "^0.35.4",
|
|
49
|
-
"@testivai/witness": "2.
|
|
49
|
+
"@testivai/witness": "2.4.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@playwright/test": "^1.63.0",
|