web-corders-vrt 0.1.4 → 0.1.7
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/README.md +44 -41
- package/bin/vrt.ts +5 -19
- package/dist/bin/vrt.js +83 -103
- package/dist/bin/vrt.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/init.ts +36 -48
- package/src/commands/run.ts +34 -38
- package/src/constants.ts +1 -0
- package/src/core/comparator.ts +7 -7
- package/src/reporters/html.ts +4 -4
- package/src/reporters/terminal.ts +1 -1
- package/src/schemas.ts +1 -3
- package/src/templates/SKILL-TEMPLATE.md +34 -0
- package/src/templates/report.html +1 -1
- package/src/templates/types.d.ts +4 -0
- package/src/types.ts +6 -8
- package/test/comparator.test.ts +5 -5
- package/tsup.config.ts +1 -0
package/src/schemas.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
export const cliOptionsSchema = z.object({
|
|
4
|
-
|
|
4
|
+
reference: z.string().url("--reference must be a valid URL"),
|
|
5
5
|
after: z.string().url("--after must be a valid URL"),
|
|
6
6
|
paths: z.string().transform((val) => val.split(",").map((p) => p.trim())),
|
|
7
7
|
threshold: z.coerce.number().min(0).max(100).default(0.1),
|
|
@@ -9,8 +9,6 @@ export const cliOptionsSchema = z.object({
|
|
|
9
9
|
.string()
|
|
10
10
|
.optional()
|
|
11
11
|
.transform((val) => (val ? val.split(",").map((s) => s.trim()) : [])),
|
|
12
|
-
html: z.boolean().default(true),
|
|
13
|
-
open: z.boolean().default(true),
|
|
14
12
|
});
|
|
15
13
|
|
|
16
14
|
export type CliOptions = z.input<typeof cliOptionsSchema>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-corders-vrt
|
|
3
|
+
description: WEB用VRT(Visual Regression Test)ツール。本番ドメインとローカル開発またはプレビュードメインの間で、特定パスのビジュアル差分を検出する。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## 使い方
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npx web-corders-vrt run \
|
|
10
|
+
--reference ${referenceDomain} \
|
|
11
|
+
--after <開発環境のドメイン|ユーザーから指示がない場合はhttp://localhost:3000> \
|
|
12
|
+
--paths <テスト対象のパス(カンマ区切り)> \
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 手順
|
|
16
|
+
|
|
17
|
+
1. ユーザーから比較対象のドメインを指定された場合、それに従う。指示がない場合、afterは開発サーバーとし、起動していなければ `npm run dev` で起動して待機する。ここで起動したドメインとプロトコルをafterのドメインとする。
|
|
18
|
+
2. 上記のコマンドでVRTを実行する(`--paths` はタスクに応じて設定する)
|
|
19
|
+
3. `./vrt-results/` 内の最新ディレクトリにある `report.json` を読む
|
|
20
|
+
4. `status: "fail"` のテスト結果に注目する
|
|
21
|
+
5. 該当するdiff画像(`*--diff.png`)をReadツールで視覚的に確認する
|
|
22
|
+
6. diff画像から修正すべきCSSやHTMLの場所を特定できるなら修正にはいる。再度VRTを実行して修正が反映されたことを確認する
|
|
23
|
+
7. 修正が不可能ならユーザーにその旨を伝え、レポートが出来たことを伝える
|
|
24
|
+
|
|
25
|
+
## オプション
|
|
26
|
+
|
|
27
|
+
| オプション | 説明 |
|
|
28
|
+
| -------------------- | ------------------------------------------- |
|
|
29
|
+
| `--reference <url>` | リファレンスプロトコル+ドメイン(本番環境) |
|
|
30
|
+
| `--after <url>` | 比較先Uプロトコル+ドメイン(開発環境) |
|
|
31
|
+
| `--paths <paths>` | テスト対象のページパス(カンマ区切り) |
|
|
32
|
+
| `--threshold <n>` | 差分許容率(%)。デフォルト: 0.1 |
|
|
33
|
+
| `--hide <selectors>` | 非表示にするCSSセレクタ(カンマ区切り) |
|
|
34
|
+
| `--no-open` | HTMLレポートをブラウザで開かない |
|
package/src/templates/types.d.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface VrtReport {
|
|
|
3
3
|
version: "1.0";
|
|
4
4
|
meta: {
|
|
5
5
|
timestamp: string;
|
|
6
|
-
|
|
6
|
+
referenceUrl: string;
|
|
7
7
|
afterUrl: string;
|
|
8
8
|
duration: number;
|
|
9
9
|
command: string;
|
|
@@ -24,7 +24,7 @@ export interface VrtTestResult {
|
|
|
24
24
|
path: string;
|
|
25
25
|
name: string;
|
|
26
26
|
url: {
|
|
27
|
-
|
|
27
|
+
reference: string;
|
|
28
28
|
after: string;
|
|
29
29
|
};
|
|
30
30
|
};
|
|
@@ -42,12 +42,12 @@ export interface VrtTestResult {
|
|
|
42
42
|
dimensions: {
|
|
43
43
|
width: number;
|
|
44
44
|
height: number;
|
|
45
|
-
|
|
45
|
+
referenceHeight: number;
|
|
46
46
|
afterHeight: number;
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
49
|
screenshots: {
|
|
50
|
-
|
|
50
|
+
reference: string;
|
|
51
51
|
after: string;
|
|
52
52
|
diff: string;
|
|
53
53
|
};
|
|
@@ -59,13 +59,11 @@ export type TestStatus = "pass" | "fail" | "error";
|
|
|
59
59
|
|
|
60
60
|
/** CLI実行時の解決済みオプション */
|
|
61
61
|
export interface ResolvedOptions {
|
|
62
|
-
|
|
62
|
+
referenceUrl: string;
|
|
63
63
|
afterUrl: string;
|
|
64
64
|
paths: string[];
|
|
65
65
|
threshold: number;
|
|
66
66
|
hideSelectors: string[];
|
|
67
|
-
html: boolean;
|
|
68
|
-
open: boolean;
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
/** スクリーンショット結果 */
|
|
@@ -88,7 +86,7 @@ export interface ComparisonResult {
|
|
|
88
86
|
dimensions: {
|
|
89
87
|
width: number;
|
|
90
88
|
height: number;
|
|
91
|
-
|
|
89
|
+
referenceHeight: number;
|
|
92
90
|
afterHeight: number;
|
|
93
91
|
};
|
|
94
92
|
}
|
package/test/comparator.test.ts
CHANGED
|
@@ -85,7 +85,7 @@ describe("compareImages", () => {
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
it("一部だけ異なる画像の場合、差分率が正しく計算される", () => {
|
|
88
|
-
const
|
|
88
|
+
const reference = createSolidPng(100, 100, 255, 255, 255);
|
|
89
89
|
// 右下10x10だけ赤にする
|
|
90
90
|
const after = createPngWithRegion(100, 100, 255, 255, 255, {
|
|
91
91
|
x: 90,
|
|
@@ -97,7 +97,7 @@ describe("compareImages", () => {
|
|
|
97
97
|
b: 0,
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
const result = compareImages(
|
|
100
|
+
const result = compareImages(reference, after);
|
|
101
101
|
|
|
102
102
|
expect(result.diffCount).toBeGreaterThan(0);
|
|
103
103
|
// 10*10=100 / 100*100=10000 = 1%
|
|
@@ -112,14 +112,14 @@ describe("compareImages", () => {
|
|
|
112
112
|
|
|
113
113
|
expect(result.dimensions.width).toBe(100);
|
|
114
114
|
expect(result.dimensions.height).toBe(100);
|
|
115
|
-
expect(result.dimensions.
|
|
115
|
+
expect(result.dimensions.referenceHeight).toBe(50);
|
|
116
116
|
expect(result.dimensions.afterHeight).toBe(100);
|
|
117
117
|
// 白でパディングされるので一部は同じ、拡張部分も白=白で差分なし
|
|
118
118
|
expect(result.diffCount).toBe(0);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
it("threshold以下の差分はpassになる", () => {
|
|
122
|
-
const
|
|
122
|
+
const reference = createSolidPng(100, 100, 255, 255, 255);
|
|
123
123
|
// 1ピクセルだけ微妙に違う
|
|
124
124
|
const afterPng = new PNG({ width: 100, height: 100 });
|
|
125
125
|
for (let i = 0; i < afterPng.data.length; i += 4) {
|
|
@@ -132,7 +132,7 @@ describe("compareImages", () => {
|
|
|
132
132
|
afterPng.data[0] = 200;
|
|
133
133
|
const after = PNG.sync.write(afterPng);
|
|
134
134
|
|
|
135
|
-
const result = compareImages(
|
|
135
|
+
const result = compareImages(reference, after, 1.0); // threshold 1%
|
|
136
136
|
// 1px / 10000px = 0.01% < 1%
|
|
137
137
|
expect(result.passed).toBe(true);
|
|
138
138
|
});
|