reg-cli 0.18.16 → 0.19.0-rc1

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/package.json CHANGED
@@ -1,129 +1,95 @@
1
1
  {
2
2
  "name": "reg-cli",
3
- "version": "0.18.16",
4
- "description": "",
5
- "main": "./dist/index.js",
6
- "start": "node ./dist/cli.js",
7
- "scripts": {
8
- "watch": "babel src --watch -d dist",
9
- "build": "npm run build:cli && npm run build:report",
10
- "build:cli": "babel src -d dist",
11
- "build:report": "sh ./scripts/build-ui.sh v0.5.0",
12
- "flow": "flow",
13
- "copy:ximgdiff": "copyfiles -u 3 node_modules/x-img-diff-js/build/cv-wasm_browser.* report/assets",
14
- "prepublishOnly": "npm run build",
15
- "reg": "node dist/cli.js ./sample/actual ./sample/expected ./sample/diff -I -R ./sample/index.html -T 0.01 -X client",
16
- "reg:from": "node dist/cli.js -F ./sample/reg.json -R ./sample/index.html",
17
- "screenshot": "node test/screenshot.js",
18
- "test:cli": "chmod +x dist/cli.js && ava test/cli.test.mjs",
19
- "test:screenshot": "npm run build:report && npm run reg && npm run screenshot",
20
- "test": "export NODE_OPTIONS=--openssl-legacy-provider && cross-env NODE_ENV=\"debug\" npm run build:report && npm run build && npm run test:cli && npm run test:screenshot"
3
+ "version": "0.19.0-rc1",
4
+ "description": "Visual regression testing CLI, Wasm-backed. Drop-in compatible with classic reg-cli's CLI flags, reg.json/junit schema, and `compare()` EventEmitter API (verified against reg-suit's processor.ts).",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": {
9
+ "types": "./dist/index.d.mts",
10
+ "default": "./dist/index.mjs"
11
+ },
12
+ "require": {
13
+ "types": "./dist/index.d.cts",
14
+ "default": "./dist/index.cjs"
15
+ }
16
+ }
21
17
  },
22
18
  "engines": {
23
- "node": ">=18"
19
+ "node": ">=20"
20
+ },
21
+ "main": "./dist/index.cjs",
22
+ "module": "./dist/index.mjs",
23
+ "types": "./dist/index.d.cts",
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "bin": {
28
+ "reg-cli": "./dist/cli.mjs"
29
+ },
30
+ "scripts": {
31
+ "build": "tsdown && node ./scripts/stage-assets.mjs",
32
+ "build:report": "sh ./scripts/build-ui.sh ${REPORT_UI_TAG:-v0.5.0}",
33
+ "build:wasm": "bash ./scripts/build-wasm.sh",
34
+ "build:all": "npm run build:report && npm run build:wasm && npm run build",
35
+ "release:prep": "bash ./scripts/release.sh",
36
+ "release:pack": "bash ./scripts/release.sh --pack",
37
+ "test": "node --test test/",
38
+ "prepublishOnly": "npm run build:all"
24
39
  },
25
40
  "repository": {
26
41
  "type": "git",
27
42
  "url": "https://github.com/reg-viz/reg-cli/"
28
43
  },
29
- "ava": {
30
- "workerThreads": false
31
- },
44
+ "keywords": [],
32
45
  "author": "bokuweb",
33
46
  "license": "MIT",
