@acutis/cli 0.5.1-dev.31 → 0.6.0-dev.33

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 (108) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/4RAEZKK5.js +1 -0
  3. package/.output/public/_nuxt/B71L_ar8.js +1 -0
  4. package/.output/public/_nuxt/{CsAwRnSX.js → B8-AOuPY.js} +1 -1
  5. package/.output/public/_nuxt/BDJSpxa5.js +1 -0
  6. package/.output/public/_nuxt/BSTaqC8B.js +1 -0
  7. package/.output/public/_nuxt/BX0w1sCd.js +64 -0
  8. package/.output/public/_nuxt/BZkyScXE.js +7 -0
  9. package/.output/public/_nuxt/Bcy6XGvf.js +1 -0
  10. package/.output/public/_nuxt/BwUN2VDn.js +28 -0
  11. package/.output/public/_nuxt/C7ujW0dH.js +1 -0
  12. package/.output/public/_nuxt/CCTDX4Ow.js +1 -0
  13. package/.output/public/_nuxt/CGBjV6IE.js +3 -0
  14. package/.output/public/_nuxt/CJwIJ5vo.js +1 -0
  15. package/.output/public/_nuxt/CRRnxrgg.js +1 -0
  16. package/.output/public/_nuxt/CW-iqL9y.js +1 -0
  17. package/.output/public/_nuxt/CX9rRDYY.js +1 -0
  18. package/.output/public/_nuxt/Cc9wzr_w.js +1 -0
  19. package/.output/public/_nuxt/Cfk1Mt0g.js +1 -0
  20. package/.output/public/_nuxt/Cha4KRz0.js +1 -0
  21. package/.output/public/_nuxt/D229JSjk.js +1 -0
  22. package/.output/public/_nuxt/D24Vvzw2.js +1 -0
  23. package/.output/public/_nuxt/DRoB9fQQ.js +1 -0
  24. package/.output/public/_nuxt/DZ5wax3g.js +1 -0
  25. package/.output/public/_nuxt/DZkgJHFm.js +1 -0
  26. package/.output/public/_nuxt/PIShll5e.js +1 -0
  27. package/.output/public/_nuxt/_oJUkNQ2.js +1 -0
  28. package/.output/public/_nuxt/builds/latest.json +1 -1
  29. package/.output/public/_nuxt/builds/meta/522d5fac-12d3-4a5c-b094-a2116ce9fbdd.json +1 -0
  30. package/.output/public/_nuxt/{entry.BmTN_nlL.css → entry.cOeTFjBb.css} +1 -1
  31. package/.output/public/_nuxt/jaiNplxU.js +1 -0
  32. package/.output/public/_nuxt/{Dn-SWUOQ.js → nocvyJKp.js} +1 -1
  33. package/.output/server/chunks/_/auth2.mjs +2 -2
  34. package/.output/server/chunks/_/environment.mjs +2 -2
  35. package/.output/server/chunks/_/execution.mjs +6 -4
  36. package/.output/server/chunks/_/execution.mjs.map +1 -1
  37. package/.output/server/chunks/_/generation.mjs +2 -2
  38. package/.output/server/chunks/_/project.mjs +1 -1
  39. package/.output/server/chunks/_/project.service.mjs +2 -2
  40. package/.output/server/chunks/_/scenario2.mjs +88 -6
  41. package/.output/server/chunks/_/scenario2.mjs.map +1 -1
  42. package/.output/server/chunks/build/{Alert-CGPbjyet.mjs → Alert-BJf39Ayb.mjs} +1 -1
  43. package/.output/server/chunks/build/{Alert-CGPbjyet.mjs.map → Alert-BJf39Ayb.mjs.map} +1 -1
  44. package/.output/server/chunks/build/Badge-BMpCypXw.mjs +394 -0
  45. package/.output/server/chunks/build/Badge-BMpCypXw.mjs.map +1 -0
  46. package/.output/server/chunks/build/{Container-Bw8GVIe-.mjs → Container-D0WjluxO.mjs} +1 -1
  47. package/.output/server/chunks/build/{Container-Bw8GVIe-.mjs.map → Container-D0WjluxO.mjs.map} +1 -1
  48. package/.output/server/chunks/build/ContextMenu-CC085wXq.mjs +1746 -0
  49. package/.output/server/chunks/build/ContextMenu-CC085wXq.mjs.map +1 -0
  50. package/.output/server/chunks/build/{Pagination-BF2ykxf_.mjs → Pagination-DxUglDxC.mjs} +1 -1
  51. package/.output/server/chunks/build/{Pagination-BF2ykxf_.mjs.map → Pagination-DxUglDxC.mjs.map} +1 -1
  52. package/.output/server/chunks/build/{_...scenario_-CPwSmhfV.mjs → _...scenario_-mkuUQnXV.mjs} +48 -28
  53. package/.output/server/chunks/build/_...scenario_-mkuUQnXV.mjs.map +1 -0
  54. package/.output/server/chunks/build/_run_-CURVtzqt.mjs +649 -0
  55. package/.output/server/chunks/build/_run_-CURVtzqt.mjs.map +1 -0
  56. package/.output/server/chunks/build/{_slug_-DjtFCLa7.mjs → _slug_-CCufladN.mjs} +373 -138
  57. package/.output/server/chunks/build/{_slug_-DjtFCLa7.mjs.map → _slug_-CCufladN.mjs.map} +1 -1
  58. package/.output/server/chunks/build/error-404-B5fzVPdQ.mjs +1 -1
  59. package/.output/server/chunks/build/error-500-Be62wrWs.mjs +1 -1
  60. package/.output/server/chunks/build/{modal-styles.BULzQjZ8.mjs → modal-styles.CLPmxixy.mjs} +3 -3
  61. package/.output/server/chunks/build/modal-styles.CLPmxixy.mjs.map +1 -0
  62. package/.output/server/chunks/build/{origin-D49r5-BY.mjs → origin-COKNa406.mjs} +102 -396
  63. package/.output/server/chunks/build/{origin-D49r5-BY.mjs.map → origin-COKNa406.mjs.map} +1 -1
  64. package/.output/server/chunks/build/{pages-Dve6n3fN.mjs → pages-BoaPn4t_.mjs} +171 -51
  65. package/.output/server/chunks/build/{pages-Dve6n3fN.mjs.map → pages-BoaPn4t_.mjs.map} +1 -1
  66. package/.output/server/chunks/build/plural-DvfNYUEX.mjs +93 -0
  67. package/.output/server/chunks/build/plural-DvfNYUEX.mjs.map +1 -0
  68. package/.output/server/chunks/build/report-ISc2vlII.mjs +725 -0
  69. package/.output/server/chunks/build/report-ISc2vlII.mjs.map +1 -0
  70. package/.output/server/chunks/build/run-stream-Dfh0fAdN.mjs +198 -0
  71. package/.output/server/chunks/build/run-stream-Dfh0fAdN.mjs.map +1 -0
  72. package/.output/server/chunks/build/{tags-CU5wN20i.mjs → tags-BiGI0PZP.mjs} +16 -299
  73. package/.output/server/chunks/build/tags-BiGI0PZP.mjs.map +1 -0
  74. package/.output/server/chunks/build/{telemetria-CU1QSpLB.mjs → telemetria-CXZfYngH.mjs} +3 -3
  75. package/.output/server/chunks/build/{telemetria-CU1QSpLB.mjs.map → telemetria-CXZfYngH.mjs.map} +1 -1
  76. package/.output/server/chunks/nitro/nitro.mjs +227 -148
  77. package/.output/server/chunks/routes/api/projects/_slug/run-stream.get.mjs +5 -1
  78. package/.output/server/chunks/routes/api/projects/_slug/run-stream.get.mjs.map +1 -1
  79. package/.output/server/chunks/routes/api/projects/_slug/runs.get.mjs +79 -0
  80. package/.output/server/chunks/routes/api/projects/_slug/runs.get.mjs.map +1 -0
  81. package/.output/server/chunks/routes/api/telemetry/report.post.mjs +1 -1
  82. package/.output/server/chunks/routes/renderer.mjs +3 -3
  83. package/.output/server/chunks/routes/ws.mjs +1 -1
  84. package/.output/server/chunks/virtual/entry.mjs +9336 -8497
  85. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  86. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  87. package/.output/server/chunks/virtual/styles.mjs +1 -1
  88. package/.output/server/package.json +1 -1
  89. package/package.json +1 -1
  90. package/.output/public/_nuxt/2nD-p2HC.js +0 -1
  91. package/.output/public/_nuxt/B9s6bjC6.js +0 -1
  92. package/.output/public/_nuxt/BNt3M20G.js +0 -3
  93. package/.output/public/_nuxt/BVORrxe1.js +0 -1
  94. package/.output/public/_nuxt/BWJi3RB7.js +0 -7
  95. package/.output/public/_nuxt/BZKoKeJ4.js +0 -1
  96. package/.output/public/_nuxt/BdD531YY.js +0 -1
  97. package/.output/public/_nuxt/Bim2Ilco.js +0 -1
  98. package/.output/public/_nuxt/BormXq2m.js +0 -1
  99. package/.output/public/_nuxt/Bv4T7S6_.js +0 -1
  100. package/.output/public/_nuxt/BwcOmYtM.js +0 -1
  101. package/.output/public/_nuxt/CJJvNaNU.js +0 -1
  102. package/.output/public/_nuxt/Dq_3AVr2.js +0 -1
  103. package/.output/public/_nuxt/builds/meta/5edd57d4-09ec-4816-9ce0-37d246a982cc.json +0 -1
  104. package/.output/public/_nuxt/jEu0WM6o.js +0 -28
  105. package/.output/public/_nuxt/x-Ln6s2E.js +0 -64
  106. package/.output/server/chunks/build/_...scenario_-CPwSmhfV.mjs.map +0 -1
  107. package/.output/server/chunks/build/modal-styles.BULzQjZ8.mjs.map +0 -1
  108. package/.output/server/chunks/build/tags-CU5wN20i.mjs.map +0 -1
