vitest-plugin-vis 1.0.2 → 1.0.4
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/esm/server/browser_provider/playwright.d.ts.map +1 -1
- package/esm/server/browser_provider/playwright.js +1 -2
- package/esm/server/browser_provider/types.d.ts +1 -1
- package/esm/server/browser_provider/webdriverio.d.ts.map +1 -1
- package/esm/server/browser_provider/webdriverio.js +1 -2
- package/esm/server/commands/match_image_snapshot.d.ts.map +1 -1
- package/esm/server/commands/match_image_snapshot.js +29 -22
- package/esm/server/file.d.ts +3 -2
- package/esm/server/file.d.ts.map +1 -1
- package/esm/server/file.js +3 -5
- package/package.json +1 -1
- package/src/server/browser_provider/playwright.ts +1 -2
- package/src/server/browser_provider/types.ts +1 -1
- package/src/server/browser_provider/webdriverio.ts +1 -2
- package/src/server/commands/match_image_snapshot.ts +33 -25
- package/src/server/file.ts +3 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/playwright.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/playwright.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAWrE"}
|
|
@@ -3,11 +3,10 @@ export function playwright(context) {
|
|
|
3
3
|
async takeScreenshot(filePath, selector, options) {
|
|
4
4
|
// The `Locator` type from `vitest` has less props than the `Locator` in `playwright`
|
|
5
5
|
const subject = context.iframe.locator(selector ?? 'body');
|
|
6
|
-
|
|
6
|
+
return subject.screenshot({
|
|
7
7
|
timeout: options?.timeout,
|
|
8
8
|
path: filePath,
|
|
9
9
|
});
|
|
10
|
-
return buffer.toString('base64');
|
|
11
10
|
},
|
|
12
11
|
};
|
|
13
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webdriverio.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/webdriverio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"webdriverio.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/webdriverio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAQtE"}
|
|
@@ -3,8 +3,7 @@ export function webdriverio(context) {
|
|
|
3
3
|
return {
|
|
4
4
|
async takeScreenshot(filePath, selector) {
|
|
5
5
|
const element = await page.$(`${selector ?? 'body'}`);
|
|
6
|
-
|
|
7
|
-
return buffer.toString('base64');
|
|
6
|
+
return element.saveScreenshot(filePath);
|
|
8
7
|
},
|
|
9
8
|
};
|
|
10
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/match_image_snapshot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAA;AAIxE,OAAO,KAAK,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAM9B,MAAM,WAAW,yBAAyB;IACzC,kBAAkB,EAAE,CACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,yBAChB,SAAQ,2BAA2B,EAClC,sBAAsB,EACtB,2BAA2B;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAC9C;IAAC,MAAM,EAAE,MAAM;IAAE,OAAO,EAAE,MAAM;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,
|
|
1
|
+
{"version":3,"file":"match_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/match_image_snapshot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAA;AAIxE,OAAO,KAAK,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAM9B,MAAM,WAAW,yBAAyB;IACzC,kBAAkB,EAAE,CACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,yBAChB,SAAQ,2BAA2B,EAClC,sBAAsB,EACtB,2BAA2B;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAC9C;IAAC,MAAM,EAAE,MAAM;IAAE,OAAO,EAAE,MAAM;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,CA4DlF,CAAA"}
|
|
@@ -19,17 +19,20 @@ export const matchImageSnapshot = async (context, taskId, subject, options) => {
|
|
|
19
19
|
options = {};
|
|
20
20
|
options.timeout = options.timeout ?? (ci ? 30000 : 5000);
|
|
21
21
|
const info = visContext.getSnapshotInfo(context.testPath, taskId, options);
|
|
22
|
-
const
|
|
23
|
-
if (!
|
|
24
|
-
|
|
22
|
+
const baselineBuffer = await file.tryReadFile(info.baselinePath);
|
|
23
|
+
if (!baselineBuffer) {
|
|
24
|
+
if (isBase64String(subject)) {
|
|
25
|
+
await writeSnapshot(info.baselinePath, subject);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
await takeSnapshotByBrowser(context, info.baselinePath, subject, options);
|
|
29
|
+
}
|
|
25
30
|
return;
|
|
26
31
|
}
|
|
27
|
-
const
|
|
28
|
-
const baselineImage = PNG.sync.read(
|
|
29
|
-
const resultImage = PNG.sync.read(
|
|
30
|
-
const [baselineAlignedImage, resultAlignedImage] =
|
|
31
|
-
? [baselineImage, resultImage]
|
|
32
|
-
: alignImageSizes(baselineImage, resultImage);
|
|
32
|
+
const resultBuffer = await takeSnapshot(context, subject, info.resultPath, options);
|
|
33
|
+
const baselineImage = PNG.sync.read(baselineBuffer, { skipRescale: true, checkCRC: false });
|
|
34
|
+
const resultImage = PNG.sync.read(resultBuffer, { skipRescale: true, checkCRC: false });
|
|
35
|
+
const [baselineAlignedImage, resultAlignedImage] = alignImageSizes(baselineImage, resultImage);
|
|
33
36
|
const { pass, diffAmount, diffImage } = compareImage(baselineAlignedImage, resultAlignedImage, options);
|
|
34
37
|
if (pass) {
|
|
35
38
|
if (sizeNotChanged(baselineImage, baselineAlignedImage) && sizeNotChanged(resultImage, resultAlignedImage)) {
|
|
@@ -42,8 +45,7 @@ export const matchImageSnapshot = async (context, taskId, subject, options) => {
|
|
|
42
45
|
Expected: ${resolve(context.project.runner.root, info.baselinePath)}
|
|
43
46
|
Actual: ${resolve(context.project.runner.root, info.resultPath)}`);
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
await writeSnapshot(diffBase64, info.diffPath);
|
|
48
|
+
await writeSnapshotBuffer(info.diffPath, diffImage.data);
|
|
47
49
|
throw new Error(dedent `Snapshot \`${taskId}\` mismatched
|
|
48
50
|
|
|
49
51
|
${options?.failureThreshold
|
|
@@ -60,30 +62,35 @@ export const matchImageSnapshot = async (context, taskId, subject, options) => {
|
|
|
60
62
|
};
|
|
61
63
|
async function takeSnapshot(context, subject, filePath, options) {
|
|
62
64
|
if (isBase64String(subject)) {
|
|
63
|
-
|
|
65
|
+
await writeSnapshot(filePath, subject);
|
|
66
|
+
return Buffer.from(subject, 'base64');
|
|
64
67
|
}
|
|
68
|
+
return takeSnapshotByBrowser(context, filePath, subject, options);
|
|
69
|
+
}
|
|
70
|
+
async function takeSnapshotByBrowser(context, filePath, subject, options) {
|
|
65
71
|
await mkdirp(dirname(filePath));
|
|
66
72
|
const browser = browserApi(context);
|
|
67
73
|
return browser.takeScreenshot(filePath, subject, {
|
|
68
74
|
timeout: options?.timeout,
|
|
69
75
|
});
|
|
70
76
|
}
|
|
71
|
-
async function writeSnapshot(
|
|
77
|
+
async function writeSnapshot(filePath, subject) {
|
|
72
78
|
await mkdirp(dirname(filePath));
|
|
73
|
-
await file.
|
|
74
|
-
|
|
79
|
+
await file.writeFile(filePath, subject, { encoding: 'base64' });
|
|
80
|
+
}
|
|
81
|
+
async function writeSnapshotBuffer(filePath, subject) {
|
|
82
|
+
await mkdirp(dirname(filePath));
|
|
83
|
+
await file.writeFile(filePath, subject);
|
|
75
84
|
}
|
|
76
85
|
function alignImageSizes(baseline, result) {
|
|
86
|
+
if (isSameSize(baseline, result))
|
|
87
|
+
return [baseline, result];
|
|
77
88
|
const size = getMaxSize(baseline, result);
|
|
78
|
-
|
|
79
|
-
baseline = resizeImage(baseline, size);
|
|
80
|
-
}
|
|
81
|
-
if (result.width !== size.width || result.height !== size.height) {
|
|
82
|
-
result = resizeImage(result, size);
|
|
83
|
-
}
|
|
84
|
-
return [baseline, result];
|
|
89
|
+
return [resizeImage(baseline, size), resizeImage(result, size)];
|
|
85
90
|
}
|
|
86
91
|
function resizeImage(image, size) {
|
|
92
|
+
if (isSameSize(image, size))
|
|
93
|
+
return image;
|
|
87
94
|
const resized = new PNG(size);
|
|
88
95
|
PNG.bitblt(image, resized, 0, 0, image.width, image.height);
|
|
89
96
|
return resized;
|
package/esm/server/file.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
1
2
|
export declare const file: {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
tryReadFile(filePath: string): Promise<Buffer | undefined>;
|
|
4
|
+
writeFile: typeof writeFile;
|
|
4
5
|
existFile(filePath: string): Promise<boolean>;
|
|
5
6
|
};
|
|
6
7
|
//# sourceMappingURL=file.d.ts.map
|
package/esm/server/file.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5D,eAAO,MAAM,IAAI;0BACY,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;;wBAI5C,MAAM;CAK1B,CAAA"}
|
package/esm/server/file.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
2
2
|
export const file = {
|
|
3
|
-
async
|
|
4
|
-
return readFile(filePath
|
|
5
|
-
},
|
|
6
|
-
writeFileBase64(filePath, data) {
|
|
7
|
-
return writeFile(filePath, data, { encoding: 'base64' });
|
|
3
|
+
async tryReadFile(filePath) {
|
|
4
|
+
return readFile(filePath).catch(() => undefined);
|
|
8
5
|
},
|
|
6
|
+
writeFile,
|
|
9
7
|
existFile(filePath) {
|
|
10
8
|
return stat(filePath)
|
|
11
9
|
.then((s) => s.isFile())
|
package/package.json
CHANGED
|
@@ -6,11 +6,10 @@ export function playwright(context: BrowserCommandContext): BrowserApi {
|
|
|
6
6
|
async takeScreenshot(filePath, selector, options) {
|
|
7
7
|
// The `Locator` type from `vitest` has less props than the `Locator` in `playwright`
|
|
8
8
|
const subject = context.iframe.locator(selector ?? 'body')
|
|
9
|
-
|
|
9
|
+
return subject.screenshot({
|
|
10
10
|
timeout: options?.timeout,
|
|
11
11
|
path: filePath,
|
|
12
12
|
})
|
|
13
|
-
return buffer.toString('base64')
|
|
14
13
|
},
|
|
15
14
|
}
|
|
16
15
|
}
|
|
@@ -6,8 +6,7 @@ export function webdriverio(context: BrowserCommandContext): BrowserApi {
|
|
|
6
6
|
return {
|
|
7
7
|
async takeScreenshot(filePath, selector) {
|
|
8
8
|
const element = await page.$(`${selector ?? 'body'}`)
|
|
9
|
-
|
|
10
|
-
return buffer.toString('base64')
|
|
9
|
+
return element.saveScreenshot(filePath)
|
|
11
10
|
},
|
|
12
11
|
}
|
|
13
12
|
}
|
|
@@ -47,18 +47,20 @@ export const matchImageSnapshot: BrowserCommand<
|
|
|
47
47
|
options.timeout = options.timeout ?? (ci ? 30000 : 5000)
|
|
48
48
|
|
|
49
49
|
const info = visContext.getSnapshotInfo(context.testPath, taskId, options)
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
|
|
50
|
+
const baselineBuffer = await file.tryReadFile(info.baselinePath)
|
|
51
|
+
if (!baselineBuffer) {
|
|
52
|
+
if (isBase64String(subject)) {
|
|
53
|
+
await writeSnapshot(info.baselinePath, subject)
|
|
54
|
+
} else {
|
|
55
|
+
await takeSnapshotByBrowser(context, info.baselinePath, subject, options)
|
|
56
|
+
}
|
|
53
57
|
return
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
const
|
|
57
|
-
const baselineImage = PNG.sync.read(
|
|
58
|
-
const resultImage = PNG.sync.read(
|
|
59
|
-
const [baselineAlignedImage, resultAlignedImage] =
|
|
60
|
-
? [baselineImage, resultImage]
|
|
61
|
-
: alignImageSizes(baselineImage, resultImage)
|
|
60
|
+
const resultBuffer = await takeSnapshot(context, subject, info.resultPath, options)
|
|
61
|
+
const baselineImage = PNG.sync.read(baselineBuffer, { skipRescale: true, checkCRC: false })
|
|
62
|
+
const resultImage = PNG.sync.read(resultBuffer, { skipRescale: true, checkCRC: false })
|
|
63
|
+
const [baselineAlignedImage, resultAlignedImage] = alignImageSizes(baselineImage, resultImage)
|
|
62
64
|
|
|
63
65
|
const { pass, diffAmount, diffImage } = compareImage(baselineAlignedImage, resultAlignedImage, options)
|
|
64
66
|
if (pass) {
|
|
@@ -75,8 +77,7 @@ export const matchImageSnapshot: BrowserCommand<
|
|
|
75
77
|
)
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
await writeSnapshot(diffBase64, info.diffPath)
|
|
80
|
+
await writeSnapshotBuffer(info.diffPath, diffImage.data)
|
|
80
81
|
|
|
81
82
|
throw new Error(
|
|
82
83
|
dedent`Snapshot \`${taskId}\` mismatched
|
|
@@ -104,9 +105,18 @@ async function takeSnapshot(
|
|
|
104
105
|
options: ImageSnapshotTimeoutOptions | undefined,
|
|
105
106
|
) {
|
|
106
107
|
if (isBase64String(subject)) {
|
|
107
|
-
|
|
108
|
+
await writeSnapshot(filePath, subject)
|
|
109
|
+
return Buffer.from(subject, 'base64')
|
|
108
110
|
}
|
|
111
|
+
return takeSnapshotByBrowser(context, filePath, subject, options)
|
|
112
|
+
}
|
|
109
113
|
|
|
114
|
+
async function takeSnapshotByBrowser(
|
|
115
|
+
context: BrowserCommandContext,
|
|
116
|
+
filePath: string,
|
|
117
|
+
subject: string,
|
|
118
|
+
options: ImageSnapshotTimeoutOptions | undefined,
|
|
119
|
+
) {
|
|
110
120
|
await mkdirp(dirname(filePath))
|
|
111
121
|
const browser = browserApi(context)
|
|
112
122
|
return browser.takeScreenshot(filePath, subject, {
|
|
@@ -114,27 +124,25 @@ async function takeSnapshot(
|
|
|
114
124
|
})
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
async function writeSnapshot(
|
|
127
|
+
async function writeSnapshot(filePath: string, subject: string) {
|
|
128
|
+
await mkdirp(dirname(filePath))
|
|
129
|
+
await file.writeFile(filePath, subject, { encoding: 'base64' })
|
|
130
|
+
}
|
|
131
|
+
async function writeSnapshotBuffer(filePath: string, subject: Buffer) {
|
|
118
132
|
await mkdirp(dirname(filePath))
|
|
119
|
-
await file.
|
|
120
|
-
return subject
|
|
133
|
+
await file.writeFile(filePath, subject)
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
function alignImageSizes(baseline: PNG, result: PNG) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (baseline.width !== size.width || baseline.height !== size.height) {
|
|
127
|
-
baseline = resizeImage(baseline, size)
|
|
128
|
-
}
|
|
137
|
+
if (isSameSize(baseline, result)) return [baseline, result] as const
|
|
129
138
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return [baseline, result] as const
|
|
139
|
+
const size = getMaxSize(baseline, result)
|
|
140
|
+
return [resizeImage(baseline, size), resizeImage(result, size)] as const
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
function resizeImage(image: PNG, size: { width: number; height: number }) {
|
|
144
|
+
if (isSameSize(image, size)) return image
|
|
145
|
+
|
|
138
146
|
const resized = new PNG(size)
|
|
139
147
|
PNG.bitblt(image, resized, 0, 0, image.width, image.height)
|
|
140
148
|
return resized
|
package/src/server/file.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { readFile, stat, writeFile } from 'node:fs/promises'
|
|
2
2
|
|
|
3
3
|
export const file = {
|
|
4
|
-
async
|
|
5
|
-
return readFile(filePath
|
|
6
|
-
},
|
|
7
|
-
writeFileBase64(filePath: string, data: string) {
|
|
8
|
-
return writeFile(filePath, data, { encoding: 'base64' })
|
|
4
|
+
async tryReadFile(filePath: string): Promise<Buffer | undefined> {
|
|
5
|
+
return readFile(filePath).catch(() => undefined)
|
|
9
6
|
},
|
|
7
|
+
writeFile,
|
|
10
8
|
existFile(filePath: string) {
|
|
11
9
|
return stat(filePath)
|
|
12
10
|
.then((s) => s.isFile())
|