34
- "pnpm": {
35
- "overrides": {
36
- "set-value": "4.1.0",
37
- "tar": "^7.5.13",
38
- "tar-fs": "3.1.2",
39
- "ws": "8.17.1",
40
- "kind-of": "^6.0.3",
41
- "randomatic": "3.1.1",
42
- "deep-extend": "0.6.0",
43
- "lodash": "4.18.1",
44
- "yargs-parser": "^21.0.0",
45
- "minimist": "^1.2.3",
46
- "ajv": "^8.0.0",
47
- "json-schema": "^0.4.0",
48
- "ansi-regex": "^5.0.1",
49
- "glob-parent": "^6.0.1",
50
- "dot-prop": "^10.0.0",
51
- "node-forge": "^1.0.0",
52
- "serialize-javascript": "^7.0.0",
53
- "y18n": "^5.0.0",
54
- "braces": "^3.0.0",
55
- "trim-newlines": "3.0.1",
56
- "brace-expansion": "5.0.5",
57
- "debug": "^4.3.4",
58
- "@octokit/request-error@>=1.0.0 <5.1.1": ">=5.1.1",
59
- "@octokit/plugin-paginate-rest@>=1.0.0 <9.2.2": ">=9.2.2",
60
- "@octokit/request@>=1.0.0 <8.4.1": ">=8.4.1",
61
- "minimatch@<3.1.4": "^3.1.4",
62
- "minimatch@>=4.0.0 <4.2.5": "^4.2.5",
63
- "minimatch@>=5.0.0 <5.1.8": "^5.1.8",
64
- "minimatch@>=6.0.0 <6.2.2": "^6.2.2",
65
- "minimatch@>=7.0.0 <7.4.8": "^7.4.8",
66
- "minimatch@>=8.0.0 <8.0.6": "^8.0.6",
67
- "minimatch@>=9.0.0 <9.0.7": "^9.0.7",
68
- "minimatch@>=10.0.0 <10.2.3": "^10.2.3",
69
- "basic-ftp@<5.2.0": ">=5.2.0",
70
- "ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0",
71
- "picomatch@<2.3.2": ">=2.3.2",
72
- "picomatch@>=4.0.0 <4.0.4": ">=4.0.4",
73
- "basic-ftp@<=5.2.1": ">=5.2.2",
74
- "simple-git@<3.32.0": ">=3.32.0",
75
- "simple-git@>=3.15.0 <3.32.3": ">=3.32.3",
76
- "basic-ftp@<=5.2.2": ">=5.3.0"
77
- }
78
- },
79
47
  "dependencies": {
80
- "bluebird": "3.7.2",
81
- "chalk": "4.1.2",
82
- "cli-spinner": "0.2.10",
83
- "cross-spawn": "7.0.6",
84
- "del": "8.0.1",
85
- "glob": "7.2.3",
86
- "img-diff-js": "0.5.4",
87
- "jpeg-js": "^0.4.4",
88
- "lodash": "4.18.1",
89
- "make-dir": "3.1.0",
90
- "md5-file": "4.0.0",
91
- "meow": "^9.0.0",
92
- "mustache": "4.2.0",
93
- "x-img-diff-js": "0.3.5",
94
- "xmlbuilder2": "^4.0.3",
95
- "yargs-parser": "^21.0.1"
48
+ "@tybys/wasm-util": "^0.10.2",
49
+ "x-img-diff-js": "^0.3.5"
96
50
  },