@@ -0,0 +1,725 @@
1
+ import { f as useRoute, g as useFetch, i as icon_default, h as _sfc_main$7, N as NuxtLink, e as _sfc_main$5 } from '../virtual/entry.mjs';
2
+ import { _ as _sfc_main$1 } from './Pagination-DxUglDxC.mjs';
3
+ import { _ as _sfc_main } from './Container-D0WjluxO.mjs';
4
+ import { r as reportUrlFor, e as empty_default } from './run-stream-Dfh0fAdN.mjs';
5
+ import { m as metric_default, p as plural, r as ranking_default, c as counted } from './plural-DvfNYUEX.mjs';
6
+ import { defineComponent, computed, ref, withAsyncContext, mergeProps, unref, withCtx, isRef, createVNode, toDisplayString, openBlock, createBlock, createCommentVNode, Fragment, createTextVNode, useSSRContext } from 'vue';
7
+ import { ssrRenderComponent, ssrInterpolate, ssrRenderAttrs, ssrRenderList, ssrRenderStyle, ssrRenderClass, ssrRenderAttr } from 'vue/server-renderer';
8
+ import 'unhead/plugins';
9
+ import 'unhead/utils';
10
+ import '../routes/renderer.mjs';
11
+ import '../nitro/nitro.mjs';
12
+ import 'node:http';
13
+ import 'node:https';
14
+ import 'node:crypto';
15
+ import 'stream';
16
+ import 'events';
17
+ import 'http';
18
+ import 'crypto';
19
+ import 'buffer';
20
+ import 'zlib';
21
+ import 'https';
22
+ import 'net';
23
+ import 'tls';
24
+ import 'url';
25
+ import 'node:events';
26
+ import 'node:buffer';
27
+ import 'node:fs';
28
+ import 'node:path';
29
+ import 'node:dns/promises';
30
+ import 'node:net';
31
+ import 'playwright';
32
+ import 'zod';
33
+ import 'node:url';
34
+ import 'node:fs/promises';
35
+ import 'node:async_hooks';
36
+ import 'node:os';
37
+ import 'typeorm';
38
+ import '@langchain/langgraph';
39
+ import '@anthropic-ai/claude-agent-sdk';
40
+ import 'langchain';
41
+ import '@iconify/utils';
42
+ import 'consola';
43
+ import 'unhead/server';
44
+ import 'unhead/legacy';
45
+ import 'nostics';
46
+ import 'vue-bundle-renderer/runtime';
47
+ import 'devalue';
48
+ import 'fnv1a-64';
49
+ import 'object-identity';
50
+ import 'tailwindcss/colors';
51
+
52
+ //#region app/components/project/report/stacked.vue?vue&type=script&setup=true&lang.ts
53
+ var stacked_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
54
+ __name: "stacked",
55
+ __ssrInlineRender: true,
56
+ props: {
57
+ title: {},
58
+ legend: { default: "" },
59
+ columns: {},
60
+ testid: {}
61
+ },
62
+ setup(__props) {
63
+ const tallest = computed(() => Math.max(...__props.columns.map((column) => column.passed + column.failed), 1));
64
+ function height(value) {
65
+ return `${value / tallest.value * 100}%`;
66
+ }
67
+ return (_ctx, _push, _parent, _attrs) => {
68
+ const _component_UTooltip = _sfc_main$7;
69
+ _push(`<div${ssrRenderAttrs(mergeProps({
70
+ class: "rounded-lg bg-elevated p-4",
71
+ "data-testid": __props.testid
72
+ }, _attrs))}><div class="mb-3 flex items-baseline justify-between gap-2"><p class="text-sm font-semibold">${ssrInterpolate(__props.title)}</p>`);
73
+ if (__props.legend) _push(`<p class="text-xs text-dimmed">${ssrInterpolate(__props.legend)}</p>`);
74
+ else _push(`<!---->`);
75
+ _push(`</div><div class="flex h-28 items-end gap-1.5"><!--[-->`);
76
+ ssrRenderList(__props.columns, (column, index) => {
77
+ _push(ssrRenderComponent(_component_UTooltip, {
78
+ key: index,
79
+ "delay-duration": 0,
80
+ text: `${column.label}: ${("counted" in _ctx ? _ctx.counted : unref(counted))(column.passed, "passou", "passaram", "nenhum passou")}, ${("counted" in _ctx ? _ctx.counted : unref(counted))(column.failed, "falhou", "falharam", "nenhum falhou")}`
81
+ }, {
82
+ default: withCtx((_, _push, _parent, _scopeId) => {
83
+ if (_push) {
84
+ _push(`<div class="flex h-full flex-1 flex-col justify-end gap-0.5"${_scopeId}>`);
85
+ if (column.failed) _push(`<div class="rounded-t-sm bg-error/80" style="${ssrRenderStyle({ height: height(column.failed) })}"${_scopeId}></div>`);
86
+ else _push(`<!---->`);
87
+ if (column.passed) _push(`<div class="${ssrRenderClass([column.failed ? "" : "rounded-t-sm", "bg-success/80"])}" style="${ssrRenderStyle({ height: height(column.passed) })}"${_scopeId}></div>`);
88
+ else _push(`<!---->`);
89
+ _push(`</div>`);
90
+ } else return [createVNode("div", { class: "flex h-full flex-1 flex-col justify-end gap-0.5" }, [column.failed ? (openBlock(), createBlock("div", {
91
+ key: 0,
92
+ class: "rounded-t-sm bg-error/80",
93
+ style: { height: height(column.failed) }
94
+ }, null, 4)) : createCommentVNode("", true), column.passed ? (openBlock(), createBlock("div", {
95
+ key: 1,
96
+ class: ["bg-success/80", column.failed ? "" : "rounded-t-sm"],
97
+ style: { height: height(column.passed) }
98
+ }, null, 6)) : createCommentVNode("", true)])];
99
+ }),
100
+ _: 2
101
+ }, _parent));
102
+ });
103
+ _push(`<!--]--></div><div class="mt-2 flex justify-between text-xs text-dimmed tabular-nums"><span>${ssrInterpolate(__props.columns[0]?.label)}</span><span>${ssrInterpolate(__props.columns.at(-1)?.label)}</span></div></div>`);
104
+ };
105
+ }
106
+ });
107
+ //#endregion
108
+ //#region app/components/project/report/stacked.vue
109
+ var _sfc_setup$4 = stacked_vue_vue_type_script_setup_true_lang_default.setup;
110
+ stacked_vue_vue_type_script_setup_true_lang_default.setup = (props, ctx) => {
111
+ const ssrContext = useSSRContext();
112
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/project/report/stacked.vue");
113
+ return _sfc_setup$4 ? _sfc_setup$4(props, ctx) : void 0;
114
+ };
115
+ var stacked_default = Object.assign(stacked_vue_vue_type_script_setup_true_lang_default, { __name: "ProjectReportStacked" });
116
+ //#endregion
117
+ //#region app/components/project/report/trend.vue?vue&type=script&setup=true&lang.ts
118
+ var WIDTH = 100;
119
+ var HEIGHT = 40;
120
+ var trend_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
121
+ __name: "trend",
122
+ __ssrInlineRender: true,
123
+ props: {
124
+ title: {},
125
+ legend: { default: "" },
126
+ points: {},
127
+ testid: {}
128
+ },
129
+ setup(__props) {
130
+ const highest = computed(() => Math.max(...__props.points.map((point) => point.value), 1));
131
+ const coordinates = computed(() => __props.points.map((point, index) => ({
132
+ x: __props.points.length === 1 ? WIDTH / 2 : index / (__props.points.length - 1) * WIDTH,
133
+ y: HEIGHT - point.value / highest.value * 36 - 2,
134
+ point
135
+ })));
136
+ const line = computed(() => coordinates.value.map(({ x, y }) => `${x},${y}`).join(" "));
137
+ const area = computed(() => `${coordinates.value[0]?.x ?? 0},${HEIGHT} ${line.value} ${coordinates.value.at(-1)?.x ?? 0},${HEIGHT}`);
138
+ /** Muitos pontos viram confete em cima da linha: aí só a última rodada fica marcada. */
139
+ const dots = computed(() => coordinates.value.length > 20 ? coordinates.value.slice(-1) : coordinates.value);
140
+ return (_ctx, _push, _parent, _attrs) => {
141
+ const _component_UTooltip = _sfc_main$7;
142
+ _push(`<div${ssrRenderAttrs(mergeProps({
143
+ class: "rounded-lg bg-elevated p-4",
144
+ "data-testid": __props.testid
145
+ }, _attrs))}><div class="mb-3 flex items-baseline justify-between gap-2"><p class="text-sm font-semibold">${ssrInterpolate(__props.title)}</p>`);
146
+ if (__props.legend) _push(`<p class="text-xs text-dimmed">${ssrInterpolate(__props.legend)}</p>`);
147
+ else _push(`<!---->`);
148
+ _push(`</div><div class="relative h-28"><svg${ssrRenderAttr("viewBox", `0 0 ${WIDTH} ${HEIGHT}`)} preserveAspectRatio="none" class="size-full" role="img"${ssrRenderAttr("aria-label", __props.title)}><!--[-->`);
149
+ ssrRenderList([
150
+ .25,
151
+ .5,
152
+ .75
153
+ ], (grid) => {
154
+ _push(`<line x1="0" x2="100"${ssrRenderAttr("y1", HEIGHT * grid)}${ssrRenderAttr("y2", HEIGHT * grid)} class="stroke-accented" stroke-width="1" vector-effect="non-scaling-stroke"></line>`);
155
+ });
156
+ _push(`<!--]--><polygon${ssrRenderAttr("points", unref(area))} class="fill-primary/10"></polygon><polyline${ssrRenderAttr("points", unref(line))} fill="none" class="stroke-primary" stroke-width="2" stroke-linejoin="round" vector-effect="non-scaling-stroke"></polyline></svg><!--[-->`);
157
+ ssrRenderList(unref(dots), ({ x, y, point }, index) => {
158
+ _push(ssrRenderComponent(_component_UTooltip, {
159
+ key: index,
160
+ "delay-duration": 0,
161
+ text: `${point.label}: ${point.display}`
162
+ }, {
163
+ default: withCtx((_, _push, _parent, _scopeId) => {
164
+ if (_push) _push(`<span class="absolute size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary ring-2 ring-elevated" style="${ssrRenderStyle({
165
+ left: `${x}%`,
166
+ top: `${y / HEIGHT * 100}%`
167
+ })}"${_scopeId}></span>`);
168
+ else return [createVNode("span", {
169
+ class: "absolute size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary ring-2 ring-elevated",
170
+ style: {
171
+ left: `${x}%`,
172
+ top: `${y / HEIGHT * 100}%`
173
+ }
174
+ }, null, 4)];
175
+ }),
176
+ _: 2
177
+ }, _parent));
178
+ });
179
+ _push(`<!--]--></div><div class="mt-2 flex justify-between text-xs text-dimmed tabular-nums"><span>${ssrInterpolate(__props.points[0]?.label)} · ${ssrInterpolate(__props.points[0]?.display)}</span><span>${ssrInterpolate(__props.points.at(-1)?.label)} · ${ssrInterpolate(__props.points.at(-1)?.display)}</span></div></div>`);
180
+ };
181
+ }
182
+ });
183
+ //#endregion
184
+ //#region app/components/project/report/trend.vue
185
+ var _sfc_setup$3 = trend_vue_vue_type_script_setup_true_lang_default.setup;
186
+ trend_vue_vue_type_script_setup_true_lang_default.setup = (props, ctx) => {
187
+ const ssrContext = useSSRContext();
188
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/project/report/trend.vue");
189
+ return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0;
190
+ };
191
+ var trend_default = Object.assign(trend_vue_vue_type_script_setup_true_lang_default, { __name: "ProjectReportTrend" });
192
+ //#endregion
193
+ //#region app/components/project/report/matrix.vue?vue&type=script&setup=true&lang.ts
194
+ var matrix_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
195
+ __name: "matrix",
196
+ __ssrInlineRender: true,
197
+ props: {
198
+ stats: {},
199
+ rounds: { default: 30 },
200
+ limit: { default: 15 }
201
+ },
202
+ setup(__props) {
203
+ const lines = computed(() => __props.stats.slice(0, __props.limit).map((stat) => ({
204
+ ...stat,
205
+ history: stat.history.slice(-__props.rounds)
206
+ })));
207
+ const hidden = computed(() => Math.max(__props.stats.length - __props.limit, 0));
208
+ const cell = {
209
+ true: "bg-success/70",
210
+ false: "bg-error/70",
211
+ null: "bg-accented"
212
+ };
213
+ function tone(passed) {
214
+ return cell[String(passed)];
215
+ }
216
+ function title(passed) {
217
+ if (passed === null) return "Não rodou";
218
+ return passed ? "Passou" : "Falhou";
219
+ }
220
+ return (_ctx, _push, _parent, _attrs) => {
221
+ const _component_UTooltip = _sfc_main$7;
222
+ _push(`<div${ssrRenderAttrs(mergeProps({
223
+ class: "rounded-lg bg-elevated p-4",
224
+ "data-testid": "relatorio-matriz"
225
+ }, _attrs))}><div class="mb-3 flex items-baseline justify-between gap-2"><p class="text-sm font-semibold">${ssrInterpolate(unref(hidden) ? `Os ${unref(lines).length} cenários que mais falham` : "Cenário")} nas últimas ${ssrInterpolate(unref(lines)[0]?.history.length ?? 0)} rodadas </p><p class="text-xs text-dimmed"> cinza é rodada em que ele ficou de fora </p></div><div class="flex flex-col gap-2"><!--[-->`);
226
+ ssrRenderList(unref(lines), (stat) => {
227
+ _push(`<div class="flex items-center gap-3" data-testid="relatorio-matriz-linha">`);
228
+ _push(ssrRenderComponent(_component_UTooltip, {
229
+ "delay-duration": 0,
230
+ text: stat.title,
231
+ class: "w-56 shrink-0"
232
+ }, {
233
+ default: withCtx((_, _push, _parent, _scopeId) => {
234
+ if (_push) _push(`<span class="block truncate text-sm"${_scopeId}>${ssrInterpolate(stat.title)}</span>`);
235
+ else return [createVNode("span", { class: "block truncate text-sm" }, toDisplayString(stat.title), 1)];
236
+ }),
237
+ _: 2
238
+ }, _parent));
239
+ if (stat.failures) _push(`<span class="w-40 shrink-0 text-xs text-error tabular-nums">${ssrInterpolate(stat.failures)} de ${ssrInterpolate(stat.runs)} ${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(stat.failures, "falhou", "falharam"))}</span>`);
240
+ else _push(`<span class="w-40 shrink-0"></span>`);
241
+ _push(`<span class="flex flex-1 justify-end gap-1 overflow-x-auto"><!--[-->`);
242
+ ssrRenderList(stat.history, (passed, index) => {
243
+ _push(ssrRenderComponent(_component_UTooltip, {
244
+ key: index,
245
+ "delay-duration": 0,
246
+ text: title(passed)
247
+ }, {
248
+ default: withCtx((_, _push, _parent, _scopeId) => {
249
+ if (_push) _push(`<span class="${ssrRenderClass([tone(passed), "block size-4 rounded-xs"])}"${_scopeId}></span>`);
250
+ else return [createVNode("span", { class: ["block size-4 rounded-xs", tone(passed)] }, null, 2)];
251
+ }),
252
+ _: 2
253
+ }, _parent));
254
+ });
255
+ _push(`<!--]--></span></div>`);
256
+ });
257
+ _push(`<!--]-->`);
258
+ if (unref(hidden)) _push(`<p class="text-xs text-dimmed">${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(unref(hidden), "outro", "outros"))} ${ssrInterpolate(unref(hidden))} ${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(unref(hidden), "cenário ficou", "cenários ficaram"))} de fora da grade. </p>`);
259
+ else _push(`<!---->`);
260
+ _push(`</div></div>`);
261
+ };
262
+ }
263
+ });
264
+ //#endregion
265
+ //#region app/components/project/report/matrix.vue
266
+ var _sfc_setup$2 = matrix_vue_vue_type_script_setup_true_lang_default.setup;
267
+ matrix_vue_vue_type_script_setup_true_lang_default.setup = (props, ctx) => {
268
+ const ssrContext = useSSRContext();
269
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/project/report/matrix.vue");
270
+ return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0;
271
+ };
272
+ var matrix_default = Object.assign(matrix_vue_vue_type_script_setup_true_lang_default, { __name: "ProjectReportMatrix" });
273
+ //#endregion
274
+ //#region app/components/project/report/runs.vue?vue&type=script&setup=true&lang.ts
275
+ var runs_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
276
+ __name: "runs",
277
+ __ssrInlineRender: true,
278
+ props: {
279
+ runs: {},
280
+ slug: {}
281
+ },
282
+ setup(__props) {
283
+ function startedAt(run) {
284
+ return new Date(run.started_at).toLocaleString("pt-BR", {
285
+ dateStyle: "short",
286
+ timeStyle: "short"
287
+ });
288
+ }
289
+ function seconds(ms) {
290
+ return `${(ms / 1e3).toLocaleString("pt-BR", { maximumFractionDigits: 1 })}s`;
291
+ }
292
+ return (_ctx, _push, _parent, _attrs) => {
293
+ const _component_NuxtLink = NuxtLink;
294
+ const _component_UIcon = _sfc_main$5;
295
+ _push(`<div${ssrRenderAttrs(mergeProps({ class: "flex flex-col gap-3" }, _attrs))}><!--[-->`);
296
+ ssrRenderList(__props.runs, (run) => {
297
+ _push(ssrRenderComponent(_component_NuxtLink, {
298
+ key: run.started_at,
299
+ to: `/projects/${__props.slug}/report/${Date.parse(run.started_at)}`,
300
+ class: "flex items-center gap-3 rounded-lg bg-elevated px-4 py-3 transition-colors hover:bg-accented/75",
301
+ "data-testid": "relatorio-execucao",
302
+ "data-status": run.passed ? "success" : "failed"
303
+ }, {
304
+ default: withCtx((_, _push, _parent, _scopeId) => {
305
+ if (_push) {
306
+ _push(`<span class="${ssrRenderClass([run.passed ? "bg-success" : "bg-error", "h-8 w-1 shrink-0 rounded-full"])}"${_scopeId}></span><span class="min-w-0 grow"${_scopeId}><span class="block truncate"${_scopeId}>${ssrInterpolate(startedAt(run))} <span class="text-muted"${_scopeId}> · `);
307
+ if (run.filter) _push(`<!--[-->${ssrInterpolate(run.totals.tests)} ${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.tests, "cenário filtrado", "cenários filtrados"))}<!--]-->`);
308
+ else _push(`<!--[-->o projeto inteiro<!--]-->`);
309
+ if (run.branch) _push(`<!--[--> · ${ssrInterpolate(run.branch)}<!--]-->`);
310
+ else _push(`<!---->`);
311
+ _push(`</span></span><span class="block text-sm text-muted tabular-nums"${_scopeId}><span class="${ssrRenderClass(run.totals.failed ? "text-error" : "text-success")}"${_scopeId}>${ssrInterpolate(run.totals.passed)} de ${ssrInterpolate(run.totals.tests)} ${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.passed, "passou", "passaram"))}</span> · ${ssrInterpolate(seconds(run.duration_ms))} · ${ssrInterpolate(run.totals.steps)} ${ssrInterpolate(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.steps, "step", "steps"))}</span></span>`);
312
+ _push(ssrRenderComponent(_component_UIcon, {
313
+ name: "i-ic-round-chevron-right",
314
+ class: "size-5 shrink-0 text-dimmed"
315
+ }, null, _parent, _scopeId));
316
+ } else return [
317
+ createVNode("span", { class: ["h-8 w-1 shrink-0 rounded-full", run.passed ? "bg-success" : "bg-error"] }, null, 2),
318
+ createVNode("span", { class: "min-w-0 grow" }, [createVNode("span", { class: "block truncate" }, [createTextVNode(toDisplayString(startedAt(run)) + " ", 1), createVNode("span", { class: "text-muted" }, [
319
+ createTextVNode(" · "),
320
+ run.filter ? (openBlock(), createBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(run.totals.tests) + " " + toDisplayString(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.tests, "cenário filtrado", "cenários filtrados")), 1)], 64)) : (openBlock(), createBlock(Fragment, { key: 1 }, [createTextVNode("o projeto inteiro")], 64)),
321
+ run.branch ? (openBlock(), createBlock(Fragment, { key: 2 }, [createTextVNode(" · " + toDisplayString(run.branch), 1)], 64)) : createCommentVNode("", true)
322
+ ])]), createVNode("span", { class: "block text-sm text-muted tabular-nums" }, [createVNode("span", { class: run.totals.failed ? "text-error" : "text-success" }, toDisplayString(run.totals.passed) + " de " + toDisplayString(run.totals.tests) + " " + toDisplayString(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.passed, "passou", "passaram")), 3), createTextVNode(" · " + toDisplayString(seconds(run.duration_ms)) + " · " + toDisplayString(run.totals.steps) + " " + toDisplayString(("plural" in _ctx ? _ctx.plural : unref(plural))(run.totals.steps, "step", "steps")), 1)])]),
323
+ createVNode(_component_UIcon, {
324
+ name: "i-ic-round-chevron-right",
325
+ class: "size-5 shrink-0 text-dimmed"
326
+ })
327
+ ];
328
+ }),
329
+ _: 2
330
+ }, _parent));
331
+ });
332
+ _push(`<!--]--></div>`);
333
+ };
334
+ }
335
+ });
336
+ //#endregion
337
+ //#region app/components/project/report/runs.vue
338
+ var _sfc_setup$1 = runs_vue_vue_type_script_setup_true_lang_default.setup;
339
+ runs_vue_vue_type_script_setup_true_lang_default.setup = (props, ctx) => {
340
+ const ssrContext = useSSRContext();
341
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/project/report/runs.vue");
342
+ return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0;
343
+ };
344
+ var runs_default = Object.assign(runs_vue_vue_type_script_setup_true_lang_default, { __name: "ProjectReportRuns" });
345
+ //#endregion
346
+ //#region app/utils/report.ts
347
+ function percent(part, total) {
348
+ return total === 0 ? 0 : Math.round(part / total * 1e3) / 10;
349
+ }
350
+ function average(values) {
351
+ return values.length === 0 ? 0 : values.reduce((total, value) => total + value, 0) / values.length;
352
+ }
353
+ /** As métricas da capa do relatório, tiradas das rodadas que vieram da API. */
354
+ function summarizeRuns(runs) {
355
+ const tests = runs.flatMap((run) => run.tests);
356
+ const stats = scenarioStats(runs);
357
+ const slowest = [...tests].sort((a, b) => b.duration_ms - a.duration_ms)[0];
358
+ return {
359
+ runs: runs.length,
360
+ lastPassed: runs[0]?.passed ?? null,
361
+ successRate: percent(runs.filter((run) => run.passed).length, runs.length),
362
+ testSuccessRate: percent(tests.filter((test) => test.passed).length, tests.length),
363
+ averageDurationMs: Math.round(average(runs.map((run) => run.duration_ms))),
364
+ averageSteps: Math.round(average(tests.map((test) => test.steps)) * 10) / 10,
365
+ totalSteps: tests.reduce((total, test) => total + test.steps, 0),
366
+ slowest: slowest ? {
367
+ title: slowest.title,
368
+ durationMs: slowest.duration_ms
369
+ } : null,
370
+ flaky: stats.filter((stat) => stat.flaky).length
371
+ };
372
+ }
373
+ /** Um resumo por cenário, do que mais falha para o que menos falha. */
374
+ function scenarioStats(runs) {
375
+ const oldestFirst = [...runs].reverse();
376
+ return [...new Set(runs.flatMap((run) => run.tests.map((test) => test.id)))].map((id) => {
377
+ const history = oldestFirst.map((run) => run.tests.find((test) => test.id === id)?.passed ?? null);
378
+ const own = runs.flatMap((run) => run.tests.filter((test) => test.id === id));
379
+ const failures = own.filter((test) => !test.passed).length;
380
+ const results = history.filter((passed) => passed !== null);
381
+ return {
382
+ id,
383
+ title: own[0].title,
384
+ runs: own.length,
385
+ failures,
386
+ failureRate: percent(failures, own.length),
387
+ averageDurationMs: Math.round(average(own.map((test) => test.duration_ms))),
388
+ averageSteps: Math.round(average(own.map((test) => test.steps)) * 10) / 10,
389
+ lastPassed: own[0].passed,
390
+ lastFailedStep: own[0].failed_step,
391
+ flaky: results.some((passed, index) => index > 0 && passed !== results[index - 1]),
392
+ history
393
+ };
394
+ }).sort((a, b) => b.failures - a.failures || b.averageDurationMs - a.averageDurationMs);
395
+ }
396
+ //#endregion
397
+ //#region app/pages/projects/[projectSlug]/report/index.vue?vue&type=script&setup=true&lang.ts
398
+ var PLOTTED = 30;
399
+ /** Quantas execuções a lista mostra por página. */
400
+ var PAGE_SIZE = 10;
401
+ var index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
402
+ __name: "index",
403
+ __ssrInlineRender: true,
404
+ async setup(__props) {
405
+ let __temp, __restore;
406
+ const route = useRoute();
407
+ const slug = computed(() => route.params.projectSlug);
408
+ const hydrated = ref(false);
409
+ const { data: project } = ([__temp, __restore] = withAsyncContext(() => useFetch(`/api/projects/${slug.value}`, "$tnX2v1FF5J")), __temp = await __temp, __restore(), __temp);
410
+ const { data } = ([__temp, __restore] = withAsyncContext(() => useFetch(`/api/projects/${slug.value}/runs`, "$r1HtBytxf0")), __temp = await __temp, __restore(), __temp);
411
+ const runs = computed(() => data.value?.runs ?? []);
412
+ const summary = computed(() => summarizeRuns(runs.value));
413
+ const stats = computed(() => scenarioStats(runs.value));
414
+ /** Quantas rodadas os gráficos desenham: além disto a barra some e a linha vira serrote. */
415
+ const plotted = computed(() => [...runs.value].slice(0, PLOTTED).reverse());
416
+ const page = ref(1);
417
+ const paginated = computed(() => runs.value.slice((page.value - 1) * PAGE_SIZE, page.value * PAGE_SIZE));
418
+ function seconds(ms) {
419
+ return `${(ms / 1e3).toLocaleString("pt-BR", { maximumFractionDigits: 1 })}s`;
420
+ }
421
+ const last = computed(() => runs.value[0]);
422
+ /** Hora e dia: as rodadas costumam ser do mesmo dia, e só a data faria todas iguais. */
423
+ function when(startedAt) {
424
+ return new Date(startedAt).toLocaleString("pt-BR", {
425
+ day: "2-digit",
426
+ month: "2-digit",
427
+ hour: "2-digit",
428
+ minute: "2-digit"
429
+ });
430
+ }
431
+ const resultColumns = computed(() => plotted.value.map((run) => ({
432
+ label: when(run.started_at),
433
+ passed: run.totals.passed,
434
+ failed: run.totals.failed
435
+ })));
436
+ const durationPoints = computed(() => plotted.value.map((run) => ({
437
+ label: when(run.started_at),
438
+ value: run.duration_ms,
439
+ display: seconds(run.duration_ms)
440
+ })));
441
+ const longest = computed(() => Math.max(...runs.value.map((run) => run.duration_ms), 0));
442
+ const mostFailed = computed(() => stats.value.filter((stat) => stat.failures > 0).slice(0, 5).map((stat) => ({
443
+ label: stat.title,
444
+ value: stat.failures,
445
+ display: `${stat.failures} de ${stat.runs} · ${stat.failureRate}%`
446
+ })));
447
+ const slowest = computed(() => [...stats.value].sort((a, b) => b.averageDurationMs - a.averageDurationMs).slice(0, 5).map((stat) => ({
448
+ label: stat.title,
449
+ value: stat.averageDurationMs,
450
+ display: seconds(stat.averageDurationMs)
451
+ })));
452
+ return (_ctx, _push, _parent, _attrs) => {
453
+ const _component_UContainer = _sfc_main;
454
+ const _component_BaseButtonIcon = icon_default;
455
+ const _component_BaseEmpty = empty_default;
456
+ const _component_ProjectReportMetric = metric_default;
457
+ const _component_ProjectReportStacked = stacked_default;
458
+ const _component_ProjectReportTrend = trend_default;
459
+ const _component_ProjectReportRanking = ranking_default;
460
+ const _component_ProjectReportMatrix = matrix_default;
461
+ const _component_ProjectReportRuns = runs_default;
462
+ const _component_UPagination = _sfc_main$1;
463
+ _push(ssrRenderComponent(_component_UContainer, mergeProps({
464
+ "data-hydrated": unref(hydrated),
465
+ class: "py-6 lg:py-10"
466
+ }, _attrs), {
467
+ default: withCtx((_, _push, _parent, _scopeId) => {
468
+ if (_push) {
469
+ _push(`<div class="flex items-start justify-between gap-4"${_scopeId}><div class="flex flex-col gap-1 min-w-0"${_scopeId}><div class="flex items-center gap-2"${_scopeId}>`);
470
+ _push(ssrRenderComponent(_component_BaseButtonIcon, {
471
+ icon: "i-ic-round-arrow-back",
472
+ label: "Voltar ao projeto",
473
+ color: "neutral",
474
+ variant: "ghost",
475
+ to: `/projects/${unref(slug)}`,
476
+ "data-testid": "relatorio-voltar"
477
+ }, null, _parent, _scopeId));
478
+ _push(`<h1 class="text-2xl font-bold truncate"${_scopeId}> Relatório de ${ssrInterpolate(unref(project)?.name)}</h1></div><p class="text-muted"${_scopeId}> O que as últimas execuções agrupadas deste projeto contam. </p></div>`);
479
+ if (unref(runs).length) _push(ssrRenderComponent(_component_BaseButtonIcon, {
480
+ icon: "i-ic-round-assessment",
481
+ label: "Abrir o relatório do Playwright, com vídeo e trace. Ele guarda só a execução mais recente, a de cima na lista.",
482
+ color: "neutral",
483
+ variant: "soft",
484
+ to: unref(reportUrlFor)(unref(slug)),
485
+ target: "_blank",
486
+ external: "",
487
+ "data-testid": "relatorio-playwright"
488
+ }, null, _parent, _scopeId));
489
+ else _push(`<!---->`);
490
+ _push(`</div>`);
491
+ if (unref(runs).length === 0) _push(ssrRenderComponent(_component_BaseEmpty, {
492
+ class: "mt-10",
493
+ icon: "i-ic-round-insert-chart-outlined",
494
+ title: "Nenhuma execução agrupada ainda",
495
+ description: "Rode os cenários filtrados na tela do projeto. Cada rodada entra aqui com o resultado, a duração e os cenários que falharam.",
496
+ testid: "relatorio-vazio"
497
+ }, null, _parent, _scopeId));
498
+ else {
499
+ _push(`<!--[--><div class="mt-8 grid grid-cols-2 gap-3 lg:grid-cols-5"${_scopeId}>`);
500
+ _push(ssrRenderComponent(_component_ProjectReportMetric, {
501
+ name: "ultima",
502
+ label: "Última rodada",
503
+ value: `${unref(last).totals.passed}/${unref(last).totals.tests}`,
504
+ tone: unref(last).passed ? "success" : "error",
505
+ hint: `${new Date(unref(last).started_at).toLocaleString("pt-BR", {
506
+ dateStyle: "short",
507
+ timeStyle: "short"
508
+ })} · ${seconds(unref(last).duration_ms)}`
509
+ }, null, _parent, _scopeId));
510
+ _push(ssrRenderComponent(_component_ProjectReportMetric, {
511
+ name: "sucesso-rodadas",
512
+ label: "Rodadas verdes",
513
+ value: `${unref(summary).successRate}%`,
514
+ hint: `${unref(summary).runs} ${("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).runs, "rodada guardada", "rodadas guardadas")}`
515
+ }, null, _parent, _scopeId));
516
+ _push(ssrRenderComponent(_component_ProjectReportMetric, {
517
+ name: "sucesso-cenarios",
518
+ label: "Cenários verdes",
519
+ value: `${unref(summary).testSuccessRate}%`,
520
+ hint: `${unref(summary).totalSteps} ${("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).totalSteps, "step", "steps")} · ${unref(summary).averageSteps.toLocaleString("pt-BR", { maximumFractionDigits: 1 })} por cenário`
521
+ }, null, _parent, _scopeId));
522
+ _push(ssrRenderComponent(_component_ProjectReportMetric, {
523
+ name: "duracao",
524
+ label: "Duração média",
525
+ value: seconds(unref(summary).averageDurationMs),
526
+ hint: `rodada mais longa: ${seconds(unref(longest))}`
527
+ }, null, _parent, _scopeId));
528
+ _push(ssrRenderComponent(_component_ProjectReportMetric, {
529
+ name: "instaveis",
530
+ label: ("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).flaky, "Cenário instável", "Cenários instáveis"),
531
+ value: `${unref(summary).flaky}`,
532
+ tone: unref(summary).flaky > 0 ? "error" : "neutral",
533
+ hint: unref(summary).flaky === 0 ? "nenhum trocou de resultado entre rodadas" : ("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).flaky, "trocou de resultado entre rodadas", "trocaram de resultado entre rodadas")
534
+ }, null, _parent, _scopeId));
535
+ _push(`</div><div class="mt-4 grid gap-3 lg:grid-cols-2"${_scopeId}>`);
536
+ _push(ssrRenderComponent(_component_ProjectReportStacked, {
537
+ title: `Resultado das últimas ${unref(resultColumns).length} rodadas`,
538
+ legend: "verde passou, vermelho falhou",
539
+ columns: unref(resultColumns),
540
+ testid: "relatorio-resultado"
541
+ }, null, _parent, _scopeId));
542
+ _push(ssrRenderComponent(_component_ProjectReportTrend, {
543
+ title: `Duração das últimas ${unref(durationPoints).length} rodadas`,
544
+ points: unref(durationPoints),
545
+ testid: "relatorio-duracao"
546
+ }, null, _parent, _scopeId));
547
+ _push(ssrRenderComponent(_component_ProjectReportRanking, {
548
+ title: "Cenários que mais falham",
549
+ empty: "Nenhum cenário falhou nas rodadas guardadas.",
550
+ tone: "error",
551
+ items: unref(mostFailed),
552
+ testid: "relatorio-ranking-falhas"
553
+ }, null, _parent, _scopeId));
554
+ _push(ssrRenderComponent(_component_ProjectReportRanking, {
555
+ title: "Cenários mais lentos",
556
+ empty: "Sem execução para medir.",
557
+ items: unref(slowest),
558
+ testid: "relatorio-ranking-lentos"
559
+ }, null, _parent, _scopeId));
560
+ _push(`</div>`);
561
+ _push(ssrRenderComponent(_component_ProjectReportMatrix, {
562
+ class: "mt-4",
563
+ stats: unref(stats),
564
+ rounds: PLOTTED
565
+ }, null, _parent, _scopeId));
566
+ _push(`<h2 class="mt-10 mb-3 text-lg font-semibold"${_scopeId}> Execuções </h2>`);
567
+ _push(ssrRenderComponent(_component_ProjectReportRuns, {
568
+ runs: unref(paginated),
569
+ slug: unref(slug)
570
+ }, null, _parent, _scopeId));
571
+ if (unref(runs).length > PAGE_SIZE) {
572
+ _push(`<div class="mt-4 flex justify-center"${_scopeId}>`);
573
+ _push(ssrRenderComponent(_component_UPagination, {
574
+ page: unref(page),
575
+ "onUpdate:page": ($event) => isRef(page) ? page.value = $event : null,
576
+ variant: "soft",
577
+ total: unref(runs).length,
578
+ "items-per-page": PAGE_SIZE,
579
+ "data-testid": "relatorio-paginacao"
580
+ }, null, _parent, _scopeId));
581
+ _push(`</div>`);
582
+ } else _push(`<!---->`);
583
+ _push(`<!--]-->`);
584
+ }
585
+ } else return [createVNode("div", { class: "flex items-start justify-between gap-4" }, [createVNode("div", { class: "flex flex-col gap-1 min-w-0" }, [createVNode("div", { class: "flex items-center gap-2" }, [createVNode(_component_BaseButtonIcon, {
586
+ icon: "i-ic-round-arrow-back",
587
+ label: "Voltar ao projeto",
588
+ color: "neutral",
589
+ variant: "ghost",
590
+ to: `/projects/${unref(slug)}`,
591
+ "data-testid": "relatorio-voltar"
592
+ }, null, 8, ["to"]), createVNode("h1", { class: "text-2xl font-bold truncate" }, " Relatório de " + toDisplayString(unref(project)?.name), 1)]), createVNode("p", { class: "text-muted" }, " O que as últimas execuções agrupadas deste projeto contam. ")]), unref(runs).length ? (openBlock(), createBlock(_component_BaseButtonIcon, {
593
+ key: 0,
594
+ icon: "i-ic-round-assessment",
595
+ label: "Abrir o relatório do Playwright, com vídeo e trace. Ele guarda só a execução mais recente, a de cima na lista.",
596
+ color: "neutral",
597
+ variant: "soft",
598
+ to: unref(reportUrlFor)(unref(slug)),
599
+ target: "_blank",
600
+ external: "",
601
+ "data-testid": "relatorio-playwright"
602
+ }, null, 8, ["to"])) : createCommentVNode("", true)]), unref(runs).length === 0 ? (openBlock(), createBlock(_component_BaseEmpty, {
603
+ key: 0,
604
+ class: "mt-10",
605
+ icon: "i-ic-round-insert-chart-outlined",
606
+ title: "Nenhuma execução agrupada ainda",
607
+ description: "Rode os cenários filtrados na tela do projeto. Cada rodada entra aqui com o resultado, a duração e os cenários que falharam.",
608
+ testid: "relatorio-vazio"
609
+ })) : (openBlock(), createBlock(Fragment, { key: 1 }, [
610
+ createVNode("div", { class: "mt-8 grid grid-cols-2 gap-3 lg:grid-cols-5" }, [
611
+ createVNode(_component_ProjectReportMetric, {
612
+ name: "ultima",
613
+ label: "Última rodada",
614
+ value: `${unref(last).totals.passed}/${unref(last).totals.tests}`,
615
+ tone: unref(last).passed ? "success" : "error",
616
+ hint: `${new Date(unref(last).started_at).toLocaleString("pt-BR", {
617
+ dateStyle: "short",
618
+ timeStyle: "short"
619
+ })} · ${seconds(unref(last).duration_ms)}`
620
+ }, null, 8, [
621
+ "value",
622
+ "tone",
623
+ "hint"
624
+ ]),
625
+ createVNode(_component_ProjectReportMetric, {
626
+ name: "sucesso-rodadas",
627
+ label: "Rodadas verdes",
628
+ value: `${unref(summary).successRate}%`,
629
+ hint: `${unref(summary).runs} ${("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).runs, "rodada guardada", "rodadas guardadas")}`
630
+ }, null, 8, ["value", "hint"]),
631
+ createVNode(_component_ProjectReportMetric, {
632
+ name: "sucesso-cenarios",
633
+ label: "Cenários verdes",
634
+ value: `${unref(summary).testSuccessRate}%`,
635
+ hint: `${unref(summary).totalSteps} ${("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).totalSteps, "step", "steps")} · ${unref(summary).averageSteps.toLocaleString("pt-BR", { maximumFractionDigits: 1 })} por cenário`
636
+ }, null, 8, ["value", "hint"]),
637
+ createVNode(_component_ProjectReportMetric, {
638
+ name: "duracao",
639
+ label: "Duração média",
640
+ value: seconds(unref(summary).averageDurationMs),
641
+ hint: `rodada mais longa: ${seconds(unref(longest))}`
642
+ }, null, 8, ["value", "hint"]),
643
+ createVNode(_component_ProjectReportMetric, {
644
+ name: "instaveis",
645
+ label: ("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).flaky, "Cenário instável", "Cenários instáveis"),
646
+ value: `${unref(summary).flaky}`,
647
+ tone: unref(summary).flaky > 0 ? "error" : "neutral",
648
+ hint: unref(summary).flaky === 0 ? "nenhum trocou de resultado entre rodadas" : ("plural" in _ctx ? _ctx.plural : unref(plural))(unref(summary).flaky, "trocou de resultado entre rodadas", "trocaram de resultado entre rodadas")
649
+ }, null, 8, [
650
+ "label",
651
+ "value",
652
+ "tone",
653
+ "hint"
654
+ ])
655
+ ]),
656
+ createVNode("div", { class: "mt-4 grid gap-3 lg:grid-cols-2" }, [
657
+ createVNode(_component_ProjectReportStacked, {
658
+ title: `Resultado das últimas ${unref(resultColumns).length} rodadas`,
659
+ legend: "verde passou, vermelho falhou",
660
+ columns: unref(resultColumns),
661
+ testid: "relatorio-resultado"
662
+ }, null, 8, ["title", "columns"]),
663
+ createVNode(_component_ProjectReportTrend, {
664
+ title: `Duração das últimas ${unref(durationPoints).length} rodadas`,
665
+ points: unref(durationPoints),
666
+ testid: "relatorio-duracao"
667
+ }, null, 8, ["title", "points"]),
668
+ createVNode(_component_ProjectReportRanking, {
669
+ title: "Cenários que mais falham",
670
+ empty: "Nenhum cenário falhou nas rodadas guardadas.",
671
+ tone: "error",
672
+ items: unref(mostFailed),
673
+ testid: "relatorio-ranking-falhas"
674
+ }, null, 8, ["items"]),
675
+ createVNode(_component_ProjectReportRanking, {
676
+ title: "Cenários mais lentos",
677
+ empty: "Sem execução para medir.",
678
+ items: unref(slowest),
679
+ testid: "relatorio-ranking-lentos"
680
+ }, null, 8, ["items"])
681
+ ]),
682
+ createVNode(_component_ProjectReportMatrix, {
683
+ class: "mt-4",
684
+ stats: unref(stats),
685
+ rounds: PLOTTED
686
+ }, null, 8, ["stats"]),
687
+ createVNode("h2", { class: "mt-10 mb-3 text-lg font-semibold" }, " Execuções "),
688
+ createVNode(_component_ProjectReportRuns, {
689
+ runs: unref(paginated),
690
+ slug: unref(slug)
691
+ }, null, 8, ["runs", "slug"]),
692
+ unref(runs).length > PAGE_SIZE ? (openBlock(), createBlock("div", {
693
+ key: 0,
694
+ class: "mt-4 flex justify-center"
695
+ }, [createVNode(_component_UPagination, {
696
+ page: unref(page),
697
+ "onUpdate:page": ($event) => isRef(page) ? page.value = $event : null,
698
+ variant: "soft",
699
+ total: unref(runs).length,
700
+ "items-per-page": PAGE_SIZE,
701
+ "data-testid": "relatorio-paginacao"
702
+ }, null, 8, [
703
+ "page",
704
+ "onUpdate:page",
705
+ "total"
706
+ ])])) : createCommentVNode("", true)
707
+ ], 64))];
708
+ }),
709
+ _: 1
710
+ }, _parent));
711
+ };
712
+ }
713
+ });
714
+ //#endregion
715
+ //#region app/pages/projects/[projectSlug]/report/index.vue
716
+ var _sfc_setup = index_vue_vue_type_script_setup_true_lang_default.setup;
717
+ index_vue_vue_type_script_setup_true_lang_default.setup = (props, ctx) => {
718
+ const ssrContext = useSSRContext();
719
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/projects/[projectSlug]/report/index.vue");
720
+ return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
721
+ };
722
+ var report_default = index_vue_vue_type_script_setup_true_lang_default;
723
+
724
+ export { report_default as default };
725
+ //# sourceMappingURL=report-ISc2vlII.mjs.map