reg-cli 0.18.16 → 0.19.0-rc0

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.
Files changed (46) hide show
  1. package/README.md +155 -46
  2. package/dist/cli.cjs +221 -0
  3. package/dist/cli.d.cts +1 -0
  4. package/dist/cli.d.mts +1 -0
  5. package/dist/cli.mjs +221 -0
  6. package/dist/entry.cjs +119 -0
  7. package/dist/entry.d.cts +15 -0
  8. package/dist/entry.d.mts +15 -0
  9. package/dist/entry.mjs +118 -0
  10. package/dist/index.cjs +212 -0
  11. package/dist/index.d.cts +52 -0
  12. package/dist/index.d.mts +52 -0
  13. package/dist/index.mjs +206 -0
  14. package/dist/progress-BB7D-xke.mjs +28 -0
  15. package/dist/progress-UOiKHaTY.cjs +33 -0
  16. package/dist/reg.wasm +0 -0
  17. package/dist/rolldown-runtime-D_mwlA32.cjs +43 -0
  18. package/{report/ui/dist/worker.js → dist/shared/report-worker.js} +859 -247
  19. package/dist/tracing-7HO8hac9.mjs +378 -0
  20. package/dist/tracing-DlLL541f.cjs +445 -0
  21. package/dist/worker.cjs +143 -0
  22. package/dist/worker.d.cts +1 -0
  23. package/dist/worker.d.mts +1 -0
  24. package/dist/worker.mjs +142 -0
  25. package/dist/ximgdiff-DzkRRnkW.mjs +41 -0
  26. package/dist/ximgdiff-wmW1BH1H.cjs +41 -0
  27. package/package.json +61 -112
  28. package/dist/.keep +0 -0
  29. package/dist/cli.js +0 -214
  30. package/dist/diff.js +0 -80
  31. package/dist/icon.js +0 -12
  32. package/dist/image-finder.js +0 -25
  33. package/dist/index.js +0 -200
  34. package/dist/log.js +0 -21
  35. package/dist/process-adaptor.js +0 -40
  36. package/dist/report.js +0 -170
  37. package/dist/tracing.js +0 -169
  38. package/report/assets/favicon_failure.png +0 -0
  39. package/report/assets/favicon_success.png +0 -0
  40. package/report/sample/actual/sample.png +0 -0
  41. package/report/sample/diff/sample.png +0 -0
  42. package/report/sample/expected/sample.png +0 -0
  43. package/report/ui/dist/report.js +0 -123
  44. package/report/ui/dist/style.css +0 -1
  45. package/template/template.html +0 -20
  46. /package/{template → dist/shared}/worker_pre.js +0 -0
