@vizzly-testing/cli 0.29.6 → 0.31.0
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 +34 -6
- package/dist/api/client.js +6 -3
- package/dist/api/endpoints.js +59 -0
- package/dist/api/index.js +1 -1
- package/dist/auth/core.js +1 -1
- package/dist/auth/index.js +2 -1
- package/dist/cli.js +206 -51
- package/dist/client/index.js +21 -29
- package/dist/commands/api.js +145 -90
- package/dist/commands/baselines.js +78 -47
- package/dist/commands/builds.js +9 -8
- package/dist/commands/comparisons.js +7 -8
- package/dist/commands/config-cmd.js +15 -7
- package/dist/commands/context.js +870 -0
- package/dist/commands/doctor.js +116 -81
- package/dist/commands/init.js +202 -201
- package/dist/commands/login.js +134 -65
- package/dist/commands/logout.js +18 -7
- package/dist/commands/preview.js +29 -57
- package/dist/commands/project.js +120 -0
- package/dist/commands/projects.js +9 -2
- package/dist/commands/review.js +236 -202
- package/dist/commands/run.js +75 -72
- package/dist/commands/status.js +228 -150
- package/dist/commands/tdd-daemon-process.js +98 -0
- package/dist/commands/tdd-daemon.js +318 -212
- package/dist/commands/tdd.js +23 -8
- package/dist/commands/upload.js +10 -9
- package/dist/commands/whoami.js +64 -26
- package/dist/config/core.js +37 -36
- package/dist/context/local-workspace-provider.js +532 -0
- package/dist/context/provider-resolver.js +36 -0
- package/dist/index.js +5 -4
- package/dist/plugin-loader.js +55 -49
- package/dist/project/core.js +2 -2
- package/dist/project/operations.js +6 -3
- package/dist/reporter/reporter-bundle.css +2 -1
- package/dist/reporter/reporter-bundle.iife.js +119 -119
- package/dist/reporter-ssr/ssr-entry.js +605 -509
- package/dist/sdk/index.js +162 -107
- package/dist/server/handlers/tdd-handler.js +30 -54
- package/dist/server/routers/assets.js +4 -0
- package/dist/server/routers/baseline.js +195 -178
- package/dist/server/routers/events.js +226 -148
- package/dist/server/routers/projects.js +14 -5
- package/dist/server/routers/screenshot.js +1 -31
- package/dist/services/build-manager.js +19 -97
- package/dist/services/config-service.js +26 -34
- package/dist/services/index.js +2 -4
- package/dist/services/static-report-generator.js +11 -12
- package/dist/services/test-runner.js +21 -27
- package/dist/tdd/core/hotspot-coverage.js +1 -1
- package/dist/tdd/index.js +1 -1
- package/dist/tdd/metadata/region-metadata.js +0 -37
- package/dist/tdd/runtime-context.js +78 -0
- package/dist/tdd/server-registry.js +38 -17
- package/dist/tdd/services/baseline-manager.js +23 -0
- package/dist/tdd/services/hotspot-service.js +1 -14
- package/dist/tdd/tdd-service.js +82 -113
- package/dist/types/client.d.ts +36 -1
- package/dist/types/index.d.ts +114 -22
- package/dist/types/sdk.d.ts +47 -7
- package/dist/uploader/core.js +5 -4
- package/dist/uploader/index.js +79 -2
- package/dist/uploader/operations.js +40 -5
- package/dist/utils/api-url.js +14 -0
- package/dist/utils/async-utils.js +26 -0
- package/dist/utils/ci-env.js +19 -12
- package/dist/utils/colors.js +46 -44
- package/dist/utils/config-loader.js +39 -65
- package/dist/utils/config-schema.js +19 -55
- package/dist/utils/fetch-utils.js +12 -5
- package/dist/utils/git.js +35 -72
- package/dist/utils/global-config.js +22 -3
- package/dist/utils/output.js +19 -7
- package/dist/utils/patterns.js +14 -0
- package/dist/utils/project-link-store.js +105 -0
- package/dist/utils/report-data.js +31 -0
- package/dist/utils/screenshot-options.js +28 -0
- package/dist/utils/secret-store.js +65 -0
- package/dist/utils/security.js +3 -2
- package/package.json +14 -11
- package/dist/services/screenshot-server.js +0 -65
- package/dist/services/server-manager.js +0 -81
- package/dist/services/uploader.js +0 -100
- package/dist/tdd/services/region-service.js +0 -75
- package/dist/utils/build-history.js +0 -103
|
@@ -1,86 +1,98 @@
|
|
|
1
|
-
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
1
|
import { renderToString } from "react-dom/server";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/utils/status-utils.js
|
|
3
4
|
function isNewComparisonStatus(status) {
|
|
4
|
-
|
|
5
|
+
return status === "new" || status === "baseline-created";
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/components/static-report-view.jsx
|
|
9
|
+
/**
|
|
10
|
+
* Static Report View
|
|
11
|
+
*
|
|
12
|
+
* A polished, hook-free component for SSR static report generation.
|
|
13
|
+
* Uses native HTML5 <details>/<summary> for expand/collapse without JavaScript.
|
|
14
|
+
* Designed for quick visual scanning with grouped status sections.
|
|
15
|
+
*/
|
|
16
|
+
var statusConfig = {
|
|
17
|
+
failed: {
|
|
18
|
+
label: "Changed",
|
|
19
|
+
borderClass: "border-l-red-500",
|
|
20
|
+
badgeClass: "bg-red-500/15 text-red-400 ring-red-500/30",
|
|
21
|
+
dotClass: "bg-red-500",
|
|
22
|
+
sectionTitle: "Visual Changes",
|
|
23
|
+
sectionIcon: "◐"
|
|
24
|
+
},
|
|
25
|
+
new: {
|
|
26
|
+
label: "New",
|
|
27
|
+
borderClass: "border-l-blue-500",
|
|
28
|
+
badgeClass: "bg-blue-500/15 text-blue-400 ring-blue-500/30",
|
|
29
|
+
dotClass: "bg-blue-500",
|
|
30
|
+
sectionTitle: "New Screenshots",
|
|
31
|
+
sectionIcon: "+"
|
|
32
|
+
},
|
|
33
|
+
passed: {
|
|
34
|
+
label: "Passed",
|
|
35
|
+
borderClass: "border-l-emerald-500",
|
|
36
|
+
badgeClass: "bg-emerald-500/15 text-emerald-400 ring-emerald-500/30",
|
|
37
|
+
dotClass: "bg-emerald-500",
|
|
38
|
+
sectionTitle: "Passed",
|
|
39
|
+
sectionIcon: "✓"
|
|
40
|
+
},
|
|
41
|
+
error: {
|
|
42
|
+
label: "Error",
|
|
43
|
+
borderClass: "border-l-orange-500",
|
|
44
|
+
badgeClass: "bg-orange-500/15 text-orange-400 ring-orange-500/30",
|
|
45
|
+
dotClass: "bg-orange-500",
|
|
46
|
+
sectionTitle: "Errors",
|
|
47
|
+
sectionIcon: "!"
|
|
48
|
+
}
|
|
39
49
|
};
|
|
40
50
|
function StatusBadge({ status }) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
children: [
|
|
47
|
-
/* @__PURE__ */ jsx("span", { className: `w-1.5 h-1.5 rounded-full ${config.dotClass}` }),
|
|
48
|
-
config.label
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
);
|
|
51
|
+
let config = statusConfig[status] || statusConfig.error;
|
|
52
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
53
|
+
className: `inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium ring-1 ring-inset ${config.badgeClass}`,
|
|
54
|
+
children: [/* @__PURE__ */ jsx("span", { className: `w-1.5 h-1.5 rounded-full ${config.dotClass}` }), config.label]
|
|
55
|
+
});
|
|
52
56
|
}
|
|
53
57
|
function DiffBadge({ percentage }) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
] });
|
|
58
|
+
if (percentage === void 0 || percentage === null || percentage === 0) return null;
|
|
59
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
60
|
+
className: "font-mono text-xs text-red-400/80 tabular-nums",
|
|
61
|
+
children: [percentage.toFixed(2), "%"]
|
|
62
|
+
});
|
|
60
63
|
}
|
|
61
64
|
function MetaInfo({ properties }) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
if (!properties) return null;
|
|
66
|
+
let { viewport_width, viewport_height, browser } = properties;
|
|
67
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
68
|
+
className: "flex items-center gap-2 text-xs text-slate-500",
|
|
69
|
+
children: [viewport_width && viewport_height && /* @__PURE__ */ jsxs("span", {
|
|
70
|
+
className: "font-mono tabular-nums",
|
|
71
|
+
children: [
|
|
72
|
+
viewport_width,
|
|
73
|
+
"×",
|
|
74
|
+
viewport_height
|
|
75
|
+
]
|
|
76
|
+
}), browser && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
77
|
+
className: "text-slate-600",
|
|
78
|
+
children: "·"
|
|
79
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
80
|
+
className: "capitalize",
|
|
81
|
+
children: browser
|
|
82
|
+
})] })]
|
|
83
|
+
});
|
|
75
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Comparison item for failed/changed screenshots
|
|
87
|
+
* Expandable with side-by-side comparison view
|
|
88
|
+
*/
|
|
76
89
|
function FailedComparison({ comparison, isEven }) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
className: `
|
|
90
|
+
let { name, status, current, baseline, diff, diffPercentage, properties } = comparison;
|
|
91
|
+
let config = statusConfig[status] || statusConfig.failed;
|
|
92
|
+
return /* @__PURE__ */ jsxs("details", {
|
|
93
|
+
className: "group",
|
|
94
|
+
children: [/* @__PURE__ */ jsxs("summary", {
|
|
95
|
+
className: `
|
|
84
96
|
flex items-center gap-4 p-4 cursor-pointer
|
|
85
97
|
${isEven ? "bg-slate-800/30" : "bg-slate-800/50"}
|
|
86
98
|
hover:bg-slate-700/50
|
|
@@ -89,125 +101,131 @@ function FailedComparison({ comparison, isEven }) {
|
|
|
89
101
|
list-none [&::-webkit-details-marker]:hidden
|
|
90
102
|
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-500/50 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900
|
|
91
103
|
`,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ jsxs("div", {
|
|
106
|
+
className: "relative w-16 h-10 flex-shrink-0 rounded overflow-hidden bg-slate-900",
|
|
107
|
+
children: [(current || baseline) && /* @__PURE__ */ jsx("img", {
|
|
108
|
+
src: current || baseline,
|
|
109
|
+
alt: "",
|
|
110
|
+
className: "w-full h-full object-cover object-top"
|
|
111
|
+
}), diff && /* @__PURE__ */ jsx("div", {
|
|
112
|
+
className: "absolute inset-0 bg-red-500/20 flex items-center justify-center",
|
|
113
|
+
children: /* @__PURE__ */ jsx("span", { className: "w-2 h-2 bg-red-500 rounded-full animate-pulse" })
|
|
114
|
+
})]
|
|
115
|
+
}),
|
|
116
|
+
/* @__PURE__ */ jsxs("div", {
|
|
117
|
+
className: "flex-1 min-w-0",
|
|
118
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
119
|
+
className: "flex items-center gap-2",
|
|
120
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
121
|
+
className: "font-medium text-white truncate",
|
|
122
|
+
children: name
|
|
123
|
+
}), /* @__PURE__ */ jsx(DiffBadge, { percentage: diffPercentage })]
|
|
124
|
+
}), /* @__PURE__ */ jsx(MetaInfo, { properties })]
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ jsxs("div", {
|
|
127
|
+
className: "flex items-center gap-3",
|
|
128
|
+
children: [/* @__PURE__ */ jsx(StatusBadge, { status }), /* @__PURE__ */ jsxs("div", {
|
|
129
|
+
className: "flex items-center gap-1.5 text-slate-500 group-hover:text-slate-400 transition-colors",
|
|
130
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
131
|
+
className: "text-xs hidden sm:inline opacity-0 group-hover:opacity-100 transition-opacity",
|
|
132
|
+
children: "Details"
|
|
133
|
+
}), /* @__PURE__ */ jsx("svg", {
|
|
134
|
+
className: "w-5 h-5 transition-transform duration-200 group-open:rotate-180",
|
|
135
|
+
fill: "none",
|
|
136
|
+
viewBox: "0 0 24 24",
|
|
137
|
+
stroke: "currentColor",
|
|
138
|
+
"aria-hidden": "true",
|
|
139
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
140
|
+
strokeLinecap: "round",
|
|
141
|
+
strokeLinejoin: "round",
|
|
142
|
+
strokeWidth: 2,
|
|
143
|
+
d: "M19 9l-7 7-7-7"
|
|
144
|
+
})
|
|
145
|
+
})]
|
|
146
|
+
})]
|
|
147
|
+
})
|
|
148
|
+
]
|
|
149
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
150
|
+
className: "mt-1 p-4 bg-slate-800/20 rounded-lg border border-slate-700/30 animate-[fadeIn_150ms_ease-out]",
|
|
151
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
152
|
+
className: "grid grid-cols-1 lg:grid-cols-2 gap-4",
|
|
153
|
+
children: [baseline && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
154
|
+
className: "flex items-center gap-2 mb-2",
|
|
155
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
156
|
+
className: "text-xs font-medium text-slate-400 uppercase tracking-wider",
|
|
157
|
+
children: "Baseline"
|
|
158
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
159
|
+
className: "text-xs text-slate-600",
|
|
160
|
+
children: "Expected"
|
|
161
|
+
})]
|
|
162
|
+
}), /* @__PURE__ */ jsx("a", {
|
|
163
|
+
href: baseline,
|
|
164
|
+
target: "_blank",
|
|
165
|
+
rel: "noopener noreferrer",
|
|
166
|
+
className: "block rounded-lg overflow-hidden border border-slate-700/50 hover:border-slate-600 transition-colors",
|
|
167
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
168
|
+
src: baseline,
|
|
169
|
+
alt: `${name} baseline`,
|
|
170
|
+
className: "w-full"
|
|
171
|
+
})
|
|
172
|
+
})] }), current && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
173
|
+
className: "flex items-center gap-2 mb-2",
|
|
174
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
175
|
+
className: "text-xs font-medium text-slate-400 uppercase tracking-wider",
|
|
176
|
+
children: "Current"
|
|
177
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
178
|
+
className: "text-xs text-slate-600",
|
|
179
|
+
children: "Actual"
|
|
180
|
+
})]
|
|
181
|
+
}), /* @__PURE__ */ jsx("a", {
|
|
182
|
+
href: current,
|
|
183
|
+
target: "_blank",
|
|
184
|
+
rel: "noopener noreferrer",
|
|
185
|
+
className: "block rounded-lg overflow-hidden border border-slate-700/50 hover:border-slate-600 transition-colors",
|
|
186
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
187
|
+
src: current,
|
|
188
|
+
alt: `${name} current`,
|
|
189
|
+
className: "w-full"
|
|
190
|
+
})
|
|
191
|
+
})] })]
|
|
192
|
+
}), diff && /* @__PURE__ */ jsxs("div", {
|
|
193
|
+
className: "mt-4 pt-4 border-t border-slate-700/30",
|
|
194
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
195
|
+
className: "flex items-center gap-2 mb-2",
|
|
196
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
197
|
+
className: "text-xs font-medium text-red-400 uppercase tracking-wider",
|
|
198
|
+
children: "Difference"
|
|
199
|
+
}), diffPercentage > 0 && /* @__PURE__ */ jsxs("span", {
|
|
200
|
+
className: "text-xs text-red-400/60 font-mono",
|
|
201
|
+
children: [diffPercentage.toFixed(2), "% of pixels changed"]
|
|
202
|
+
})]
|
|
203
|
+
}), /* @__PURE__ */ jsx("a", {
|
|
204
|
+
href: diff,
|
|
205
|
+
target: "_blank",
|
|
206
|
+
rel: "noopener noreferrer",
|
|
207
|
+
className: "block rounded-lg overflow-hidden border border-red-500/30 hover:border-red-500/50 transition-colors max-w-2xl",
|
|
208
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
209
|
+
src: diff,
|
|
210
|
+
alt: `${name} diff`,
|
|
211
|
+
className: "w-full"
|
|
212
|
+
})
|
|
213
|
+
})]
|
|
214
|
+
})]
|
|
215
|
+
})]
|
|
216
|
+
});
|
|
202
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Comparison item for new screenshots
|
|
220
|
+
* Expandable to show the new screenshot
|
|
221
|
+
*/
|
|
203
222
|
function NewComparison({ comparison, isEven }) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
className: `
|
|
223
|
+
let { name, current, baseline, properties } = comparison;
|
|
224
|
+
let imageSrc = current || baseline;
|
|
225
|
+
return /* @__PURE__ */ jsxs("details", {
|
|
226
|
+
className: "group",
|
|
227
|
+
children: [/* @__PURE__ */ jsxs("summary", {
|
|
228
|
+
className: `
|
|
211
229
|
flex items-center gap-4 p-4 cursor-pointer
|
|
212
230
|
${isEven ? "bg-slate-800/30" : "bg-slate-800/50"}
|
|
213
231
|
hover:bg-slate-700/50
|
|
@@ -216,346 +234,424 @@ function NewComparison({ comparison, isEven }) {
|
|
|
216
234
|
list-none [&::-webkit-details-marker]:hidden
|
|
217
235
|
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-500/50 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900
|
|
218
236
|
`,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
237
|
+
children: [
|
|
238
|
+
/* @__PURE__ */ jsx("div", {
|
|
239
|
+
className: "w-16 h-10 flex-shrink-0 rounded overflow-hidden bg-slate-900",
|
|
240
|
+
children: imageSrc && /* @__PURE__ */ jsx("img", {
|
|
241
|
+
src: imageSrc,
|
|
242
|
+
alt: "",
|
|
243
|
+
className: "w-full h-full object-cover object-top"
|
|
244
|
+
})
|
|
245
|
+
}),
|
|
246
|
+
/* @__PURE__ */ jsxs("div", {
|
|
247
|
+
className: "flex-1 min-w-0",
|
|
248
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
249
|
+
className: "font-medium text-white truncate block",
|
|
250
|
+
children: name
|
|
251
|
+
}), /* @__PURE__ */ jsx(MetaInfo, { properties })]
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ jsxs("div", {
|
|
254
|
+
className: "flex items-center gap-3",
|
|
255
|
+
children: [/* @__PURE__ */ jsx(StatusBadge, { status: "new" }), /* @__PURE__ */ jsxs("div", {
|
|
256
|
+
className: "flex items-center gap-1.5 text-slate-500 group-hover:text-slate-400 transition-colors",
|
|
257
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
258
|
+
className: "text-xs hidden sm:inline opacity-0 group-hover:opacity-100 transition-opacity",
|
|
259
|
+
children: "Preview"
|
|
260
|
+
}), /* @__PURE__ */ jsx("svg", {
|
|
261
|
+
className: "w-5 h-5 transition-transform duration-200 group-open:rotate-180",
|
|
262
|
+
fill: "none",
|
|
263
|
+
viewBox: "0 0 24 24",
|
|
264
|
+
stroke: "currentColor",
|
|
265
|
+
"aria-hidden": "true",
|
|
266
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
267
|
+
strokeLinecap: "round",
|
|
268
|
+
strokeLinejoin: "round",
|
|
269
|
+
strokeWidth: 2,
|
|
270
|
+
d: "M19 9l-7 7-7-7"
|
|
271
|
+
})
|
|
272
|
+
})]
|
|
273
|
+
})]
|
|
274
|
+
})
|
|
275
|
+
]
|
|
276
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
277
|
+
className: "mt-1 p-4 bg-slate-800/20 rounded-lg border border-slate-700/30 animate-[fadeIn_150ms_ease-out]",
|
|
278
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
279
|
+
className: "flex items-center gap-2 mb-2",
|
|
280
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
281
|
+
className: "text-xs font-medium text-blue-400 uppercase tracking-wider",
|
|
282
|
+
children: "New Screenshot"
|
|
283
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
284
|
+
className: "text-xs text-slate-600",
|
|
285
|
+
children: "No baseline to compare"
|
|
286
|
+
})]
|
|
287
|
+
}), imageSrc && /* @__PURE__ */ jsx("a", {
|
|
288
|
+
href: imageSrc,
|
|
289
|
+
target: "_blank",
|
|
290
|
+
rel: "noopener noreferrer",
|
|
291
|
+
className: "block rounded-lg overflow-hidden border border-blue-500/30 hover:border-blue-500/50 transition-colors max-w-2xl",
|
|
292
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
293
|
+
src: imageSrc,
|
|
294
|
+
alt: name,
|
|
295
|
+
className: "w-full"
|
|
296
|
+
})
|
|
297
|
+
})]
|
|
298
|
+
})]
|
|
299
|
+
});
|
|
277
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Compact passed item - no expand needed
|
|
303
|
+
*/
|
|
278
304
|
function PassedComparison({ comparison }) {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
{
|
|
283
|
-
className: `
|
|
305
|
+
let { name, properties } = comparison;
|
|
306
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
307
|
+
className: `
|
|
284
308
|
flex items-center gap-3 px-4 py-2.5
|
|
285
309
|
bg-slate-800/20 hover:bg-slate-800/30
|
|
286
310
|
border-l-4 border-l-emerald-500/50
|
|
287
311
|
rounded-r-lg transition-colors
|
|
288
312
|
`,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
);
|
|
313
|
+
children: [
|
|
314
|
+
/* @__PURE__ */ jsx("div", {
|
|
315
|
+
className: "w-5 h-5 rounded-full bg-emerald-500/20 flex items-center justify-center flex-shrink-0",
|
|
316
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
317
|
+
className: "w-3 h-3 text-emerald-400",
|
|
318
|
+
fill: "currentColor",
|
|
319
|
+
viewBox: "0 0 20 20",
|
|
320
|
+
"aria-hidden": "true",
|
|
321
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
322
|
+
fillRule: "evenodd",
|
|
323
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
324
|
+
clipRule: "evenodd"
|
|
325
|
+
})
|
|
326
|
+
})
|
|
327
|
+
}),
|
|
328
|
+
/* @__PURE__ */ jsx("span", {
|
|
329
|
+
className: "flex-1 text-sm text-slate-300 truncate",
|
|
330
|
+
children: name
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ jsx(MetaInfo, { properties })
|
|
333
|
+
]
|
|
334
|
+
});
|
|
312
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Section header for grouping
|
|
338
|
+
*/
|
|
313
339
|
function SectionHeader({ title, count, icon, colorClass }) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
340
|
+
if (count === 0) return null;
|
|
341
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
342
|
+
className: "flex items-center gap-3 mb-3",
|
|
343
|
+
children: [
|
|
344
|
+
/* @__PURE__ */ jsx("span", {
|
|
345
|
+
className: `text-lg font-mono ${colorClass}`,
|
|
346
|
+
children: icon
|
|
347
|
+
}),
|
|
348
|
+
/* @__PURE__ */ jsx("h3", {
|
|
349
|
+
className: "text-sm font-semibold text-slate-300 uppercase tracking-wider",
|
|
350
|
+
children: title
|
|
351
|
+
}),
|
|
352
|
+
/* @__PURE__ */ jsxs("span", {
|
|
353
|
+
className: "text-sm text-slate-500 font-mono",
|
|
354
|
+
children: [
|
|
355
|
+
"(",
|
|
356
|
+
count,
|
|
357
|
+
")"
|
|
358
|
+
]
|
|
359
|
+
})
|
|
360
|
+
]
|
|
361
|
+
});
|
|
324
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Summary stats bar
|
|
365
|
+
*/
|
|
325
366
|
function SummaryBar({ stats }) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
{
|
|
330
|
-
className: `
|
|
367
|
+
let hasIssues = stats.failed > 0 || stats.new > 0;
|
|
368
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
369
|
+
className: `
|
|
331
370
|
flex flex-wrap items-center gap-6 p-4 rounded-xl mb-8
|
|
332
371
|
${hasIssues ? "bg-slate-800/60 border border-slate-700/50" : "bg-emerald-500/10 border border-emerald-500/20"}
|
|
333
372
|
`,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
373
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
374
|
+
className: "flex items-center gap-3",
|
|
375
|
+
children: hasIssues ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
376
|
+
className: "w-10 h-10 rounded-full bg-amber-500/20 flex items-center justify-center",
|
|
377
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
378
|
+
className: "text-amber-400 text-lg",
|
|
379
|
+
children: "◐"
|
|
380
|
+
})
|
|
381
|
+
}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
382
|
+
className: "text-white font-semibold",
|
|
383
|
+
children: "Review Required"
|
|
384
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
385
|
+
className: "text-sm text-slate-400",
|
|
386
|
+
children: [stats.failed + (stats.new || 0), " items need attention"]
|
|
387
|
+
})] })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
388
|
+
className: "w-10 h-10 rounded-full bg-emerald-500/20 flex items-center justify-center",
|
|
389
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
390
|
+
className: "w-5 h-5 text-emerald-400",
|
|
391
|
+
fill: "currentColor",
|
|
392
|
+
viewBox: "0 0 20 20",
|
|
393
|
+
"aria-hidden": "true",
|
|
394
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
395
|
+
fillRule: "evenodd",
|
|
396
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
397
|
+
clipRule: "evenodd"
|
|
398
|
+
})
|
|
399
|
+
})
|
|
400
|
+
}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
401
|
+
className: "text-white font-semibold",
|
|
402
|
+
children: "All Tests Passed"
|
|
403
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
404
|
+
className: "text-sm text-slate-400",
|
|
405
|
+
children: "No visual changes detected"
|
|
406
|
+
})] })] })
|
|
407
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
408
|
+
className: "flex items-center gap-6 ml-auto",
|
|
409
|
+
children: [
|
|
410
|
+
/* @__PURE__ */ jsxs("div", {
|
|
411
|
+
className: "text-center",
|
|
412
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
413
|
+
className: "text-2xl font-bold text-white tabular-nums",
|
|
414
|
+
children: stats.total
|
|
415
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
416
|
+
className: "text-xs text-slate-500 uppercase tracking-wider",
|
|
417
|
+
children: "Total"
|
|
418
|
+
})]
|
|
419
|
+
}),
|
|
420
|
+
/* @__PURE__ */ jsxs("div", {
|
|
421
|
+
className: "text-center",
|
|
422
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
423
|
+
className: "text-2xl font-bold text-emerald-400 tabular-nums",
|
|
424
|
+
children: stats.passed
|
|
425
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
426
|
+
className: "text-xs text-slate-500 uppercase tracking-wider",
|
|
427
|
+
children: "Passed"
|
|
428
|
+
})]
|
|
429
|
+
}),
|
|
430
|
+
stats.failed > 0 && /* @__PURE__ */ jsxs("div", {
|
|
431
|
+
className: "text-center",
|
|
432
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
433
|
+
className: "text-2xl font-bold text-red-400 tabular-nums",
|
|
434
|
+
children: stats.failed
|
|
435
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
436
|
+
className: "text-xs text-slate-500 uppercase tracking-wider",
|
|
437
|
+
children: "Changed"
|
|
438
|
+
})]
|
|
439
|
+
}),
|
|
440
|
+
(stats.new || 0) > 0 && /* @__PURE__ */ jsxs("div", {
|
|
441
|
+
className: "text-center",
|
|
442
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
443
|
+
className: "text-2xl font-bold text-blue-400 tabular-nums",
|
|
444
|
+
children: stats.new
|
|
445
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
446
|
+
className: "text-xs text-slate-500 uppercase tracking-wider",
|
|
447
|
+
children: "New"
|
|
448
|
+
})]
|
|
449
|
+
})
|
|
450
|
+
]
|
|
451
|
+
})]
|
|
452
|
+
});
|
|
388
453
|
}
|
|
389
454
|
function formatTimestamp(timestamp) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
});
|
|
455
|
+
if (!timestamp) return null;
|
|
456
|
+
return new Date(timestamp).toLocaleDateString(void 0, {
|
|
457
|
+
year: "numeric",
|
|
458
|
+
month: "short",
|
|
459
|
+
day: "numeric",
|
|
460
|
+
hour: "2-digit",
|
|
461
|
+
minute: "2-digit"
|
|
462
|
+
});
|
|
399
463
|
}
|
|
400
464
|
function Header({ timestamp }) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
465
|
+
return /* @__PURE__ */ jsx("header", {
|
|
466
|
+
className: "bg-slate-950/80 backdrop-blur-sm border-b border-slate-800/60 sticky top-0 z-10",
|
|
467
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
468
|
+
className: "max-w-6xl mx-auto px-6 py-4 flex items-center justify-between",
|
|
469
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
470
|
+
className: "flex items-center gap-3",
|
|
471
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
472
|
+
className: "w-9 h-9 bg-gradient-to-br from-amber-400 to-amber-600 rounded-lg flex items-center justify-center shadow-lg shadow-amber-500/20",
|
|
473
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
474
|
+
className: "w-5 h-5 text-slate-900",
|
|
475
|
+
viewBox: "0 0 24 24",
|
|
476
|
+
fill: "currentColor",
|
|
477
|
+
"aria-hidden": "true",
|
|
478
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
479
|
+
cx: "12",
|
|
480
|
+
cy: "12",
|
|
481
|
+
r: "3"
|
|
482
|
+
}), /* @__PURE__ */ jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" })]
|
|
483
|
+
})
|
|
484
|
+
}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
485
|
+
className: "text-lg font-semibold text-white tracking-tight",
|
|
486
|
+
children: "Vizzly"
|
|
487
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
488
|
+
className: "text-xs text-slate-500",
|
|
489
|
+
children: "Visual Test Report"
|
|
490
|
+
})] })]
|
|
491
|
+
}), timestamp && /* @__PURE__ */ jsx("div", {
|
|
492
|
+
className: "text-xs text-slate-500 tabular-nums",
|
|
493
|
+
children: formatTimestamp(timestamp)
|
|
494
|
+
})]
|
|
495
|
+
})
|
|
496
|
+
});
|
|
423
497
|
}
|
|
424
498
|
function StaticReportView({ reportData }) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
499
|
+
if (!reportData?.comparisons) return /* @__PURE__ */ jsx("div", {
|
|
500
|
+
className: "min-h-screen bg-slate-900 text-white flex items-center justify-center",
|
|
501
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
502
|
+
className: "text-center",
|
|
503
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
504
|
+
className: "text-xl font-medium mb-2",
|
|
505
|
+
children: "No Report Data"
|
|
506
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
507
|
+
className: "text-slate-400",
|
|
508
|
+
children: "No comparison data available for this report."
|
|
509
|
+
})]
|
|
510
|
+
})
|
|
511
|
+
});
|
|
512
|
+
let { comparisons } = reportData;
|
|
513
|
+
let stats = {
|
|
514
|
+
total: comparisons.length,
|
|
515
|
+
passed: comparisons.filter((c) => c.status === "passed").length,
|
|
516
|
+
failed: comparisons.filter((c) => c.status === "failed").length,
|
|
517
|
+
new: comparisons.filter((c) => isNewComparisonStatus(c.status)).length,
|
|
518
|
+
error: comparisons.filter((c) => c.status === "error").length
|
|
519
|
+
};
|
|
520
|
+
let failed = comparisons.filter((c) => c.status === "failed");
|
|
521
|
+
let newItems = comparisons.filter((c) => isNewComparisonStatus(c.status));
|
|
522
|
+
let passed = comparisons.filter((c) => c.status === "passed");
|
|
523
|
+
let errors = comparisons.filter((c) => c.status === "error");
|
|
524
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
525
|
+
className: "min-h-screen bg-slate-900 text-white",
|
|
526
|
+
children: [/* @__PURE__ */ jsx(Header, { timestamp: reportData.timestamp }), /* @__PURE__ */ jsxs("main", {
|
|
527
|
+
className: "max-w-6xl mx-auto px-6 py-8",
|
|
528
|
+
children: [
|
|
529
|
+
/* @__PURE__ */ jsx(SummaryBar, { stats }),
|
|
530
|
+
failed.length > 0 && /* @__PURE__ */ jsxs("section", {
|
|
531
|
+
className: "mb-8",
|
|
532
|
+
children: [/* @__PURE__ */ jsx(SectionHeader, {
|
|
533
|
+
title: "Visual Changes",
|
|
534
|
+
count: failed.length,
|
|
535
|
+
icon: "◐",
|
|
536
|
+
colorClass: "text-red-400"
|
|
537
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
538
|
+
className: "space-y-2",
|
|
539
|
+
children: failed.map((comparison, index) => /* @__PURE__ */ jsx(FailedComparison, {
|
|
540
|
+
comparison,
|
|
541
|
+
isEven: index % 2 === 0
|
|
542
|
+
}, comparison.id || comparison.signature || `failed-${index}`))
|
|
543
|
+
})]
|
|
544
|
+
}),
|
|
545
|
+
newItems.length > 0 && /* @__PURE__ */ jsxs("section", {
|
|
546
|
+
className: "mb-8",
|
|
547
|
+
children: [/* @__PURE__ */ jsx(SectionHeader, {
|
|
548
|
+
title: "New Screenshots",
|
|
549
|
+
count: newItems.length,
|
|
550
|
+
icon: "+",
|
|
551
|
+
colorClass: "text-blue-400"
|
|
552
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
553
|
+
className: "space-y-2",
|
|
554
|
+
children: newItems.map((comparison, index) => /* @__PURE__ */ jsx(NewComparison, {
|
|
555
|
+
comparison,
|
|
556
|
+
isEven: index % 2 === 0
|
|
557
|
+
}, comparison.id || comparison.signature || `new-${index}`))
|
|
558
|
+
})]
|
|
559
|
+
}),
|
|
560
|
+
errors.length > 0 && /* @__PURE__ */ jsxs("section", {
|
|
561
|
+
className: "mb-8",
|
|
562
|
+
children: [/* @__PURE__ */ jsx(SectionHeader, {
|
|
563
|
+
title: "Errors",
|
|
564
|
+
count: errors.length,
|
|
565
|
+
icon: "!",
|
|
566
|
+
colorClass: "text-orange-400"
|
|
567
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
568
|
+
className: "space-y-2",
|
|
569
|
+
children: errors.map((comparison, index) => /* @__PURE__ */ jsx(FailedComparison, {
|
|
570
|
+
comparison,
|
|
571
|
+
isEven: index % 2 === 0
|
|
572
|
+
}, comparison.id || comparison.signature || `error-${index}`))
|
|
573
|
+
})]
|
|
574
|
+
}),
|
|
575
|
+
passed.length > 0 && /* @__PURE__ */ jsx("section", {
|
|
576
|
+
className: "mb-8",
|
|
577
|
+
children: /* @__PURE__ */ jsxs("details", {
|
|
578
|
+
className: "group",
|
|
579
|
+
children: [/* @__PURE__ */ jsx("summary", {
|
|
580
|
+
className: "cursor-pointer list-none [&::-webkit-details-marker]:hidden",
|
|
581
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
582
|
+
className: "flex items-center gap-3 mb-3",
|
|
583
|
+
children: [
|
|
584
|
+
/* @__PURE__ */ jsx("span", {
|
|
585
|
+
className: "text-lg font-mono text-emerald-400",
|
|
586
|
+
children: "✓"
|
|
587
|
+
}),
|
|
588
|
+
/* @__PURE__ */ jsx("h3", {
|
|
589
|
+
className: "text-sm font-semibold text-slate-300 uppercase tracking-wider",
|
|
590
|
+
children: "Passed"
|
|
591
|
+
}),
|
|
592
|
+
/* @__PURE__ */ jsxs("span", {
|
|
593
|
+
className: "text-sm text-slate-500 font-mono",
|
|
594
|
+
children: [
|
|
595
|
+
"(",
|
|
596
|
+
passed.length,
|
|
597
|
+
")"
|
|
598
|
+
]
|
|
599
|
+
}),
|
|
600
|
+
/* @__PURE__ */ jsx("svg", {
|
|
601
|
+
className: "w-4 h-4 text-slate-500 transition-transform group-open:rotate-180 ml-auto",
|
|
602
|
+
fill: "none",
|
|
603
|
+
viewBox: "0 0 24 24",
|
|
604
|
+
stroke: "currentColor",
|
|
605
|
+
"aria-hidden": "true",
|
|
606
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
607
|
+
strokeLinecap: "round",
|
|
608
|
+
strokeLinejoin: "round",
|
|
609
|
+
strokeWidth: 2,
|
|
610
|
+
d: "M19 9l-7 7-7-7"
|
|
611
|
+
})
|
|
612
|
+
})
|
|
613
|
+
]
|
|
614
|
+
})
|
|
615
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
616
|
+
className: "space-y-1",
|
|
617
|
+
children: passed.map((comparison, index) => /* @__PURE__ */ jsx(PassedComparison, { comparison }, comparison.id || comparison.signature || `passed-${index}`))
|
|
618
|
+
})]
|
|
619
|
+
})
|
|
620
|
+
}),
|
|
621
|
+
/* @__PURE__ */ jsx("footer", {
|
|
622
|
+
className: "mt-12 pt-6 border-t border-slate-800/60 text-center",
|
|
623
|
+
children: /* @__PURE__ */ jsxs("p", {
|
|
624
|
+
className: "text-sm text-slate-500",
|
|
625
|
+
children: [
|
|
626
|
+
"Visual regression report generated by",
|
|
627
|
+
" ",
|
|
628
|
+
/* @__PURE__ */ jsx("a", {
|
|
629
|
+
href: "https://vizzly.dev",
|
|
630
|
+
className: "text-amber-400 hover:text-amber-300 transition-colors",
|
|
631
|
+
children: "Vizzly"
|
|
632
|
+
})
|
|
633
|
+
]
|
|
634
|
+
})
|
|
635
|
+
})
|
|
636
|
+
]
|
|
637
|
+
})]
|
|
638
|
+
});
|
|
555
639
|
}
|
|
640
|
+
//#endregion
|
|
641
|
+
//#region src/ssr-entry.jsx
|
|
642
|
+
/**
|
|
643
|
+
* SSR Entry Point
|
|
644
|
+
*
|
|
645
|
+
* This module exports a function to render the static report to HTML string.
|
|
646
|
+
* It's built by Vite as a Node-compatible module for use in the CLI.
|
|
647
|
+
*/
|
|
648
|
+
/**
|
|
649
|
+
* Render the static report to an HTML string
|
|
650
|
+
* @param {Object} reportData - The report data from report-data.json
|
|
651
|
+
* @returns {string} The rendered HTML
|
|
652
|
+
*/
|
|
556
653
|
function renderStaticReport(reportData) {
|
|
557
|
-
|
|
654
|
+
return renderToString(/* @__PURE__ */ jsx(StaticReportView, { reportData }));
|
|
558
655
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
};
|
|
656
|
+
//#endregion
|
|
657
|
+
export { renderStaticReport };
|