97
- "devDependencies": {
98
- "@babel/cli": "^7.28.3",
99
- "@babel/core": "^7.28.5",
100
- "@babel/plugin-transform-block-scoping": "^7.28.5",
101
- "@babel/plugin-transform-flow-strip-types": "^7.27.1",
102
- "@babel/preset-env": "^7.28.5",
103
- "@babel/preset-flow": "^7.27.1",
104
- "@babel/preset-stage-2": "^7.8.3",
105
- "ava": "8.0.0",
106
- "copyfiles": "2.4.1",
107
- "cross-env": "10.1.0",
108
- "finalhandler": "2.1.1",
109
- "flow-bin": "0.77.0",
110
- "flow-typed": "4.1.1",
111
- "puppeteer": "24.42.0",
112
- "rimraf": "3.0.2",
113
- "serve-static": "2.2.1"
51
+ "peerDependencies": {
52
+ "@opentelemetry/api": "^1.9.1",
53
+ "@opentelemetry/exporter-trace-otlp-http": "^0.216.0",
54
+ "@opentelemetry/resources": "^2.7.1",
55
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
56
+ "@opentelemetry/sdk-trace-node": "^2.7.1",
57
+ "@opentelemetry/semantic-conventions": "^1.40.0"
114
58
  },
115
- "files": [
116
- "dist",
117
- "template",
118
- "report/ui/dist/report.js",
119
- "report/ui/dist/worker.js",
120
- "report/ui/dist/style.css",
121
- "report/assets/favicon_failure.png",
122
- "report/assets/favicon_success.png",
123
- "report/sample"
124
- ],
125
- "bin": {
126
- "reg-cli": "./dist/cli.js"
59
+ "peerDependenciesMeta": {
60
+ "@opentelemetry/api": {
61
+ "optional": true
62
+ },
63
+ "@opentelemetry/exporter-trace-otlp-http": {
64
+ "optional": true
65
+ },
66
+ "@opentelemetry/resources": {
67
+ "optional": true
68
+ },
69
+ "@opentelemetry/sdk-trace-base": {
70
+ "optional": true
71
+ },
72
+ "@opentelemetry/sdk-trace-node": {
73
+ "optional": true
74
+ },
75
+ "@opentelemetry/semantic-conventions": {
76
+ "optional": true
77
+ }
127
78
  },
128
- "packageManager": "pnpm@10.33.2+sha512.a90faf6feeab71ad6c6e57f94e0fe1a12f5dcc22cd754db40ae9593eb6a3e0b6b12e3540218bb37ae083404b1f2ce6db2a4121e979829b4aff94b99f49da1cf8"
79
+ "devDependencies": {
80
+ "@types/node": "^22.5.5",
81
+ "@opentelemetry/api": "^1.9.1",
82
+ "@opentelemetry/exporter-trace-otlp-http": "^0.216.0",
83
+ "@opentelemetry/resources": "^2.7.1",
84
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
85
+ "@opentelemetry/sdk-trace-node": "^2.7.1",
86
+ "@opentelemetry/semantic-conventions": "^1.40.0",
87
+ "tsdown": "^0.22.0"
88
+ },
89
+ "packageManager": "pnpm@10.33.3+sha512.a19744364a7e248b92657a4ca5973f9354d21caf982579674b1c539f32c7420c47138ad8b1254df07aba9bc782d9b3029e3db34d5dbff974326eb74dac8ff489",
90
+ "pnpm": {
91
+ "overrides": {
92
+ "protobufjs": "^8.6.5"
93
+ }
94
+ }
129
95
  }
package/dist/.keep DELETED
File without changes
package/dist/cli.js DELETED
@@ -1,214 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- var _cliSpinner = require("cli-spinner");
5
- var _meow = _interopRequireDefault(require("meow"));
6
- var _path = _interopRequireDefault(require("path"));
7
- var _ = _interopRequireDefault(require("./"));
8
- var _log = _interopRequireDefault(require("./log"));
9
- var _fs = _interopRequireDefault(require("fs"));
10
- var _icon = require("./icon");
11
- var _report = _interopRequireDefault(require("./report"));
12
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- // import notifier from './notifier';
14
- var spinner = new _cliSpinner.Spinner();
15
- spinner.setSpinnerString(18);
16
- var cli = (0, _meow.default)(`
17
- Usage
18
- $ reg-cli /path/to/actual-dir /path/to/expected-dir /path/to/diff-dir
19
- Options
20
- -U, --update Update expected images.(Copy \`actual images\` to \`expected images\`).
21
- -J, --json Specified json report path. If omitted ./reg.json.
22
- -I, --ignoreChange If true, error will not be thrown when image change detected.
23
- -E, --extendedErrors If true, also added/deleted images will throw an error. If omitted false.
24
- -R, --report Output html report to specified directory.
25
- --junit Output junit report to specified file.
26
- -P, --urlPrefix Add prefix to all image src.
27
- -M, --matchingThreshold Matching threshold, ranges from 0 to 1. Smaller values make the comparison more sensitive. 0 by default.
28
- -T, --thresholdRate Rate threshold for detecting change. When the difference ratio of the image is larger than the set rate detects the change.
29
- -S, --thresholdPixel Pixel threshold for detecting change. When the difference pixel of the image is larger than the set pixel detects the change. This value takes precedence over \`thresholdRate\`.
30
- -C, --concurrency How many processes launches in parallel. If omitted 4.
31
- -A, --enableAntialias. Enable antialias. If omitted false.
32
- -X, --additionalDetection. Enable additional difference detection(highly experimental). Select "none" or "client" (default: "none").
33
- -F, --from Generate report from json. Please specify json file. If set, only report will be output without comparing images.
34
- -D, --customDiffMessage Pass custom massage that will logged to the terminal when there is a diff.
35
- Examples
36
- $ reg-cli /path/to/actual-dir /path/to/expected-dir /path/to/diff-dir -U -D ./reg.json
37
- `, {
38
- flags: {
39
- update: {
40
- type: 'boolean',
41
- alias: 'U'
42
- },
43
- json: {
44
- type: 'string',
45
- alias: 'J',
46
- default: './reg.json'
47
- },
48
- ignoreChange: {
49
- type: 'boolean',
50
- alias: 'I'
51
- },
52
- extendedErrors: {
53
- type: 'boolean',
54
- alias: 'E',
55
- default: false
56
- },
57
- report: {
58
- type: 'string',
59
- alias: 'R'
60
- },
61
- junit: {
62
- type: 'string'
63
- },
64
- urlPrefix: {
65
- type: 'string',
66
- alias: 'P'
67
- },
68
- matchingThreshold: {
69
- type: 'number',
70
- alias: 'M',
71
- default: 0
72
- },
73
- thresholdRate: {
74
- type: 'number',
75
- alias: 'T'
76
- },
77
- thresholdPixel: {
78
- type: 'number',
79
- alias: 'S'
80
- },
81
- concurrency: {
82
- type: 'number',
83
- alias: 'C',
84
- default: 4
85
- },
86
- enableAntialias: {
87
- type: 'boolean',
88
- alias: 'A',
89
- default: false
90
- },
91
- additionalDetection: {
92
- type: 'string',
93
- alias: 'X',
94
- default: 'none'
95
- },
96
- from: {
97
- type: 'string',
98
- alias: 'F'
99
- },
100
- customDiffMessage: {
101
- type: 'string',
102
- alias: 'D'
103
- }
104
- }
105
- });
106
- if (!cli.flags.from) {
107
- if (!process.argv[2] || !process.argv[3] || !process.argv[4]) {
108
- _log.default.fail('please specify actual, expected and diff images directory.');
109
- _log.default.fail('e.g.: $ reg-cli /path/to/actual-dir /path/to/expected-dir /path/to/diff-dir');
110
- process.exit(1);
111
- }
112
- }
113
- var json = cli.flags.json ? cli.flags.json.toString() : './reg.json'; // default output path
114
-
115
- var urlPrefix = typeof cli.flags.urlPrefix === 'string' ? cli.flags.urlPrefix : './';
116
- var report = typeof cli.flags.report === 'string' ? cli.flags.report : !!cli.flags.report ? './report.html' : '';
117
- var junitReport = typeof cli.flags.junit === 'string' ? cli.flags.junit : !!cli.flags.junit ? './junit.xml' : '';
118
- var actualDir = process.argv[2];
119
- var expectedDir = process.argv[3];
120
- var diffDir = process.argv[4];
121
- var update = !!cli.flags.update;
122
- var extendedErrors = !!cli.flags.extendedErrors;
123
- var ignoreChange = !!cli.flags.ignoreChange;
124
- var enableClientAdditionalDetection = cli.flags.additionalDetection === 'client';
125
- var from = String(cli.flags.from || '');
126
- var customDiffMessage = String(cli.flags.customDiffMessage || `\nInspect your code changes, re-run with \`-U\` to update them. `);
127
-
128
- // If from option specified, generate report from json and exit.
129
- if (from) {
130
- var _json = '';
131
- try {
132
- _json = _fs.default.readFileSync(from, {
133
- encoding: 'utf8'
134
- });
135
- } catch (e) {
136
- _log.default.fail('Failed to read specify json.');
137
- _log.default.fail(e);
138
- process.exit(1);
139
- }
140
- try {
141
- var params = JSON.parse(_json);
142
- (0, _report.default)({
143
- ...params,
144
- json: _json || './reg.json',
145
- report: report || './report.html',
146
- junitReport: junitReport || '',
147
- extendedErrors,
148
- urlPrefix: urlPrefix || '',
149
- enableClientAdditionalDetection,
150
- fromJSON: true
151
- });
152
- process.exit(0);
153
- } catch (e) {
154
- _log.default.fail('Failed to parse json. Please specify valid json.');
155
- _log.default.fail(e);
156
- process.exit(1);
157
- }
158
- }
159
- var observer = (0, _.default)({
160
- actualDir,
161
- expectedDir,
162
- diffDir,
163
- update,
164
- report,
165
- junitReport,
166
- extendedErrors,
167
- json,
168
- urlPrefix,
169
- matchingThreshold: Number(cli.flags.matchingThreshold || 0),
170
- thresholdRate: Number(cli.flags.thresholdRate),
171
- thresholdPixel: Number(cli.flags.thresholdPixel),
172
- concurrency: Number(cli.flags.concurrency || 4),
173
- enableAntialias: !!cli.flags.enableAntialias,
174
- enableClientAdditionalDetection
175
- });
176
- observer.once('start', () => spinner.start());
177
- observer.on('compare', params => {
178
- spinner.stop(true);
179
- var file = _path.default.join(`${actualDir}`, `${params.path}`);
180
- switch (params.type) {
181
- case 'delete':
182
- return _log.default.warn(`${_icon.MINUS} delete ${file}`);
183
- case 'new':
184
- return _log.default.info(`${_icon.GREEK_CROSS} append ${file}`);
185
- case 'pass':
186
- return _log.default.success(`${_icon.CHECK_MARK} pass ${file}`);
187
- case 'fail':
188
- return _log.default.fail(`${_icon.BALLOT_X} change ${file}`);
189
- }
190
- spinner.start();
191
- });
192
- observer.once('update', () => _log.default.success(`✨ your expected images are updated ✨`));
193
- observer.once('complete', ({
194
- failedItems,
195
- deletedItems,
196
- newItems,
197
- passedItems
198
- }) => {
199
- spinner.stop(true);
200
- _log.default.info('\n');
201
- if (failedItems.length) _log.default.fail(`${_icon.BALLOT_X} ${failedItems.length} file(s) changed.`);
202
- if (deletedItems.length) _log.default.warn(`${_icon.MINUS} ${deletedItems.length} file(s) deleted.`);
203
- if (newItems.length) _log.default.info(`${_icon.GREEK_CROSS} ${newItems.length} file(s) appended.`);
204
- if (passedItems.length) _log.default.success(`${_icon.CHECK_MARK} ${passedItems.length} file(s) passed.`);
205
- if (!update && (failedItems.length > 0 || extendedErrors && (newItems.length > 0 || deletedItems.length > 0))) {
206
- _log.default.fail(customDiffMessage);
207
- if (!ignoreChange) process.exit(1);
208
- }
209
- return process.exit(0);
210
- });
211
- observer.once('error', error => {
212
- _log.default.fail(error);
213
- process.exit(1);
214
- });
package/dist/diff.js DELETED
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- var _imgDiffJs = require("img-diff-js");
4
- var _md5File = _interopRequireDefault(require("md5-file"));
5
- var _path = _interopRequireDefault(require("path"));
6
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
- // $FlowIgnore
8
- // $FlowIgnore
9
- var getMD5 = file => new Promise((resolve, reject) => {
10
- (0, _md5File.default)(file, (err, hash) => {
11
- if (err) reject(err);
12
- resolve(hash);
13
- });
14
- });
15
- var isPassed = ({
16
- width,
17
- height,
18
- diffCount,
19
- thresholdPixel,
20
- thresholdRate
21
- }) => {
22
- if (typeof thresholdPixel === "number") {
23
- return diffCount <= thresholdPixel;
24
- } else if (typeof thresholdRate === "number") {
25
- var totalPixel = width * height;
26
- var ratio = diffCount / totalPixel;
27
- return ratio <= thresholdRate;
28
- }
29
- return diffCount === 0;
30
- };
31
- var createDiff = ({
32
- actualDir,
33
- expectedDir,
34
- diffDir,
35
- image,
36
- matchingThreshold,
37
- thresholdRate,
38
- thresholdPixel,
39
- enableAntialias
40
- }) => {
41
- return Promise.all([getMD5(_path.default.join(actualDir, image)), getMD5(_path.default.join(expectedDir, image))]).then(([actualHash, expectedHash]) => {
42
- if (actualHash === expectedHash) {
43
- if (!process || !process.send) return;
44
- return process.send({
45
- passed: true,
46
- image
47
- });
48
- }
49
- var diffImage = image.replace(/\.[^\.]+$/, ".png");
50
- return (0, _imgDiffJs.imgDiff)({
51
- actualFilename: _path.default.join(actualDir, image),
52
- expectedFilename: _path.default.join(expectedDir, image),
53
- diffFilename: _path.default.join(diffDir, diffImage),
54
- options: {
55
- threshold: matchingThreshold,
56
- includeAA: !enableAntialias
57
- }
58
- }).then(({
59
- width,
60
- height,
61
- diffCount
62
- }) => {
63
- var passed = isPassed({
64
- width,
65
- height,
66
- diffCount,
67
- thresholdPixel,
68
- thresholdRate
69
- });
70
- if (!process || !process.send) return;
71
- process.send({
72
- passed,
73
- image
74
- });
75
- });
76
- });
77
- };
78
- process.on('message', data => {
79
- createDiff(data);
80
- });
package/dist/icon.js DELETED
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TEARDROP = exports.MULTIPLICATION_X = exports.MINUS = exports.GREEK_CROSS = exports.CHECK_MARK = exports.BALLOT_X = void 0;
7
- var BALLOT_X = exports.BALLOT_X = '\u2718';
8
- var CHECK_MARK = exports.CHECK_MARK = '\u2714';
9
- var TEARDROP = exports.TEARDROP = '\u274B';
10
- var MULTIPLICATION_X = exports.MULTIPLICATION_X = '\u2716';
11
- var GREEK_CROSS = exports.GREEK_CROSS = '\u271A';
12
- var MINUS = exports.MINUS = '\u2212';
@@ -1,25 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.findImages = void 0;
7
- var _glob = _interopRequireDefault(require("glob"));
8
- var _path = _interopRequireDefault(require("path"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- // $FlowIgnore
11
- var difference = (arrA, arrB) => arrA.filter(a => !arrB.includes(a));
12
- var IMAGE_FILES = '/**/*.+(tiff|jpeg|jpg|gif|png|bmp)';
13
- var findImages = (expectedDir, actualDir) => {
14
- var expectedImages = _glob.default.sync(`${expectedDir}${IMAGE_FILES}`).map(p => _path.default.relative(expectedDir, p)).map(p => p[0] === _path.default.sep ? p.slice(1) : p);
15
- var actualImages = _glob.default.sync(`${actualDir}${IMAGE_FILES}`).map(p => _path.default.relative(actualDir, p)).map(p => p[0] === _path.default.sep ? p.slice(1) : p);
16
- var deletedImages = difference(expectedImages, actualImages);
17
- var newImages = difference(actualImages, expectedImages);
18
- return {
19
- expectedImages,
20
- actualImages,
21
- deletedImages,
22
- newImages
23
- };
24
- };
25
- exports.findImages = findImages;