@@ -0,0 +1,142 @@
1
+ import { c as computeWasiSandbox, u as readWasm } from "./tracing-7HO8hac9.mjs";
2
+ import { t as createPrintErrHook } from "./progress-BB7D-xke.mjs";
3
+ import { parentPort, workerData } from "node:worker_threads";
4
+ import { env } from "node:process";
5
+ import fs from "node:fs";
6
+ import { WASI } from "@tybys/wasm-util";
7
+ //#region src/proxy.ts
8
+ const kIsProxy = Symbol("kIsProxy");
9
+ const createInstanceProxy = (instance, memory) => {
10
+ if (instance[kIsProxy]) return instance;
11
+ const originalExports = instance.exports;
12
+ const createHandler = function(target) {
13
+ const handlers = [
14
+ "apply",
15
+ "construct",
16
+ "defineProperty",
17
+ "deleteProperty",
18
+ "get",
19
+ "getOwnPropertyDescriptor",
20
+ "getPrototypeOf",
21
+ "has",
22
+ "isExtensible",
23
+ "ownKeys",
24
+ "preventExtensions",
25
+ "set",
26
+ "setPrototypeOf"
27
+ ];
28
+ const handler = {};
29
+ for (let i = 0; i < handlers.length; i++) {
30
+ const name = handlers[i];
31
+ handler[name] = function() {
32
+ const args = Array.prototype.slice.call(arguments, 1);
33
+ args.unshift(target);
34
+ return Reflect[name].apply(Reflect, args);
35
+ };
36
+ }
37
+ return handler;
38
+ };
39
+ const handler = createHandler(originalExports);
40
+ const _initialize = () => {};
41
+ const _start = () => 0;
42
+ handler.get = function(_target, p, receiver) {
43
+ if (p === "memory") return (typeof memory === "function" ? memory() : memory) ?? Reflect.get(originalExports, p, receiver);
44
+ if (p === "_initialize") return p in originalExports ? _initialize : void 0;
45
+ if (p === "_start") return p in originalExports ? _start : void 0;
46
+ return Reflect.get(originalExports, p, receiver);
47
+ };
48
+ handler.has = function(_target, p) {
49
+ if (p === "memory") return true;
50
+ return Reflect.has(originalExports, p);
51
+ };
52
+ const exportsProxy = new Proxy(Object.create(null), handler);
53
+ return new Proxy(instance, { get(target, p, receiver) {
54
+ if (p === "exports") return exportsProxy;
55
+ if (p === kIsProxy) return true;
56
+ return Reflect.get(target, p, receiver);
57
+ } });
58
+ };
59
+ //#endregion
60
+ //#region src/worker.ts
61
+ const isTracingEnabled = () => env.OTEL_ENABLED === "true" || env.JAEGER_ENABLED === "true";
62
+ const sandbox = computeWasiSandbox(workerData.argv);
63
+ const printErr = createPrintErrHook((ev) => {
64
+ parentPort?.postMessage({
65
+ cmd: "compare-event",
66
+ event: ev
67
+ });
68
+ });
69
+ const wasi = new WASI({
70
+ version: "preview1",
71
+ args: workerData.argv,
72
+ env: sandbox.env,
73
+ returnOnExit: true,
74
+ preopens: sandbox.preopens,
75
+ fs,
76
+ printErr
77
+ });
78
+ const imports = wasi.getImportObject();
79
+ const file = readWasm();
80
+ const handler = async ({ startArg, tid, memory }) => {
81
+ const workerSpans = [];
82
+ const workerLabel = `thread-${tid}`;
83
+ const handler_start_ms = Date.now();
84
+ const tSpan = async (name, fn, attributes) => {
85
+ if (!isTracingEnabled()) return fn();
86
+ const start_ms = Date.now();
87
+ const r = await fn();
88
+ workerSpans.push({
89
+ name,
90
+ start_ms,
91
+ end_ms: Date.now(),
92
+ attributes,
93
+ worker_label: workerLabel
94
+ });
95
+ return r;
96
+ };
97
+ try {
98
+ const wasm = await tSpan("worker.wasm_compile", async () => WebAssembly.compile(await file));
99
+ let instance = await tSpan("worker.wasm_instantiate", async () => WebAssembly.instantiate(wasm, {
100
+ ...imports,
101
+ wasi: { "thread-spawn": (startArg) => {
102
+ const threadIdBuffer = new SharedArrayBuffer(4);
103
+ const id = new Int32Array(threadIdBuffer);
104
+ Atomics.store(id, 0, -1);
105
+ parentPort?.postMessage({
106
+ cmd: "thread-spawn",
107
+ startArg,
108
+ threadId: id,
109
+ memory
110
+ });
111
+ Atomics.wait(id, 0, -1);
112
+ return Atomics.load(id, 0);
113
+ } },
114
+ env: { memory }
115
+ }));
116
+ instance = createInstanceProxy(instance, memory);
117
+ await tSpan("worker.wasi_start", async () => {
118
+ wasi.start(instance);
119
+ });
120
+ await tSpan("worker.wasi_thread_start", async () => {
121
+ instance.exports.wasi_thread_start(tid, startArg);
122
+ }, { tid });
123
+ if (isTracingEnabled()) {
124
+ workerSpans.push({
125
+ name: "worker.thread_total",
126
+ start_ms: handler_start_ms,
127
+ end_ms: Date.now(),
128
+ worker_label: workerLabel,
129
+ attributes: { tid }
130
+ });
131
+ parentPort?.postMessage({
132
+ cmd: "worker-spans",
133
+ workerSpans
134
+ });
135
+ }
136
+ } catch (e) {
137
+ throw e;
138
+ }
139
+ };
140
+ parentPort?.addListener("message", handler);
141
+ //#endregion
142
+ export {};
@@ -0,0 +1,41 @@
1
+ import { createRequire } from "node:module";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ //#region \0rolldown/runtime.js
5
+ var __defProp = Object.defineProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ //#endregion
16
+ //#region src/ximgdiff.ts
17
+ var ximgdiff_exports = /* @__PURE__ */ __exportAll({ writeXimgdiffAssets: () => writeXimgdiffAssets });
18
+ const requireShim = createRequire(import.meta.url);
19
+ const renderWorkerPre = (template, wasmUrl) => template.replace(/\{\{&\s*ximgdiffWasmUrl\s*\}\}/g, wasmUrl);
20
+ /**
21
+ * Concatenate worker_pre.js + report-ui worker + x-img-diff-js loader and
22
+ * write the result + the wasm binary next to the HTML report. Safe to call
23
+ * whether or not the report dir already exists.
24
+ */
25
+ const writeXimgdiffAssets = async (opts) => {
26
+ const outDir = dirname(opts.reportPath);
27
+ const wasmUrl = `${opts.urlPrefix ?? ""}detector.wasm`;
28
+ const xImgDiff = requireShim("x-img-diff-js");
29
+ const sharedDir = join(opts.distDir, "shared");
30
+ const [workerPreTpl, reportWorkerJs, wasmLoaderJs, wasmBuf] = await Promise.all([
31
+ readFile(join(sharedDir, "worker_pre.js"), "utf8"),
32
+ readFile(join(sharedDir, "report-worker.js"), "utf8"),
33
+ readFile(xImgDiff.getBrowserJsPath(), "utf8"),
34
+ readFile(xImgDiff.getBrowserWasmPath())
35
+ ]);
36
+ const workerJs = renderWorkerPre(workerPreTpl, wasmUrl) + "\n" + reportWorkerJs + "\n" + wasmLoaderJs;
37
+ await mkdir(outDir, { recursive: true });
38
+ await Promise.all([writeFile(join(outDir, "worker.js"), workerJs, "utf8"), writeFile(join(outDir, "detector.wasm"), wasmBuf)]);
39
+ };
40
+ //#endregion
41
+ export { ximgdiff_exports as n, writeXimgdiffAssets as t };
@@ -0,0 +1,41 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-D_mwlA32.cjs");
2
+ let node_fs_promises = require("node:fs/promises");
3
+ let node_path = require("node:path");
4
+ let node_module = require("node:module");
5
+ //#region src/ximgdiff.ts
6
+ var ximgdiff_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ writeXimgdiffAssets: () => writeXimgdiffAssets });
7
+ const requireShim = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
8
+ const renderWorkerPre = (template, wasmUrl) => template.replace(/\{\{&\s*ximgdiffWasmUrl\s*\}\}/g, wasmUrl);
9
+ /**
10
+ * Concatenate worker_pre.js + report-ui worker + x-img-diff-js loader and
11
+ * write the result + the wasm binary next to the HTML report. Safe to call
12
+ * whether or not the report dir already exists.
13
+ */
14
+ const writeXimgdiffAssets = async (opts) => {
15
+ const outDir = (0, node_path.dirname)(opts.reportPath);
16
+ const wasmUrl = `${opts.urlPrefix ?? ""}detector.wasm`;
17
+ const xImgDiff = requireShim("x-img-diff-js");
18
+ const sharedDir = (0, node_path.join)(opts.distDir, "shared");
19
+ const [workerPreTpl, reportWorkerJs, wasmLoaderJs, wasmBuf] = await Promise.all([
20
+ (0, node_fs_promises.readFile)((0, node_path.join)(sharedDir, "worker_pre.js"), "utf8"),
21
+ (0, node_fs_promises.readFile)((0, node_path.join)(sharedDir, "report-worker.js"), "utf8"),
22
+ (0, node_fs_promises.readFile)(xImgDiff.getBrowserJsPath(), "utf8"),
23
+ (0, node_fs_promises.readFile)(xImgDiff.getBrowserWasmPath())
24
+ ]);
25
+ const workerJs = renderWorkerPre(workerPreTpl, wasmUrl) + "\n" + reportWorkerJs + "\n" + wasmLoaderJs;
26
+ await (0, node_fs_promises.mkdir)(outDir, { recursive: true });
27
+ await Promise.all([(0, node_fs_promises.writeFile)((0, node_path.join)(outDir, "worker.js"), workerJs, "utf8"), (0, node_fs_promises.writeFile)((0, node_path.join)(outDir, "detector.wasm"), wasmBuf)]);
28
+ };
29
+ //#endregion
30
+ Object.defineProperty(exports, "writeXimgdiffAssets", {
31
+ enumerable: true,
32
+ get: function() {
33
+ return writeXimgdiffAssets;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "ximgdiff_exports", {
37
+ enumerable: true,
38
+ get: function() {
39
+ return ximgdiff_exports;
40
+ }
41
+ });
package/package.json CHANGED
@@ -1,129 +1,78 @@
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-rc0",
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.9.0",
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": { "optional": true },
61
+ "@opentelemetry/exporter-trace-otlp-http": { "optional": true },
62
+ "@opentelemetry/resources": { "optional": true },
63
+ "@opentelemetry/sdk-trace-base": { "optional": true },
64
+ "@opentelemetry/sdk-trace-node": { "optional": true },
65
+ "@opentelemetry/semantic-conventions": { "optional": true }
66
+ },
67
+ "devDependencies": {
68
+ "@types/node": "^22.5.5",
69
+ "@opentelemetry/api": "^1.9.1",
70
+ "@opentelemetry/exporter-trace-otlp-http": "^0.216.0",
71
+ "@opentelemetry/resources": "^2.7.1",
72
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
73
+ "@opentelemetry/sdk-trace-node": "^2.7.1",
74
+ "@opentelemetry/semantic-conventions": "^1.40.0",
75
+ "tsdown": "^0.21.10"
127
76
  },
128
77
  "packageManager": "pnpm@10.33.2+sha512.a90faf6feeab71ad6c6e57f94e0fe1a12f5dcc22cd754db40ae9593eb6a3e0b6b12e3540218bb37ae083404b1f2ce6db2a4121e979829b4aff94b99f49da1cf8"
129
78
  }
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
- });