@piwitests/server 0.23.0 → 0.24.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.
Files changed (346) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Clg2Qx0r.js → -COcylA_.js} +1 -1
  3. package/.output/public/_nuxt/03FA4-rI.js +1 -0
  4. package/.output/public/_nuxt/{B7tiBVLW.js → 5a7jHE9s.js} +1 -1
  5. package/.output/public/_nuxt/{roaTZkYi.js → 6Z_ZwH8I.js} +1 -1
  6. package/.output/public/_nuxt/{xZQGtnVA.js → 7ZHq6PCI.js} +1 -1
  7. package/.output/public/_nuxt/{5SkLJHl8.js → 98sAB6Gu.js} +1 -1
  8. package/.output/public/_nuxt/{DnxrNGE_.js → B--J7VNt.js} +1 -1
  9. package/.output/public/_nuxt/{DJzFYrBt.js → B1LUinhp.js} +1 -1
  10. package/.output/public/_nuxt/{axj2iIDK.js → B33YjaHr.js} +1 -1
  11. package/.output/public/_nuxt/B69RP95P.js +1 -0
  12. package/.output/public/_nuxt/{DNKZmhbX.js → B8H4XydJ.js} +1 -1
  13. package/.output/public/_nuxt/{DmqCquDx.js → B8Xm4_S_.js} +1 -1
  14. package/.output/public/_nuxt/{Ya8ZzWuY.js → BBhrClA9.js} +1 -1
  15. package/.output/public/_nuxt/{BZFiz2UB.js → BCGljaM0.js} +1 -1
  16. package/.output/public/_nuxt/{oSLbl-p0.js → BFxvHlO9.js} +1 -1
  17. package/.output/public/_nuxt/{PDSNX4Te.js → BKrWWV14.js} +1 -1
  18. package/.output/public/_nuxt/BN1zZw5b.js +9 -0
  19. package/.output/public/_nuxt/{Dbf8eT28.js → BPXqL9vK.js} +1 -1
  20. package/.output/public/_nuxt/{DgEa6_av.js → BUnwEAjq.js} +1 -1
  21. package/.output/public/_nuxt/{CUOS6S13.js → BVLqydCr.js} +1 -1
  22. package/.output/public/_nuxt/{CvVbKrcH.js → BWMSVSNM.js} +1 -1
  23. package/.output/public/_nuxt/{Wk7ZKG4B.js → B_r0xHVS.js} +1 -1
  24. package/.output/public/_nuxt/{DAhv9aNg.js → BakMHV79.js} +1 -1
  25. package/.output/public/_nuxt/{BDUfBn3i.js → Bd8B-yeR.js} +1 -1
  26. package/.output/public/_nuxt/{sqqg4oXL.js → BevElZaK.js} +1 -1
  27. package/.output/public/_nuxt/{B0tmRAhY.js → BfA6lfg4.js} +1 -1
  28. package/.output/public/_nuxt/{D3SJGdl4.js → Bg93Rnts.js} +1 -1
  29. package/.output/public/_nuxt/{Ck_fTH5z.js → BgABj4Ty.js} +1 -1
  30. package/.output/public/_nuxt/{B2L0-Lzp.js → BkM2KXUo.js} +1 -1
  31. package/.output/public/_nuxt/{CBJFORiZ.js → BkxRbXIj.js} +1 -1
  32. package/.output/public/_nuxt/{Bsc11YIJ.js → Bme1UkOl.js} +1 -1
  33. package/.output/public/_nuxt/{BfcMJBTf.js → BmzxRbcg.js} +1 -1
  34. package/.output/public/_nuxt/{D7fxV-UA.js → Bn0jaRxI.js} +1 -1
  35. package/.output/public/_nuxt/{C77tM5Hz.js → BoNKdx5o.js} +1 -1
  36. package/.output/public/_nuxt/{Bb2mDqKr.js → Bp3FRuEm.js} +1 -1
  37. package/.output/public/_nuxt/{BjOFxi54.js → BrUBOQ0y.js} +1 -1
  38. package/.output/public/_nuxt/{DXkFgrsT.js → BtSGUY-7.js} +1 -1
  39. package/.output/public/_nuxt/{QZYo3ErV.js → BtbpLWDs.js} +1 -1
  40. package/.output/public/_nuxt/{Bag08cIY.js → BvAfKk6C.js} +1 -1
  41. package/.output/public/_nuxt/{BOvtXn3m.js → BwEN1fJ1.js} +1 -1
  42. package/.output/public/_nuxt/{DYjxDsYC.js → C-XjxjG5.js} +1 -1
  43. package/.output/public/_nuxt/{RkNtgoTD.js → C3W_wyr9.js} +1 -1
  44. package/.output/public/_nuxt/{CNu3kken.js → C5TrTuWv.js} +3 -3
  45. package/.output/public/_nuxt/{B4mZElvM.js → C7D5Wl7T.js} +1 -1
  46. package/.output/public/_nuxt/{ZLfZolDM.js → C7fq_rHE.js} +1 -1
  47. package/.output/public/_nuxt/{B_JSV0yG.js → C8Paf_V1.js} +1 -1
  48. package/.output/public/_nuxt/{C2_7XZo0.js → CD8ZzAFC.js} +1 -1
  49. package/.output/public/_nuxt/{CTTmX4gy.js → CDTeSrLO.js} +1 -1
  50. package/.output/public/_nuxt/{CLWMETf9.js → CGHV0Y2d.js} +1 -1
  51. package/.output/public/_nuxt/{AQ86C4c2.js → CIpF9l75.js} +1 -1
  52. package/.output/public/_nuxt/{jR2xm3_t.js → CJ1rmnk4.js} +1 -1
  53. package/.output/public/_nuxt/{7_9fts7T.js → CMuzkARi.js} +1 -1
  54. package/.output/public/_nuxt/{a8Z6VC7V.js → COuZu9FO.js} +1 -1
  55. package/.output/public/_nuxt/{D7t0Dn3h.js → CX5Q0dZ8.js} +1 -1
  56. package/.output/public/_nuxt/{9_aJhhcm.js → CX_G-FHC.js} +14 -14
  57. package/.output/public/_nuxt/{C9I1Dp3S.js → Ce5_Tq63.js} +1 -1
  58. package/.output/public/_nuxt/{BtZNYmZO.js → Cf4MFOuf.js} +1 -1
  59. package/.output/public/_nuxt/{mi22nGUC.js → CgkXEZMo.js} +1 -1
  60. package/.output/public/_nuxt/{Ce89VyHE.js → CjBktNrC.js} +1 -1
  61. package/.output/public/_nuxt/{Bj_v57Zu.js → CjtjQV60.js} +1 -1
  62. package/.output/public/_nuxt/{BuGAn4f7.js → CpcrljrH.js} +1 -1
  63. package/.output/public/_nuxt/{6vX5JdHr.js → Cq33x7yV.js} +1 -1
  64. package/.output/public/_nuxt/{jxc14CqP.js → CsV7pmcT.js} +1 -1
  65. package/.output/public/_nuxt/{DTrPCv7R.js → Cu2Q4iPh.js} +1 -1
  66. package/.output/public/_nuxt/{DylyATWU.js → CyLcEDg2.js} +1 -1
  67. package/.output/public/_nuxt/{Ce_j5NtN.js → D0Kop4bS.js} +1 -1
  68. package/.output/public/_nuxt/{DCE2_MKD.js → D1Y43xM1.js} +1 -1
  69. package/.output/public/_nuxt/{499RbBSX.js → D1vqYZsL.js} +1 -1
  70. package/.output/public/_nuxt/{BjMo2tKC.js → D2rZosKf.js} +1 -1
  71. package/.output/public/_nuxt/D7jpwkRG.js +5 -0
  72. package/.output/public/_nuxt/{BFYkWpPx.js → D8NAb7VE.js} +1 -1
  73. package/.output/public/_nuxt/{CIQeRUSy.js → D8vguZKg.js} +1 -1
  74. package/.output/public/_nuxt/{Bq4_kqIp.js → DEvYVl9M.js} +1 -1
  75. package/.output/public/_nuxt/{DBWM_xs-.js → DF6Mes5z.js} +1 -1
  76. package/.output/public/_nuxt/{CGDPUNcO.js → DGq4A2Pd.js} +1 -1
  77. package/.output/public/_nuxt/{CF_eDZHu.js → DH5H1DJh.js} +1 -1
  78. package/.output/public/_nuxt/{kWnH8yJq.js → DL8knjzi.js} +1 -1
  79. package/.output/public/_nuxt/{CC8wk-N0.js → DM3bDZC6.js} +1 -1
  80. package/.output/public/_nuxt/{Ce47NgZw.js → DMAiMrNr.js} +1 -1
  81. package/.output/public/_nuxt/{HbnAkiyK.js → DMWfVJCj.js} +1 -1
  82. package/.output/public/_nuxt/{B3AG2m76.js → DMsm-RGQ.js} +1 -1
  83. package/.output/public/_nuxt/{DeewM3Wg.js → DMtrFQqi.js} +1 -1
  84. package/.output/public/_nuxt/{D1Ucra3E.js → DPZBpFOX.js} +1 -1
  85. package/.output/public/_nuxt/{DiWxW-w3.js → DVEGfqtt.js} +1 -1
  86. package/.output/public/_nuxt/{DZ-KbUZi.js → D_y2VS8k.js} +1 -1
  87. package/.output/public/_nuxt/DaNC-xl1.js +1 -0
  88. package/.output/public/_nuxt/{DZECGgZm.js → DbmGeOus.js} +1 -1
  89. package/.output/public/_nuxt/{HIGGZ_c-.js → DcLbz6DV.js} +1 -1
  90. package/.output/public/_nuxt/{B_MVJP17.js → DcR0Mmdl.js} +1 -1
  91. package/.output/public/_nuxt/{DNqm5cWU.js → DhYznn-U.js} +1 -1
  92. package/.output/public/_nuxt/DhuRRlmK.js +1 -0
  93. package/.output/public/_nuxt/{pZbe82l5.js → Drw8yQg6.js} +1 -1
  94. package/.output/public/_nuxt/{CPQRQqXU.js → DuO5wfAC.js} +1 -1
  95. package/.output/public/_nuxt/{FJTsZ5Aa.js → DuOH5jcQ.js} +1 -1
  96. package/.output/public/_nuxt/{BM5BPKlc.js → DvEsAuE9.js} +1 -1
  97. package/.output/public/_nuxt/{dUPMBJ4f.js → Dz6g_QJT.js} +1 -1
  98. package/.output/public/_nuxt/{BAbrtVp3.js → DzZpIs4W.js} +1 -1
  99. package/.output/public/_nuxt/DzzNS-K1.js +1 -0
  100. package/.output/public/_nuxt/{BwwfasRt.js → Fsw2W4TA.js} +1 -1
  101. package/.output/public/_nuxt/{CdEzDaDI.js → LwoTUb-r.js} +1 -1
  102. package/.output/public/_nuxt/{DuBtaw3j.js → OfPjZaky.js} +1 -1
  103. package/.output/public/_nuxt/{LTMoFvEY.js → P5uOaRUZ.js} +1 -1
  104. package/.output/public/_nuxt/{B3G-TIoP.js → Qo6oszaF.js} +1 -1
  105. package/.output/public/_nuxt/{DprkT7rM.js → T5UuMUxA.js} +1 -1
  106. package/.output/public/_nuxt/UY8pjaZA.js +1 -0
  107. package/.output/public/_nuxt/{CmTzxoQt.js → V9p3z39z.js} +1 -1
  108. package/.output/public/_nuxt/{5QBnDbs_.js → VACXezo0.js} +1 -1
  109. package/.output/public/_nuxt/{6sA-GK37.js → YmCeJkZ2.js} +1 -1
  110. package/.output/public/_nuxt/builds/latest.json +1 -1
  111. package/.output/public/_nuxt/builds/meta/70224ee0-4d1f-45d2-b380-2ecb18064bf1.json +1 -0
  112. package/.output/public/_nuxt/entry.DzPSf_u5.css +1 -0
  113. package/.output/public/_nuxt/fXUwH_3d.js +1 -0
  114. package/.output/public/_nuxt/{CAoQUDI4.js → opwuUqHG.js} +1 -1
  115. package/.output/public/_nuxt/{2yLW7WU0.js → opyDpgSw.js} +1 -1
  116. package/.output/public/_nuxt/{B070fjS-.js → sVV8xB9f.js} +1 -1
  117. package/.output/public/_nuxt/{C6t4kxaa.js → xa5UHCot.js} +1 -1
  118. package/.output/server/chunks/_/collect.mjs +1 -1
  119. package/.output/server/chunks/_/markers.mjs +1 -1
  120. package/.output/server/chunks/_/quarantine.mjs +1 -1
  121. package/.output/server/chunks/_/users.mjs +1 -1
  122. package/.output/server/chunks/build/Checkbox-BisdHf8n.mjs +1 -1
  123. package/.output/server/chunks/build/CodeBlock-B8BNtZAe.mjs +1 -1
  124. package/.output/server/chunks/build/DashboardSidebarToggle-C3HdHvlE.mjs +1 -1
  125. package/.output/server/chunks/build/DiagnosisPanel-BVb2LgHu.mjs +1 -1
  126. package/.output/server/chunks/build/DiagnosisResult-xVgZlfKK.mjs +1 -1
  127. package/.output/server/chunks/build/EntityLinks-Dzn73fbq.mjs +1 -1
  128. package/.output/server/chunks/build/HelpHint-plioHKA0.mjs +27 -0
  129. package/.output/server/chunks/build/NavigationMenu-RfBOyS32.mjs +1 -1
  130. package/.output/server/chunks/build/OpenInIdeLink-Jp6SzEtD.mjs +1 -1
  131. package/.output/server/chunks/build/RunReports-nuLb-Nm3.mjs +1 -1
  132. package/.output/server/chunks/build/Select-CEyw7HGK.mjs +1 -1
  133. package/.output/server/chunks/build/SelectMenu-C02Hs2_F.mjs +1 -1
  134. package/.output/server/chunks/build/Table-qZdnm9t2.mjs +1 -1
  135. package/.output/server/chunks/build/Tooltip-BI3WQErw.mjs +1 -1
  136. package/.output/server/chunks/build/{_id_-D7UtAIPR.mjs → _id_-26komi8G.mjs} +15 -8
  137. package/.output/server/chunks/build/{_id_-D7UtAIPR.mjs.map → _id_-26komi8G.mjs.map} +1 -1
  138. package/.output/server/chunks/build/{_id_-CrGTZymJ.mjs → _id_-w7YCSiiy.mjs} +2 -2
  139. package/.output/server/chunks/build/{_id_-CrGTZymJ.mjs.map → _id_-w7YCSiiy.mjs.map} +1 -1
  140. package/.output/server/chunks/build/_id_-wiULjAVc.mjs +1 -1
  141. package/.output/server/chunks/build/ai-DYhpzbqp.mjs +1 -1
  142. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  143. package/.output/server/chunks/build/{db.client-Bdqk_eYQ.mjs → db.client-DijpEH6i.mjs} +3 -1
  144. package/.output/server/chunks/build/db.client-DijpEH6i.mjs.map +1 -0
  145. package/.output/server/chunks/build/{default-DO1izI2V.mjs → default-CQa_bmAf.mjs} +2 -2
  146. package/.output/server/chunks/build/{default-DO1izI2V.mjs.map → default-CQa_bmAf.mjs.map} +1 -1
  147. package/.output/server/chunks/build/fetch-tkz5_OA-.mjs +1 -1
  148. package/.output/server/chunks/build/import-B27Sv7h5.mjs +1 -1
  149. package/.output/server/chunks/build/{index-vRwzDXLs.mjs → index-Dq6nk6OB.mjs} +367 -87
  150. package/.output/server/chunks/build/index-Dq6nk6OB.mjs.map +1 -0
  151. package/.output/server/chunks/build/isValueEqualOrExist-D4lZ8uRY.mjs +1 -1
  152. package/.output/server/chunks/build/login-hxCF06JT.mjs +1 -1
  153. package/.output/server/chunks/build/mcp-BVW1llyW.mjs +1 -1
  154. package/.output/server/chunks/build/server.mjs +6 -6
  155. package/.output/server/chunks/build/settings-metadata-DnAK4Rzg.mjs +1 -1
  156. package/.output/server/chunks/build/storage-zN92cA9q.mjs +1 -1
  157. package/.output/server/chunks/build/test-functions-DVRJgiWo.mjs +1 -1
  158. package/.output/server/chunks/build/{useCopyRich-CZxJ7IY_.mjs → useCopyRich-BM9GTjJi.mjs} +64 -18
  159. package/.output/server/chunks/build/{useCopyRich-CZxJ7IY_.mjs.map → useCopyRich-BM9GTjJi.mjs.map} +1 -1
  160. package/.output/server/chunks/nitro/nitro.mjs +1037 -733
  161. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  162. package/.output/server/chunks/routes/__piwi/session.get.mjs +1 -1
  163. package/.output/server/chunks/routes/api/ai/step-resolution.post.mjs +88 -0
  164. package/.output/server/chunks/routes/api/ai/step-resolution.post.mjs.map +1 -0
  165. package/.output/server/chunks/routes/api/analytics/_widget_.get.mjs +1 -1
  166. package/.output/server/chunks/routes/api/auth/change-password.post.mjs +1 -1
  167. package/.output/server/chunks/routes/api/auth/forgot-password.post.mjs +1 -1
  168. package/.output/server/chunks/routes/api/auth/login.post.mjs +1 -1
  169. package/.output/server/chunks/routes/api/auth/logout.post.mjs +1 -1
  170. package/.output/server/chunks/routes/api/auth/me.get.mjs +1 -1
  171. package/.output/server/chunks/routes/api/auth/oauth/_provider/callback.get.mjs +1 -1
  172. package/.output/server/chunks/routes/api/auth/oauth/_provider/login.get.mjs +1 -1
  173. package/.output/server/chunks/routes/api/auth/oauth/_provider/unlink.post.mjs +1 -1
  174. package/.output/server/chunks/routes/api/auth/reset-password.post.mjs +1 -1
  175. package/.output/server/chunks/routes/api/auth/send-verify-email.post.mjs +1 -1
  176. package/.output/server/chunks/routes/api/auth/setup.get.mjs +1 -1
  177. package/.output/server/chunks/routes/api/auth/setup.post.mjs +1 -1
  178. package/.output/server/chunks/routes/api/auth/verify-email.get.mjs +1 -1
  179. package/.output/server/chunks/routes/api/channels/_id/test.post.mjs +1 -1
  180. package/.output/server/chunks/routes/api/channels/_id_.delete.mjs +1 -1
  181. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/approve.post.mjs +1 -1
  182. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/reject.post.mjs +1 -1
  183. package/.output/server/chunks/routes/api/desktop/import-local.post.mjs +1 -1
  184. package/.output/server/chunks/routes/api/failure-clusters/_id/base-commit.patch.mjs +1 -1
  185. package/.output/server/chunks/routes/api/failure-clusters/_id/branches.get.mjs +1 -1
  186. package/.output/server/chunks/routes/api/failure-clusters/_id/commit-diff.get.mjs +1 -1
  187. package/.output/server/chunks/routes/api/failure-clusters/_id/commits.get.mjs +1 -1
  188. package/.output/server/chunks/routes/api/failure-clusters/_id/context.get.mjs +1 -1
  189. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose/stream.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose.post.mjs +1 -1
  191. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnoses.get.mjs +1 -1
  192. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnosis.get.mjs +1 -1
  193. package/.output/server/chunks/routes/api/failure-clusters/_id/export.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/failure-clusters/_id/extract-cases.post.mjs +1 -1
  195. package/.output/server/chunks/routes/api/failure-clusters/_id/fix-plan.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/failure-clusters/_id/status.patch.mjs +1 -1
  197. package/.output/server/chunks/routes/api/failure-clusters/_id_.get.mjs +1 -1
  198. package/.output/server/chunks/routes/api/failure-diagnoses/_id/feedback.patch.mjs +1 -1
  199. package/.output/server/chunks/routes/api/files/_...path_.get.mjs +1 -1
  200. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  201. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  202. package/.output/server/chunks/routes/api/index.get2.mjs +1 -1
  203. package/.output/server/chunks/routes/api/index.get3.mjs +1 -1
  204. package/.output/server/chunks/routes/api/index.get4.mjs +1 -1
  205. package/.output/server/chunks/routes/api/index.get5.mjs +1 -1
  206. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  207. package/.output/server/chunks/routes/api/index.post2.mjs +1 -1
  208. package/.output/server/chunks/routes/api/index.post3.mjs +1 -1
  209. package/.output/server/chunks/routes/api/index.post4.mjs +1 -1
  210. package/.output/server/chunks/routes/api/index.post5.mjs +1 -1
  211. package/.output/server/chunks/routes/api/index.post6.mjs +1 -1
  212. package/.output/server/chunks/routes/api/links/_id/refresh.post.mjs +1 -1
  213. package/.output/server/chunks/routes/api/links/_id_.delete.mjs +1 -1
  214. package/.output/server/chunks/routes/api/links/_id_.patch.mjs +1 -1
  215. package/.output/server/chunks/routes/api/markers/_id_.delete.mjs +1 -1
  216. package/.output/server/chunks/routes/api/markers/_id_.put.mjs +1 -1
  217. package/.output/server/chunks/routes/api/notifications/stream.get.mjs +1 -1
  218. package/.output/server/chunks/routes/api/projects/_id/ai-steps.get.mjs +63 -0
  219. package/.output/server/chunks/routes/api/projects/_id/ai-steps.get.mjs.map +1 -0
  220. package/.output/server/chunks/routes/api/projects/_id/cluster-merge-suggestions.get.mjs +1 -1
  221. package/.output/server/chunks/routes/api/projects/_id/failure-clusters.get.mjs +1 -1
  222. package/.output/server/chunks/routes/api/projects/_id/flaky-classify.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/projects/_id/flaky-tests.get.mjs +1 -1
  224. package/.output/server/chunks/routes/api/projects/_id/latest-run.get.mjs +1 -1
  225. package/.output/server/chunks/routes/api/projects/_id/markers.get.mjs +1 -1
  226. package/.output/server/chunks/routes/api/projects/_id/markers.post.mjs +1 -1
  227. package/.output/server/chunks/routes/api/projects/_id/members.get.mjs +1 -1
  228. package/.output/server/chunks/routes/api/projects/_id/members.put.mjs +1 -1
  229. package/.output/server/chunks/routes/api/projects/_id/performance.get.mjs +1 -1
  230. package/.output/server/chunks/routes/api/projects/_id/quarantine/_testCaseId_.delete.mjs +1 -1
  231. package/.output/server/chunks/routes/api/projects/_id/quarantine.get.mjs +1 -1
  232. package/.output/server/chunks/routes/api/projects/_id/quarantine.post.mjs +1 -1
  233. package/.output/server/chunks/routes/api/projects/_id/slow-tests.get.mjs +1 -1
  234. package/.output/server/chunks/routes/api/projects/_id/spec-health.get.mjs +1 -1
  235. package/.output/server/chunks/routes/api/projects/_id/test-cases.get.mjs +1 -1
  236. package/.output/server/chunks/routes/api/projects/_id/test-functions/extract.post.mjs +1 -1
  237. package/.output/server/chunks/routes/api/projects/_id/test-functions/validate-proposal.post.mjs +1 -1
  238. package/.output/server/chunks/routes/api/projects/_id/test-functions.get.mjs +1 -1
  239. package/.output/server/chunks/routes/api/projects/_id/test-functions.post.mjs +1 -1
  240. package/.output/server/chunks/routes/api/projects/_id/timeout-opportunities.get.mjs +1 -1
  241. package/.output/server/chunks/routes/api/projects/_id_.delete.mjs +1 -1
  242. package/.output/server/chunks/routes/api/projects/_id_.get.mjs +1 -1
  243. package/.output/server/chunks/routes/api/projects/_id_.put.mjs +1 -1
  244. package/.output/server/chunks/routes/api/projects/menu.get.mjs +1 -1
  245. package/.output/server/chunks/routes/api/projects/overview.get.mjs +1 -1
  246. package/.output/server/chunks/routes/api/projects.get.mjs +1 -1
  247. package/.output/server/chunks/routes/api/search.get.mjs +1 -1
  248. package/.output/server/chunks/routes/api/settings/ai/limits.get.mjs +1 -1
  249. package/.output/server/chunks/routes/api/settings/ai/limits.put.mjs +1 -1
  250. package/.output/server/chunks/routes/api/settings/ai/test.post.mjs +1 -1
  251. package/.output/server/chunks/routes/api/settings/ai/usage.get.mjs +1 -1
  252. package/.output/server/chunks/routes/api/settings/ai.get.mjs +1 -1
  253. package/.output/server/chunks/routes/api/settings/ai.put.mjs +1 -1
  254. package/.output/server/chunks/routes/api/settings/pr-feedback.get.mjs +1 -1
  255. package/.output/server/chunks/routes/api/settings/pr-feedback.put.mjs +1 -1
  256. package/.output/server/chunks/routes/api/settings/smtp/test.post.mjs +1 -1
  257. package/.output/server/chunks/routes/api/settings/smtp.get.mjs +1 -1
  258. package/.output/server/chunks/routes/api/settings/timeout-hygiene.get.mjs +1 -1
  259. package/.output/server/chunks/routes/api/settings/timeout-hygiene.put.mjs +1 -1
  260. package/.output/server/chunks/routes/api/settings/wasted-waits.get.mjs +1 -1
  261. package/.output/server/chunks/routes/api/settings/wasted-waits.put.mjs +1 -1
  262. package/.output/server/chunks/routes/api/setup-status.get.mjs +1 -1
  263. package/.output/server/chunks/routes/api/stream.get.mjs +1 -1
  264. package/.output/server/chunks/routes/api/subscriptions/_id_.delete.mjs +1 -1
  265. package/.output/server/chunks/routes/api/subscriptions/_id_.patch.mjs +1 -1
  266. package/.output/server/chunks/routes/api/tags/_id_.delete.mjs +1 -1
  267. package/.output/server/chunks/routes/api/tags/_id_.put.mjs +1 -1
  268. package/.output/server/chunks/routes/api/test-cases/_id/history.get.mjs +1 -1
  269. package/.output/server/chunks/routes/api/test-cases/_id/stability-trend.get.mjs +1 -1
  270. package/.output/server/chunks/routes/api/test-cases/_id_.get.mjs +1 -1
  271. package/.output/server/chunks/routes/api/test-functions/_id_.delete.mjs +1 -1
  272. package/.output/server/chunks/routes/api/test-functions/_id_.put.mjs +1 -1
  273. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnose.post.mjs +1 -1
  274. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis-context.get.mjs +1 -1
  275. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis.get.mjs +1 -1
  276. package/.output/server/chunks/routes/api/test-run-cases/_id/export.get.mjs +1 -1
  277. package/.output/server/chunks/routes/api/test-run-cases/_id/traces.get.mjs +1 -1
  278. package/.output/server/chunks/routes/api/test-run-cases/_id_.get.mjs +1 -1
  279. package/.output/server/chunks/routes/api/test-runs/_id/begin.post.mjs +1 -1
  280. package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs +1 -1
  281. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/dom-snapshot.get.mjs +1 -1
  282. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/environment-diff.get.mjs +1 -1
  283. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-healing.get.mjs +1 -1
  284. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-pick.post.mjs +1 -1
  285. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network-body.get.mjs +1 -1
  286. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network.get.mjs +1 -1
  287. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-stacks.get.mjs +1 -1
  288. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/visual-diff.get.mjs +1 -1
  289. package/.output/server/chunks/routes/api/test-runs/_id/events.post.mjs +1 -1
  290. package/.output/server/chunks/routes/api/test-runs/_id/failure-groups.get.mjs +1 -1
  291. package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/test-runs/_id/gate.post.mjs +1 -1
  293. package/.output/server/chunks/routes/api/test-runs/_id/heartbeat.post.mjs +1 -1
  294. package/.output/server/chunks/routes/api/test-runs/_id/insights.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/test-runs/_id/network-requests.get.mjs +1 -1
  296. package/.output/server/chunks/routes/api/test-runs/_id/regression-context.get.mjs +1 -1
  297. package/.output/server/chunks/routes/api/test-runs/_id/stream.get.mjs +1 -1
  298. package/.output/server/chunks/routes/api/test-runs/_id/summary.get.mjs +1 -1
  299. package/.output/server/chunks/routes/api/test-runs/_id_.delete.mjs +1 -1
  300. package/.output/server/chunks/routes/api/test-runs/_id_.get.mjs +1 -1
  301. package/.output/server/chunks/routes/api/test-runs/_id_.patch.mjs +1 -1
  302. package/.output/server/chunks/routes/api/test-runs/import/check.post.mjs +1 -1
  303. package/.output/server/chunks/routes/api/test-runs/import.post.mjs +1 -1
  304. package/.output/server/chunks/routes/api/test-runs/recent.get.mjs +1 -1
  305. package/.output/server/chunks/routes/api/test-runs/setup.post.mjs +1 -1
  306. package/.output/server/chunks/routes/api/test-runs/start.post.mjs +1 -1
  307. package/.output/server/chunks/routes/api/test-runs/submit.post.mjs +3 -1
  308. package/.output/server/chunks/routes/api/test-runs/submit.post.mjs.map +1 -1
  309. package/.output/server/chunks/routes/api/test-runs/upload.post.mjs +2 -1
  310. package/.output/server/chunks/routes/api/test-runs/upload.post.mjs.map +1 -1
  311. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs +2 -1
  312. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs.map +1 -1
  313. package/.output/server/chunks/routes/api/traces/check.post.mjs +1 -1
  314. package/.output/server/chunks/routes/api/users/_id/api-keys/_keyId_.delete.mjs +1 -1
  315. package/.output/server/chunks/routes/api/users/_id/index.get.mjs +1 -1
  316. package/.output/server/chunks/routes/api/users/_id/index.post.mjs +1 -1
  317. package/.output/server/chunks/routes/api/users/_id/invite.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/users/_id/projects.get.mjs +1 -1
  319. package/.output/server/chunks/routes/api/users/_id/projects.put.mjs +1 -1
  320. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -1
  321. package/.output/server/chunks/routes/api/users/_id_.patch.mjs +1 -1
  322. package/.output/server/chunks/routes/api/version.get.mjs +1 -1
  323. package/.output/server/chunks/routes/mcp.post.mjs +1 -1
  324. package/.output/server/chunks/routes/renderer.mjs +1 -1
  325. package/.output/server/database/migrations/0045_productive_stingray.sql +1 -0
  326. package/.output/server/database/migrations/meta/0045_snapshot.json +3779 -0
  327. package/.output/server/database/migrations/meta/_journal.json +7 -0
  328. package/.output/server/database/migrations-pg/0046_gorgeous_hercules.sql +1 -0
  329. package/.output/server/database/migrations-pg/meta/0046_snapshot.json +4486 -0
  330. package/.output/server/database/migrations-pg/meta/_journal.json +7 -0
  331. package/.output/server/index.mjs +1 -1
  332. package/.output/server/package.json +1 -1
  333. package/package.json +1 -1
  334. package/.output/public/_nuxt/BNyTWIad.js +0 -9
  335. package/.output/public/_nuxt/BVyjw9Bi.js +0 -1
  336. package/.output/public/_nuxt/BZOykMLD.js +0 -1
  337. package/.output/public/_nuxt/CEai-PWF.js +0 -1
  338. package/.output/public/_nuxt/CYhm2FBS.js +0 -5
  339. package/.output/public/_nuxt/CfhOanaF.js +0 -1
  340. package/.output/public/_nuxt/Cz7SCzdW.js +0 -1
  341. package/.output/public/_nuxt/DFfqRQxk.js +0 -1
  342. package/.output/public/_nuxt/builds/meta/6d1766a0-0aba-46b8-9d97-7dd174130359.json +0 -1
  343. package/.output/public/_nuxt/eT2oObCh.js +0 -1
  344. package/.output/public/_nuxt/entry.D_eWXrnD.css +0 -1
  345. package/.output/server/chunks/build/db.client-Bdqk_eYQ.mjs.map +0 -1
  346. package/.output/server/chunks/build/index-vRwzDXLs.mjs.map +0 -1
@@ -323,6 +323,13 @@
323
323
  "when": 1785430068658,
324
324
  "tag": "0045_loose_runaways",
325
325
  "breakpoints": true
326
+ },
327
+ {
328
+ "idx": 46,
329
+ "version": "7",
330
+ "when": 1785584930327,
331
+ "tag": "0046_gorgeous_hercules",
332
+ "breakpoints": true
326
333
  }
327
334
  ]
328
335
  }
@@ -1,6 +1,6 @@
1
1
  import process from 'node:process';globalThis._importMeta_={url:import.meta.url,env:process.env};import 'node:http';
2
2
  import 'node:https';
3
- export { e8 as default } from './chunks/nitro/nitro.mjs';
3
+ export { ea as default } from './chunks/nitro/nitro.mjs';
4
4
  import 'node:crypto';
5
5
  import 'drizzle-orm';
6
6
  import 'path';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piwitests/dashboard-prod",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piwitests/server",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Self-hosted dashboard that keeps and explains your Playwright test results — run with npx @piwitests/server",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,9 +0,0 @@
1
- import{_ as Yt}from"./DTrPCv7R.js";import{_ as es}from"./B3G-TIoP.js";import{d as re,o as s,f as _,g as u,i as o,j as r,t as c,c as a,F as U,y as ee,k as e,s as pe,m as f,v as i,D as pt,q as X,p as ue,h as C,G as Pe,_ as Ie,b as ts,B as yt,l as ge,r as A,ab as $e,J as ve,ac as ss,A as Ee,R as Ce,u as ns,a as as,w as mt,e as os,ad as rs,N as is}from"./CNu3kken.js";import{d as ls,e as cs,h as Oe,a as us,b as ds,c as ms,_ as fs,n as gs,o as ps,p as ys,u as hs,f as xs,i as vs,j as _s,k as ks,l as bs,m as ws}from"./CYhm2FBS.js";import{_ as $s}from"./DylyATWU.js";import{_ as Cs}from"./pZbe82l5.js";import{_ as Ts,a as Ss}from"./2yLW7WU0.js";import{_ as Is,a as Rs,b as js,c as Ls}from"./dUPMBJ4f.js";import{_ as Re}from"./CdEzDaDI.js";import{_ as zs}from"./5SkLJHl8.js";import{_ as Ms}from"./7_9fts7T.js";import{_ as ht}from"./Ce_j5NtN.js";import{_ as xt}from"./jR2xm3_t.js";import{_ as vt}from"./DAhv9aNg.js";import{_ as _t,a as kt}from"./CfhOanaF.js";import{_ as Ns}from"./CvVbKrcH.js";import{_ as Ds}from"./B_JSV0yG.js";import{_ as Ps,d as As,e as Us,f as Bs,g as Fs,h as Vs,a as bt,i as Te,b as De,c as Es}from"./9_aJhhcm.js";import{f as Se,m as Os,c as Hs,e as Ks,n as wt,o as He,q as Ke,a as Ws,j as Gs,r as ft}from"./DeewM3Wg.js";import{_ as $t}from"./FJTsZ5Aa.js";import{_ as ye}from"./Ce47NgZw.js";import{_ as Js}from"./B0tmRAhY.js";import{u as qs}from"./CLWMETf9.js";import{_ as We}from"./DNqm5cWU.js";import{_ as Ge}from"./HIGGZ_c-.js";import{_ as Ct}from"./C2_7XZo0.js";import{f as we}from"./D-c8ZSws.js";import{_ as Qs}from"./DJzFYrBt.js";import{_ as Zs}from"./Bb2mDqKr.js";import{_ as Xs}from"./D3SJGdl4.js";import{_ as Ys}from"./DZECGgZm.js";import{_ as en}from"./oSLbl-p0.js";import{_ as tn}from"./CC8wk-N0.js";import{b as sn}from"./D7t0Dn3h.js";import{a as nn,u as gt}from"./DprkT7rM.js";import"./BZFiz2UB.js";import"./BjOFxi54.js";import"./jxc14CqP.js";import"./DFfqRQxk.js";import"./Ya8ZzWuY.js";import"./roaTZkYi.js";import"./C9I1Dp3S.js";import"./BVyjw9Bi.js";import"./CF_eDZHu.js";import"./DZ-KbUZi.js";import"./DYjxDsYC.js";import"./BZOykMLD.js";import"./B3AG2m76.js";import"./D7fxV-UA.js";import"./BjaRappk.js";import"./Bq4_kqIp.js";import"./CmTzxoQt.js";import"./CGDPUNcO.js";import"./Bag08cIY.js";import"./D7W_4Sqc.js";import"./LTMoFvEY.js";const an={class:"text-sm font-semibold truncate min-w-0"},on={class:"flex items-center gap-3 ml-auto max-sm:hidden"},rn={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},ln={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},cn={class:"text-gray-700 dark:text-gray-300"},un={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},dn={class:"text-gray-700 dark:text-gray-300"},mn={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},fn={class:"text-gray-700 dark:text-gray-300"},gn={key:0,class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},pn={class:"text-gray-700 dark:text-gray-300"},yn={class:"@container"},hn={class:"space-y-3"},xn={class:"flex items-start gap-2.5 pr-8"},vn={class:"min-w-0 flex-1"},_n={class:"flex items-center gap-2 flex-wrap"},kn={class:"text-base font-bold truncate max-w-full"},bn={class:"text-xs text-gray-500 mt-0.5 flex items-center gap-x-2 gap-y-0.5 flex-wrap"},wn=["title"],$n={key:1},Cn={key:0,class:"flex items-center gap-2 text-sm"},Tn={class:"text-gray-700 dark:text-gray-300 truncate"},Sn={key:0,class:"text-gray-500 shrink-0"},In={key:1,class:"flex items-center gap-1.5 text-sm"},Rn={key:0,class:"font-medium"},jn=["title"],Ln={key:2,class:"text-muted"},zn=["title"],Mn={key:0,class:"rounded-full border border-default px-2 py-0.5 text-xs bg-elevated/60"},Nn={key:1},Dn=["href"],Pn={key:1},An={class:"text-muted"},Un={key:0,class:"tabular-nums text-muted"},Bn={key:0,class:"text-dimmed"},Fn=re({__name:"TestCaseSummary",props:{testCase:{},scmInfo:{},ciInfo:{},browser:{},environment:{},stepsCount:{},historicalTiming:{},stableLinks:{},projectKey:{},projectName:{}},emits:["refresh"],setup(t){const k=t,h=C(()=>{const n=k.testCase;if(!n)return[];const l=[];return n.isNewRegression&&l.push({label:"New regression",color:"error",title:"Passed in the baseline run, failing here"}),n.isNewFlaky&&l.push({label:"New flaky",color:"warning",title:"Newly started passing only on retry"}),n.status==="passed"&&(n.retries??0)>0&&l.push({label:"Passed on retry",color:"warning",title:"This test failed then passed on a retry"}),l}),w=C(()=>(k.testCase?.testAnnotations??[]).filter(n=>!Os(n.type))),$=C(()=>k.testCase?.startedAt??null),g=C(()=>!!(k.ciInfo||k.environment));return(n,l)=>{const d=Is,D=Re,M=zs,b=pe,v=Ms,F=ht,L=pt,m=xt,S=vt,V=ue,B=_t,I=js,G=Ns,J=Rs,N=Ds,ne=Ps;return s(),_(ne,{"storage-key":"test-case"},{folded:u(()=>[r(d,{status:t.testCase?.status??"",size:"sm"},null,8,["status"]),o("span",an,c(t.testCase?.title),1),o("div",on,[o("span",rn,[l[1]||(l[1]=f(" Dur: ",-1)),r(D,{ms:t.testCase?.duration,class:"font-bold text-gray-700 dark:text-gray-300"},null,8,["ms"])]),o("span",ln,[l[2]||(l[2]=f(" Retries: ",-1)),o("strong",cn,c(t.testCase?.retries??0),1)]),o("span",un,[l[3]||(l[3]=f(" Steps: ",-1)),o("strong",dn,c(t.stepsCount),1)]),o("span",mn,[l[4]||(l[4]=f(" Worker: ",-1)),o("strong",fn,c(t.testCase?.workerIndex??"—"),1)]),t.testCase?.shardIndex!=null?(s(),a("span",gn,[l[5]||(l[5]=f(" Shard: ",-1)),o("strong",pn,c(t.testCase.shardIndex),1)])):i("",!0)]),t.browser?(s(),_(M,{key:0,browser:t.browser,size:"sm",class:"shrink-0 max-sm:hidden"},null,8,["browser"])):i("",!0)]),default:u(()=>[o("div",yn,[r(N,{class:"shadow-xs",ui:{footer:"px-4 py-2.5 sm:px-4 bg-muted/30"}},{footer:u(()=>[r(J,null,{default:u(()=>[t.scmInfo?(s(),_(I,{key:0,label:"Source",icon:"i-lucide-git-branch"},{default:u(()=>[t.scmInfo.branch?(s(),a("span",Rn,c(t.scmInfo.branch),1)):i("",!0),t.scmInfo.commit?(s(),a("code",{key:1,class:"text-xs font-mono bg-zinc-100 dark:bg-zinc-800 px-1 py-0.5 rounded",title:t.scmInfo.commit},c(t.scmInfo.commit.length>=8?t.scmInfo.commit.substring(0,8):t.scmInfo.commit),9,jn)):i("",!0),t.scmInfo.author?(s(),a("span",Ln,c(t.scmInfo.author),1)):i("",!0),t.scmInfo.commitMessage?(s(),a("span",{key:3,class:"text-xs text-dimmed truncate max-w-[40ch]",title:t.scmInfo.commitMessage},c(t.scmInfo.commitMessage),9,zn)):i("",!0)]),_:1})):i("",!0),e(g)?(s(),_(I,{key:1,label:"CI & environment",icon:"i-lucide-cloud",help:"run.ci-env"},{default:u(()=>[t.environment?(s(),a("span",Mn,c(t.environment),1)):i("",!0),t.ciInfo?.provider?(s(),a("span",Nn,c(t.ciInfo.provider),1)):i("",!0),t.ciInfo?.buildNumber||t.ciInfo?.buildUrl?(s(),a(U,{key:2},[l[12]||(l[12]=o("span",{class:"text-dimmed"},"·",-1)),t.ciInfo?.buildUrl?(s(),a("a",{key:0,href:t.ciInfo.buildUrl,target:"_blank",class:"text-primary hover:underline"},c(t.ciInfo?.buildNumber?`Build #${t.ciInfo.buildNumber}`:"View build"),9,Dn)):(s(),a("span",Pn,"Build #"+c(t.ciInfo.buildNumber),1))],64)):i("",!0),t.ciInfo?.workflow||t.ciInfo?.jobName?(s(),a(U,{key:3},[l[13]||(l[13]=o("span",{class:"text-dimmed"},"·",-1)),o("span",An,[t.ciInfo?.workflow?(s(),a(U,{key:0},[f(c(t.ciInfo.workflow),1)],64)):i("",!0),t.ciInfo?.workflow&&t.ciInfo?.jobName?(s(),a(U,{key:1},[f(" · ")],64)):i("",!0),t.ciInfo?.jobName?(s(),a(U,{key:2},[f(c(t.ciInfo.jobName),1)],64)):i("",!0)])],64)):i("",!0)]),_:1})):i("",!0),t.browser?(s(),_(I,{key:2,label:"Browser"},{default:u(()=>[r(M,{browser:{...t.browser,viewport:void 0},size:"sm"},null,8,["browser"]),t.browser.viewport?(s(),a("span",Un,[f(c(t.browser.viewport.width)+"×"+c(t.browser.viewport.height)+" ",1),t.browser.deviceScaleFactor&&t.browser.deviceScaleFactor!==1?(s(),a("span",Bn,"@"+c(t.browser.deviceScaleFactor)+"x",1)):i("",!0)])):i("",!0)]),_:1})):i("",!0),r(I,{label:"Links",icon:"i-lucide-link"},{default:u(()=>[t.testCase?.id?(s(),_(G,{key:0,"entity-type":"test_case","entity-id":t.testCase.id,links:t.stableLinks??null,onUpdated:l[0]||(l[0]=O=>n.$emit("refresh"))},null,8,["entity-id","links"])):i("",!0)]),_:1})]),_:1})]),default:u(()=>[o("div",hn,[o("div",xn,[r(d,{status:t.testCase?.status??"",class:"mt-0.5"},null,8,["status"]),o("div",vn,[o("div",_n,[o("h2",kn,c(t.testCase?.title),1),(s(!0),a(U,null,ee(e(h),O=>(s(),_(b,{key:O.label,color:O.color,variant:"subtle",size:"xs",title:O.title},{default:u(()=>[f(c(O.label),1)]),_:2},1032,["color","title"]))),128)),(s(!0),a(U,null,ee(e(w),(O,le)=>(s(),_(b,{key:`ann-${le}`,color:"neutral",variant:"soft",size:"xs",class:"font-mono",title:O.description||O.type},{default:u(()=>[f(" @"+c(O.type),1)]),_:2},1032,["title"]))),128)),r(v,{tags:t.testCase?.tags,meta:t.testCase?.testMeta},null,8,["tags","meta"])]),o("p",bn,[t.testCase?.location?(s(),_(F,{key:0,location:t.testCase.location,"project-key":t.projectKey,"project-name":t.projectName},null,8,["location","project-key","project-name"])):i("",!0),r(L,null,{default:u(()=>[e($)?(s(),a("span",{key:0,class:"text-gray-400",title:new Date(e($)).toLocaleString()}," started "+c(("formatRelativeTime"in n?n.formatRelativeTime:e(Se))(e($))),9,wn)):i("",!0)]),_:1}),t.historicalTiming?(s(),a("span",$n,[l[6]||(l[6]=f(" Avg ",-1)),r(D,{ms:t.historicalTiming.avg},null,8,["ms"]),l[7]||(l[7]=f(" · ",-1)),o("span",{class:X(t.historicalTiming.diff>0?"text-red-600":"text-green-600")},c(t.historicalTiming.diff>0?"+":"")+c(t.historicalTiming.pct)+"% ",3)])):i("",!0)])])]),r(S,null,{default:u(()=>[r(m,{label:"Duration"},{default:u(()=>[r(D,{ms:t.testCase?.duration},null,8,["ms"])]),_:1}),r(m,{label:"Retries",value:t.testCase?.retries??0},null,8,["value"]),r(m,{label:"Steps",value:t.stepsCount},null,8,["value"]),r(m,{label:"Worker",value:t.testCase?.workerIndex??"—"},null,8,["value"])]),_:1}),t.testCase?.slowestStep?(s(),a("div",Cn,[r(V,{name:"i-lucide-zap",class:"size-4 text-amber-500 shrink-0"}),l[10]||(l[10]=o("span",{class:"font-medium text-amber-700 dark:text-amber-300"},"Slowest step:",-1)),o("span",Tn,c(t.testCase.slowestStep),1),t.testCase.slowestStepDuration?(s(),a("span",Sn,[l[8]||(l[8]=f("(",-1)),r(D,{ms:t.testCase.slowestStepDuration},null,8,["ms"]),l[9]||(l[9]=f(")",-1))])):i("",!0)])):i("",!0),(t.testCase?.wastedTimeMs??0)>0?(s(),a("div",In,[r(V,{name:"i-lucide-hourglass",class:"size-4 text-amber-500 shrink-0"}),l[11]||(l[11]=o("span",{class:"font-medium text-amber-700 dark:text-amber-300"},"Wasted in fixed waits:",-1)),r(D,{ms:t.testCase?.wastedTimeMs,class:"text-gray-700 dark:text-gray-300"},null,8,["ms"]),r(B,{topic:"case.wasted-time"})])):i("",!0)])]),_:1})])]),_:1})}}}),Vn=Object.assign(Fn,{__name:"TestCaseSummary"}),En={class:"space-y-3"},On={key:0,class:"flex flex-wrap gap-1.5"},Hn={key:0,class:"text-sm text-gray-600 dark:text-gray-400"},Kn={class:"text-gray-800 dark:text-gray-200"},Wn={key:1},Gn={class:"flex items-center gap-1 flex-wrap"},Jn=re({__name:"TestCaseVerdictCard",props:{testCase:{},history:{},currentId:{}},setup(t){const k=t,h=l=>l==="failed"||l==="timedOut"||l==="timedout",w=C(()=>{const l=k.testCase;if(!l)return[];const d=[];return l.isNewRegression&&d.push({label:"New regression",color:"error",icon:"i-lucide-git-pull-request-arrow",title:"Passed in the baseline run, failing here — likely fallout from the latest change"}),l.isNewFlaky&&d.push({label:"New flaky",color:"warning",icon:"i-lucide-shuffle",title:"Newly started passing only on retry — intermittent failure"}),l.status==="timedOut"&&d.push({label:"Timed out",color:"warning",icon:"i-lucide-timer-off",title:"The test exceeded its timeout"}),(l.retries??0)>0&&d.push({label:l.status==="passed"?`Passed on retry ${l.retries}`:`Retried ${l.retries}×`,color:l.status==="passed"?"warning":"neutral",icon:"i-lucide-refresh-cw",title:`This execution retried ${l.retries} time${l.retries===1?"":"s"}`}),d}),$=C(()=>k.history.slice(0,24).slice().reverse()),g=C(()=>{const l=k.history;if(!l.length)return null;const d=Math.max(0,l.findIndex(b=>b.id===k.currentId));let D=0;for(let b=d;b<l.length&&h(l[b].status);b++)D++;let M=null;for(let b=d+1;b<l.length;b++)if(l[b].status==="passed"){M=l[b];break}return{streak:D,lastPass:M,total:l.length,anchorFailing:h(l[d]?.status)}}),n=l=>({"bg-red-500 hover:bg-red-600":h(l),"bg-green-500 hover:bg-green-600":l==="passed","bg-yellow-500 hover:bg-yellow-600":l==="skipped","bg-gray-400 hover:bg-gray-500":!h(l)&&!["passed","skipped"].includes(l)});return(l,d)=>{const D=ue,M=pe,b=Pe,v=$t,F=pt,L=ye;return s(),_(L,{icon:"i-lucide-clipboard-check","icon-class":"text-amber-500",title:"Verdict",help:"case.verdict"},{default:u(()=>[o("div",En,[e(w).length?(s(),a("div",On,[(s(!0),a(U,null,ee(e(w),m=>(s(),_(M,{key:m.label,color:m.color,variant:"subtle",size:"sm",title:m.title,class:"inline-flex items-center gap-1"},{default:u(()=>[r(D,{name:m.icon,class:"size-3 shrink-0"},null,8,["name"]),f(" "+c(m.label),1)]),_:2},1032,["color","title"]))),128))])):i("",!0),r(F,null,{default:u(()=>[e(g)?(s(),a("p",Hn,[e(g).streak>=1?(s(),a(U,{key:0},[d[1]||(d[1]=f(" Failing for ",-1)),o("strong",Kn,c(e(g).streak),1),f(" consecutive run"+c(e(g).streak===1?"":"s")+". ",1),e(g).lastPass?(s(),a(U,{key:0},[d[0]||(d[0]=f(" Last passed in ",-1)),r(b,{to:`/test-run-cases/${e(g).lastPass.id}`,class:"text-primary hover:underline"},{default:u(()=>[f(" run #"+c(e(g).lastPass.runId),1)]),_:1},8,["to"]),f(" ("+c(("formatRelativeTime"in l?l.formatRelativeTime:e(Se))(e(g).lastPass.startTime))+"). ",1)],64)):e(g).total>1?(s(),a(U,{key:1},[f(" No passing run in the last "+c(e(g).total)+" recorded. ",1)],64)):(s(),a(U,{key:2},[f(" First recorded run of this test. ")],64))],64)):t.testCase?.status==="passed"?(s(),a(U,{key:1},[f(" This execution passed. ")],64)):i("",!0)])):i("",!0),e($).length>1?(s(),a("div",Wn,[d[2]||(d[2]=o("p",{class:"text-xs text-gray-400 mb-1"},"Recent runs (oldest → newest)",-1)),o("div",Gn,[(s(!0),a(U,null,ee(e($),m=>(s(),_(v,{key:m.id,text:`Run #${m.runId}: ${m.status}`},{default:u(()=>[r(b,{to:`/test-run-cases/${m.id}`,class:X(["size-3.5 rounded-sm inline-block transition-colors",[n(m.status),m.id===t.currentId?"ring-2 ring-offset-1 ring-primary":""]])},null,8,["to","class"])]),_:2},1032,["text"]))),128))])])):i("",!0)]),_:1})])]),_:1})}}}),qn=Object.assign(Jn,{__name:"TestCaseVerdictCard"}),Qn={class:"space-y-3"},Zn={class:"space-y-1.5"},Xn={class:"flex items-center gap-2 flex-wrap"},Yn={class:"text-xs text-gray-500"},ea=["title"],ta={class:"text-xs text-gray-500 dark:text-gray-400"},sa={key:0,class:"rounded-lg border border-default bg-elevated/40 p-2.5 space-y-1"},na={class:"flex items-center gap-1.5 flex-wrap"},aa={class:"text-xs text-gray-600 dark:text-gray-400 line-clamp-3"},oa=["title"],ra=re({__name:"FailureClusterCard",props:{cluster:{}},setup(t){const k=t,h=C(()=>Math.max(0,k.cluster.sameRunCaseCount-1)),w=C(()=>{const g=k.cluster.diagnosis;return g&&g.status==="completed"&&g.summary?g:null}),$=g=>g==="high"?"success":g==="medium"?"warning":"neutral";return(g,n)=>{const l=pe,d=Pe,D=ue,M=Ie,b=ye;return s(),_(b,{icon:"i-lucide-layers","icon-class":"text-primary",title:"Failure cluster",help:"cluster.concept"},{actions:u(()=>[t.cluster.isNew?(s(),_(l,{key:0,color:"warning",variant:"subtle",size:"sm"},{default:u(()=>[...n[0]||(n[0]=[f("New",-1)])]),_:1})):i("",!0),t.cluster.status&&t.cluster.status!=="open"?(s(),_(l,{key:1,color:t.cluster.status==="resolved"?"success":"neutral",variant:"subtle",size:"sm",class:"capitalize"},{default:u(()=>[f(c(t.cluster.status),1)]),_:1},8,["color"])):i("",!0)]),default:u(()=>[o("div",Qn,[o("div",Zn,[o("div",Xn,[t.cluster.errorType?(s(),_(l,{key:0,color:e(Hs)(t.cluster.errorType),variant:"soft",size:"sm"},{default:u(()=>[f(c(t.cluster.errorType),1)]),_:1},8,["color"])):i("",!0),o("span",Yn,c(t.cluster.occurrences??0)+" occurrence"+c((t.cluster.occurrences??0)===1?"":"s"),1)]),o("p",{class:"font-mono text-xs text-gray-600 dark:text-gray-400 break-all line-clamp-2",title:t.cluster.signature},c(t.cluster.signature),9,ea)]),o("p",ta,[e(h)>0?(s(),a(U,{key:0},[f(" Matches "+c(e(h))+" other failing "+c(e(h)===1?"test":"tests")+" in this run. ",1)],64)):i("",!0),t.cluster.isNew?(s(),a(U,{key:2},[f("Opened a new cluster in this run.")],64)):(s(),a(U,{key:1},[n[1]||(n[1]=f(" Known failure — first seen in ",-1)),r(d,{to:`/test-runs/${t.cluster.firstSeenRunId}`,class:"text-primary hover:underline"},{default:u(()=>[f(" run #"+c(t.cluster.firstSeenRunId),1)]),_:1},8,["to"]),t.cluster.firstSeenAt?(s(),a(U,{key:0},[f(" ("+c(("formatRelativeTime"in g?g.formatRelativeTime:e(Se))(t.cluster.firstSeenAt))+")",1)],64)):i("",!0),n[2]||(n[2]=f(". ",-1))],64))]),e(w)?(s(),a("div",sa,[o("div",na,[r(D,{name:"i-lucide-sparkles",class:"size-3.5 text-primary shrink-0"}),n[3]||(n[3]=o("span",{class:"text-xs font-medium"},"AI verdict",-1)),e(w).category?(s(),_(l,{key:0,color:"neutral",variant:"soft",size:"xs"},{default:u(()=>[f(c(e(w).category),1)]),_:1})):i("",!0),e(w).confidence?(s(),_(l,{key:1,color:$(e(w).confidence),variant:"soft",size:"xs"},{default:u(()=>[f(c(e(w).confidence)+" confidence ",1)]),_:1},8,["color"])):i("",!0)]),o("p",aa,c(e(w).summary),1)])):i("",!0),t.cluster.triageNote?(s(),a("p",{key:1,class:"text-xs italic text-gray-500 dark:text-gray-400",title:t.cluster.triageNote}," “"+c(t.cluster.triageNote)+"” ",9,oa)):i("",!0),r(M,{to:`/failure-clusters/${t.cluster.id}`,size:"sm",color:"primary",variant:"solid",block:"","trailing-icon":"i-lucide-arrow-right"},{default:u(()=>[...n[4]||(n[4]=[f(" Open cluster investigation ",-1)])]),_:1},8,["to"])])]),_:1})}}}),ia=Object.assign(ra,{__name:"FailureClusterCard"}),la={class:"space-y-3"},ca={class:"text-xs text-gray-400 inline-flex items-center gap-1"},ua={key:0,class:"text-primary"},da={key:0,class:"flex items-center justify-between gap-2 rounded-lg border border-default bg-elevated/40 p-2.5"},ma={class:"inline-flex items-center gap-2 text-sm text-gray-500"},fa={key:1,class:"flex items-center gap-2"},ga={key:2,class:"rounded-lg border border-dashed border-default p-4 text-center text-gray-400"},pa={class:"text-sm inline-flex items-center gap-1 justify-center"},ya={class:"pt-1 text-center"},ha=re({__name:"TestCaseAiCard",props:{testRunsCaseId:{}},setup(t){const k=t,{aiStatus:h}=qs(),w=ts(),$=A(null),g=A(!1),n=A(null),l=A([]),d=A(0),D=A(0),M=A(null),b=A(!1),v=A(!1),F=A(null),L=A(!1),m=A("");async function S(){b.value=!0;try{const y=await $fetch(`/api/test-run-cases/${k.testRunsCaseId}/diagnosis-context`,{query:{format:"json"}});n.value=y.text,l.value=y.sections,d.value=y.tokenEstimate,D.value=y.imageTokenEstimate??0,M.value=y.coverage}catch{n.value=null,l.value=[],d.value=0,M.value=null}finally{b.value=!1}}async function V(){try{const y=await $fetch(`/api/test-run-cases/${k.testRunsCaseId}/diagnosis`);$.value=y.diagnosis}catch{}}yt(()=>{V(),S()});const B=C(()=>{const y=$.value?.details;if(!y)return[];const P=[];if(Array.isArray(y.evidence)&&P.push(...y.evidence),Array.isArray(y.hypotheses))for(const se of y.hypotheses)Array.isArray(se?.evidence)&&P.push(...se.evidence);return Vs(P)});function I(y){F.value=y,v.value=!0}function G(y){m.value=m.value?`${m.value}
2
-
3
- ${y}`:y,L.value=!0}async function J(y=!1){g.value=!0;try{const P=y?`/api/test-run-cases/${k.testRunsCaseId}/diagnose?force=true`:`/api/test-run-cases/${k.testRunsCaseId}/diagnose`,se=m.value.trim()?{additionalContext:m.value.trim()}:void 0;$.value=await $fetch(P,{method:"POST",body:se})}catch(P){const se=P?.statusCode;se===409?(w.add({title:"Diagnosis already running",color:"warning"}),V()):se===503?w.add({title:"AI diagnosis is not configured",color:"warning"}):w.add({title:"Diagnosis failed",description:Ks(P),color:"error"})}finally{g.value=!1}}function N(y){return y.status==="running"&&Date.now()-new Date(y.updatedAt).getTime()>300*1e3}const ne=C(()=>$.value&&($.value.status==="completed"||$.value.status==="failed")),O=C(()=>!$.value||$.value.status==="failed"||$.value.status==="running"&&N($.value)),le=C(()=>$.value?.status==="running"&&!N($.value)&&!g.value);return(y,P)=>{const se=Fs,x=ue,T=As,K=Js,q=Ie,Q=Us,te=_t,H=Bs,Z=Pe,Y=ye;return s(),_(Y,{icon:"i-lucide-sparkles","icon-class":"text-primary",title:"AI diagnosis",help:"case.ai"},{actions:u(()=>[r(se,{"context-endpoint":`/api/test-run-cases/${t.testRunsCaseId}/diagnosis-context`},null,8,["context-endpoint"])]),default:u(()=>[o("div",la,[o("p",ca,[r(x,{name:"i-lucide-triangle-alert",class:"size-3 shrink-0"}),P[6]||(P[6]=f(" AI-generated — verify before applying. ",-1))]),e(h)?.configured?(s(),_(T,{key:0,sections:e(l),"not-applicable":e(M)?.notApplicable,"token-estimate":e(d),loading:e(b),onViewSection:I,onOpen:P[0]||(P[0]=ae=>v.value=!0)},null,8,["sections","not-applicable","token-estimate","loading"])):i("",!0),e(h)?.configured?(s(),a(U,{key:1},[o("div",null,[o("button",{class:"flex items-center gap-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 dark:hover:text-gray-300",onClick:P[1]||(P[1]=ae=>L.value=!e(L))},[r(x,{name:e(L)?"i-lucide-chevron-down":"i-lucide-chevron-right",class:"size-3.5"},null,8,["name"]),P[7]||(P[7]=f(" Additional context ",-1)),e(m).trim()?(s(),a("span",ua,"(1)")):i("",!0)]),e(L)?(s(),_(K,{key:0,modelValue:e(m),"onUpdate:modelValue":P[2]||(P[2]=ae=>ge(m)?m.value=ae:null),placeholder:"e.g. We deployed a new auth middleware yesterday…",rows:3,class:"w-full text-sm mt-1"},null,8,["modelValue"])):i("",!0)]),e(le)?(s(),a("div",da,[o("span",ma,[r(x,{name:"i-lucide-loader-circle",class:"size-4 animate-spin text-primary shrink-0"}),P[8]||(P[8]=f(" Diagnosis in progress… ",-1))]),r(q,{size:"xs",color:"neutral",variant:"outline",icon:"i-lucide-refresh-cw",loading:e(g),onClick:V},{default:u(()=>[...P[9]||(P[9]=[f(" Refresh ",-1)])]),_:1},8,["loading"])])):(s(),a("div",fa,[e(O)?(s(),_(q,{key:0,icon:"i-lucide-sparkles",size:"sm",color:"primary",variant:"solid",loading:e(g),onClick:P[3]||(P[3]=ae=>J(e($)?.status==="running"))},{default:u(()=>[f(c(e($)?.status==="running"?"Restart diagnosis":"Diagnose with AI"),1)]),_:1},8,["loading"])):e($)?.status==="completed"?(s(),_(q,{key:1,icon:"i-lucide-refresh-cw",size:"xs",color:"primary",variant:"soft",loading:e(g),onClick:P[4]||(P[4]=ae=>J(!0))},{default:u(()=>[...P[10]||(P[10]=[f(" Re-diagnose ",-1)])]),_:1},8,["loading"])):i("",!0)])),e(ne)?(s(),_(Q,{key:2,diagnosis:e($),onViewSection:I,onPrefillContext:G},null,8,["diagnosis"])):i("",!0)],64)):(s(),a("div",ga,[o("p",pa,[P[11]||(P[11]=f(" AI diagnosis is not configured ",-1)),r(te,{topic:"cluster.ai-setup"})]),P[13]||(P[13]=o("p",{class:"text-xs mt-2 max-w-xs mx-auto"},[f(" Use "),o("strong",null,"Export → AI context"),f(" in the header to grab the full evidence bundle for your own AI tool, or configure a provider. ")],-1)),r(q,{to:"/settings/ai",size:"xs",color:"neutral",variant:"outline",class:"mt-3"},{default:u(()=>[...P[12]||(P[12]=[f(" Configure in Settings ",-1)])]),_:1})])),r(H,{open:e(v),sections:e(l),"token-estimate":e(d),"image-token-estimate":e(D),loading:e(b),"focus-section":e(F),"cited-sections":e(B),"not-applicable-sections":e(M)?.notApplicable,"onUpdate:open":P[5]||(P[5]=ae=>{v.value=ae,ae||(F.value=null)}),onRefresh:S},null,8,["open","sections","token-estimate","image-token-estimate","loading","focus-section","cited-sections","not-applicable-sections"]),o("div",ya,[r(Z,{to:"/mcp",class:"inline-flex items-center gap-1 text-xs text-gray-400 hover:text-primary transition-colors"},{default:u(()=>[r(x,{name:"i-lucide-bot",class:"size-3"}),P[14]||(P[14]=f(" Query this failure from your AI agent via MCP ",-1))]),_:1})])])]),_:1})}}}),xa=Object.assign(ha,{__name:"TestCaseAiCard"});function Tt(t,k,h){const w=A(null),$=A(!1),g=A(!1);async function n(){const l=t();if(!(!l||!$e(k)||$.value)){g.value=!0,$.value=!0;try{w.value=await $fetch(l)}catch{w.value=null}finally{$.value=!1}}}return yt(()=>{ve(()=>$e(k),l=>{l&&(h||g.value)&&!w.value&&n()},{immediate:!0})}),{data:w,pending:$,load:n}}function va(t,k,h,w={}){return Tt(()=>{const $=$e(t),g=$e(k);return $&&g?`/api/test-runs/${$}/cases/${g}/trace-stacks`:null},h,w.auto??!0)}function _a(t,k,h,w={}){return Tt(()=>{const $=$e(t),g=$e(k);return $&&g?`/api/test-runs/${$}/cases/${g}/trace-network`:null},h,w.auto??!1)}const ka={class:"max-h-[32rem] overflow-y-auto"},ba={key:0,class:"mb-2 flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500"},wa={key:0,class:"mt-3 flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500"},$a=re({__name:"TestSourceCard",props:{frames:{},testSource:{},runId:{},testRunsCaseId:{},hasTrace:{type:Boolean},projectKey:{},projectName:{},storageKey:{}},setup(t,{expose:k}){const h=t,{data:w,pending:$}=va(()=>h.runId,()=>h.testRunsCaseId,()=>h.hasTrace,{auto:!0}),g=C(()=>w.value?.status==="ok"?w.value.frames??[]:[]),n=C(()=>g.value.length>0),l=C(()=>h.frames?.length??0),d=C(()=>l.value>0||!!h.testSource),D=A(null),M=C({get:()=>D.value??(n.value?"trace":"captured"),set:L=>{D.value=L}}),b=C(()=>[{label:`Full stack (${g.value.length})`,value:"trace"},{label:`Captured (${l.value||1})`,value:"captured"}]),v=C(()=>M.value==="trace"&&n.value?g.value.length:l.value||null),F=A(null);return k({reveal:()=>F.value?.reveal()}),(L,m)=>{const S=We,V=ue,B=ls,I=cs,G=bt,J=Ge,N=kt,ne=Oe;return s(),_(ne,{ref_key:"card",ref:F,"storage-key":t.storageKey,icon:"i-lucide-code",count:e(v),title:"Test source",help:"case.test-source"},ss({folded:u(()=>[e(M)==="trace"&&e(n)?(s(),a(U,{key:0},[f(" Full call stack from the trace"+c(e(w)?.hasSources===!1?" (recorded without sources)":""),1)],64)):e(l)>1?(s(),a(U,{key:1},[f(" The failing line and "+c(e(l)-1)+" caller"+c(e(l)-1===1?"":"s"),1)],64)):(s(),a(U,{key:2},[f("Source around the failing assertion")],64))]),default:u(()=>[o("div",ka,[e(M)==="trace"&&e(n)?(s(),a(U,{key:0},[e(w)?.hasSources===!1?(s(),a("p",ba,[r(V,{name:"i-lucide-info",class:"size-3.5 shrink-0"}),m[1]||(m[1]=f(" Trace recorded without sources — frame list only. ",-1))])):i("",!0),r(B,{frames:e(g),"project-key":t.projectKey,"project-name":t.projectName},null,8,["frames","project-key","project-name"])],64)):(s(),a(U,{key:1},[t.frames?.length?(s(),_(I,{key:0,frames:t.frames,"project-key":t.projectKey,"project-name":t.projectName},null,8,["frames","project-key","project-name"])):t.testSource?(s(),_(G,{key:1,text:"```typescript\n"+t.testSource+"\n```"},null,8,["text"])):t.hasTrace&&e($)?(s(),_(J,{key:2,text:"Loading call stack from trace…"})):i("",!0)],64))]),t.hasTrace?i("",!0):(s(),a("p",wa,[r(V,{name:"i-lucide-info",class:"size-3.5 shrink-0"}),o("span",null,[m[3]||(m[3]=f(" Want to go deeper? Record traces (",-1)),m[4]||(m[4]=o("code",null,"trace: 'retain-on-failure'",-1)),m[5]||(m[5]=f(") to see the full call stack with source here. ",-1)),r(N,{to:"ui-overview#trace-powered-deep-views","no-icon":"",class:"underline"},{default:u(()=>[...m[2]||(m[2]=[f("Learn more",-1)])]),_:1})])]))]),_:2},[e(n)&&e(d)?{name:"actions",fn:u(()=>[r(S,{modelValue:e(M),"onUpdate:modelValue":m[0]||(m[0]=O=>ge(M)?M.value=O:null),items:e(b),size:"xs",variant:"link",ui:{list:"gap-2",trigger:"px-1.5"}},null,8,["modelValue","items"])]),key:"0"}:void 0]),1032,["storage-key","count"])}}}),Ca=Object.assign($a,{__name:"TestSourceCard"}),Ta={class:"space-y-3"},Sa={class:"divide-y divide-default"},Ia={class:"flex items-center gap-2 min-w-0"},Ra={class:"text-sm truncate"},ja={key:0,class:"text-xs text-gray-400 shrink-0"},La=re({__name:"TestCaseEvidenceCard",props:{attachments:{},traces:{},storageKey:{}},setup(t,{expose:k}){const h=t,w=Ee(),$=C(()=>h.attachments.filter(v=>Te(v.path,v.contentType)).length),g=C(()=>h.attachments.filter(v=>De(v.path,v.contentType)).length),n=C(()=>h.attachments.filter(v=>!Te(v.path,v.contentType)&&!De(v.path,v.contentType))),l=C(()=>$.value+g.value+h.traces.length+n.value.length),d=C(()=>{const v=[];return $.value&&v.push(`${$.value} screenshot${$.value===1?"":"s"}`),g.value&&v.push(`${g.value} video${g.value===1?"":"s"}`),h.traces.length&&v.push(`${h.traces.length} trace${h.traces.length===1?"":"s"}`),n.value.length&&v.push(`${n.value.length} file${n.value.length===1?"":"s"}`),v.join(" · ")||"No evidence captured"});function D(v,F){return wt(v,F,w.app?.baseURL)}function M(v){return v.split("/").pop()||v}const b=A(null);return k({reveal:()=>b.value?.reveal?.()}),(v,F)=>{const L=us,m=ds,S=ms,V=ue,B=Ie,I=fs,G=Ct,J=Oe;return s(),_(J,{ref_key:"card",ref:b,"storage-key":t.storageKey,icon:"i-lucide-camera",title:"Failure evidence",count:e(l),help:"case.evidence"},{folded:u(()=>[f(c(e(d)),1)]),default:u(()=>[o("div",Ta,[r(L,{attachments:t.attachments},null,8,["attachments"]),r(m,{attachments:t.attachments},null,8,["attachments"]),r(S,{traces:t.traces},null,8,["traces"]),e(n).length?(s(),_(I,{key:0,icon:"i-lucide-paperclip",label:"Attachments",count:e(n).length,collapsible:!1},{default:u(()=>[o("div",Sa,[(s(!0),a(U,null,ee(e(n),N=>(s(),a("div",{key:N.id,class:"flex items-center justify-between gap-2 px-3 py-2"},[o("div",Ia,[r(V,{name:"i-lucide-file",class:"size-4 text-gray-400 shrink-0"}),o("span",Ra,c(M(N.path)),1),N.size?(s(),a("span",ja,c(("formatBytes"in v?v.formatBytes:e(we))(N.size)),1)):i("",!0)]),r(B,{to:D(N.path,N.contentType),target:"_blank",icon:"i-lucide-external-link",size:"xs",color:"neutral",variant:"soft",label:"Open"},null,8,["to"])]))),128))])]),_:1},8,["count"])):i("",!0),e(l)===0?(s(),_(G,{key:1,icon:"i-lucide-camera-off",title:"No screenshots, video or traces captured",text:"Evidence comes from Playwright's own capture settings — set trace, screenshot and video in your config (trace: 'retain-on-failure' is the usual starting point).",doc:"reporter"})):i("",!0)])]),_:1},8,["storage-key","count"])}}}),za=Object.assign(La,{__name:"TestCaseEvidenceCard"}),Ma={class:"space-y-1 max-h-80 overflow-y-auto"},Na={class:"min-w-0 flex-1"},Da={class:"flex items-center gap-2"},Pa={class:"truncate"},Aa={key:0,class:"text-xs text-gray-400 mt-0.5 ml-0"},Ua=re({__name:"TestCaseConsoleCard",props:{entries:{}},setup(t){function k(w){switch(w){case"error":return"error";case"warning":return"warning";case"assert":return"error";default:return"neutral"}}function h(w){switch(w){case"error":return"i-lucide-octagon-x";case"warning":return"i-lucide-alert-triangle";case"assert":return"i-lucide-octagon-x";default:return"i-lucide-message-square"}}return(w,$)=>{const g=ue,n=pe,l=ye;return t.entries.length>0?(s(),_(l,{key:0,icon:"i-lucide-terminal",title:"Console output",count:t.entries.length,help:"case.console"},{default:u(()=>[o("div",Ma,[(s(!0),a(U,null,ee(t.entries,(d,D)=>(s(),a("div",{key:D,class:"flex items-start gap-2 py-1.5 px-2 rounded hover:bg-gray-50 dark:hover:bg-gray-800 text-sm"},[r(g,{name:h(d.type),class:X([d.type==="error"||d.type==="assert"?"text-red-500":d.type==="warning"?"text-amber-500":"text-gray-400","size-4 mt-0.5 shrink-0"])},null,8,["name","class"]),o("div",Na,[o("div",Da,[r(n,{color:k(d.type),variant:"soft",size:"xs",class:"shrink-0"},{default:u(()=>[f(c(d.type),1)]),_:2},1032,["color"]),o("span",Pa,c(d.text),1)]),d.location?(s(),a("div",Aa,c(d.location),1)):i("",!0)])]))),128))])]),_:1},8,["count"])):i("",!0)}}}),Ba=Object.assign(Ua,{__name:"TestCaseConsoleCard"}),Fa={key:0,class:"space-y-4 text-sm"},Va={class:"space-y-1.5"},Ea={class:"flex items-center gap-2"},Oa={key:0,class:"text-xs text-gray-500"},Ha={class:"block text-xs break-all text-gray-700 dark:text-gray-300"},Ka={key:0,class:"text-xs text-red-600 dark:text-red-400 font-mono"},Wa={class:"flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-400"},Ga={key:0,class:"font-mono"},Ja={key:1,class:"font-mono"},qa={key:2},Qa={key:3,title:"Bytes on the wire"},Za={key:0},Xa={class:"flex h-2 rounded overflow-hidden bg-gray-100 dark:bg-gray-800"},Ya=["title"],eo={class:"flex flex-wrap gap-x-3 gap-y-1 mt-1.5 text-xs text-gray-500"},to={class:"text-xs font-medium text-gray-500 dark:text-gray-400 mb-1.5 capitalize"},so={key:0,class:"rounded border border-default divide-y divide-default max-h-48 overflow-y-auto"},no={class:"text-gray-500 dark:text-gray-400 shrink-0"},ao={class:"break-all text-gray-700 dark:text-gray-300"},oo={key:1,class:"text-xs text-gray-400"},ro={key:1},io={key:0,class:"rounded border border-default p-2"},lo=["src","alt"],co={key:1,class:"max-h-96 overflow-y-auto"},uo={key:0,class:"mt-1 text-xs text-gray-400"},mo={key:2,class:"text-xs text-gray-400"},fo={key:2,class:"text-xs text-gray-400"},go=re({__name:"TraceNetworkDrawer",props:{open:{type:Boolean},entry:{},runId:{},testRunsCaseId:{}},emits:["update:open"],setup(t,{emit:k}){const h=t,w=k,$=[{key:"dns",label:"DNS",color:"bg-sky-400"},{key:"connect",label:"Connect",color:"bg-violet-400"},{key:"ssl",label:"TLS",color:"bg-rose-400"},{key:"send",label:"Send",color:"bg-amber-400"},{key:"wait",label:"Wait",color:"bg-blue-400"},{key:"receive",label:"Receive",color:"bg-emerald-400"}],g=C(()=>{const b=h.entry?.timings;return b?$.map(v=>({...v,value:b[v.key]??-1})).filter(v=>typeof v.value=="number"&&v.value>=0):[]}),n=C(()=>g.value.reduce((b,v)=>b+v.value,0)),l=C(()=>{const b=h.entry?.requestPostData??"";return b.startsWith("{")||b.startsWith("[")}),d=A(null),D=A(!1),M=new Map;return ve(()=>[h.open,h.entry?.bodySha1],async([b,v])=>{if(d.value=null,!b||!v||!h.runId)return;const F=M.get(v);if(F){d.value=F;return}D.value=!0;try{const L=await $fetch(`/api/test-runs/${h.runId}/cases/${h.testRunsCaseId}/trace-network-body`,{query:{sha1:v}});M.set(v,L),d.value=L}catch{d.value={status:"not-found"}}finally{D.value=!1}},{immediate:!0}),(b,v)=>{const F=pe,L=Re,m=Qs,S=Ge,V=Zs;return s(),_(V,{open:t.open,title:"Request detail",ui:{content:"max-w-xl"},"onUpdate:open":v[0]||(v[0]=B=>w("update:open",B))},{body:u(()=>[t.entry?(s(),a("div",Fa,[o("div",Va,[o("div",Ea,[r(F,{color:("httpMethodColor"in b?b.httpMethodColor:e(He))(t.entry.method),variant:"soft",size:"sm",class:"font-mono shrink-0"},{default:u(()=>[f(c(t.entry.method),1)]),_:1},8,["color"]),r(F,{color:("httpStatusColor"in b?b.httpStatusColor:e(Ke))(t.entry.status),variant:"soft",size:"sm",class:"font-mono shrink-0 tabular-nums"},{default:u(()=>[f(c(t.entry.status>0?t.entry.status:"—"),1)]),_:1},8,["color"]),t.entry.statusText?(s(),a("span",Oa,c(t.entry.statusText),1)):i("",!0)]),o("code",Ha,c(t.entry.url),1),t.entry.failureText?(s(),a("p",Ka,c(t.entry.failureText),1)):i("",!0),o("div",Wa,[t.entry.resourceType?(s(),a("span",Ga,c(t.entry.resourceType),1)):i("",!0),t.entry.mimeType?(s(),a("span",Ja,c(t.entry.mimeType),1)):i("",!0),t.entry.responseBodySize!=null?(s(),a("span",qa,c(("formatBytes"in b?b.formatBytes:e(we))(t.entry.responseBodySize)),1)):i("",!0),t.entry.transferSize!=null?(s(),a("span",Qa,c(("formatBytes"in b?b.formatBytes:e(we))(t.entry.transferSize))+" transferred",1)):i("",!0),r(L,{ms:t.entry.duration},null,8,["ms"]),t.entry.duringFailure?(s(),_(F,{key:4,color:"error",variant:"subtle",size:"xs"},{default:u(()=>[...v[1]||(v[1]=[f("During failing action",-1)])]),_:1})):i("",!0)])]),e(g).length>0&&e(n)>0?(s(),a("div",Za,[v[2]||(v[2]=o("p",{class:"text-xs font-medium text-gray-500 dark:text-gray-400 mb-1.5"},"Timing",-1)),o("div",Xa,[(s(!0),a(U,null,ee(e(g),B=>(s(),a("div",{key:B.key,class:X(B.color),style:Ce({width:`${Math.max(.5,B.value/e(n)*100)}%`}),title:`${B.label}: ${("formatDuration"in b?b.formatDuration:e(Ws))(B.value)}`},null,14,Ya))),128))]),o("div",eo,[(s(!0),a(U,null,ee(e(g),B=>(s(),a("span",{key:B.key,class:"inline-flex items-center gap-1"},[o("span",{class:X(["size-2 rounded-full",B.color])},null,2),f(" "+c(B.label)+" ",1),r(L,{ms:B.value,"no-title":""},null,8,["ms"])]))),128))])])):i("",!0),(s(),a(U,null,ee(["request","response"],B=>o("div",{key:B},[o("p",to,c(B)+" headers",1),(B==="request"?t.entry.requestHeaders:t.entry.responseHeaders).length>0?(s(),a("div",so,[(s(!0),a(U,null,ee(B==="request"?t.entry.requestHeaders:t.entry.responseHeaders,I=>(s(),a("div",{key:`${B}-${I.name}`,class:"px-2 py-1 text-xs font-mono flex gap-2"},[o("span",no,c(I.name)+":",1),o("span",ao,c(I.value),1)]))),128))])):(s(),a("p",oo,"None recorded."))])),64)),t.entry.requestPostData?(s(),a("div",ro,[v[3]||(v[3]=o("p",{class:"text-xs font-medium text-gray-500 dark:text-gray-400 mb-1.5"},"Request body",-1)),r(m,{code:t.entry.requestPostData,lang:e(l)?"json":"text"},null,8,["code","lang"])])):i("",!0),o("div",null,[v[4]||(v[4]=o("p",{class:"text-xs font-medium text-gray-500 dark:text-gray-400 mb-1.5"},"Response body",-1)),e(D)?(s(),_(S,{key:0,text:"Loading body…",padded:!1})):e(d)?(s(),a(U,{key:1},[e(d).status==="ok"&&e(d).kind==="image"?(s(),a("div",io,[o("img",{src:e(d).dataUri,alt:t.entry.url,class:"max-w-full max-h-96"},null,8,lo)])):e(d).status==="ok"?(s(),a("div",co,[r(m,{code:e(d).content??"",lang:e(d).kind==="json"?"json":"text"},null,8,["code","lang"]),e(d).truncated?(s(),a("p",uo,"Preview truncated.")):i("",!0)])):(s(),a("p",mo,c(e(d).status==="too-large"?`Body too large to preview (${("formatBytes"in b?b.formatBytes:e(we))(e(d).size??0)}) — open the trace viewer to inspect it.`:e(d).status==="unsupported"?`No preview for ${e(d).mimeType||"this content type"} — open the trace viewer to inspect it.`:"Body not stored in the trace."),1))],64)):t.entry.bodySha1?i("",!0):(s(),a("p",fo,"No body captured for this request."))])])):i("",!0)]),_:1},8,["open"])}}}),po=Object.assign(go,{__name:"TraceNetworkDrawer"}),yo={class:"flex items-center justify-between gap-2 mb-2"},ho={key:0,class:"hidden sm:flex items-center gap-1.5 text-xs text-gray-400"},xo={class:"space-y-1 max-h-[28rem] overflow-y-auto"},vo=["title","onClick"],_o={class:"flex items-center gap-2 text-sm min-w-0"},ko={class:"truncate text-xs flex-1 min-w-0"},bo={key:0,class:"shrink-0 text-xs text-gray-400 font-mono hidden md:inline"},wo={key:1,class:"shrink-0 text-xs text-gray-400 tabular-nums hidden sm:inline"},$o={class:"relative h-1.5 mt-1 rounded bg-gray-100 dark:bg-gray-800 overflow-hidden"},Co={key:0,class:"mt-2 text-xs text-gray-400 dark:text-gray-500"},To=re({__name:"TraceNetworkList",props:{data:{},runId:{},testRunsCaseId:{}},setup(t){const k=t,h=A("all"),w=C(()=>k.data.requests??[]),$=C(()=>({total:w.value.length,failed:w.value.filter(S=>S.failed).length,duringFailure:w.value.filter(S=>S.duringFailure).length})),g=C(()=>[{label:`All (${$.value.total})`,value:"all"},{label:`Failed (${$.value.failed})`,value:"failed",disabled:$.value.failed===0},{label:`During failure (${$.value.duringFailure})`,value:"duringFailure",disabled:$.value.duringFailure===0}]),n=C(()=>h.value==="failed"?w.value.filter(S=>S.failed):h.value==="duringFailure"?w.value.filter(S=>S.duringFailure):w.value);function l(S){try{return new URL(S).pathname||S}catch{return S}}const d=C(()=>Math.max(1,k.data.timelineDuration??1));function D(S){const V=Math.max(0,Math.min(100,S.start/d.value*100)),B=Math.min(100-V,Math.max(1.5,S.duration/d.value*100));return{left:`${V}%`,width:`${B}%`}}const M=C(()=>{const S=k.data.failingWindow;if(!S||S.end<=S.start)return null;const V=Math.max(0,Math.min(100,S.start/d.value*100)),B=Math.max(.5,Math.min(100-V,(S.end-S.start)/d.value*100));return{left:`${V}%`,width:`${B}%`}});function b(S){return S.failed?"bg-red-500":S.duration>1e3?"bg-orange-400":"bg-gray-400 dark:bg-gray-500"}function v(S){return S.failed?"border-l-2 border-l-red-400 dark:border-l-red-600":S.duringFailure?"border-l-2 border-l-amber-400 dark:border-l-amber-600":"border-l-2 border-l-transparent"}const F=A(null),L=A(!1);function m(S){F.value=S,L.value=!0}return(S,V)=>{const B=We,I=pe,G=Re,J=po;return s(),a("div",null,[o("div",yo,[r(B,{modelValue:e(h),"onUpdate:modelValue":V[0]||(V[0]=N=>ge(h)?h.value=N:null),items:e(g),size:"xs",variant:"link",ui:{list:"gap-2",trigger:"px-1.5"}},null,8,["modelValue","items"]),t.data.failingWindow?(s(),a("span",ho,[...V[2]||(V[2]=[o("span",{class:"inline-block w-3 h-2 rounded-sm bg-red-500/10 border border-red-300 dark:border-red-800"},null,-1),f(" failing action ",-1)])])):i("",!0)]),o("div",xo,[(s(!0),a(U,null,ee(e(n),N=>(s(),a("button",{key:N.index,type:"button",class:X([v(N),"w-full rounded bg-gray-50/60 dark:bg-gray-800/40 py-1.5 px-2 text-left cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"]),title:N.url,onClick:ne=>m(N)},[o("div",_o,[r(I,{color:("httpMethodColor"in S?S.httpMethodColor:e(He))(N.method),variant:"soft",size:"xs",class:"font-mono shrink-0"},{default:u(()=>[f(c(N.method),1)]),_:2},1032,["color"]),r(I,{color:("httpStatusColor"in S?S.httpStatusColor:e(Ke))(N.status),variant:"soft",size:"xs",class:"font-mono shrink-0 tabular-nums",title:N.failureText||N.statusText},{default:u(()=>[f(c(N.status>0?N.status:"—"),1)]),_:2},1032,["color","title"]),o("code",ko,c(l(N.url)),1),N.resourceType?(s(),a("span",bo,c(N.resourceType),1)):i("",!0),N.responseBodySize!=null?(s(),a("span",wo,c(("formatBytes"in S?S.formatBytes:e(we))(N.responseBodySize)),1)):i("",!0),o("span",{class:X(["ml-1 shrink-0 text-xs tabular-nums",N.duration>1e3?"text-red-600 font-medium":N.duration>500?"text-orange-500":"text-gray-500"])},[r(G,{ms:N.duration,"unit-class":"opacity-60"},null,8,["ms"])],2)]),o("div",$o,[e(M)?(s(),a("div",{key:0,class:"absolute inset-y-0 bg-red-500/10 border-x border-red-300/60 dark:border-red-800/60",style:Ce(e(M))},null,4)):i("",!0),o("div",{class:X(["absolute inset-y-0 rounded-full",b(N)]),style:Ce(D(N))},null,6)])],10,vo))),128))]),t.data.truncated?(s(),a("p",Co," Showing the first "+c(e(w).length)+" of "+c(t.data.totalBeforeCap)+" requests recorded in the trace. ",1)):i("",!0),r(J,{open:e(L),"onUpdate:open":V[1]||(V[1]=N=>ge(L)?L.value=N:null),entry:e(F),"run-id":t.runId,"test-runs-case-id":t.testRunsCaseId},null,8,["open","entry","run-id","test-runs-case-id"])])}}}),So=Object.assign(To,{__name:"TraceNetworkList"}),Io={class:"flex flex-wrap items-center gap-x-3 gap-y-1"},Ro={key:0,class:"flex items-center gap-2 text-xs"},jo={key:0,class:"flex items-center gap-1 text-red-600 dark:text-red-400"},Lo={key:1,class:"flex items-center gap-1 text-amber-600 dark:text-amber-400"},zo={key:2,class:"text-xs text-gray-400 py-2"},Mo={key:1,class:"space-y-1 max-h-[28rem] overflow-y-auto"},No=["disabled","onClick"],Do={key:1,class:"size-3.5 shrink-0"},Po=["title"],Ao=["title"],Uo=["title"],Bo=["title"],Fo=["title"],Vo=["title"],Eo={key:0,class:"px-2 pt-1.5 pb-2 pl-7 space-y-1"},Oo={class:"flex items-center gap-1.5 text-[11px] uppercase tracking-wide text-gray-400"},Ho=["title"],Ko={key:0,class:"shrink-0 text-[10px] uppercase text-gray-400 font-mono hidden sm:inline"},Wo={class:"relative flex-1 h-3 rounded bg-gray-100 dark:bg-gray-800 min-w-0"},Go={key:1,class:"px-2 pb-2 pl-7 space-y-1.5"},Jo={class:"flex items-start gap-2"},qo={key:0,class:"text-gray-400 shrink-0 font-mono"},Qo={class:"font-mono break-all text-gray-700 dark:text-gray-300 flex-1 min-w-0"},Zo=["title"],Xo={key:0,class:"mt-1.5"},Yo=["onClick"],er={key:0,class:"mt-1 whitespace-pre-wrap break-all font-mono text-[11px] leading-relaxed text-gray-500 dark:text-gray-400 max-h-48 overflow-y-auto"},tr={key:2,class:"mt-3 flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500"},sr={key:3,class:"mt-3 flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500"},nr=re({__name:"TestCaseNetworkRequests",props:{requests:{},runId:{},testRunsCaseId:{},hasTrace:{type:Boolean}},setup(t,{expose:k}){const h=t,w=A("all"),{data:$,pending:g,load:n}=_a(()=>h.runId,()=>h.testRunsCaseId,()=>!!h.hasTrace),l=A(null),d=C({get:()=>l.value??(h.requests.length===0&&h.hasTrace?"trace":"captured"),set:x=>{l.value=x}});ve(()=>d.value==="trace",x=>{x&&n()},{immediate:!0});const D=C(()=>$.value?.status==="ok"?$.value.requests?.length??0:null),M=C(()=>[{label:`Captured (${h.requests.length})`,value:"captured",disabled:h.requests.length===0},{label:D.value!=null?`Full trace (${D.value})`:"Full trace",value:"trace"}]);function b(){h.hasTrace&&(l.value="trace")}k({showTraceMode:b});const v=A(new Set);function F(x){const T=new Set(v.value);T.has(x)?T.delete(x):T.add(x),v.value=T}const L=A(new Set);function m(x){const T=new Set(L.value);T.has(x)?T.delete(x):T.add(x),L.value=T}function S(x){if(x.length===0)return[];const T=Math.min(...x.map(H=>H.startMs)),K=Math.max(...x.map(H=>H.startMs+H.durMs)),q=Math.max(1,K-T),Q=new Map(x.map(H=>[H.id,H])),te=H=>{let Z=0,Y=H;const ae=new Set;for(;Y?.parentId&&Q.has(Y.parentId)&&!ae.has(Y.id)&&(ae.add(Y.id),Y=Q.get(Y.parentId),Z++,!(Z>8)););return Z};return[...x].sort((H,Z)=>H.startMs-Z.startMs||Z.durMs-H.durMs).map(H=>({...H,offsetPct:(H.startMs-T)/q*100,widthPct:Math.max(1.5,H.durMs/q*100),depth:te(H)}))}function V(x){return x.status==="error"?"bg-red-400 dark:bg-red-500":x.kind==="db"?"bg-violet-400 dark:bg-violet-500":x.kind==="client"?"bg-sky-400 dark:bg-sky-500":x.kind==="internal"?"bg-gray-400 dark:bg-gray-500":"bg-emerald-400 dark:bg-emerald-500"}function B(x){const T=x.toLowerCase();return T==="critical"||T==="fatal"?3:T==="error"?2:T==="warning"||T==="warn"?1:0}function I(x){const T=B(x);if(T>=2)return"error";if(T===1)return"warning";const K=x.toLowerCase();return K==="info"||K==="information"?"info":"neutral"}function G(x){try{return new URL(x).pathname||x}catch{return x}}function J(x){return(x.split("/")[1]??x).replace(/^vnd\.[^+]*\+?/,"").replace(/^x-/,"")||x}function N(x){return x?new Date(x).toLocaleString():""}const ne=C(()=>h.requests.map((x,T)=>{const K=Array.isArray(x.serverLogs)?x.serverLogs:[],q=Array.isArray(x.serverTraces)?x.serverTraces:[];let Q=0,te=0;for(const Z of K){const Y=B(Z.level);Y>=2?Q++:Y===1&&te++}const H=q.find(Z=>!Z.parentId)??q[0];return{...x,_index:T,logs:[...K].sort((Z,Y)=>Z.timestamp-Y.timestamp),spans:q,serverMs:H?H.durMs:null,errorLogCount:Q,warnLogCount:te,failed:x.status>=400,hasDetail:K.length>0||q.length>0,path:G(x.url)}})),O=C(()=>{let x=0,T=0,K=0,q=0,Q=0;for(const te of ne.value)te.failed&&x++,te.logs.length>0&&T++,te.spans.length>0&&K++,q+=te.errorLogCount,Q+=te.warnLogCount;return{total:ne.value.length,failed:x,withLogs:T,withSpans:K,errorLogs:q,warnLogs:Q}}),le=C(()=>{let x=ne.value;return w.value==="failed"?x=x.filter(T=>T.failed):w.value==="logs"&&(x=x.filter(T=>T.logs.length>0)),[...x].sort((T,K)=>{const q=Q=>(Q.errorLogCount>0?3:0)+(Q.failed?2:0)+(Q.logs.length>0?1:0);return q(K)-q(T)||T._index-K._index})}),y=C(()=>[{label:`All (${O.value.total})`,value:"all"},{label:`Failed (${O.value.failed})`,value:"failed",disabled:O.value.failed===0},{label:`With logs (${O.value.withLogs})`,value:"logs",disabled:O.value.withLogs===0}]),P=C(()=>O.value.withLogs>0);function se(x){return x.errorLogCount>0||x.status>=500?"border-l-2 border-l-red-400 dark:border-l-red-600":x.failed||x.warnLogCount>0?"border-l-2 border-l-amber-400 dark:border-l-amber-600":"border-l-2 border-l-transparent"}return(x,T)=>{const K=ue,q=We,Q=Ge,te=So,H=pe,Z=Re,Y=kt,ae=ye;return s(),_(ae,{icon:"i-lucide-network",title:"Network & backend logs",count:e(d)==="trace"?e(D):e(O).total,help:"case.network"},{actions:u(()=>[o("div",Io,[e(d)==="captured"?(s(),a(U,{key:0},[e(O).errorLogs>0||e(O).warnLogs>0?(s(),a("div",Ro,[e(O).errorLogs>0?(s(),a("span",jo,[r(K,{name:"i-lucide-octagon-alert",class:"size-3.5"}),f(c(e(O).errorLogs),1)])):i("",!0),e(O).warnLogs>0?(s(),a("span",Lo,[r(K,{name:"i-lucide-triangle-alert",class:"size-3.5"}),f(c(e(O).warnLogs),1)])):i("",!0)])):i("",!0),r(q,{modelValue:e(w),"onUpdate:modelValue":T[0]||(T[0]=z=>ge(w)?w.value=z:null),items:e(y),size:"xs",variant:"link",ui:{list:"gap-2",trigger:"px-1.5"}},null,8,["modelValue","items"])],64)):i("",!0),t.hasTrace?(s(),_(q,{key:1,modelValue:e(d),"onUpdate:modelValue":T[1]||(T[1]=z=>ge(d)?d.value=z:null),items:e(M),size:"xs",variant:"pill",ui:{list:"gap-1 p-0.5",trigger:"px-2"}},null,8,["modelValue","items"])):i("",!0)])]),default:u(()=>[e(d)==="trace"?(s(),a(U,{key:0},[e(g)||!e($)?(s(),_(Q,{key:0,text:"Parsing trace network stream…"})):e($).status==="ok"?(s(),_(te,{key:1,data:e($),"run-id":t.runId??null,"test-runs-case-id":t.testRunsCaseId??0},null,8,["data","run-id","test-runs-case-id"])):(s(),a("p",zo,"No network activity recorded in this trace."))],64)):(s(),a("div",Mo,[(s(!0),a(U,null,ee(e(le),z=>(s(),a("div",{key:z._index,class:X([se(z),"rounded bg-gray-50/60 dark:bg-gray-800/40"])},[o("button",{type:"button",class:X(["w-full flex items-center gap-2 py-1.5 px-2 text-sm text-left",z.hasDetail?"cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800":"cursor-default"]),disabled:!z.hasDetail,onClick:W=>z.hasDetail&&F(z._index)},[z.hasDetail?(s(),_(K,{key:0,name:e(v).has(z._index)?"i-lucide-chevron-down":"i-lucide-chevron-right",class:"size-3.5 shrink-0 text-gray-400"},null,8,["name"])):(s(),a("span",Do)),r(H,{color:("httpMethodColor"in x?x.httpMethodColor:e(He))(z.method),variant:"soft",size:"xs",class:"font-mono shrink-0"},{default:u(()=>[f(c(z.method),1)]),_:2},1032,["color"]),r(H,{color:("httpStatusColor"in x?x.httpStatusColor:e(Ke))(z.status),variant:"soft",size:"xs",class:"font-mono shrink-0 tabular-nums"},{default:u(()=>[f(c(z.status||"—"),1)]),_:2},1032,["color"]),o("code",{class:"truncate text-xs flex-1 min-w-0",title:z.url},c(z.path),9,Po),z.contentType?(s(),a("span",{key:2,class:"shrink-0 text-xs text-gray-400 font-mono hidden md:inline",title:`Response content type: ${z.contentType}`},c(J(z.contentType)),9,Ao)):i("",!0),z.errorLogCount>0?(s(),a("span",{key:3,class:"shrink-0 inline-flex items-center gap-1 text-xs text-red-600 dark:text-red-400",title:`${z.errorLogCount} backend error log(s)`},[r(K,{name:"i-lucide-octagon-alert",class:"size-3.5"}),f(c(z.errorLogCount),1)],8,Uo)):i("",!0),z.warnLogCount>0?(s(),a("span",{key:4,class:"shrink-0 inline-flex items-center gap-1 text-xs text-amber-600 dark:text-amber-400",title:`${z.warnLogCount} backend warning log(s)`},[r(K,{name:"i-lucide-triangle-alert",class:"size-3.5"}),f(c(z.warnLogCount),1)],8,Bo)):i("",!0),z.serverMs!=null?(s(),a("span",{key:5,class:"shrink-0 inline-flex items-center gap-1 text-xs text-emerald-600 dark:text-emerald-400 tabular-nums",title:`Server-side processing time (${z.spans.length} span${z.spans.length===1?"":"s"})`},[r(K,{name:"i-lucide-server",class:"size-3.5"}),r(Z,{ms:z.serverMs,"no-title":""},null,8,["ms"])],8,Fo)):i("",!0),z.startTime?(s(),a("span",{key:6,class:"shrink-0 text-xs text-gray-400 hidden sm:inline",title:N(z.startTime)},c(("formatRelativeTime"in x?x.formatRelativeTime:e(Se))(z.startTime)),9,Vo)):i("",!0),o("span",{class:X(["ml-1 shrink-0 text-xs tabular-nums",(z.duration??0)>1e3?"text-red-600 font-medium":(z.duration??0)>500?"text-orange-500":"text-gray-500"])},[r(Z,{ms:z.duration,"unit-class":"opacity-60"},null,8,["ms"])],2)],10,No),z.spans.length>0&&e(v).has(z._index)?(s(),a("div",Eo,[o("div",Oo,[r(K,{name:"i-lucide-waypoints",class:"size-3.5"}),T[2]||(T[2]=f("Server trace ",-1))]),(s(!0),a(U,null,ee(S(z.spans),W=>(s(),a("div",{key:W.id,class:"flex items-center gap-2 text-xs",title:W.status==="error"?`${W.name} (error)`:W.name},[o("div",{class:"w-40 sm:w-56 shrink-0 flex items-center gap-1 min-w-0",style:Ce({paddingLeft:`${W.depth*12}px`})},[W.kind?(s(),a("span",Ko,c(W.kind),1)):i("",!0),o("span",{class:X(["truncate font-mono",W.status==="error"?"text-red-600 dark:text-red-400":"text-gray-600 dark:text-gray-300"])},c(W.name),3)],4),o("div",Wo,[o("div",{class:X(["absolute top-0 h-3 rounded",V(W)]),style:Ce({left:`${W.offsetPct}%`,width:`${W.widthPct}%`})},null,6)]),r(Z,{ms:W.durMs,class:"w-12 shrink-0 text-right text-gray-500"},null,8,["ms"])],8,Ho))),128))])):i("",!0),z.logs.length>0&&e(v).has(z._index)?(s(),a("div",Go,[(s(!0),a(U,null,ee(z.logs,(W,he)=>(s(),a("div",{key:he,class:"rounded border border-default bg-white dark:bg-gray-900/60 p-2 text-xs"},[o("div",Jo,[r(H,{color:I(W.level),variant:"soft",size:"xs",class:"shrink-0 capitalize"},{default:u(()=>[f(c(W.level),1)]),_:2},1032,["color"]),W.category?(s(),a("span",qo,"["+c(W.category)+"]",1)):i("",!0),o("span",Qo,c(W.message),1),W.timestamp?(s(),a("span",{key:1,class:"shrink-0 text-gray-400 tabular-nums",title:N(W.timestamp)},c(("formatRelativeTime"in x?x.formatRelativeTime:e(Se))(W.timestamp)),9,Zo)):i("",!0)]),W.stack?(s(),a("div",Xo,[o("button",{type:"button",class:"inline-flex items-center gap-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200",onClick:Je=>m(`${z._index}:${he}`)},[r(K,{name:e(L).has(`${z._index}:${he}`)?"i-lucide-chevron-down":"i-lucide-chevron-right",class:"size-3"},null,8,["name"]),T[3]||(T[3]=f(" Stack trace ",-1))],8,Yo),e(L).has(`${z._index}:${he}`)?(s(),a("pre",er,c(W.stack),1)):i("",!0)])):i("",!0)]))),128))])):i("",!0)],2))),128))])),e(d)==="captured"&&!e(P)?(s(),a("p",tr,[r(K,{name:"i-lucide-info",class:"size-3.5 shrink-0"}),T[5]||(T[5]=f(" No backend server logs captured — install ",-1)),r(Y,{to:"backend-logs","no-icon":"",class:"underline"},{default:u(()=>[...T[4]||(T[4]=[f("a Piwi backend integration",-1)])]),_:1}),T[6]||(T[6]=f(" to see server-side warnings and errors under each request. ",-1))])):i("",!0),t.hasTrace?i("",!0):(s(),a("p",sr,[r(K,{name:"i-lucide-info",class:"size-3.5 shrink-0"}),o("span",null,[T[8]||(T[8]=f(" Want to go deeper? Record traces (",-1)),T[9]||(T[9]=o("code",null,"trace: 'retain-on-failure'",-1)),T[10]||(T[10]=f(") to see every request with headers, timing and bodies here. ",-1)),r(Y,{to:"ui-overview#trace-powered-deep-views","no-icon":"",class:"underline"},{default:u(()=>[...T[7]||(T[7]=[f("Learn more",-1)])]),_:1})])]))]),_:1},8,["count"])}}}),ar=Object.assign(nr,{__name:"TestCaseNetworkRequests"}),or={class:"space-y-2"},rr=re({__name:"TestCaseTracesCard",props:{traces:{}},setup(t){return(k,h)=>{const w=gs,$=ye;return t.traces.length>0?(s(),_($,{key:0,icon:"i-lucide-bug-play",title:"Traces",count:t.traces.length,help:"case.traces"},{default:u(()=>[o("div",or,[(s(!0),a(U,null,ee(t.traces,g=>(s(),_(w,{key:g.id,trace:g,class:"py-2 px-3 rounded-lg border"},null,8,["trace"]))),128))])]),_:1},8,["count"])):i("",!0)}}}),ir=Object.assign(rr,{__name:"TestCaseTracesCard"}),lr={class:"space-y-3"},cr={class:"flex items-center justify-between px-3 py-2 bg-gray-50 dark:bg-gray-800/50 border-b"},ur={class:"flex items-center gap-2 min-w-0"},dr={class:"text-sm font-medium truncate"},mr={key:0,class:"text-xs text-gray-400 shrink-0"},fr={class:"text-xs text-gray-400"},gr={class:"flex items-center gap-1 shrink-0"},pr=["href"],yr={key:0,class:"bg-gray-100 dark:bg-gray-900"},hr=["src","alt","onClick"],xr={key:1,class:"bg-black"},vr={key:2,class:"bg-gray-50 dark:bg-gray-900"},_r={key:0,class:"flex items-center justify-center py-8"},kr={key:1,class:"p-4 text-red-500 text-sm"},br={key:2,class:"p-4 overflow-auto max-h-96"},wr={class:"text-sm whitespace-pre-wrap font-sans leading-relaxed"},$r=re({__name:"TestCaseAttachmentsCard",props:{attachments:{}},setup(t){const k=t,h=Ee(),w=A(null),$=C(()=>k.attachments.filter(I=>Te(I.path,I.contentType)).map(I=>({src:M(I.path,I.contentType),name:I.name||b(I.path)})));function g(I){w.value=I}const n=new Set([".md",".mdx",".markdown"]),l=new Set(["text/markdown","text/x-markdown"]);function d(I){return I.toLowerCase().split(".").pop()||""}function D(I,G){return!!(n.has(d(I))||G&&l.has(G.toLowerCase()))}function M(I,G){return wt(I,G,h.app?.baseURL)}function b(I){return I.split("/").pop()||I}function v(I){return I==null?"":we(I)}const F=A({}),L=A({}),m=A({}),S=A(new Set);async function V(I){if(F.value[I.id]===void 0&&!m.value[I.id]){m.value[I.id]=!0,L.value[I.id]=null;try{const G=await $fetch(M(I.path,I.contentType),{responseType:"text"});F.value[I.id]=G}catch{L.value[I.id]="Failed to load preview"}finally{m.value[I.id]=!1}}}function B(I,G){const J=new Set(S.value);J.has(I)?J.delete(I):(J.add(I),V(G)),S.value=J}return(I,G)=>{const J=ue,N=Ie,ne=ps,O=ys,le=ye;return t.attachments.length>0?(s(),_(le,{key:0,icon:"i-lucide-paperclip",title:"Attachments",count:t.attachments.length},{default:u(()=>[o("div",lr,[(s(!0),a(U,null,ee(t.attachments,y=>(s(),a("div",{key:y.id,class:"rounded-lg border overflow-hidden"},[o("div",cr,[o("div",ur,[r(J,{name:e(Te)(y.path,y.contentType)?"i-lucide-image":e(De)(y.path,y.contentType)?"i-lucide-video":D(y.path,y.contentType)?"i-lucide-file-text":"i-lucide-file",class:"size-4 text-gray-400 shrink-0"},null,8,["name"]),o("span",dr,c(b(y.path)),1),y.name&&y.name!==b(y.path)?(s(),a("span",mr,c(y.name),1)):i("",!0),o("span",fr,c(v(y.size)),1)]),o("div",gr,[D(y.path,y.contentType)?(s(),_(N,{key:0,size:"xs",color:"neutral",variant:"soft",onClick:P=>B(y.id,y)},{default:u(()=>[f(c(e(S).has(y.id)?"Hide preview":"Preview"),1)]),_:2},1032,["onClick"])):i("",!0),o("a",{href:M(y.path,y.contentType),target:"_blank",class:"text-primary hover:underline text-xs shrink-0"},"Open",8,pr)])]),e(Te)(y.path,y.contentType)?(s(),a("div",yr,[o("img",{src:M(y.path,y.contentType),alt:y.name||"Screenshot",class:"max-w-full max-h-96 object-contain mx-auto cursor-pointer hover:opacity-90 transition-opacity",loading:"lazy",onClick:P=>g(e($).findIndex(se=>se.src===M(y.path,y.contentType)))},null,8,hr)])):e(De)(y.path,y.contentType)?(s(),a("div",xr,[r(ne,{src:M(y.path,y.contentType)},null,8,["src"])])):D(y.path,y.contentType)&&e(S).has(y.id)?(s(),a("div",vr,[e(m)[y.id]?(s(),a("div",_r,[r(J,{name:"i-lucide-loader-circle",class:"size-5 animate-spin text-gray-400"})])):e(L)[y.id]?(s(),a("div",kr,c(e(L)[y.id]),1)):e(F)[y.id]?(s(),a("div",br,[o("pre",wr,c(e(F)[y.id]),1)])):i("",!0)])):i("",!0)]))),128))]),r(O,{modelValue:e(w),"onUpdate:modelValue":G[0]||(G[0]=y=>ge(w)?w.value=y:null),images:e($)},null,8,["modelValue","images"])]),_:1},8,["count"])):i("",!0)}}}),Cr=Object.assign($r,{__name:"TestCaseAttachmentsCard"});function Tr(t){return Array.isArray(t)?t.some(k=>k&&typeof k.type=="string"&&k.type.toLowerCase()==="slow"):!1}function Sr(t){const k=[];if(!t)return k;const h=t.steps||[],$=h.filter(n=>n.category==="navigation").filter(n=>n.duration>3e3);if($.length>0){const n=$.sort((l,d)=>d.duration-l.duration)[0];k.push({type:"warning",message:"Slow navigation detected",details:`"${n.title}" took ${(n.duration/1e3).toFixed(1)}s. The tested page may have performance issues (slow server response, heavy JS bundles, etc.).`})}h.length>20&&k.push({type:"info",message:"Many sequential actions",details:`This test has ${h.length} steps. Consider splitting it into smaller, focused tests for better isolation and faster feedback.`}),t.status==="passed"&&(t.retries||0)>0&&k.push({type:"warning",message:"Flaky test — passed after retries",details:`This test needed ${t.retries} ${t.retries===1?"retry":"retries"} to pass. Consider reviewing locator strategies, adding explicit waits, or checking for race conditions.`});const g=h.filter(n=>n.category==="assertion"&&n.duration>2e3);if(g.length>0){const n=g.sort((l,d)=>d.duration-l.duration)[0];k.push({type:"info",message:"Slow assertions detected",details:`"${n.title}" took ${(n.duration/1e3).toFixed(1)}s. The UI may be slow to render or the assertion timeout may need tuning.`})}return Tr(t.testAnnotations)&&typeof t.duration=="number"&&t.duration<1e4&&k.push({type:"info",message:"test.slow() may be unnecessary",details:`This run finished in ${(t.duration/1e3).toFixed(1)}s, yet the test is marked test.slow(), which triples its timeout budget. If it is consistently this fast, removing test.slow() lets a failure surface sooner.`}),typeof t.timeout=="number"&&t.timeout>0&&typeof t.duration=="number"&&t.duration>0&&t.timeout>=4*t.duration&&t.timeout-t.duration>=3e4&&k.push({type:"info",message:"Oversized timeout",details:`The timeout is ${(t.timeout/1e3).toFixed(0)}s but this run took ${(t.duration/1e3).toFixed(1)}s. A large timeout means a hang or failure waits far longer than necessary — consider lowering it toward the test's real duration.`}),k}function Ir(t,k){const h=t.search(/\n at /);if(h===-1)return k!==void 0&&t.length>k?t.slice(0,k)+`
4
- [truncated]`:t;const w=t.slice(0,h),g=t.slice(h).split(`
5
- `),n=[];let l=0;const d=()=>{l>0&&(n.push(`… (${l} internal frame${l>1?"s":""})`),l=0)};for(const M of g){const b=M.trimStart();b.startsWith("at ")?M.includes("node_modules")||b.startsWith("at node:")?l++:(d(),n.push(M)):(b===""||d(),n.push(M))}d();let D=w+`
6
- `+n.join(`
7
- `);return k!==void 0&&D.length>k&&(D=D.slice(0,k)+`
8
- [truncated]`),D}const Rr={class:"space-y-4"},jr=["innerHTML"],Lr={class:"grid grid-cols-1 xl:grid-cols-[3fr_2fr] gap-4"},zr={class:"space-y-4 xl:order-2"},Mr={class:"space-y-4 xl:order-1 min-w-0"},Nr={class:"max-h-96 overflow-y-auto"},Dr={class:"space-y-3"},Pr={key:0},Ar={class:"flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs mb-3"},Ur={class:"font-medium text-gray-600 dark:text-gray-300"},Br={class:"tabular-nums text-gray-500 dark:text-gray-400"},Fr={class:"text-xs tabular-nums text-gray-400 dark:text-gray-500"},Vr={key:0,class:"inline-flex items-center justify-center size-5 rounded-full bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400 text-xs leading-none",title:"Step failed"},Er={key:1,class:"inline-flex items-center justify-center size-5 rounded-full bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 text-xs leading-none",title:"Step passed"},Or={class:"flex items-center gap-2"},Hr={key:0,class:"text-xs text-red-500 mt-1 whitespace-pre-wrap break-words font-mono"},Kr={class:"min-w-[6rem]"},Wr={class:"flex items-center justify-between gap-2"},Gr={key:0,class:"text-xs tabular-nums text-gray-400 dark:text-gray-500"},Jr={class:"relative mt-1 h-1.5 w-full overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800"},qr={class:"space-y-4 pt-4"},Qr={key:3,class:"flex flex-col items-center justify-center py-12 text-gray-400"},Zr={class:"space-y-4 pt-1"},Xr={key:0,class:"space-y-2"},Yr={class:"flex items-start gap-2"},ei={class:"space-y-4"},ti={key:3,class:"text-xs text-gray-400 pt-1"},si={class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},ni={class:"space-y-4 pt-4"},ai={key:0,class:"space-y-4"},oi={class:"flex items-center justify-end"},ri={class:"text-xs whitespace-nowrap"},ii={class:"text-gray-500"},li={class:"text-gray-400 ml-1"},ci={key:1,class:"text-gray-400"},ui=["title"],fl=re({__name:"[id]",async setup(t){let k,h;const w=ns(),$=as(),g=w.params.id,{data:n,refresh:l}=([k,h]=mt(()=>gt(`/api/test-run-cases/${g}`,"$rX1OuZQOSq")),k=await k,h(),k),d=A([]);ve(()=>n.value?.testCaseId,async p=>{if(p)try{d.value=await $fetch(`/api/test-cases/${p}/history`)}catch{d.value=[]}else d.value=[]},{immediate:!0});const{data:D,refresh:M}=([k,h]=mt(()=>gt(`/api/test-run-cases/${g}/traces`,"$bq3dlhiM5e")),k=await k,h(),k),b=C(()=>(D.value?.length??0)>0);os(C(()=>({title:n.value?.title?`${n.value.title} — execution — Piwi Dashboard`:`Execution #${g} — Piwi Dashboard`})));const v=C(()=>!!n.value?.error),F=C(()=>n.value?Sr(n.value):[]),L=C(()=>n.value?.steps?n.value.steps:[]),m=C(()=>n.value?.webVitals??null),S=C(()=>n.value?.networkRequests??[]),V=C(()=>{if(!d.value||d.value.length<2||!n.value?.duration)return null;const p=d.value.filter(ce=>ce.duration!==null&&ce.id!==n.value?.id);if(p.length===0)return null;const R=p.reduce((ce,fe)=>ce+(fe.duration||0),0)/p.length,E=n.value.duration,oe=E-R,me=R>0?Math.round(oe/R*100):0;return{avg:Math.round(R),current:E,diff:Math.round(oe),pct:me}}),B=C(()=>n.value?.testRun?.metadata),I=C(()=>{const p=B.value;return p?.scm?p.scm:null}),G=C(()=>{const p=B.value;return p?.ci?p.ci:null}),J=C(()=>n.value?.failureCluster??null),N=C(()=>{const p=[];return v.value&&p.push({label:"Diagnosis",icon:"i-lucide-stethoscope",value:"diagnosis",slot:"diagnosis"}),p.push({label:`Steps (${L.value.length})`,icon:"i-lucide-list-checks",value:"steps",slot:"steps"}),v.value||p.push({label:"Artifacts",icon:"i-lucide-paperclip",value:"artifacts",slot:"artifacts"}),p.push({label:"Performance",icon:"i-lucide-gauge",value:"performance",slot:"performance"}),p.push({label:`History${d.value?.length?` (${d.value.length})`:""}`,icon:"i-lucide-trending-up",value:"history",slot:"history"}),p}),ne=C(()=>N.value.map(p=>p.value));function O(){return v.value?"diagnosis":"steps"}function le(p){let R=typeof p=="string"?p:"";return R==="error"&&(R="diagnosis"),R==="traces"&&(R=v.value?"diagnosis":"artifacts"),ne.value.includes(R)?R:O()}const y=A(le(w.query.tab));ve(ne,p=>{p.includes(y.value)||(y.value=le(w.query.tab))}),ve(y,p=>{w.query.tab!==p&&$.replace({query:{...w.query,tab:p}})},{immediate:!0});const P=[{accessorKey:"startTime",header:"Date"},{accessorKey:"status",header:"Status"},{accessorKey:"duration",header:"Duration"},{accessorKey:"retries",header:"Retries"},{accessorKey:"runId",header:"Run"},{accessorKey:"error",header:"Error"}],se={navigation:"info",assertion:"success",action:"warning",input:"warning",api:"info",wait:"neutral",hook:"neutral",fixture:"neutral"},x=[{id:"index",header:"#",meta:{class:{th:"w-12",td:"w-12"}}},{id:"status",header:"",meta:{class:{th:"w-10",td:"w-10"}}},{accessorKey:"category",header:"Category",meta:{class:{th:"w-28",td:"w-28"}}},{accessorKey:"title",header:"Step"},{accessorKey:"duration",header:"Duration",meta:{class:{th:"w-44",td:"w-44"}}}],T=C(()=>{const p=new Map;for(const R of L.value){const E=p.get(R.category)??{count:0,duration:0};E.count+=1,E.duration+=R.duration||0,p.set(R.category,E)}return Array.from(p,([R,E])=>({category:R,...E})).sort((R,E)=>E.duration-R.duration)}),K=C(()=>{let p=-1,R=-1;return L.value.forEach((E,oe)=>{(E.duration||0)>R&&(R=E.duration||0,p=oe)}),p}),q=C(()=>L.value.reduce((p,R)=>Math.max(p,R.duration||0),0)),Q=C(()=>L.value.length>0&&L.value.every(p=>typeof p.startTime=="number")),te=C(()=>n.value?.startedAt??(Q.value?Math.min(...L.value.map(p=>p.startTime)):0)),H=C(()=>{const p=n.value?.duration??0;if(p>0)return p;if(Q.value){const R=Math.max(...L.value.map(E=>E.startTime+(E.duration||0)));return Math.max(1,R-te.value)}return 0});function Z(p){if(Q.value&&H.value>0){const E=Math.max(0,Math.min(100,(p.startTime-te.value)/H.value*100)),oe=Math.min(100-E,Math.max(1.5,(p.duration||0)/H.value*100));return{left:`${E}%`,width:`${oe}%`}}return{left:"0%",width:`${q.value>0?Math.max(2,(p.duration||0)/q.value*100):0}%`}}function Y(p){const R=n.value?.duration??0;if(R<=0)return"";const E=p/R*100;return E>0&&E<1?"<1%":`${Math.round(E)}%`}function ae(p){return p>2e3?"text-red-600 font-medium":p>500?"text-orange-500":"text-gray-500"}function z(p){return p>2e3?"bg-red-500":p>500?"bg-orange-400":"bg-gray-400 dark:bg-gray-500"}const W=C(()=>n.value?.testRun?.environment),he=C(()=>[{filePath:n.value?.filePath??"",title:n.value?.title??"",line:n.value?.line??null,projectName:n.value?.browser?.projectName??null}]),Je=C(()=>sn(he.value)),{copy:St,copied:qe}=nn(),It=C(()=>[{label:qe.value?"Copied":"Retry command",icon:qe.value?"i-lucide-check":"i-lucide-play",onClick:()=>St(Je.value,{toast:"Retry command copied"})},{label:"Refresh",icon:"i-lucide-refresh-cw",onClick:()=>l()}]),Rt=!!Ee().public.demoMode;let xe=null;const Qe=C(()=>{const p=n.value?.testRun?.status;return p==="running"||p==="finalizing"});function jt(){if(Rt||xe)return;const p=n.value?.testRun?.id;p&&(xe=new EventSource(`/api/test-runs/${p}/stream`),xe.onmessage=R=>{try{const E=JSON.parse(R.data);E.type==="case-files"&&E.data?.testRunsCaseId===Number(g)?(l(),M()):E.type==="run-finished"&&(l(),M(),Ae())}catch{}},xe.onerror=()=>{})}function Ae(){xe&&(xe.close(),xe=null)}ve(Qe,p=>{p?jt():Ae()},{immediate:!0}),rs(Ae);const{copyRich:Lt,copied:Ze}=hs();function zt(){const p=n.value;if(!p?.error)return;const R=window.location.origin,E=p.title??"Unknown test",oe=p.location??"",me=p.error.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,""),ce=be=>be.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),fe=J.value?`${R}/failure-clusters/${J.value.id}`:null,Me=`${R}/test-run-cases/${g}?tab=diagnosis`,ke=n.value?.testCaseId?`${R}/test-cases/${n.value.testCaseId}`:null,Be=[`❌ Test failed: ${E}`,oe?`Location: ${oe}`:null,"","Error:",me,"",fe?`Failure cluster: ${fe}`:null,`Execution: ${Me}`,ke?`History: ${ke}`:null].filter(be=>be!==null).join(`
9
- `),Fe=[`<p><strong>❌ Test failed: ${ce(E)}</strong>${oe?`<br><code>${ce(oe)}</code>`:""}</p>`,`<p><strong>Error:</strong></p><pre>${ft(p.error)}</pre>`,`<p>🔗 ${fe?`<a href="${fe}">View failure cluster</a> · `:""}<a href="${Me}">Execution details</a>${ke?` · <a href="${ke}">Test history</a>`:""}</p>`].join("");Lt(Be,Fe,{toast:"Failure copied"})}const Ue=A(null),Xe=A(null),je=A(null),Le=A(null),Ye=A(null),ze=A(null),et=A(null),tt=A(null),st=A(null),nt=A(null);function _e(p){p?.scrollIntoView({behavior:"smooth",block:"start"})}const at={sampleError:()=>_e(Ue.value),executionError:()=>_e(Ue.value),testSource:()=>Le.value?.reveal(),sourceFiles:()=>Le.value?.reveal(),environmentDiff:()=>et.value?.reveal(),visualDiff:()=>tt.value?.reveal(),domSnapshot:()=>st.value?.reveal(),ariaSnapshot:()=>nt.value?.reveal(),screenshots:()=>ze.value?.reveal(),tracePointers:()=>ze.value?.reveal(),artifacts:()=>ze.value?.reveal(),console:()=>_e(Xe.value),networkRequests:()=>_e(je.value),serverTraces:()=>_e(je.value),traceCallStack:()=>Le.value?.reveal(),traceNetwork:()=>{Ye.value?.showTraceMode(),_e(je.value)},steps:()=>{y.value="steps"},failingSteps:()=>{y.value="steps"}};return is(Es,{canLocate:p=>p in at,open:p=>at[p]?.()}),(p,R)=>{const E=Yt,oe=es,me=ue,ce=Pe,fe=ws,Me=$s,ke=Cs,Be=Ss,Fe=Vn,be=Ie,Mt=$t,ot=ye,Nt=qn,Dt=ia,Pt=xa,At=Ca,Ut=za,Bt=vs,Ft=_s,Vt=ks,rt=Ba,it=ar,lt=xs,Et=bt,Ot=Oe,Ht=bs,Ne=pe,ie=Re,Kt=ht,ct=Xs,ut=Ys,dt=en,Wt=ir,Gt=Cr,de=xt,Ve=vt,Jt=Ct,qt=tn,Qt=Ls,Zt=Ts;return s(),_(Zt,{id:"test-run-case-detail"},{header:u(()=>[r(Be,null,{leading:u(()=>[r(E),r(oe,{items:[{label:"Home",icon:"i-lucide-house",to:"/"},{label:"Projects",to:"/projects"},...e(n)?.testRun?.project?.id?[{label:e(n).testRun.project.name||"Project",to:`/projects/${e(n).testRun.project.id}`}]:[{label:"Project"}],...e(n)?.testRun?.id?[{label:`Run #${e(n).testRun.id}`+(e(n).testRun.label?` — ${e(n).testRun.label}`:""),to:`/test-runs/${e(n).testRun.id}`}]:[{label:"Test run"}],{label:e(n)?.title||`Execution #${e(g)}`}]},null,8,["items"])]),right:u(()=>[e(n)?.testCaseId?(s(),_(ce,{key:0,to:`/test-cases/${e(n).testCaseId}`,class:"text-xs text-gray-500 hover:text-primary mr-2 flex items-center gap-1",title:"View test case evolution and history"},{default:u(()=>[r(me,{name:"i-lucide-trending-up",class:"size-3.5"}),R[2]||(R[2]=o("span",{class:"hidden sm:inline"},"Evolution",-1))]),_:1},8,["to"])):i("",!0),e(n)?(s(),_(fe,{key:1,endpoint:`/api/test-run-cases/${e(n).id}/export`,"base-name":`piwi-execution-${e(n).id}`,class:"mr-2"},null,8,["endpoint","base-name"])):i("",!0),r(Me,{"project-id":e(n)?.testRun?.project?.id,"project-label":e(n)?.testRun?.project?.label??e(n)?.testRun?.project?.name,cases:e(he),class:"mr-2"},null,8,["project-id","project-label","cases"]),r(ke,{actions:e(It)},null,8,["actions"])]),_:1})]),body:u(()=>[r(Qt,{modelValue:e(y),"onUpdate:modelValue":R[1]||(R[1]=j=>ge(y)?y.value=j:null),"tab-items":e(N)},{summary:u(()=>[r(Fe,{"test-case":e(n)??null,"scm-info":e(I),"ci-info":e(G),browser:e(n)?.browser??null,environment:e(W),"steps-count":e(L).length,"historical-timing":e(V),"stable-links":e(n)?.stableLinks??null,"project-key":e(n)?.testRun?.project?.id,"project-name":e(n)?.testRun?.project?.name,onRefresh:R[0]||(R[0]=j=>e(l)())},null,8,["test-case","scm-info","ci-info","browser","environment","steps-count","historical-timing","stable-links","project-key","project-name"])]),"tab-diagnosis":u(()=>[o("div",Rr,[o("div",{ref_key:"errorEl",ref:Ue,class:"scroll-mt-4"},[e(n)?.error?(s(),_(ot,{key:0,icon:"i-lucide-circle-x","icon-class":"text-red-500",title:"Error"},{actions:u(()=>[r(Mt,{text:e(Ze)?"Copied!":"Copy failure"},{default:u(()=>[r(be,{size:"xs",variant:"ghost",color:"neutral",icon:e(Ze)?"i-lucide-check":"i-lucide-clipboard",onClick:zt},null,8,["icon"])]),_:1},8,["text"])]),default:u(()=>[o("div",{class:"text-xs font-mono whitespace-pre-wrap break-words max-h-96 overflow-y-auto rounded bg-red-50 dark:bg-red-950/20 p-3",innerHTML:e(ft)(e(Ir)(e(n).error))},null,8,jr)]),_:1})):i("",!0)],512),o("div",Lr,[o("div",zr,[r(Nt,{"test-case":e(n)??null,history:e(d),"current-id":Number(e(g))},null,8,["test-case","history","current-id"]),e(J)?(s(),_(Dt,{key:0,cluster:e(J)},null,8,["cluster"])):i("",!0),r(Pt,{"test-runs-case-id":Number(e(g))},null,8,["test-runs-case-id"])]),o("div",Mr,[e(n)?.testSourceFrames?.length||e(n)?.testSource||e(b)?(s(),_(At,{key:0,ref_key:"testSourceCard",ref:Le,"storage-key":"case-test-source",frames:e(n)?.testSourceFrames??null,"test-source":e(n)?.testSource??null,"run-id":e(n)?.testRun?.id??null,"test-runs-case-id":Number(e(g)),"has-trace":e(b),"project-key":e(n)?.testRun?.project?.id,"project-name":e(n)?.testRun?.project?.name},null,8,["frames","test-source","run-id","test-runs-case-id","has-trace","project-key","project-name"])):i("",!0),r(Ut,{ref_key:"evidenceCard",ref:ze,"storage-key":"case-evidence",attachments:e(n)?.attachments??[],traces:e(D)??[]},null,8,["attachments","traces"]),e(n)?.testRun?.id?(s(),_(Bt,{key:1,"storage-key":"case-locators","run-id":e(n).testRun.id,"test-runs-case-id":Number(e(g))},null,8,["run-id","test-runs-case-id"])):i("",!0),e(n)?.testRun?.id?(s(),_(Ft,{key:2,ref_key:"envDiffCard",ref:et,"storage-key":"case-env-diff","run-id":e(n).testRun.id,"test-runs-case-id":Number(e(g))},null,8,["run-id","test-runs-case-id"])):i("",!0),e(n)?.testRun?.id?(s(),_(Vt,{key:3,ref_key:"visualDiffCard",ref:tt,"storage-key":"case-visual-diff","run-id":e(n).testRun.id,"test-runs-case-id":Number(e(g))},null,8,["run-id","test-runs-case-id"])):i("",!0),e(n)?.consoleLogs?.length?(s(),a("div",{key:4,ref_key:"consoleEl",ref:Xe,class:"scroll-mt-4"},[r(rt,{entries:e(n)?.consoleLogs??[]},null,8,["entries"])],512)):i("",!0),e(S).length>0||e(b)?(s(),a("div",{key:5,ref_key:"networkEl",ref:je,class:"scroll-mt-4"},[r(it,{ref_key:"networkCard",ref:Ye,requests:e(S),"run-id":e(n)?.testRun?.id??null,"test-runs-case-id":Number(e(g)),"has-trace":e(b)},null,8,["requests","run-id","test-runs-case-id","has-trace"])],512)):i("",!0),e(n)?.pageState?(s(),_(lt,{key:6,"storage-key":"case-page-state","page-state":e(n).pageState},null,8,["page-state"])):i("",!0),e(n)?.ariaSnapshot?(s(),_(Ot,{key:7,ref_key:"ariaCard",ref:nt,"storage-key":"case-aria",icon:"i-lucide-scan-text",title:"ARIA snapshot",help:"case.aria"},{folded:u(()=>[...R[3]||(R[3]=[f("Accessibility tree captured at the moment of failure",-1)])]),default:u(()=>[o("div",Nr,[r(Et,{text:"```yaml\n"+e(n).ariaSnapshot+"\n```"},null,8,["text"])])]),_:1},512)):i("",!0),e(n)?.testRun?.id?(s(),_(Ht,{key:8,ref_key:"domSnapshotCard",ref:st,"storage-key":"case-dom-snapshot","run-id":e(n).testRun.id,"test-runs-case-id":Number(e(g))},null,8,["run-id","test-runs-case-id"])):i("",!0)])])])]),"tab-steps":u(()=>[o("div",Dr,[e(L).length>0?(s(),a("div",Pr,[o("div",Ar,[o("span",Ur,c(e(L).length)+" steps",1),R[4]||(R[4]=o("span",{class:"text-gray-300 dark:text-gray-600"},"·",-1)),(s(!0),a(U,null,ee(e(T),j=>(s(),a("span",{key:j.category,class:"inline-flex items-center gap-1"},[r(Ne,{color:se[j.category]||"neutral",variant:"soft",size:"xs"},{default:u(()=>[f(c(j.category),1)]),_:2},1032,["color"]),o("span",Br,[f("×"+c(j.count)+" · ",1),r(ie,{ms:j.duration},null,8,["ms"])])]))),128))]),r(ut,{"min-width":"40rem",bleed:!1},{default:u(()=>[r(ct,{data:e(L),columns:x,ui:{base:"table-fixed w-full border-separate border-spacing-0 min-w-[40rem]",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default align-top"}},{"index-cell":u(({row:j})=>[o("span",Fr,c(j.index+1),1)]),"status-cell":u(({row:j})=>[j.original.failed?(s(),a("span",Vr,"✗")):(s(),a("span",Er,"✓"))]),"category-cell":u(({row:j})=>[r(Ne,{color:se[j.original.category]||"neutral",variant:"soft",size:"xs"},{default:u(()=>[f(c(j.original.category),1)]),_:2},1032,["color"])]),"title-cell":u(({row:j})=>[o("div",Or,[o("span",{class:X(j.original.failed?"text-red-600 dark:text-red-400 font-medium":"")},c(j.original.title),3),j.index===e(K)?(s(),_(Ne,{key:0,color:"warning",variant:"subtle",size:"xs",class:"shrink-0",title:"Slowest step in this test"},{default:u(()=>[...R[5]||(R[5]=[f(" slowest ",-1)])]),_:1})):i("",!0)]),j.original.failed&&j.original.error?.message?(s(),a("p",Hr,c(j.original.error.message),1)):i("",!0),j.original.location?(s(),_(Kt,{key:1,location:j.original.location,"project-key":e(n)?.testRun?.project?.id,"project-name":e(n)?.testRun?.project?.name,class:"text-xs text-gray-400 dark:text-gray-500 mt-0.5"},null,8,["location","project-key","project-name"])):i("",!0)]),"duration-cell":u(({row:j})=>[o("div",Kr,[o("div",Wr,[r(ie,{ms:j.original.duration,class:X(`text-sm ${ae(j.original.duration)}`),"unit-class":"opacity-60"},null,8,["ms","class"]),Y(j.original.duration)?(s(),a("span",Gr,c(Y(j.original.duration)),1)):i("",!0)]),o("div",Jr,[o("div",{class:X(["absolute inset-y-0 rounded-full",z(j.original.duration)]),style:Ce(Z(j.original))},null,6)])])]),_:1},8,["data"])]),_:1})])):(s(),_(dt,{key:1,icon:"i-lucide-list-checks",text:"No steps recorded for this execution"}))])]),"tab-artifacts":u(()=>[o("div",qr,[r(Wt,{traces:e(D)||[]},null,8,["traces"]),r(Gt,{attachments:e(n)?.attachments??[]},null,8,["attachments"]),e(n)?.pageState?(s(),_(lt,{key:0,"storage-key":"case-page-state","page-state":e(n).pageState},null,8,["page-state"])):i("",!0),e(n)?.consoleLogs?.length?(s(),_(rt,{key:1,entries:e(n)?.consoleLogs??[]},null,8,["entries"])):i("",!0),e(S).length>0||e(b)?(s(),_(it,{key:2,requests:e(S),"run-id":e(n)?.testRun?.id??null,"test-runs-case-id":Number(e(g)),"has-trace":e(b)},null,8,["requests","run-id","test-runs-case-id","has-trace"])):i("",!0),!e(D)?.length&&!e(n)?.attachments?.length&&!e(n)?.consoleLogs?.length&&!e(S).length?(s(),a("div",Qr,[e(Qe)?(s(),a(U,{key:0},[r(me,{name:"i-lucide-loader-circle",class:"size-8 mb-2 animate-spin"}),R[6]||(R[6]=o("p",{class:"text-sm"}," Run in progress — traces and attachments appear here as soon as they are uploaded. ",-1))],64)):(s(),a(U,{key:1},[r(me,{name:"i-lucide-inbox",class:"size-8 mb-2"}),R[7]||(R[7]=o("p",{class:"text-sm"},"No traces, console logs, or network requests captured for this test case.",-1))],64))])):i("",!0)])]),"tab-performance":u(()=>[o("div",Zr,[e(F).length>0?(s(),a("div",Xr,[(s(!0),a(U,null,ee(e(F),(j,Xt)=>(s(),a("div",{key:Xt,class:X(["p-3 rounded-lg border",j.type==="warning"?"bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800":"bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800"])},[o("div",Yr,[r(me,{name:j.type==="warning"?"i-lucide-alert-triangle":"i-lucide-lightbulb",class:X([j.type==="warning"?"text-amber-600":"text-blue-600","size-4 mt-0.5 shrink-0"])},null,8,["name","class"]),o("div",null,[o("p",{class:X(j.type==="warning"?"text-amber-800 dark:text-amber-200 font-medium":"text-blue-800 dark:text-blue-200 font-medium")},c(j.message),3),o("p",{class:X([j.type==="warning"?"text-amber-700 dark:text-amber-300":"text-blue-700 dark:text-blue-300","mt-1"])},c(j.details),3)])])],2))),128))])):i("",!0),e(m)?(s(),_(ot,{key:1,icon:"i-lucide-gauge",title:"Browser performance (Web Vitals)",help:"case.web-vitals"},{default:u(()=>[o("div",ei,[e(m).navigation?(s(),_(Ve,{key:0,"min-tile-width":"10rem"},{default:u(()=>[r(de,{label:"TTFB",hint:"Time to first byte","value-class":e(m).navigation.ttfb>600?"text-red-600":e(m).navigation.ttfb>200?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).navigation.ttfb},null,8,["ms"])]),_:1},8,["value-class"]),r(de,{label:"DOM Interactive",hint:"DOM interactive","value-class":e(m).navigation.domInteractive>3e3?"text-red-600":e(m).navigation.domInteractive>1500?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).navigation.domInteractive},null,8,["ms"])]),_:1},8,["value-class"]),r(de,{label:"DOMContentLoaded",hint:"DOMContentLoaded","value-class":e(m).navigation.domContentLoaded>3e3?"text-red-600":e(m).navigation.domContentLoaded>1500?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).navigation.domContentLoaded},null,8,["ms"])]),_:1},8,["value-class"]),r(de,{label:"Load Complete",hint:"Page fully loaded","value-class":e(m).navigation.loadComplete>5e3?"text-red-600":e(m).navigation.loadComplete>3e3?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).navigation.loadComplete},null,8,["ms"])]),_:1},8,["value-class"])]),_:1})):i("",!0),e(m).paint&&(e(m).paint.firstPaint||e(m).paint.firstContentfulPaint)?(s(),_(Ve,{key:1,"min-tile-width":"10rem",class:"pt-2 border-t"},{default:u(()=>[e(m).paint.firstPaint!==void 0?(s(),_(de,{key:0,label:"First Paint (FP)"},{default:u(()=>[r(ie,{ms:e(m).paint.firstPaint},null,8,["ms"])]),_:1})):i("",!0),e(m).paint.firstContentfulPaint!==void 0?(s(),_(de,{key:1,label:"First Contentful Paint (FCP)","value-class":e(m).paint.firstContentfulPaint>3e3?"text-red-600":e(m).paint.firstContentfulPaint>1800?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).paint.firstContentfulPaint},null,8,["ms"])]),_:1},8,["value-class"])):i("",!0)]),_:1})):i("",!0),e(m).vitals?(s(),_(Ve,{key:2,"min-tile-width":"10rem",class:"pt-2 border-t"},{default:u(()=>[r(de,{label:"Largest Contentful Paint (LCP)","value-class":e(m).vitals.lcp==null?"text-gray-400":e(m).vitals.lcp>4e3?"text-red-600":e(m).vitals.lcp>2500?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).vitals.lcp,fallback:"n/a"},null,8,["ms"])]),_:1},8,["value-class"]),r(de,{label:"Cumulative Layout Shift (CLS)",value:e(m).vitals.cls!=null?String(e(m).vitals.cls):"n/a","value-class":e(m).vitals.cls==null?"text-gray-400":e(m).vitals.cls>.25?"text-red-600":e(m).vitals.cls>.1?"text-orange-500":"text-green-600"},null,8,["value","value-class"]),r(de,{label:"Interaction to Next Paint (INP)","value-class":e(m).vitals.inp==null?"text-gray-400":e(m).vitals.inp>500?"text-red-600":e(m).vitals.inp>200?"text-orange-500":"text-green-600"},{default:u(()=>[r(ie,{ms:e(m).vitals.inp,fallback:"n/a"},null,8,["ms"])]),_:1},8,["value-class"])]),_:1})):i("",!0),e(m).navigation?.url?(s(),a("div",ti,[R[8]||(R[8]=f(" Page: ",-1)),o("code",si,c(e(m).navigation.url),1)])):i("",!0)])]),_:1})):i("",!0),e(F).length===0&&!e(m)?(s(),_(Jt,{key:2,icon:"i-lucide-gauge",title:"No performance hints or Web Vitals for this execution",text:"Web Vitals and step timing come from the Piwi capture fixtures — extend your Playwright test with piwiFixtures to collect them.",doc:"capture-fixtures"})):i("",!0)])]),"tab-history":u(()=>[o("div",ni,[e(d)&&e(d).length>0?(s(),a("div",ai,[o("div",oi,[e(n)?.testCaseId?(s(),_(be,{key:0,to:`/test-cases/${e(n).testCaseId}`,size:"xs",variant:"outline",color:"neutral","trailing-icon":"i-lucide-arrow-right"},{default:u(()=>[...R[9]||(R[9]=[f(" View full test history ",-1)])]),_:1},8,["to"])):i("",!0)]),r(qt,{data:e(d),height:200},null,8,["data"]),r(ut,{"min-width":"44rem",bleed:!1},{default:u(()=>[r(ct,{data:e(d),columns:P,ui:{base:"table-fixed border-separate border-spacing-0 min-w-[44rem]",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"startTime-cell":u(({row:j})=>[o("span",ri,[o("span",ii,c(new Date(j.original.startTime).toLocaleDateString("en-US",{month:"short",day:"numeric"})),1),o("span",li,c(new Date(j.original.startTime).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"})),1)])]),"status-cell":u(({row:j})=>[r(Ne,{color:("getStatusColor"in p?p.getStatusColor:e(Gs))(j.original.status),variant:"subtle",class:"capitalize"},{default:u(()=>[f(c(j.original.status),1)]),_:2},1032,["color"])]),"duration-cell":u(({row:j})=>[j.original.duration!==null?(s(),_(ie,{key:0,ms:j.original.duration},null,8,["ms"])):(s(),a("span",ci,"—"))]),"runId-cell":u(({row:j})=>[r(ce,{to:`/test-runs/${j.original.runId}`,class:"text-primary hover:underline"},{default:u(()=>[f(" #"+c(j.original.runId),1)]),_:2},1032,["to"])]),"error-cell":u(({row:j})=>[j.original.error?(s(),a("span",{key:0,class:"text-red-600 text-xs truncate max-w-xs block",title:j.original.error},c(j.original.error.length>80?`${j.original.error.substring(0,80)}…`:j.original.error),9,ui)):i("",!0)]),_:1},8,["data"])]),_:1})])):(s(),_(dt,{key:1,icon:"i-lucide-trending-up",text:"No prior executions of this test yet."},{default:u(()=>[...R[10]||(R[10]=[o("p",{class:"text-xs text-gray-400"}," This is the first recorded run. Once it runs again, its status and duration trend appear here. ",-1)])]),_:1}))])]),_:1},8,["modelValue","tab-items"])]),_:1})}}});export{fl as default};
@@ -1 +0,0 @@
1
- import{h as e,ab as r,bX as t}from"./CNu3kken.js";function a(o){return e(()=>r(o)?!!t(o)?.closest("form"):!0)}export{a as u};
@@ -1 +0,0 @@
1
- import{aw as o}from"./CNu3kken.js";function n(){const e=o()?.vnode?.scopeId;return e?{[e]:""}:{}}export{n as u};
@@ -1 +0,0 @@
1
- import{_ as Is}from"./DTrPCv7R.js";import{_ as Ms}from"./B3G-TIoP.js";import{b as Ae,A as wt,d as ie,O as Ot,w as xe,J as ye,k as e,o as s,f,g as t,j as a,_ as ke,c as r,i as n,m as d,t as c,v as R,F as X,y as ae,p as Pe,G as Ee,l as J,P as Lt,Q as Nt,q as re,h as N,r as I,K as Fs,s as $e,R as qt,n as Rt,D as Dt,E as Ht,M as Ps,u as Es,a as Bs,e as Vs,C as Kt,S as Ls,T as Ns}from"./CNu3kken.js";import{_ as Ks}from"./BjOFxi54.js";import{_ as Qe,a as Os}from"./CfhOanaF.js";import{_ as Be}from"./C9I1Dp3S.js";import{_ as Qt}from"./CF_eDZHu.js";import{u as qs}from"./CUOS6S13.js";import{u as be}from"./DprkT7rM.js";import{_ as Hs}from"./pZbe82l5.js";import{_ as Qs,a as Gs}from"./2yLW7WU0.js";import{_ as Gt}from"./Ce89VyHE.js";import{_ as ct}from"./Ce47NgZw.js";import{u as Xs}from"./D7t0Dn3h.js";import{_ as Xt}from"./CGDPUNcO.js";import{_ as Ce}from"./oSLbl-p0.js";import{C as St,w as Jt,O as rt,a as Wt,_ as Yt,u as Zt}from"./LTMoFvEY.js";import{N as Js}from"./DBWM_xs-.js";import{_ as Ws}from"./CBJFORiZ.js";import{_ as Ys}from"./DYjxDsYC.js";import{_ as Zs}from"./6vX5JdHr.js";import{_ as es}from"./FJTsZ5Aa.js";import{_ as en}from"./5SkLJHl8.js";import{_ as tn}from"./5QBnDbs_.js";import{_ as sn}from"./CdEzDaDI.js";import{_ as nn}from"./kWnH8yJq.js";import{_ as Ve}from"./D3SJGdl4.js";import{_ as Ge}from"./B_JSV0yG.js";import{_ as Xe}from"./DZECGgZm.js";import{f as At,b as an,c as on,d as ln,i as V,t as rn,e as ts,p as it,j as at}from"./DeewM3Wg.js";import{_ as ss}from"./7_9fts7T.js";import{_ as ut}from"./Ce_j5NtN.js";import{_ as dt}from"./HIGGZ_c-.js";import{_ as cn}from"./BM5BPKlc.js";import{_ as un}from"./BDUfBn3i.js";import{_ as dn}from"./B_MVJP17.js";import{_ as mn}from"./jR2xm3_t.js";import{_ as pn}from"./DAhv9aNg.js";import{_ as gn}from"./BtZNYmZO.js";import{_ as fn}from"./Bag08cIY.js";import{_ as _n}from"./B0tmRAhY.js";import{_ as zt}from"./roaTZkYi.js";import{M as vn,D as Tt,g as jt}from"./D7W_4Sqc.js";import{_ as yn}from"./DNqm5cWU.js";import{u as hn}from"./sqqg4oXL.js";import{u as xn}from"./Bsc11YIJ.js";import"./BZFiz2UB.js";import"./BjaRappk.js";import"./BVyjw9Bi.js";import"./DZ-KbUZi.js";import"./BZOykMLD.js";import"./B3AG2m76.js";import"./D-c8ZSws.js";import"./CmTzxoQt.js";import"./DNKZmhbX.js";import"./Ya8ZzWuY.js";import"./BAbrtVp3.js";import"./BuGAn4f7.js";import"./Bq4_kqIp.js";const bn=["run.finished","run.failed","run.failed.default_branch","cluster.new","flakiness.spike","perf.regression","diagnosis.completed"],ot=new Map,lt=new Map;function kn(U,$){const k=[{event:"run.failed",scenario:{title:`Test run failed — ${U}`,description:"3 of 12 tests failed on main — checkout › applies discount code +2 more",icon:"i-lucide-circle-x",color:"error"}},{event:"run.failed.default_branch",scenario:{title:`Test run failed on main — ${U}`,description:"2 of 12 tests failed · main — auth › logs in with valid credentials +1 more",icon:"i-lucide-circle-x",color:"error"}},{event:"cluster.new",scenario:{title:`New failure cluster — ${U}`,description:"TimeoutError: locator.click: Timeout 30000ms exceeded",icon:"i-lucide-layers",color:"warning"}},{event:"flakiness.spike",scenario:{title:`Flakiness spike — ${U}`,description:"3 tests became flaky (8.3% rate)",icon:"i-lucide-shuffle",color:"warning"}},{event:"perf.regression",scenario:{title:`Performance regression — ${U}`,description:"p90 duration increased by 42% vs last week",icon:"i-lucide-trending-down",color:"warning"}},{event:"run.finished",scenario:{title:`Test run recovered — ${U}`,description:"All 12 tests passed on main",icon:"i-lucide-circle-check",color:"success"}},{event:"diagnosis.completed",scenario:{title:`Diagnosis complete — ${U}`,description:"Root cause: test bug — confidence: high",icon:"i-lucide-sparkles",color:"info"}}],C=k.filter(x=>$.length===0||$.includes(x.event)).map(x=>x.scenario);return C.length===0?[k[0].scenario,k[k.length-1].scenario]:C}function $n(){if(!wt().public.demoMode)return null;const $=Ae();function k(x,m,i){C(x);const M=kn(m,i);lt.set(x,0);function D(){const A=(lt.get(x)??0)%M.length;lt.set(x,A+1);const v=M[A];$.add({title:v.title,description:v.description,icon:v.icon,color:v.color,duration:7e3});const _=25e3+Math.random()*1e4;ot.set(x,setTimeout(D,_))}ot.set(x,setTimeout(D,8e3))}function C(x){const m=ot.get(x);m!==void 0&&(clearTimeout(m),ot.delete(x)),lt.delete(x)}return{scheduleFor:k,cancelFor:C}}const Cn={key:0,class:"p-3 space-y-3"},Tn={key:0,class:"text-xs text-gray-500"},jn={key:1,class:"text-xs text-gray-500"},Sn={key:2,class:"text-xs text-gray-500"},wn={class:"space-y-1"},Rn=["checked","onChange"],Dn={key:1,class:"p-3 space-y-3"},An={class:"flex items-center justify-between"},zn={class:"font-medium text-sm inline-flex items-center gap-1"},Un={key:0,class:"text-xs text-muted bg-primary/5 rounded px-2 py-1.5"},In={key:1,class:"text-xs text-muted text-center py-2"},Mn={key:2,class:"space-y-1.5"},Fn={key:0,class:"space-y-2 rounded border border-primary/30 bg-primary/5 px-2 py-2"},Pn={class:"space-y-1"},En=["value"],Bn={class:"flex gap-1.5 justify-end"},Vn={class:"flex-1 font-medium truncate"},Ln={key:3,class:"text-xs text-muted text-center py-1"},Nn={key:4,class:"space-y-2 border-t border-default pt-2"},Kn={class:"space-y-1"},On=["value"],qn={class:"flex gap-1.5 justify-end"},Hn=ie({__name:"SubscribeBell",props:{projectId:{},projectLabel:{}},async setup(U){let $,k;const C=U,x=wt(),m=x.public.demoMode,i=N(()=>x.public.authEnabled),{authState:M}=Ot(),D=N(()=>M.value.authenticated),A=Ae(),v=I(!1),_=m?$n():null,b=!i.value&&!m?qs():null,z=I("default"),p=N(()=>"Notification"in window);"Notification"in window&&(z.value=Notification.permission);const y=N(()=>b?.getProject(C.projectId).events??[]),P=N(()=>b?.isSubscribed(C.projectId)??!1);async function K(){!p.value||z.value!=="default"||(z.value=await Notification.requestPermission())}function S(L){return y.value.includes(L)}function g(L){b?.toggleEvent(C.projectId,L)}const T=m||i.value&&D.value,Q=m?{server:!1}:{},{data:w,refresh:H}=([$,k]=xe(()=>be(`/api/subscriptions?projectId=${C.projectId}`,{immediate:T,...Q},"$APDuK86tlj")),$=await $,k(),$),B=N(()=>w.value?.subscriptions??[]),ue=N(()=>B.value.length>0),{data:ge}=([$,k]=xe(()=>be("/api/channels",{immediate:T,...Q},"$uK3f0xlELn")),$=await $,k(),$),h=N(()=>ge.value?.channels??[]),j=I(!1),q=I(void 0),de=I(["run.failed"]),ze=I(!1),me=I(null),he=I(void 0),fe=I([]),Ue=I(!1);function mt(L){me.value=L,he.value=L.channel.id,fe.value=[...L.events]}function pt(){me.value=null}async function Y(){if(!(!me.value||!he.value||fe.value.length===0)){Ue.value=!0;try{await $fetch(`/api/subscriptions/${me.value.id}`,{method:"PATCH",body:{channelId:he.value,events:fe.value}}),await H(),me.value=null}catch(L){A.add({title:"Update failed",description:String(L?.message??L),color:"error"})}finally{Ue.value=!1}}}const Je=N(()=>h.value.map(L=>({label:L.type==="personal_email"?`${L.name} (${L.config.address})`:L.name,value:L.id}))),Le=bn.map(L=>({label:L.replace(/\./g," › "),value:L}));ye(v,L=>{L?(T&&H(),h.value.length>0&&!q.value&&(q.value=h.value[0].id)):(j.value=!1,me.value=null)});async function Ne(){if(!(!q.value||de.value.length===0)){ze.value=!0;try{await $fetch("/api/subscriptions",{method:"POST",body:{channelId:q.value,projectId:C.projectId,events:de.value,mode:"realtime"}}),await H(),j.value=!1,A.add({title:"Subscribed",color:"success"}),m&&_?.scheduleFor(C.projectId,C.projectLabel||"this project",de.value)}catch(L){A.add({title:"Subscribe failed",description:String(L?.message??L),color:"error"})}finally{ze.value=!1}}}async function gt(L){try{await $fetch(`/api/subscriptions/${L}`,{method:"DELETE"}),await H(),A.add({title:"Unsubscribed",color:"success"}),m&&B.value.length===0&&_?.cancelFor(C.projectId)}catch(F){A.add({title:"Failed",description:String(F?.message??F),color:"error"})}}async function ne(L){const F=L.mutedUntil&&new Date(L.mutedUntil)>new Date;try{await $fetch(`/api/subscriptions/${L.id}`,{method:"PATCH",body:{mutedUntil:F?null:new Date(Date.now()+10080*60*1e3).toISOString()}}),await H()}catch(Z){A.add({title:"Failed",description:String(Z?.message??Z),color:"error"})}}function pe(L){return L.mutedUntil&&new Date(L.mutedUntil)>new Date}function Ke(L){return L==="personal_email"?"i-lucide-user-round":L==="email"?"i-lucide-mail":L==="slack"?"i-lucide-slack":"i-lucide-webhook"}const ft=N(()=>m||i.value&&D.value||b!=null),Oe=N(()=>m||i.value?ue.value:P.value);return(L,F)=>{const Z=ke,_t=Ks,Te=Qe,We=Pe,Ye=Ee,Ie=Be,je=Qt,vt=Fs;return e(ft)?(s(),f(vt,{key:0,open:e(v),"onUpdate:open":F[6]||(F[6]=O=>J(v)?v.value=O:null),ui:{content:"w-72"}},{content:t(()=>[e(b)?(s(),r("div",Cn,[F[9]||(F[9]=n("div",{class:"flex items-center justify-between"},[n("span",{class:"font-medium text-sm"},"Browser notifications")],-1)),e(p)&&e(z)==="default"?(s(),r("p",Tn,[a(Z,{variant:"link",size:"xs",class:"p-0",onClick:K},{default:t(()=>[...F[7]||(F[7]=[d(" Allow notifications ",-1)])]),_:1}),F[8]||(F[8]=d(" "+c(" ")+"in your browser to get alerts for this project. ",-1))])):e(p)&&e(z)==="denied"?(s(),r("p",jn," Notifications are blocked. Check your browser settings to allow them. ")):e(p)?R("",!0):(s(),r("p",Sn,"Notifications are not supported in this browser.")),e(p)&&e(z)==="granted"?(s(),r(X,{key:3},[a(_t),n("div",wn,[(s(!0),r(X,null,ae(e(Le),O=>(s(),r("label",{key:O.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[n("input",{type:"checkbox",checked:S(O.value),class:"accent-primary size-3",onChange:oe=>g(O.value)},null,40,Rn),d(" "+c(O.label),1)]))),128))])],64)):R("",!0)])):(s(),r("div",Dn,[n("div",An,[n("span",zn,[F[10]||(F[10]=d(" Notifications ",-1)),a(Te,{topic:"notifications.subscribe"})]),e(j)?R("",!0):(s(),f(Z,{key:0,size:"xs",icon:"i-lucide-plus",variant:"ghost",color:"neutral",disabled:e(h).length===0,onClick:F[0]||(F[0]=O=>j.value=!0)},{default:t(()=>[...F[11]||(F[11]=[d(" Add ",-1)])]),_:1},8,["disabled"]))]),e(m)?(s(),r("div",Un,[a(We,{name:"i-lucide-sparkles",class:"size-3 inline-block mr-1 text-primary"}),F[12]||(F[12]=d(" Demo — notifications will appear as toasts in ~8 s. ",-1))])):e(h).length===0?(s(),r("div",In,[F[14]||(F[14]=d(" No channels configured.",-1)),F[15]||(F[15]=n("br",null,null,-1)),a(Ye,{to:"/settings/notifications",class:"text-primary underline"},{default:t(()=>[...F[13]||(F[13]=[d("Add one in Settings",-1)])]),_:1})])):R("",!0),e(B).length>0?(s(),r("div",Mn,[(s(!0),r(X,null,ae(e(B),O=>(s(),r(X,{key:O.id},[e(me)?.id===O.id?(s(),r("div",Fn,[a(je,{label:"Channel",size:"xs"},{default:t(()=>[a(Ie,{modelValue:e(he),"onUpdate:modelValue":F[1]||(F[1]=oe=>J(he)?he.value=oe:null),items:e(Je),"value-key":"value",class:"w-full text-xs",size:"xs"},null,8,["modelValue","items"])]),_:1}),a(je,{label:"Events",size:"xs"},{default:t(()=>[n("div",Pn,[(s(!0),r(X,null,ae(e(Le),oe=>(s(),r("label",{key:oe.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[Lt(n("input",{type:"checkbox",value:oe.value,"onUpdate:modelValue":F[2]||(F[2]=qe=>J(fe)?fe.value=qe:null),class:"accent-primary size-3"},null,8,En),[[Nt,e(fe)]]),d(" "+c(oe.label),1)]))),128))])]),_:1}),n("div",Bn,[a(Z,{size:"xs",color:"neutral",variant:"ghost",onClick:pt},{default:t(()=>[...F[16]||(F[16]=[d("Cancel",-1)])]),_:1}),a(Z,{size:"xs",color:"primary",loading:e(Ue),disabled:!e(he)||e(fe).length===0,onClick:Y},{default:t(()=>[...F[17]||(F[17]=[d(" Save ",-1)])]),_:1},8,["loading","disabled"])])])):(s(),r("div",{key:1,class:re(["flex items-center gap-2 rounded px-2 py-1.5 text-xs",pe(O)?"opacity-60":""])},[a(We,{name:Ke(O.channel.type),class:"size-3.5 text-muted shrink-0"},null,8,["name"]),n("span",Vn,c(O.channel.name),1),a(Z,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"xs",title:"Edit subscription",onClick:oe=>mt(O)},null,8,["onClick"]),a(Z,{icon:pe(O)?"i-lucide-bell":"i-lucide-bell-off",color:"neutral",variant:"ghost",size:"xs",title:pe(O)?"Unmute":"Mute 7 days",onClick:oe=>ne(O)},null,8,["icon","title","onClick"]),a(Z,{icon:"i-lucide-x",color:"error",variant:"ghost",size:"xs",title:"Unsubscribe",onClick:oe=>gt(O.id)},null,8,["onClick"])],2))],64))),128))])):!e(j)&&e(h).length>0?(s(),r("div",Ln," Not subscribed to this project. ")):R("",!0),e(j)?(s(),r("div",Nn,[a(je,{label:"Channel",size:"xs"},{default:t(()=>[a(Ie,{modelValue:e(q),"onUpdate:modelValue":F[3]||(F[3]=O=>J(q)?q.value=O:null),items:e(Je),"value-key":"value",class:"w-full text-xs",size:"xs"},null,8,["modelValue","items"])]),_:1}),a(je,{label:"Events",size:"xs"},{default:t(()=>[n("div",Kn,[(s(!0),r(X,null,ae(e(Le),O=>(s(),r("label",{key:O.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[Lt(n("input",{type:"checkbox",value:O.value,"onUpdate:modelValue":F[4]||(F[4]=oe=>J(de)?de.value=oe:null),class:"accent-primary size-3"},null,8,On),[[Nt,e(de)]]),d(" "+c(O.label),1)]))),128))])]),_:1}),n("div",qn,[a(Z,{size:"xs",color:"neutral",variant:"ghost",onClick:F[5]||(F[5]=O=>j.value=!1)},{default:t(()=>[...F[18]||(F[18]=[d("Cancel",-1)])]),_:1}),a(Z,{size:"xs",color:"primary",loading:e(ze),disabled:!e(q)||e(de).length===0,onClick:Ne},{default:t(()=>[...F[19]||(F[19]=[d(" Subscribe ",-1)])]),_:1},8,["loading","disabled"])])])):R("",!0)]))]),default:t(()=>[a(Z,{icon:e(Oe)?"i-lucide-bell-ring":"i-lucide-bell",size:"sm",color:e(Oe)?"primary":"neutral",variant:e(Oe)?"soft":"outline",title:"Notification subscriptions for this project"},null,8,["icon","color","variant"])]),_:1},8,["open"])):R("",!0)}}}),Qn=Object.assign(Hn,{__name:"SubscribeBell"}),Gn={key:0,class:"flex items-center justify-between gap-3"},Xn={class:"flex items-center gap-2 min-w-0 text-sm"},Jn={class:"text-xs break-all"},Wn={class:"flex items-center gap-1.5 shrink-0"},Yn={key:1,class:"flex items-center justify-between gap-3"},Zn=ie({__name:"DesktopProjectLinkCard",props:{projectId:{}},setup(U){const $=U,{available:k,link:C,busy:x,pickAndLink:m,unlink:i}=Xs(()=>$.projectId);return(M,D)=>{const A=Pe,v=$e,_=ke,b=ct;return e(k)?(s(),f(b,{key:0,icon:"i-lucide-folder-symlink",title:"Local folder"},{subtitle:t(()=>[...D[0]||(D[0]=[d(" Link this project to its checkout on this machine to retry failures from here and open files in your IDE. ",-1)])]),default:t(()=>[e(C)?(s(),r("div",Gn,[n("div",Xn,[a(A,{name:e(C).exists?"i-lucide-folder-check":"i-lucide-folder-x",class:re(["size-4 shrink-0",e(C).exists?"text-success":"text-warning"])},null,8,["name","class"]),n("code",Jn,c(e(C).path),1),e(C).exists?R("",!0):(s(),f(v,{key:0,color:"warning",variant:"subtle",size:"sm"},{default:t(()=>[...D[1]||(D[1]=[d("missing",-1)])]),_:1}))]),n("div",Wn,[a(_,{size:"xs",color:"neutral",variant:"soft",icon:"i-lucide-folder-search",loading:e(x),onClick:e(m)},{default:t(()=>[...D[2]||(D[2]=[d(" Change ",-1)])]),_:1},8,["loading","onClick"]),a(_,{size:"xs",color:"neutral",variant:"ghost",icon:"i-lucide-unlink",disabled:e(x),onClick:e(i)},{default:t(()=>[...D[3]||(D[3]=[d(" Unlink ",-1)])]),_:1},8,["disabled","onClick"])])])):(s(),r("div",Yn,[D[5]||(D[5]=n("p",{class:"text-sm text-muted"},"No folder linked yet.",-1)),a(_,{size:"xs",icon:"i-lucide-folder-plus",loading:e(x),onClick:e(m)},{default:t(()=>[...D[4]||(D[4]=[d("Choose folder…",-1)])]),_:1},8,["loading","onClick"])]))]),_:1})):R("",!0)}}}),ea=Object.assign(Zn,{__name:"DesktopProjectLinkCard"}),ta={class:"w-full relative"},sa={key:0},na={class:"p-2 text-sm text-gray-900 dark:text-gray-100"},aa={class:"font-semibold mb-1"},oa={class:"capitalize mb-1"},la={class:"space-y-0.5"},ra={class:"font-medium mt-1"},ia=ie({__name:"TestRunsChart",props:{testRuns:{},height:{default:300},markers:{default:()=>[]}},emits:["marker-click"],setup(U,{emit:$}){const k=U,C=$,x=N(()=>k.markers),m=N(()=>!k.testRuns||k.testRuns.length===0?[]:[...k.testRuns].sort((T,Q)=>new Date(T.startTime).getTime()-new Date(Q.startTime).getTime()).slice(-30).map(T=>({id:T.id,date:new Date(T.startTime),passed:T.passedTests||0,failed:T.failedTests||0,skipped:T.skippedTests||0,flaky:T.flakyTests||0,total:T.totalTests||0,status:T.status}))),i=g=>g.date,M=g=>g.passed,D=g=>g.failed,A=g=>g.skipped,v=g=>g.flaky,_=["rgb(34, 197, 94)","rgb(239, 68, 68)","rgb(245, 158, 11)","rgb(147, 51, 234)"],b=I(null),{tooltipData:z,tooltipPos:p,markerTooltip:y,markerTooltipPos:P,onRenderComplete:K}=Zt(b,m,{x:g=>g.date,series:[{y:g=>g.passed,color:_[0]},{y:g=>g.failed,color:_[1]},{y:g=>g.skipped,color:_[2]},{y:g=>g.flaky,color:_[3]}],onClick:g=>Rt(`/test-runs/${g.id}`),markers:x,onMarkerClick:g=>C("marker-click",g.id)}),S=[{color:_[0],label:"Passed"},{color:_[1],label:"Failed"},{color:_[2],label:"Skipped"},{color:_[3],label:"Flaky"}];return(g,T)=>{const Q=Xt,w=Ce,H=Yt;return s(),r("div",ta,[e(m).length>0?(s(),r("div",sa,[a(e(Wt),{ref_key:"xyContainerRef",ref:b,data:e(m),height:U.height,padding:{top:10,right:10,bottom:0,left:0},"on-render-complete":e(K)},{default:t(()=>[a(e(Js),{x:i,y:[M,D,A,v],color:_,"curve-type":e(St).MonotoneX},null,8,["y","curve-type"]),a(e(Jt),{x:i,y:[M,D,A,v],color:_,"curve-type":e(St).MonotoneX,"line-width":2},null,8,["y","curve-type"]),a(e(rt),{type:"x","tick-format":B=>new Date(B).toLocaleDateString("en-US",{month:"short",day:"numeric"})},null,8,["tick-format"]),a(e(rt),{type:"y",label:"Tests","tick-format":B=>B.toString()},null,8,["tick-format"])]),_:1},8,["data","height","on-render-complete"]),e(z)?(s(),r("div",{key:0,class:"fixed z-50 pointer-events-none bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 max-w-[260px]",style:qt({left:`${e(p).x}px`,top:`${e(p).y}px`})},[n("div",na,[n("div",aa,c(new Date(e(z).date).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})),1),n("div",oa,"Status: "+c(e(z).status),1),n("div",la,[n("div",null,[T[0]||(T[0]=n("span",{class:"text-green-500 dark:text-green-400"},"●",-1)),d(" Passed: "+c(e(z).passed),1)]),n("div",null,[T[1]||(T[1]=n("span",{class:"text-red-500 dark:text-red-400"},"●",-1)),d(" Failed: "+c(e(z).failed),1)]),n("div",null,[T[2]||(T[2]=n("span",{class:"text-orange-500 dark:text-orange-400"},"●",-1)),d(" Skipped: "+c(e(z).skipped),1)]),n("div",null,[T[3]||(T[3]=n("span",{class:"text-purple-500 dark:text-purple-400"},"●",-1)),d(" Flaky: "+c(e(z).flaky),1)]),n("div",ra,"Total: "+c(e(z).total),1)]),T[4]||(T[4]=n("div",{class:"text-gray-400 dark:text-gray-500 text-xs mt-1"},"Click to view run details",-1))])],4)):R("",!0),a(Q,{marker:e(y),pos:e(P)},null,8,["marker","pos"])])):(s(),f(w,{key:1,text:"No test run data available to display chart"})),a(H,{items:S})])}}}),ca=Object.assign(ia,{__name:"TestRunsChart"}),ua={class:"space-y-3"},da={class:"min-w-0 space-y-1"},ma={class:"flex items-center gap-2 flex-wrap text-sm"},pa={key:0,class:"text-gray-500"},ga=["title"],fa=["title"],_a={key:0,class:"text-xs text-gray-500 italic"},va={class:"flex items-center gap-2 shrink-0"},ya=ie({__name:"ClusterMergeSuggestions",props:{projectId:{}},emits:["merged"],setup(U,{emit:$}){const k=U,C=$,x=Ae(),m=I([]),i=I(null);async function M(){try{m.value=await $fetch(`/api/projects/${k.projectId}/cluster-merge-suggestions`)}catch{m.value=[]}}ye(()=>k.projectId,M,{immediate:!0});async function D(v,_){i.value=v;try{await $fetch(`/api/cluster-merge-suggestions/${v}/${_}`,{method:"POST"}),x.add({title:_==="approve"?"Clusters merged":"Suggestion dismissed",color:"success"}),await M(),_==="approve"&&C("merged")}catch(b){x.add({title:"Action failed",description:String(b?.message??b),color:"error"})}finally{i.value=null}}const A=v=>v==null?"":`${Math.round(v*100)}% similar`;return(v,_)=>{const b=$e,z=ke,p=ct;return e(m).length?(s(),f(p,{key:0,icon:"i-lucide-git-merge",title:"Suggested merges",count:e(m).length,class:"mb-4"},{subtitle:t(()=>[..._[0]||(_[0]=[d(" Likely-duplicate clusters found by semantic analysis. Approving merges them into the older cluster. ",-1)])]),default:t(()=>[n("div",ua,[(s(!0),r(X,null,ae(e(m),y=>(s(),r("div",{key:y.id,class:"rounded-lg border border-default p-3 flex items-start justify-between gap-4"},[n("div",da,[n("div",ma,[a(b,{color:y.method==="llm"?"primary":"neutral",variant:"subtle",size:"sm"},{default:t(()=>[d(c(y.method==="llm"?`AI · ${y.llmConfidence??""}`:"similarity"),1)]),_:2},1032,["color"]),A(y.score)?(s(),r("span",pa,c(A(y.score)),1)):R("",!0)]),n("p",{class:"text-sm truncate",title:y.clusterA?.signature||""},[_[1]||(_[1]=n("span",{class:"text-gray-400"},"A:",-1)),d(" "+c(y.clusterA?.signature||`#${y.id}`),1)],8,ga),n("p",{class:"text-sm truncate",title:y.clusterB?.signature||""},[_[2]||(_[2]=n("span",{class:"text-gray-400"},"B:",-1)),d(" "+c(y.clusterB?.signature||""),1)],8,fa),y.llmReason?(s(),r("p",_a,c(y.llmReason),1)):R("",!0)]),n("div",va,[a(z,{size:"sm",color:"primary",icon:"i-lucide-git-merge",loading:e(i)===y.id,onClick:P=>D(y.id,"approve")},{default:t(()=>[..._[3]||(_[3]=[d(" Merge ",-1)])]),_:1},8,["loading","onClick"]),a(z,{size:"sm",color:"neutral",variant:"ghost",icon:"i-lucide-x",disabled:e(i)===y.id,onClick:P=>D(y.id,"reject")},{default:t(()=>[..._[4]||(_[4]=[d(" Dismiss ",-1)])]),_:1},8,["disabled","onClick"])])]))),128))])]),_:1},8,["count"])):R("",!0)}}}),ha=Object.assign(ya,{__name:"ClusterMergeSuggestions"}),xa={class:"flex items-center justify-between"},ba={class:"text-sm text-gray-500 inline-flex items-center gap-1"},ka={class:"min-w-0 space-y-0.5"},$a={key:0,class:"text-xs text-gray-500 italic truncate"},Ca={key:1,class:"text-gray-400 text-xs"},Ta={class:"space-y-1"},ja={class:"text-sm tabular-nums"},Sa={class:"text-sm tabular-nums"},wa={key:1,class:"text-gray-400 text-xs"},Ra={class:"text-sm text-gray-500 whitespace-nowrap"},Da={key:0,class:"ml-1 text-xs text-gray-400"},Aa={class:"flex justify-end"},za=ie({__name:"FailureClustersList",props:{projectId:{}},async setup(U){let $,k;const C=U,x=I(void 0),{data:m,pending:i}=([$,k]=xe(()=>be(()=>{const A=new URLSearchParams;x.value&&A.set("status",x.value);const v=A.toString();return`/api/projects/${C.projectId}/failure-clusters${v?`?${v}`:""}`},{lazy:!0,server:!1,watch:[x]},"$fqv4nq7Mtw")),$=await $,k(),$),M=A=>ln(A.fixVerification),D=[{accessorKey:"signature",header:V("Signature")},{accessorKey:"errorType",header:V("Type")},{accessorKey:"status",header:V("Status")},{accessorKey:"affectedTests",header:V("Tests")},{accessorKey:"occurrences",header:V("Occurrences")},{accessorKey:"diagnosis",header:"AI"},{accessorKey:"lastSeenAt",header:V("Last seen")},{id:"actions",header:"Actions"}];return(A,v)=>{const _=Qe,b=Be,z=Ee,p=$e,y=Pe,P=es,K=ke,S=Ve,g=Xe,T=Ce,Q=Ge;return s(),f(Q,null,{header:t(()=>[n("div",xa,[n("p",ba,[v[1]||(v[1]=d(" Ongoing failure signatures grouped by normalized error. ",-1)),a(_,{topic:"cluster.concept"})]),a(b,{modelValue:e(x),"onUpdate:modelValue":v[0]||(v[0]=w=>J(x)?x.value=w:null),items:[{label:"All",value:void 0},{label:"Open",value:"open"},{label:"Resolved",value:"resolved"},{label:"Ignored",value:"ignored"}],size:"xs",class:"w-32"},null,8,["modelValue"])])]),default:t(()=>[a(g,{"min-width":"48rem",bleed:!1},{default:t(()=>[a(S,{data:e(m)??[],columns:D,loading:e(i)},{"actions-header":t(()=>[...v[2]||(v[2]=[n("div",{class:"text-right"},"Actions",-1)])]),"signature-cell":t(({row:w})=>[n("div",ka,[a(z,{to:`/failure-clusters/${w.original.id}`,class:re(["text-sm text-primary hover:underline truncate block",w.original.title?"":"font-mono"]),title:w.original.signature},{default:t(()=>[d(c(w.original.title||w.original.signature),1)]),_:2},1032,["to","class","title"]),w.original.triageNote?(s(),r("p",$a,c(w.original.triageNote),1)):R("",!0)])]),"errorType-cell":t(({row:w})=>[w.original.errorType?(s(),f(p,{key:0,color:("clusterErrorTypeColor"in A?A.clusterErrorTypeColor:e(on))(w.original.errorType),variant:"subtle",size:"sm"},{default:t(()=>[d(c(w.original.errorType),1)]),_:2},1032,["color"])):(s(),r("span",Ca,"—"))]),"status-cell":t(({row:w})=>[n("div",Ta,[a(p,{color:("clusterStatusColor"in A?A.clusterStatusColor:e(an))(w.original.status),variant:"subtle",size:"sm"},{default:t(()=>[d(c(w.original.status),1)]),_:2},1032,["color"]),M(w.original)?(s(),f(P,{key:0,text:M(w.original).hint},{default:t(()=>[a(p,{color:M(w.original).color,variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(y,{name:M(w.original).icon,class:"size-3"},null,8,["name"]),d(" "+c(M(w.original).label),1)]),_:2},1032,["color"])]),_:2},1032,["text"])):R("",!0)])]),"affectedTests-cell":t(({row:w})=>[n("span",ja,c(w.original.affectedTests),1)]),"occurrences-cell":t(({row:w})=>[n("span",Sa,c(w.original.occurrences),1)]),"diagnosis-cell":t(({row:w})=>[w.original.diagnosis?.status==="completed"&&w.original.diagnosis.category?(s(),f(p,{key:0,color:"neutral",variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(y,{name:"i-lucide-sparkles",class:"size-3"}),d(" "+c(w.original.diagnosis.category),1)]),_:2},1024)):(s(),r("span",wa,"—"))]),"lastSeenAt-cell":t(({row:w})=>[n("div",Ra,[a(z,{to:`/test-runs/${w.original.lastSeenRunId}`,class:"text-primary hover:underline"},{default:t(()=>[d(" run #"+c(w.original.lastSeenRunId),1)]),_:2},1032,["to"]),w.original.lastSeenAt?(s(),r("span",Da," ("+c(("formatRelativeTime"in A?A.formatRelativeTime:e(At))(w.original.lastSeenAt))+") ",1)):R("",!0)])]),"actions-cell":t(({row:w})=>[n("div",Aa,[a(K,{to:`/failure-clusters/${w.original.id}`,size:"sm",variant:"outline","trailing-icon":"i-lucide-arrow-right"},{default:t(()=>[...v[3]||(v[3]=[d(" View ",-1)])]),_:1},8,["to"])])]),_:1},8,["data","loading"])]),_:1}),!e(i)&&e(m)&&e(m).length===0?(s(),f(T,{key:0,text:"No failure clusters recorded for this project.",padded:!1,class:"py-4"})):R("",!0)]),_:1})}}}),Ua=Object.assign(za,{__name:"FailureClustersList"}),Ia={class:"flex items-center justify-between"},Ma={class:"flex items-center gap-3"},Fa={class:"text-sm text-gray-500 inline-flex items-center gap-1"},Pa={class:"flex items-center gap-1.5"},Ea={class:"min-w-0 space-y-0.5"},Ba={class:"flex items-center gap-2"},Va={class:"text-sm tabular-nums"},La={class:"text-sm tabular-nums"},Na={key:1,class:"text-gray-400 text-xs"},Ka={key:1,class:"text-gray-400 text-xs"},Oa={key:1,class:"text-gray-400 text-xs"},qa={key:0,class:"text-sm text-gray-500"},Ha={key:1,class:"text-gray-400 text-xs"},Qa={class:"flex justify-end"},Ga={key:0,class:"text-sm text-gray-500 py-4 text-center"},Xa=ie({__name:"FlakyTestsList",props:{projectId:{},environment:{},projectName:{}},async setup(U){let $,k;const C=U,x=I(50),m=I([]),{data:i,pending:M}=([$,k]=xe(()=>be(()=>{const p=new URLSearchParams({runs:String(x.value)});return C.environment&&p.set("environment",C.environment),`/api/projects/${C.projectId}/flaky-tests?${p.toString()}`},{lazy:!0,server:!1,watch:[x,()=>C.environment]},"$BbmtLKIPAB")),$=await $,k(),$),D=N(()=>m.value.length===0?i.value??[]:(i.value??[]).filter(p=>m.value.includes(p.rootCause??"")));function A(p){return p>=60?"error":p>=30?"warning":"neutral"}function v(p){switch(p){case"timing":return"amber";case"network":return"red";case"assertion":return"blue";case"environment":return"purple";default:return"gray"}}function _(p){m.value.indexOf(p)>=0?m.value=m.value.filter(P=>P!==p):m.value=[...m.value,p]}const b=[{label:"Timing",value:"timing"},{label:"Network",value:"network"},{label:"Assertion",value:"assertion"},{label:"Environment",value:"environment"},{label:"Other",value:"other"}],z=[{accessorKey:"title",header:V("Test")},{accessorKey:"impact",header:V("Impact")},{accessorKey:"score",header:V("Score")},{accessorKey:"failureRate",header:V("Failure rate")},{accessorKey:"retryPassRuns",header:V("Retry passes")},{accessorKey:"alternations",header:V("Flips")},{accessorKey:"rootCause",header:"Root cause"},{accessorKey:"lastFlakeAt",header:V("Last flake")},{id:"actions",header:"Actions"}];return(p,y)=>{const P=Qe,K=Pe,S=$e,g=ke,T=Be,Q=Ee,w=ss,H=ut,B=Gt,ue=Ve,ge=Xe,h=Ge;return s(),f(h,null,{header:t(()=>[n("div",Ia,[n("div",Ma,[n("p",Fa,[y[1]||(y[1]=d(" Tests that fail intermittently — detected by retry passes and status alternations ",-1)),a(P,{topic:"project.flaky-tests"})]),U.environment?(s(),f(S,{key:0,color:"neutral",variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(K,{name:"i-lucide-layers",class:"size-3"}),d(" "+c(U.environment),1)]),_:1})):R("",!0),n("div",Pa,[(s(),r(X,null,ae(b,j=>a(g,{key:j.value,size:"xs",variant:e(m).includes(j.value)?"solid":"outline",color:(e(m).includes(j.value),"neutral"),onClick:q=>_(j.value)},{default:t(()=>[d(c(j.label),1)]),_:2},1032,["variant","color","onClick"])),64))])]),a(T,{modelValue:e(x),"onUpdate:modelValue":y[0]||(y[0]=j=>J(x)?x.value=j:null),items:[{label:"Last 20 runs",value:20},{label:"Last 50 runs",value:50},{label:"Last 100 runs",value:100}],size:"xs",class:"w-36"},null,8,["modelValue"])])]),default:t(()=>[a(ge,{"min-width":"52rem",bleed:!1},{default:t(()=>[a(ue,{data:e(D),columns:z,loading:e(M),sticky:"",class:"max-h-[32rem]"},{"actions-header":t(()=>[...y[2]||(y[2]=[n("div",{class:"text-right"},"Actions",-1)])]),"title-cell":t(({row:j})=>[n("div",Ea,[a(Q,{to:`/test-run-cases/${j.original.latestRunsCaseId}`,class:"text-sm font-medium text-primary hover:underline truncate block",title:j.original.title},{default:t(()=>[d(c(j.original.title),1)]),_:2},1032,["to","title"]),a(w,{tags:j.original.tags,meta:{owner:j.original.owner??void 0,priority:("toTestPriority"in p?p.toTestPriority:e(rn))(j.original.priority)},"max-tags":3},null,8,["tags","meta"]),a(H,{"file-path":j.original.filePath,"project-key":U.projectId,"project-name":U.projectName,class:"text-xs text-gray-400"},null,8,["file-path","project-key","project-name"])])]),"impact-cell":t(({row:j})=>[n("div",Ba,[n("span",{class:re(["inline-block w-2 h-2 rounded-full shrink-0",{"bg-red-500":j.original.wastedCiMinutes>=30,"bg-amber-500":j.original.wastedCiMinutes>=5&&j.original.wastedCiMinutes<30,"bg-green-500":j.original.wastedCiMinutes>=0&&j.original.wastedCiMinutes<5}])},null,2),n("span",Va,c(Math.round(j.original.wastedCiMinutes))+" min wasted",1)])]),"score-cell":t(({row:j})=>[a(S,{color:A(j.original.score),variant:"subtle",size:"sm"},{default:t(()=>[d(c(j.original.score),1)]),_:2},1032,["color"])]),"failureRate-cell":t(({row:j})=>[n("span",La,c(Math.round(j.original.failureRate*100))+"%",1)]),"retryPassRuns-cell":t(({row:j})=>[j.original.retryPassRuns?(s(),f(S,{key:0,color:"warning",variant:"outline",size:"sm"},{default:t(()=>[d(c(j.original.retryPassRuns)+" run"+c(j.original.retryPassRuns===1?"":"s"),1)]),_:2},1024)):(s(),r("span",Na,"—"))]),"alternations-cell":t(({row:j})=>[j.original.alternations>=2?(s(),f(S,{key:0,color:"neutral",variant:"outline",size:"sm"},{default:t(()=>[d(c(j.original.alternations),1)]),_:2},1024)):(s(),r("span",Ka,"—"))]),"rootCause-cell":t(({row:j})=>[j.original.rootCause?(s(),f(B,{key:0,text:j.original.rootCause,color:v(j.original.rootCause)},null,8,["text","color"])):(s(),r("span",Oa,"—"))]),"lastFlakeAt-cell":t(({row:j})=>[j.original.lastFlakeAt?(s(),r("span",qa,c(("formatRelativeTime"in p?p.formatRelativeTime:e(At))(j.original.lastFlakeAt)),1)):(s(),r("span",Ha,"—"))]),"actions-cell":t(({row:j})=>[n("div",Qa,[a(g,{to:`/test-run-cases/${j.original.latestRunsCaseId}`,size:"sm",variant:"outline","trailing-icon":"i-lucide-arrow-right"},{default:t(()=>[...y[3]||(y[3]=[d(" View ",-1)])]),_:1},8,["to"])])]),_:1},8,["data","loading"])]),_:1}),!e(M)&&e(D).length===0?(s(),r("p",Ga," No flaky tests detected in the last "+c(e(x))+" runs. ",1)):R("",!0)]),_:1})}}}),Ja=Object.assign(Xa,{__name:"FlakyTestsList"}),Wa={class:"w-full relative"},Ya={key:0},Za={class:"p-2 text-sm text-gray-900 dark:text-gray-100"},eo={class:"font-semibold mb-1"},to={class:"capitalize mb-1"},so={class:"space-y-0.5"},no={class:"mt-1"},ao={key:0,class:"text-gray-400 dark:text-gray-500 text-xs"},oo=ie({__name:"PerformanceTrendChart",props:{data:{},height:{default:300},markers:{default:()=>[]}},emits:["marker-click"],setup(U,{emit:$}){const k=U,C=$,x=N(()=>k.markers),m=N(()=>!k.data||k.data.length===0?[]:k.data.map(S=>({id:S.id,date:new Date(S.startTime),duration:S.duration?Math.round(S.duration/1e3):null,avgTestDuration:S.avgTestDuration?Math.round(S.avgTestDuration/1e3):null,p90TestDuration:S.p90TestDuration?Math.round(S.p90TestDuration/1e3):null,commit:S.commit?S.commit.substring(0,7):null,status:S.status,totalTests:S.totalTests}))),i=S=>S.date,M=S=>S.duration??void 0,D=S=>S.avgTestDuration??void 0,A=S=>S.p90TestDuration??void 0,v=["rgb(59, 130, 246)","rgb(34, 197, 94)","rgb(249, 115, 22)"],_=I(null),{tooltipData:b,tooltipPos:z,markerTooltip:p,markerTooltipPos:y,onRenderComplete:P}=Zt(_,m,{x:S=>S.date,series:[{y:S=>S.duration,color:v[0]},{y:S=>S.avgTestDuration,color:v[1]},{y:S=>S.p90TestDuration,color:v[2]}],onClick:S=>Rt(`/test-runs/${S.id}`),markers:x,onMarkerClick:S=>C("marker-click",S.id)}),K=[{color:v[0],label:"Total Duration"},{color:v[1],label:"Avg Test Duration"},{color:v[2],label:"P90 Test Duration"}];return(S,g)=>{const T=Xt,Q=Ce,w=Yt;return s(),r("div",Wa,[e(m).length>0?(s(),r("div",Ya,[a(e(Wt),{ref_key:"xyContainerRef",ref:_,data:e(m),height:U.height,padding:{top:10,right:10,bottom:0,left:0},"on-render-complete":e(P)},{default:t(()=>[a(e(Jt),{x:i,y:[M,D,A],color:v,"curve-type":e(St).MonotoneX,"line-width":2},null,8,["y","curve-type"]),a(e(rt),{type:"x","tick-format":H=>new Date(H).toLocaleDateString("en-US",{month:"short",day:"numeric"}),label:"Date"},null,8,["tick-format"]),a(e(rt),{type:"y",label:"Duration (s)","tick-format":H=>`${H}s`},null,8,["tick-format"])]),_:1},8,["data","height","on-render-complete"]),e(b)?(s(),r("div",{key:0,class:"fixed z-50 pointer-events-none bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 max-w-[260px]",style:qt({left:`${e(z).x}px`,top:`${e(z).y}px`})},[n("div",Za,[n("div",eo,c(new Date(e(b).date).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})),1),n("div",to,"Status: "+c(e(b).status),1),n("div",so,[n("div",null,[g[0]||(g[0]=n("span",{class:"text-blue-500 dark:text-blue-400"},"●",-1)),d(" Total: "+c(e(b).duration??"-")+"s ",1)]),n("div",null,[g[1]||(g[1]=n("span",{class:"text-green-500 dark:text-green-400"},"●",-1)),d(" Avg: "+c(e(b).avgTestDuration??"-")+"s ",1)]),n("div",null,[g[2]||(g[2]=n("span",{class:"text-orange-500 dark:text-orange-400"},"●",-1)),d(" P90: "+c(e(b).p90TestDuration??"-")+"s ",1)]),n("div",no,"Tests: "+c(e(b).totalTests),1),e(b).commit?(s(),r("div",ao," Commit: "+c(e(b).commit),1)):R("",!0)]),g[3]||(g[3]=n("div",{class:"text-gray-400 dark:text-gray-500 text-xs mt-1"},"Click to view run details",-1))])],4)):R("",!0),a(T,{marker:e(p),pos:e(y)},null,8,["marker","pos"])])):(s(),f(Q,{key:1,text:"No performance data available to display chart"})),a(w,{items:K})])}}}),lo=Object.assign(oo,{__name:"PerformanceTrendChart"}),ro={class:"min-w-0"},io={class:"mt-1"},co={class:"tabular-nums"},uo={key:0,class:"ml-1 text-xs text-gray-500",title:"timeout ÷ p95"},mo={class:"tabular-nums text-gray-500"},po={key:0,class:"text-sm"},go={key:1,class:"tabular-nums"},fo={class:"tabular-nums font-medium text-green-600 dark:text-green-400"},_o={class:"tabular-nums text-gray-500"},vo=ie({__name:"TimeoutOpportunitiesTable",props:{projectId:{},projectName:{}},async setup(U){let $,k;const C=U,{data:x,pending:m}=([$,k]=xe(()=>be(()=>`/api/projects/${C.projectId}/timeout-opportunities`,{lazy:!0,server:!1},"$zikJNhkkxJ")),$=await $,k(),$),i=N(()=>x.value??[]);function M(A){return A==null?"—":A<1e3?`${A}ms`:`${(A/1e3).toFixed(1)}s`}const D=[{accessorKey:"title",header:V("Test case")},{accessorKey:"kind",header:"Type"},{accessorKey:"timeout",header:V("Timeout")},{accessorKey:"p95",header:V("p95")},{accessorKey:"recommendedTimeout",header:"Recommendation"},{accessorKey:"estimatedSavingMs",header:V("Est. saving / failure")},{accessorKey:"runCount",header:V("Runs")}];return(A,v)=>{const _=dt,b=Ce,z=Ee,p=ut,y=$e,P=Ve,K=Xe,S=Ge;return s(),f(S,null,{header:t(()=>[...v[0]||(v[0]=[n("h2",{class:"text-xl font-semibold"},"Timeout opportunities",-1),n("p",{class:"text-sm text-gray-600 mt-1"},[d(" Tests whose configured timeout far exceeds their real duration, or that still carry a stale "),n("code",{class:"text-xs"},"test.slow()"),d(" mark — tightening these makes failures surface sooner. ")],-1)])]),default:t(()=>[e(m)?(s(),f(_,{key:0})):e(i).length===0?(s(),f(b,{key:1,text:"No timeout opportunities",description:"No oversized timeouts or stale test.slow() marks were found for this project."})):(s(),f(K,{key:2,"min-width":"52rem",bleed:!1},{default:t(()=>[a(P,{data:e(i),columns:D,sticky:"",class:"max-h-[32rem]"},{"title-cell":t(({row:g})=>[n("div",ro,[a(z,{to:`/test-cases/${g.original.testCaseId}`,class:"font-medium truncate block hover:text-primary hover:underline"},{default:t(()=>[d(c(g.original.title),1)]),_:2},1032,["to"]),n("div",io,[a(p,{"file-path":g.original.filePath,"project-key":U.projectId,"project-name":U.projectName,class:"text-xs"},null,8,["file-path","project-key","project-name"])])])]),"kind-cell":t(({row:g})=>[a(y,{color:g.original.kind==="oversized-timeout"?"warning":"info",variant:"subtle",size:"sm"},{default:t(()=>[d(c(g.original.kind==="oversized-timeout"?"Oversized timeout":"Stale test.slow()"),1)]),_:2},1032,["color"])]),"timeout-cell":t(({row:g})=>[n("span",co,c(M(g.original.timeout)),1),g.original.headroomRatio!=null?(s(),r("span",uo," ("+c(g.original.headroomRatio)+"×) ",1)):R("",!0)]),"p95-cell":t(({row:g})=>[n("span",mo,c(M(g.original.p95)),1)]),"recommendedTimeout-cell":t(({row:g})=>[g.original.kind==="stale-slow"?(s(),r("span",po,[...v[1]||(v[1]=[d("Remove ",-1),n("code",{class:"text-xs"},"test.slow()",-1)])])):(s(),r("span",go,"Lower to ~"+c(M(g.original.recommendedTimeout)),1))]),"estimatedSavingMs-cell":t(({row:g})=>[n("span",fo,c(M(g.original.estimatedSavingMs)),1)]),"runCount-cell":t(({row:g})=>[n("span",_o,c(g.original.runCount),1)]),_:1},8,["data"])]),_:1}))]),_:1})}}}),yo=Object.assign(vo,{__name:"TimeoutOpportunitiesTable"}),ho={class:"flex items-center justify-between"},xo={class:"text-sm text-gray-500 inline-flex items-center gap-1"},bo={class:"truncate font-mono text-xs"},ko={class:"tabular-nums"},$o={class:"tabular-nums text-gray-500"},Co={class:"tabular-nums text-gray-500"},To=ie({__name:"SpecHealthTable",props:{projectId:{}},async setup(U){let $,k;const C=U,x=I(30),{data:m,pending:i}=([$,k]=xe(()=>be(()=>`/api/projects/${C.projectId}/spec-health?days=${x.value}`,{lazy:!0,server:!1,watch:[x]},"$SX5aqvhtuX")),$=await $,k(),$),M=N(()=>m.value?.specs??[]);function D(p){return p>=.9?"bg-green-500":p>=.7?"bg-amber-500":p>0?"bg-red-500":"bg-gray-300 dark:bg-gray-600"}function A(p){return p>=.9?"text-green-600 dark:text-green-400":p>=.7?"text-amber-600 dark:text-amber-400":p>0?"text-red-600 dark:text-red-400":"text-gray-500"}function v(p){return`${Math.round(p*100)}%`}function _(p){return p<1e3?`${p}ms`:`${(p/1e3).toFixed(1)}s`}const b=[{label:"Last 7 days",value:7},{label:"Last 30 days",value:30},{label:"Last 90 days",value:90}],z=[{accessorKey:"prefix",header:V("Spec prefix")},{accessorKey:"passRate",header:V("Pass rate")},{accessorKey:"flakyRate",header:V("Flaky")},{accessorKey:"failureCount",header:V("Failures")},{accessorKey:"testCount",header:V("Tests")},{accessorKey:"avgDuration",header:V("Avg time")}];return(p,y)=>{const P=Qe,K=Be,S=dt,g=Ce,T=Ee,Q=Ve,w=Xe,H=Ge;return s(),f(H,null,{header:t(()=>[n("div",ho,[n("p",xo,[y[1]||(y[1]=d(" Spec-file health overview — pass rate, flaky rate, and failure count per spec prefix ",-1)),a(P,{topic:"project.spec-health"})]),a(K,{modelValue:e(x),"onUpdate:modelValue":y[0]||(y[0]=B=>J(x)?x.value=B:null),items:b,size:"xs",class:"w-32"},null,8,["modelValue"])])]),default:t(()=>[e(i)?(s(),f(S,{key:0})):e(M).length===0?(s(),f(g,{key:1,text:"No data",description:"No spec health data available for the selected period."})):(s(),f(w,{key:2,"min-width":"46rem",bleed:!1},{default:t(()=>[a(Q,{data:e(M),columns:z,sticky:"",class:"max-h-[32rem]"},{"prefix-cell":t(({row:B})=>[a(T,{to:`/projects/${U.projectId}/test-cases?file=${encodeURIComponent(B.original.prefix)}`,class:"flex items-center gap-2 min-w-0 text-primary hover:underline",title:B.original.prefix},{default:t(()=>[n("span",{class:re(["inline-block size-3 rounded shrink-0",D(B.original.passRate)])},null,2),n("span",bo,c(B.original.prefix),1)]),_:2},1032,["to","title"])]),"passRate-cell":t(({row:B})=>[n("span",{class:re(["font-medium tabular-nums",A(B.original.passRate)])},c(v(B.original.passRate)),3)]),"flakyRate-cell":t(({row:B})=>[n("span",ko,c(Math.round(B.original.flakyRate*100))+"%",1)]),"failureCount-cell":t(({row:B})=>[n("span",{class:re(["tabular-nums",B.original.failureCount>0?"text-red-600 dark:text-red-400":""])},c(B.original.failureCount),3)]),"testCount-cell":t(({row:B})=>[n("span",$o,c(B.original.testCount),1)]),"avgDuration-cell":t(({row:B})=>[n("span",Co,c(_(B.original.avgDuration)),1)]),_:1},8,["data"])]),_:1}))]),_:1})}}}),jo=Object.assign(To,{__name:"SpecHealthTable"}),So={class:"space-y-6"},wo={class:"w-full text-sm"},Ro={class:"px-3 py-2 min-w-0"},Do={class:"text-xs text-muted"},Ao={class:"px-3 py-2 text-muted"},zo={class:"px-3 py-2 whitespace-nowrap"},Uo={key:1,class:"text-xs text-muted"},Io={key:2,class:"text-xs"},Mo={class:"px-3 py-2 whitespace-nowrap text-muted"},Fo={class:"px-3 py-2 text-right"},Po={class:"w-full text-sm"},Eo={class:"px-3 py-2 min-w-0"},Bo={class:"text-xs text-muted"},Vo={class:"px-3 py-2 text-right whitespace-nowrap"},Lo=ie({__name:"QuarantineTable",props:{projectId:{},projectName:{}},async setup(U){let $,k;const C=U,x=Ae(),m=I(null),{data:i,status:M,error:D,refresh:A}=([$,k]=xe(()=>be(()=>`/api/projects/${C.projectId}/quarantine`,"$BSyDdCMaDx")),$=await $,k(),$);function v(z){const p=Math.round(z/36e5);return p<48?`${Math.max(1,p)}h`:`${Math.round(p/24)}d`}async function _(z,p){m.value=z;try{await $fetch(`/api/projects/${C.projectId}/quarantine`,{method:"POST",body:{testCaseId:z,reason:p,source:"proposed"}}),x.add({title:"Quarantined",color:"success"}),await A()}catch{x.add({title:"Could not quarantine that test",color:"error"})}finally{m.value=null}}async function b(z){m.value=z;try{await $fetch(`/api/projects/${C.projectId}/quarantine/${z}`,{method:"DELETE"}),x.add({title:"Released",color:"success"}),await A()}catch{x.add({title:"Could not release that test",color:"error"})}finally{m.value=null}}return(z,p)=>{const y=dt,P=dn,K=mn,S=pn,g=Ce,T=Ee,Q=ss,w=ut,H=$e,B=ke,ue=Xe,ge=ct;return s(),r("div",So,[a(ge,{title:"Quarantine",icon:"i-lucide-shield-alert",count:e(i)?.debt.active,help:"project.quarantine"},{subtitle:t(()=>[...p[0]||(p[0]=[d(" A quarantined test keeps running and keeps reporting — it is excluded from the CI gate's verdict and nothing else. That is what lets it earn its way back out. ",-1)])]),default:t(()=>[e(M)==="pending"?(s(),f(y,{key:0})):e(D)?(s(),f(P,{key:1,text:String(e(D))},null,8,["text"])):(s(),r(X,{key:2},[e(i)&&e(i).debt.active>0?(s(),f(S,{key:0,class:"mb-4"},{default:t(()=>[a(K,{label:"Quarantined",value:e(i).debt.active},null,8,["value"]),a(K,{label:"Ready to release",value:e(i).debt.readyToRelease,"value-class":e(i).debt.readyToRelease>0?"text-green-600 dark:text-green-400":"",hint:"earned their way out"},null,8,["value","value-class"]),a(K,{label:"Still failing",value:e(i).debt.stillFailing,hint:"no passing streak"},null,8,["value"]),a(K,{label:"Oldest",value:v(e(i).debt.oldestAgeMs),size:"sm"},null,8,["value"])]),_:1})):R("",!0),!e(i)||e(i).entries.length===0?(s(),f(g,{key:1,icon:"i-lucide-shield-check",text:"Nothing quarantined. Tests you quarantine appear here with their progress back out."})):(s(),f(ue,{key:2},{default:t(()=>[n("table",wo,[p[2]||(p[2]=n("thead",{class:"text-left text-xs text-muted"},[n("tr",null,[n("th",{class:"px-3 py-2"},"Test"),n("th",{class:"px-3 py-2"},"Reason"),n("th",{class:"px-3 py-2 whitespace-nowrap"},"Streak"),n("th",{class:"px-3 py-2 whitespace-nowrap"},"Age"),n("th",{class:"px-3 py-2 text-right"},"Actions")])],-1)),n("tbody",null,[(s(!0),r(X,null,ae(e(i).entries,h=>(s(),r("tr",{key:h.id,class:"border-t border-default"},[n("td",Ro,[a(T,{to:`/test-cases/${h.testCaseId}`,class:"text-primary hover:underline font-medium"},{default:t(()=>[d(c(h.title),1)]),_:2},1032,["to"]),a(Q,{tags:h.tags,meta:{owner:h.owner??void 0},"max-tags":3,class:"ml-1"},null,8,["tags","meta"]),n("div",Do,[a(w,{"file-path":h.filePath,"project-key":U.projectId,"project-name":U.projectName},null,8,["file-path","project-key","project-name"])])]),n("td",Ao,c(h.reason||"—"),1),n("td",zo,[h.releaseProposed?(s(),f(H,{key:0,color:"success",variant:"soft",size:"xs"},{default:t(()=>[d(c(h.consecutivePasses)+" green — ready ",1)]),_:2},1024)):h.runsSinceQuarantine===0?(s(),r("span",Uo,"not run yet")):(s(),r("span",Io,c(h.consecutivePasses)+" / "+c(e(i).releaseAfterConsecutivePasses),1))]),n("td",Mo,c(v(h.ageMs)),1),n("td",Fo,[a(B,{size:"xs",color:h.releaseProposed?"primary":"neutral",variant:"soft",loading:e(m)===h.testCaseId,onClick:j=>b(h.testCaseId)},{default:t(()=>[...p[1]||(p[1]=[d(" Release ",-1)])]),_:1},8,["color","loading","onClick"])])]))),128))])])]),_:1}))],64))]),_:1},8,["count"]),e(i)&&e(i).candidates.length>0?(s(),f(ge,{key:0,title:"Worth quarantining",icon:"i-lucide-lightbulb",count:e(i).candidates.length},{subtitle:t(()=>[...p[3]||(p[3]=[d(" Ranked by the CI minutes their flakiness wastes, not by how often they flake — a test that flakes constantly but finishes instantly costs nothing. ",-1)])]),default:t(()=>[a(ue,null,{default:t(()=>[n("table",Po,[n("tbody",null,[(s(!0),r(X,null,ae(e(i).candidates,h=>(s(),r("tr",{key:h.testCaseId,class:"border-t border-default"},[n("td",Eo,[a(T,{to:`/test-cases/${h.testCaseId}`,class:"text-primary hover:underline font-medium"},{default:t(()=>[d(c(h.title),1)]),_:2},1032,["to"]),n("div",Bo,c(h.rationale),1)]),n("td",Vo,[a(B,{size:"xs",color:"neutral",variant:"soft",loading:e(m)===h.testCaseId,onClick:j=>_(h.testCaseId,h.rationale)},{default:t(()=>[...p[4]||(p[4]=[d(" Quarantine ",-1)])]),_:1},8,["loading","onClick"])])]))),128))])])]),_:1})]),_:1},8,["count"])):R("",!0)])}}}),No=Object.assign(Lo,{__name:"QuarantineTable"}),Ko={class:"space-y-4"},Oo={class:"grid grid-cols-1 sm:grid-cols-2 gap-4"},qo={id:"marker-environments"},Ho=["value"],Qo=ie({__name:"MarkerFormModal",props:{open:{type:Boolean},projectId:{},marker:{},environments:{}},emits:["update:open","saved"],setup(U,{emit:$}){const k=U,C=$,x=Ae(),m=vn.map(_=>({label:_.label,value:_.id,icon:_.icon})),i=Ps({label:"",occurredAt:"",category:Tt,environment:"",description:""}),M=N(()=>!!k.marker),D=I(!1);function A(_){const b=new Date(_),z=p=>String(p).padStart(2,"0");return`${b.getFullYear()}-${z(b.getMonth()+1)}-${z(b.getDate())}T${z(b.getHours())}:${z(b.getMinutes())}`}ye(()=>k.open,_=>{_&&(k.marker?(i.label=k.marker.label,i.occurredAt=A(k.marker.occurredAt),i.category=k.marker.category||Tt,i.environment=k.marker.environment??"",i.description=k.marker.description??""):(i.label="",i.occurredAt=A(new Date),i.category=Tt,i.environment="",i.description=""))});async function v(){if(!i.label.trim()){x.add({title:"Label is required",color:"error"});return}if(!i.occurredAt){x.add({title:"Date is required",color:"error"});return}D.value=!0;const _={label:i.label.trim(),occurredAt:new Date(i.occurredAt).toISOString(),category:i.category,environment:i.environment.trim()||null,description:i.description.trim()||null};try{k.marker?(await $fetch(`/api/markers/${k.marker.id}`,{method:"PUT",body:_}),x.add({title:"Marker updated",color:"success"})):(await $fetch(`/api/projects/${k.projectId}/markers`,{method:"POST",body:_}),x.add({title:"Marker created",color:"success"})),C("update:open",!1),C("saved")}catch(b){x.add({title:M.value?"Failed to update marker":"Failed to create marker",description:ts(b),color:"error"})}finally{D.value=!1}}return(_,b)=>{const z=Ht,p=Qt,y=Be,P=_n,K=ke,S=zt,g=Dt;return s(),f(g,null,{default:t(()=>[a(S,{open:U.open,title:e(M)?"Edit marker":"Add marker","onUpdate:open":b[6]||(b[6]=T=>C("update:open",T))},{body:t(()=>[n("div",Ko,[a(p,{label:"Label",name:"label",required:""},{default:t(()=>[a(z,{modelValue:e(i).label,"onUpdate:modelValue":b[0]||(b[0]=T=>e(i).label=T),placeholder:"e.g. Migrated CI to new runners",class:"w-full"},null,8,["modelValue"])]),_:1}),n("div",Oo,[a(p,{label:"Date & time",name:"occurredAt",required:""},{default:t(()=>[a(z,{modelValue:e(i).occurredAt,"onUpdate:modelValue":b[1]||(b[1]=T=>e(i).occurredAt=T),type:"datetime-local",class:"w-full"},null,8,["modelValue"])]),_:1}),a(p,{label:"Category",name:"category"},{default:t(()=>[a(y,{modelValue:e(i).category,"onUpdate:modelValue":b[2]||(b[2]=T=>e(i).category=T),items:e(m),class:"w-full"},null,8,["modelValue","items"])]),_:1})]),a(p,{label:"Environment",name:"environment",help:"Optional. Leave empty to apply to all environments."},{default:t(()=>[a(z,{modelValue:e(i).environment,"onUpdate:modelValue":b[3]||(b[3]=T=>e(i).environment=T),list:"marker-environments",placeholder:"e.g. production",class:"w-full"},null,8,["modelValue"]),n("datalist",qo,[(s(!0),r(X,null,ae(U.environments||[],T=>(s(),r("option",{key:T,value:T},null,8,Ho))),128))])]),_:1}),a(p,{label:"Description",name:"description"},{default:t(()=>[a(P,{modelValue:e(i).description,"onUpdate:modelValue":b[4]||(b[4]=T=>e(i).description=T),rows:3,placeholder:"Optional details",class:"w-full"},null,8,["modelValue"])]),_:1})])]),footer:t(()=>[a(K,{color:"neutral",variant:"ghost",label:"Cancel",onClick:b[5]||(b[5]=T=>C("update:open",!1))}),a(K,{label:e(M)?"Save changes":"Add marker",icon:e(M)?"i-lucide-check":"i-lucide-plus",loading:e(D),onClick:v},null,8,["label","icon","loading"])]),_:1},8,["open","title"])]),_:1})}}}),Go=Object.assign(Qo,{__name:"MarkerFormModal"}),Xo={class:"md:hidden space-y-3"},Jo={class:"flex items-start justify-between gap-2"},Wo={key:0,class:"flex gap-1 shrink-0"},Yo={class:"text-sm text-muted"},Zo={key:0,class:"text-xs"},el={key:1,class:"text-sm text-muted"},tl={class:"whitespace-nowrap"},sl={class:"text-sm"},nl={class:"text-xs text-muted"},al={class:"font-medium flex items-center gap-1"},ol={key:0,class:"text-xs text-muted line-clamp-1"},ll={key:1,class:"text-xs text-muted"},rl={key:0,class:"flex gap-1 justify-end"},il=ie({__name:"ProjectTimeline",props:{projectId:{},markers:{},environments:{},canEdit:{type:Boolean},focusMarkerId:{}},emits:["changed","clear-focus"],setup(U,{emit:$}){const k=U,C=$,x=Ae(),m=N(()=>[...k.markers].sort((y,P)=>+new Date(P.occurredAt)-+new Date(y.occurredAt))),i=[{accessorKey:"occurredAt",header:"When"},{accessorKey:"category",header:"Category"},{accessorKey:"label",header:"Label"},{accessorKey:"environment",header:"Environment"},{accessorKey:"actions",header:""}],M=I(!1),D=I(null);function A(){D.value=null,M.value=!0}function v(y){D.value=y,M.value=!0}ye(()=>k.focusMarkerId,y=>{if(y==null)return;const P=k.markers.find(K=>K.id===y);P&&v(P),C("clear-focus")},{immediate:!0});const _=I(!1),b=I(null);function z(y){b.value=y,_.value=!0}async function p(){const y=b.value;if(_.value=!1,b.value=null,!!y)try{await $fetch(`/api/markers/${y.id}`,{method:"DELETE"}),x.add({title:"Marker deleted",color:"success"}),C("changed")}catch(P){x.add({title:"Failed to delete marker",description:ts(P),color:"error"})}}return(y,P)=>{const K=ke,S=Ce,g=fn,T=$e,Q=Pe,w=Ve,H=Go,B=zt,ue=Dt,ge=ct;return s(),f(ge,{title:"Timeline markers",count:U.markers.length,icon:"i-lucide-milestone",help:"project.timeline",subtitle:"Dated events overlaid on the analytics charts"},{actions:t(()=>[U.canEdit?(s(),f(K,{key:0,label:"Add marker",icon:"i-lucide-plus",size:"sm",onClick:A})):R("",!0)]),default:t(()=>[U.markers.length===0?(s(),f(S,{key:0,icon:"i-lucide-milestone",text:"No markers yet. Add a deploy, config change, or incident to see it on the charts."})):(s(),r(X,{key:1},[n("div",Xo,[(s(!0),r(X,null,ae(e(m),h=>(s(),r("div",{key:h.id,class:"rounded-lg border border-default p-3 space-y-2"},[n("div",Jo,[a(g,{marker:h},null,8,["marker"]),U.canEdit?(s(),r("div",Wo,[a(K,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"xs",onClick:j=>v(h)},null,8,["onClick"]),a(K,{icon:"i-lucide-trash-2",color:"error",variant:"ghost",size:"xs",onClick:j=>z(h)},null,8,["onClick"])])):R("",!0)]),n("div",Yo,c(("prettyDateFormat"in y?y.prettyDateFormat:e(it))(h.occurredAt)),1),h.environment?(s(),r("div",Zo,[a(T,{color:"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(c(h.environment),1)]),_:2},1024)])):R("",!0),h.description?(s(),r("p",el,c(h.description),1)):R("",!0)]))),128))]),a(w,{data:e(m),columns:i,class:"hidden md:block"},{"occurredAt-cell":t(({row:h})=>[n("div",tl,[n("div",sl,c(("prettyDateFormat"in y?y.prettyDateFormat:e(it))(h.original.occurredAt)),1),n("div",nl,c(("formatRelativeTime"in y?y.formatRelativeTime:e(At))(h.original.occurredAt)),1)])]),"category-cell":t(({row:h})=>[a(T,{color:e(jt)(h.original.category).color,variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(Q,{name:e(jt)(h.original.category).icon,class:"size-3"},null,8,["name"]),d(" "+c(e(jt)(h.original.category).label),1)]),_:2},1032,["color"])]),"label-cell":t(({row:h})=>[n("div",null,[n("div",al,[d(c(h.original.label)+" ",1),h.original.source==="auto"?(s(),f(Q,{key:0,name:"i-lucide-sparkles",class:"size-3 text-muted",title:"Automatically detected"})):R("",!0)]),h.original.description?(s(),r("div",ol,c(h.original.description),1)):R("",!0)])]),"environment-cell":t(({row:h})=>[h.original.environment?(s(),f(T,{key:0,color:"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(c(h.original.environment),1)]),_:2},1024)):(s(),r("span",ll,"All"))]),"actions-cell":t(({row:h})=>[U.canEdit?(s(),r("div",rl,[a(K,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"sm",onClick:j=>v(h.original)},null,8,["onClick"]),a(K,{icon:"i-lucide-trash-2",color:"error",variant:"ghost",size:"sm",onClick:j=>z(h.original)},null,8,["onClick"])])):R("",!0)]),_:1},8,["data"])],64)),a(H,{open:e(M),"onUpdate:open":P[0]||(P[0]=h=>J(M)?M.value=h:null),"project-id":U.projectId,marker:e(D),environments:U.environments,onSaved:P[1]||(P[1]=h=>C("changed"))},null,8,["open","project-id","marker","environments"]),a(ue,null,{default:t(()=>[a(B,{open:e(_),title:"Delete marker","onUpdate:open":P[3]||(P[3]=h=>_.value=h)},{body:t(()=>[n("p",null,[P[4]||(P[4]=d(" Delete marker ",-1)),e(b)?(s(),f(g,{key:0,marker:e(b),class:"inline-flex align-middle"},null,8,["marker"])):R("",!0),P[5]||(P[5]=d("? This can't be undone. ",-1))])]),footer:t(()=>[a(K,{color:"neutral",variant:"ghost",label:"Cancel",onClick:P[2]||(P[2]=h=>_.value=!1)}),a(K,{color:"error",label:"Delete",icon:"i-lucide-trash-2",onClick:p})]),_:1},8,["open"])]),_:1})]),_:1},8,["count"])}}}),cl=Object.assign(il,{__name:"ProjectTimeline"}),ul={class:"flex flex-col h-full overflow-y-auto gap-4"},dl={key:0,class:"pb-0 space-y-4"},ml={key:0,class:"text-gray-600"},pl={key:1,class:"flex flex-wrap gap-1 mt-2"},gl={class:"flex flex-wrap items-center gap-3 mb-4"},fl={class:"inline-flex items-center gap-1"},_l=["onClick"],vl={key:0,class:"flex items-center gap-3 px-3 py-2 mb-3 rounded-lg bg-primary-50 dark:bg-primary-900/20 border border-primary-200 dark:border-primary-800"},yl={class:"text-sm text-primary-700 dark:text-primary-300"},hl={key:1,class:"text-xs text-primary-500"},xl=["checked","onClick"],bl={class:"flex items-center gap-2"},kl=["href","onClick"],$l={key:0,class:"text-xs text-gray-500 dark:text-gray-400 truncate max-w-32"},Cl={class:"inline-flex items-center gap-1"},Tl={key:0,class:"flex items-center gap-1"},jl={class:"text-xs text-gray-600"},Sl={key:0,class:"flex items-center gap-1 flex-wrap"},wl={key:0,class:"text-xs font-medium bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded"},Rl={key:1,class:"text-xs text-gray-500"},Dl={class:"space-y-1"},Al={class:"flex justify-end gap-2"},zl={key:2,class:"text-center py-8 text-gray-500"},Ul={class:"text-xs text-gray-400 max-w-sm"},Il={class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},Ml={class:"flex flex-wrap items-center gap-3"},Fl={class:"text-xl font-semibold inline-flex items-center gap-1"},Pl={class:"font-medium"},El={class:"mt-1"},Bl={key:0,class:"text-red-600 font-medium"},Vl={key:1,class:"text-green-600 font-medium"},Ll={key:2,class:"text-gray-500"},Nl={key:2,class:"text-center py-8 text-red-500"},Kl={key:3,class:"text-center py-8 text-gray-500"},Ol={class:"flex items-center justify-between"},ql={class:"text-xl font-semibold inline-flex items-center gap-1"},Hl={class:"space-y-4"},Ql={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},Gl={key:0,class:"text-center py-4 text-gray-500"},Xl={key:1,class:"space-y-4"},Jl={class:"flex gap-4 text-sm"},Wl={key:0,class:"text-gray-400"},Yl={key:0,class:"text-gray-400"},Zl={key:1,class:"text-gray-400"},er={key:1,class:"text-gray-400"},tr={key:0,class:"text-gray-400"},sr={key:0,class:"text-gray-400"},nr={key:2,class:"text-center py-8 text-gray-500"},ar={key:3,class:"text-center py-8 text-gray-500"},or={class:"flex items-center justify-between"},lr={class:"text-sm text-gray-600 inline-flex items-center gap-1"},rr={class:"space-y-4"},ir={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},cr={key:0,class:"text-center py-8 text-gray-500"},ur={key:1,class:"space-y-4"},dr={class:"space-y-2"},mr={class:"flex flex-wrap gap-4 text-sm"},pr={key:3,class:"text-sm text-gray-500"},gr={class:"flex flex-wrap gap-4 text-sm"},fr={key:0,class:"text-gray-400"},_r={key:0,class:"text-gray-400"},vr={key:1,class:"text-gray-400"},yr={key:1,class:"text-gray-400"},hr={key:0,class:"text-gray-400"},xr={key:0,class:"text-gray-400"},br={key:2,class:"text-center py-8 text-gray-500"},kr={key:3,class:"text-center py-8 text-gray-500"},$r={class:"flex items-center justify-between"},Cr={class:"text-sm text-gray-600 inline-flex items-center gap-1"},Tr={key:0,class:"space-y-2"},jr={class:"font-medium text-sm"},Sr={class:"text-xs text-muted flex items-center gap-2"},wr={key:0,class:"italic"},Rr={key:1,class:"text-xs text-muted italic"},Dr={key:1,class:"text-center py-8 text-muted text-sm"},Ar={class:"space-y-4"},zr={class:"text-sm text-gray-600 dark:text-gray-400"},Ur={class:"block text-sm font-medium mb-1"},Ir={class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},Vi=ie({__name:"index",async setup(U){let $,k;const C=Es(),x=Bs(),m=C.params.id,{data:i,refresh:M}=([$,k]=xe(()=>be(`/api/projects/${m}`,"$F60FKvNOBL")),$=await $,k(),$);Vs(N(()=>({title:`${i.value?.label||i.value?.name||"Project"} — Piwi Dashboard`})));const D=Ae(),A=I(null),v=I(null),{isAdmin:_,isReporter:b}=Ot(),z=wt(),p=N(()=>!z.public.authEnabled||_.value),y=p,P=I(!1),K=I(""),S=I(!1),g=N(()=>K.value===i.value?.name);async function T(){if(g.value){S.value=!0;try{await $fetch(`/api/projects/${m}`,{method:"DELETE"}),D.add({title:"Project deleted",color:"success"}),await Ns(),await x.push("/")}catch(u){const o=u&&typeof u=="object"&&"data"in u?u.data?.message:void 0;D.add({title:"Delete failed",description:o||"An error occurred",color:"error"}),S.value=!1}}}xn(M);async function Q(u){v.value=null,A.value=u;try{await $fetch(`/api/test-runs/${u}`,{method:"DELETE"}),D.add({title:"Test run deleted",color:"success"}),await M()}catch(o){const E=o&&typeof o=="object"&&"data"in o?o.data?.message:void 0;D.add({title:"Delete failed",description:E||"An error occurred",color:"error"})}finally{A.value=null}}const w=I([]),H=I([]),B=I([]),ue=N(()=>{const u=new Map(w.value.map(E=>[E.id,E])),o=[];for(const E of H.value){if(E.role==="administrator")continue;const G=u.get(E.id);o.push({id:E.id,username:E.username,name:E.name??null,role:E.role,global:G?.global??!1,hasAccess:!!G})}for(const E of w.value)E.role==="administrator"&&o.push({...E,hasAccess:!0});return o}),ge=N(()=>{const u=w.value.filter(E=>E.role!=="administrator"&&!E.global).map(E=>E.id).sort(),o=[...B.value].sort();return JSON.stringify(u)!==JSON.stringify(o)});ye(()=>i.value?.id,async u=>{if(!(!u||!_.value))try{const[o,E]=await Promise.all([$fetch(`/api/projects/${m}/members`),$fetch("/api/users")]);w.value=o.users,H.value=E.users,B.value=o.users.filter(G=>G.role!=="administrator"&&!G.global).map(G=>G.id)}catch{w.value=[],H.value=[],B.value=[]}},{immediate:!0});function h(u){const o=B.value.indexOf(u);o>=0?B.value.splice(o,1):B.value.push(u)}async function j(){try{await $fetch(`/api/projects/${m}/members`,{method:"PUT",body:{userIds:B.value}}),D.add({title:"Members updated",color:"success"});const u=await $fetch(`/api/projects/${m}/members`);w.value=u.users}catch(u){const o=u&&typeof u=="object"&&"data"in u?u.data?.message:void 0;D.add({title:"Update failed",description:o||"An error occurred",color:"error"})}}const q=I("test-runs"),de=I(0),ze=["test-runs","failure-clusters","flaky-tests","performance","test-cases","compare","spec-health","quarantine","timeline","members"],me=C.query.tab;typeof me=="string"&&ze.includes(me)&&(q.value=me),ye(q,u=>{C.query.tab!==u&&ze.includes(u)&&x.replace({query:{...C.query,tab:u}})});const he=N(()=>i.value?.testRuns?.some(u=>u.failedTests>0)??!1),fe=N(()=>[{label:"Results",items:[{label:`Test runs (${L.value.length})`,icon:"i-lucide-play-circle",value:"test-runs",slot:"test-runs"},{label:`Test cases${qe.value!=null?` (${qe.value})`:""}`,icon:"i-lucide-list-checks",value:"test-cases",slot:"test-cases"},{label:"Compare",icon:"i-lucide-git-compare-arrows",value:"compare",slot:"compare"}]},{label:"Failures",items:[...he.value?[{label:"Failure clusters",icon:"i-lucide-layers",value:"failure-clusters",slot:"failure-clusters"}]:[],{label:"Flaky tests",icon:"i-lucide-shuffle",value:"flaky-tests",slot:"flaky-tests"},{label:"Quarantine",icon:"i-lucide-shield-alert",value:"quarantine",slot:"quarantine"}]},{label:"Health",items:[{label:"Spec health",icon:"i-lucide-table-2",value:"spec-health",slot:"spec-health"},{label:"Performance",icon:"i-lucide-trending-up",value:"performance",slot:"performance"},{label:`Timeline${Te.value.length?` (${Te.value.length})`:""}`,icon:"i-lucide-milestone",value:"timeline",slot:"timeline"}]},..._.value?[{label:"Admin",items:[{label:"Members",icon:"i-lucide-users",value:"members",slot:"members"}]}]:[]]),Ue=N(()=>fe.value.flatMap(u=>u.items)),mt=N(()=>fe.value.map(u=>u.items).filter(u=>u.length>0)),pt=N(()=>Ue.value.find(u=>u.value===q.value)?.icon),Y=I([]),Je=u=>Y.value.includes(u);function Le(u){const o=Y.value.indexOf(u);if(o>=0)Y.value.splice(o,1);else{if(Y.value.length>=2){D.add({title:"Maximum 2 runs",description:"Select at most 2 runs to compare. Deselect one first.",color:"warning"});return}Y.value.push(u)}}const Ne=I(null);function gt(){Y.value.length===2&&(Ne.value=[Y.value[0],Y.value[1]],q.value="compare")}const ne=I([]),pe=I(!0),Ke=N(()=>{const u=new Set;for(const o of i.value?.testRuns||[])o.environment&&u.add(o.environment);return[...u].sort()});function ft(u){const o=ne.value.indexOf(u);o===-1?ne.value.push(u):ne.value.splice(o,1)}function Oe(u){return ne.value.includes(u)}const L=N(()=>{let u=i.value?.testRuns||[];return pe.value&&(u=u.filter(o=>o.isFullRun!==!1)),ne.value.length===0?u:u.filter(o=>o.environment&&ne.value.includes(o.environment))}),F=N(()=>ne.value.length===1?ne.value[0]:void 0),{data:Z,refresh:_t}=([$,k]=xe(()=>be(`/api/projects/${m}/markers`,{default:()=>({markers:[]})},"$jubPXy8o3y")),$=await $,k(),$),Te=N(()=>Z.value?.markers??[]),We=N(()=>!z.public.authEnabled||_.value||b.value),Ye=N(()=>ne.value.length===0?Te.value:Te.value.filter(u=>u.environment==null||ne.value.includes(u.environment))),Ie=I(null);function je(u){Ie.value=u,q.value="timeline"}const vt=N(()=>{const u=i.value?.testRuns||[];return pe.value?u.filter(o=>o.isFullRun!==!1):u});function O(u){if(u.isFullRun!==!1)return"Full run — the complete test suite ran";const o=[],E=u.filterDetails?.grep?.trim(),G=u.filterDetails?.grepInvert?.trim(),_e=u.filterDetails?.files;return E&&E!==".*"&&o.push(`grep: ${E}`),G&&o.push(`grep-invert: ${G}`),_e?.length&&o.push(`files: ${_e.join(", ")}`),o.length?`Partial run — ${o.join(" · ")}`:"Partial run — only a filtered subset of tests ran (grep, file, or line filter)"}const oe=[{accessorKey:"select",header:""},{accessorKey:"id",header:V("Run")},{accessorKey:"status",header:V("Status")},{accessorKey:"isFullRun",header:"Scope"},{id:"browsers",accessorFn:u=>u.browsers,header:""},{accessorKey:"startTime",header:V("Started")},{accessorKey:"environment",header:V("Environment")},{accessorKey:"metadata",header:"Branch / Commit"},{accessorKey:"duration",header:V("Test status / Dur.")},{accessorKey:"reports",header:"Reports"},{id:"actions",header:"Actions"}],qe=I(null),Se=I(""),we=I(""),ns=N(()=>{const u={};return Se.value&&(u.from=Se.value),we.value&&(u.to=we.value),u}),yt=I(null),ht=I(!1),Me=I(null),xt=I(!1),Ze=I(!1),as=N(()=>ht.value&&yt.value===null);ye([q,ns,pe],async([u,o])=>{if(u!=="performance")return;ht.value=!0,Me.value||(Ze.value=!0);const E=new URLSearchParams(o).toString(),G=pe.value?`${E?"&":""}fullRunsOnly=true`:"",_e=E||G?`?${E}${G}`:"";yt.value=await $fetch(`/api/projects/${m}/performance${_e}`).catch(ve=>(console.warn("[PerformanceTab] Failed to fetch performance trend:",ve),null)),ht.value=!1,Ze.value&&(xt.value=!1,Me.value=await $fetch(`/api/projects/${m}/slow-tests`).catch(ve=>(xt.value=!0,console.warn("[PerformanceTab] Failed to fetch slow tests:",ve),null)),Ze.value=!1)},{immediate:!0});const os=[{accessorKey:"title",header:V("Test case")},{accessorKey:"avgDuration",header:V("Avg duration")},{accessorKey:"maxDuration",header:V("Max")},{accessorKey:"minDuration",header:V("Min")},{accessorKey:"latestDuration",header:V("Latest")},{accessorKey:"trend",header:V("Trend")},{accessorKey:"runCount",header:V("Runs")}];function ls(u){const o=it(u.startTime,{dateOnly:!0}),E=u.metadata?.scm?.commit?` (${u.metadata.scm.commit.substring(0,7)})`:"";return`Run #${u.id} — ${o}${E}`}const ce=N(()=>i.value?.testRuns?[...i.value.testRuns].reverse().map(u=>({label:ls(u),value:u.id})):[]),ee=I(void 0),te=I(void 0),Ut=N(()=>C.query.runA?Number(C.query.runA):null),It=N(()=>C.query.runB?Number(C.query.runB):null);ye(ce,u=>{if(Ut.value){const o=u.find(E=>E.value===Ut.value);o&&(ee.value=o)}if(It.value){const o=u.find(E=>E.value===It.value);o&&(te.value=o)}},{immediate:!0}),ye(Ne,u=>{if(u){const o=ce.value.find(G=>G.value===u[0]),E=ce.value.find(G=>G.value===u[1]);o&&(ee.value=o),E&&(te.value=E),Ne.value=null}});function Mt(){ce.value.length>=2&&(ee.value=ce.value[1],te.value=ce.value[0])}const bt=I(null),kt=I(null),et=I(!1);async function rs(){const u=ee.value,o=te.value;if(!(!u?.value&&!o?.value)){et.value=!0;try{const E=[];u?.value&&E.push(u.value),o?.value&&E.push(o.value);const G=await Promise.all(E.map(ve=>$fetch(`/api/test-runs/${ve}/summary`))),_e=new Map;for(const ve of G)_e.set(ve.id,ve);bt.value=u?.value?_e.get(u.value)??null:null,kt.value=o?.value?_e.get(o.value)??null:null}catch{bt.value=null,kt.value=null}finally{et.value=!1}}}ye([ee,te],()=>{rs()});const{comparisonData:tt,comparisonSummary:W}=hn(bt,kt),Ft=[{accessorKey:"title",header:V("Test case")},{accessorKey:"statusA",header:V("Status A")},{accessorKey:"statusB",header:V("Status B")},{accessorKey:"durationA",header:V("Duration A")},{accessorKey:"durationB",header:V("Duration B")},{accessorKey:"delta",header:V("Delta")},{accessorKey:"percentChange",header:V("Change")}];return(u,o)=>{const E=Is,G=Ms,_e=Qn,ve=Hs,is=Gs,cs=Gt,us=ea,ds=Be,ms=ca,Pt=Ws,ps=Ys,Fe=Qe,le=ke,gs=Zs,$t=Pe,fs=es,_s=en,se=$e,vs=tn,Re=sn,ys=nn,st=Ve,hs=Os,xs=Ce,He=Ge,bs=ha,ks=Ua,$s=Ja,Ct=Ht,Et=dt,Cs=lo,Ts=ut,js=yo,nt=cn,Ss=un,ws=jo,Rs=No,Ds=gn,As=cl,zs=yn,Us=Qs,Bt=zt,Vt=Dt;return s(),r(X,null,[a(Us,{id:"project-detail"},{header:t(()=>[a(is,null,{leading:t(()=>[a(E),a(G,{items:[{label:"Home",icon:"i-lucide-house",to:"/"},{label:"Projects",to:"/projects"},{label:e(i)?.label||e(i)?.name||"Project"}]},null,8,["items"])]),right:t(()=>[a(ve,{size:"sm",actions:[...e(p)?[{label:"Delete",icon:"i-lucide-trash-2",color:"error",variant:"ghost",onClick:()=>{K.value="",P.value=!0}}]:[],...e(y)?[{label:"Import",icon:"i-lucide-import",variant:"outline",to:`/projects/${e(m)}/import`}]:[],{label:"Test functions",icon:"i-lucide-function-square",variant:"outline",to:`/projects/${e(m)}/test-functions`},{label:"Edit",icon:"i-lucide-pencil",variant:"outline",to:`/projects/${e(m)}/edit`},{label:"Refresh",icon:"i-lucide-refresh-cw",variant:"outline",onClick:()=>e(M)()}]},{leading:t(()=>[a(_e,{"project-id":parseInt(e(m)),"project-label":e(i)?.label||e(i)?.name},null,8,["project-id","project-label"])]),_:1},8,["actions"])]),_:1})]),body:t(()=>[n("div",ul,[e(i)?.description||e(i)?.tags&&e(i).tags.length>0?(s(),r("div",dl,[e(i)?.description?(s(),r("p",ml,c(e(i).description),1)):R("",!0),e(i)?.tags&&e(i).tags.length>0?(s(),r("div",pl,[(s(!0),r(X,null,ae(e(i).tags,l=>(s(),f(cs,{key:l.id,text:l.text,color:l.color},null,8,["text","color"]))),128))])):R("",!0)])):R("",!0),a(us,{"project-id":e(m)},null,8,["project-id"]),a(ds,{modelValue:e(q),"onUpdate:modelValue":o[0]||(o[0]=l=>J(q)?q.value=l:null),items:e(mt),icon:e(pt),size:"md",class:"w-full mx-1 mb-1 sm:hidden"},null,8,["modelValue","items","icon"]),a(zs,{modelValue:e(q),"onUpdate:modelValue":o[14]||(o[14]=l=>J(q)?q.value=l:null),items:e(Ue),size:"sm",class:"p-1",ui:{list:"max-sm:hidden overflow-x-auto",trigger:"shrink-0"}},{"test-runs":t(()=>[e(i)?.testRuns&&e(i).testRuns.length>0?(s(),f(Pt,{key:0,title:"Run trend",subtitle:`Test run statistics over time for ${e(i)?.label||e(i)?.name}`,help:"project.runs-trend"},{default:t(()=>[a(ms,{"test-runs":e(vt),height:200,markers:e(Ye),onMarkerClick:je},null,8,["test-runs","markers"])]),_:1},8,["subtitle"])):R("",!0),a(He,{class:"mt-4"},{default:t(()=>[n("div",gl,[n("div",fl,[a(ps,{modelValue:e(pe),"onUpdate:modelValue":o[1]||(o[1]=l=>J(pe)?pe.value=l:null),label:"Full runs only",ui:{label:"text-sm"}},null,8,["modelValue"]),a(Fe,{topic:"project.run-scope"})]),e(Ke).length>0?(s(),r(X,{key:0},[o[21]||(o[21]=n("span",{class:"text-sm text-muted shrink-0"},"Environment:",-1)),(s(!0),r(X,null,ae(e(Ke),l=>(s(),r("button",{key:l,type:"button",class:re(["text-xs font-medium px-2 py-1 rounded border cursor-pointer focus:outline-none transition-colors",Oe(l)?"bg-blue-100 text-blue-700 border-blue-300 dark:bg-blue-900/40 dark:text-blue-300 dark:border-blue-700":"bg-zinc-100 text-zinc-500 border-zinc-200 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-400 dark:border-zinc-700 dark:hover:bg-zinc-700"]),onClick:De=>ft(l)},c(l),11,_l))),128)),e(ne).length>0?(s(),f(le,{key:0,size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear filter",onClick:o[2]||(o[2]=l=>ne.value=[])})):R("",!0)],64)):R("",!0)]),e(Y).length>0?(s(),r("div",vl,[n("span",yl,c(e(Y).length)+" run"+c(e(Y).length>1?"s":"")+" selected ",1),e(Y).length===2?(s(),f(le,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",color:"primary",label:"Compare selected runs",onClick:gt})):(s(),r("span",hl," Select another run to compare ")),a(le,{size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear",onClick:o[3]||(o[3]=l=>Y.value=[])})])):R("",!0),e(L).length>0?(s(),f(st,{key:1,data:e(L),columns:oe,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"select-cell":t(({row:l})=>[n("input",{type:"checkbox",checked:Je(l.original.id),class:"cursor-pointer size-4 accent-primary",onClick:Kt(De=>Le(l.original.id),["stop"])},null,8,xl)]),"id-cell":t(({row:l})=>[n("div",bl,[n("a",{href:`/test-runs/${l.original.id}`,class:"text-primary hover:underline font-medium",onClick:Kt(De=>("navigateTo"in u?u.navigateTo:e(Rt))(`/test-runs/${l.original.id}`),["prevent"])}," Run #"+c(l.original.id),9,kl),l.original.label?(s(),r("span",$l,c(l.original.label),1)):R("",!0)])]),"status-cell":t(({row:l})=>[a(gs,{status:l.original.status},null,8,["status"])]),"isFullRun-header":t(()=>[n("span",Cl,[o[22]||(o[22]=d("Scope ",-1)),a(Fe,{topic:"run.partial"})])]),"isFullRun-cell":t(({row:l})=>[a(fs,{text:O(l.original)},{default:t(()=>[a($t,{name:l.original.isFullRun===!1?"i-lucide-list-filter":"i-lucide-list-checks",class:re(["size-4 shrink-0 cursor-help",l.original.isFullRun===!1?"text-amber-500":"text-green-500"])},null,8,["name","class"])]),_:2},1032,["text"])]),"browsers-cell":t(({row:l})=>[l.original.browsers?.length?(s(),r("div",Tl,[(s(!0),r(X,null,ae(l.original.browsers,De=>(s(),f(_s,{key:De,browser:{projectName:De},size:"sm"},null,8,["browser"]))),128))])):R("",!0)]),"startTime-cell":t(({row:l})=>[n("span",jl,c(("prettyDateFormat"in u?u.prettyDateFormat:e(it))(l.original.startTime)),1)]),"environment-cell":t(({row:l})=>[l.original.environment?(s(),f(se,{key:0,color:"info",variant:"subtle",size:"sm"},{default:t(()=>[d(c(l.original.environment),1)]),_:2},1024)):R("",!0)]),"metadata-cell":t(({row:l})=>[l.original.metadata?.scm?(s(),r("div",Sl,[l.original.metadata.scm.branch?(s(),r("span",wl,c(l.original.metadata.scm.branch),1)):R("",!0),l.original.metadata.scm.commit?(s(),r("code",Rl,c(l.original.metadata.scm.commit.substring(0,7)),1)):R("",!0)])):R("",!0)]),"duration-cell":t(({row:l})=>[n("div",Dl,[a(vs,{passed:l.original.passedTests,failed:l.original.failedTests,skipped:l.original.skippedTests,flaky:l.original.flakyTests,"did-not-run":l.original.didNotRunTests??0,total:l.original.totalTests},null,8,["passed","failed","skipped","flaky","did-not-run","total"]),a(Re,{ms:l.original.duration,class:"text-xs text-gray-500"},null,8,["ms"])])]),"reports-cell":t(({row:l})=>[a(ys,{reports:l.original.reports},null,8,["reports"])]),"actions-header":t(()=>[...o[23]||(o[23]=[n("div",{class:"text-right"},"Actions",-1)])]),"actions-cell":t(({row:l})=>[n("div",Al,[a(le,{to:`/test-runs/${l.original.id}`,size:"sm",variant:"outline"},{default:t(()=>[...o[24]||(o[24]=[d(" View ",-1)])]),_:1},8,["to"]),a(le,{size:"sm",color:"error",variant:"soft",icon:"i-lucide-trash-2",loading:e(A)===l.original.id,onClick:De=>v.value=l.original.id},{default:t(()=>[...o[25]||(o[25]=[d(" Delete ",-1)])]),_:1},8,["loading","onClick"])])]),_:1},8,["data"])):e(i)?.testRuns&&e(i).testRuns.length>0?(s(),r("div",zl," No test runs match the selected environment filter. ")):(s(),f(xs,{key:3,icon:"i-lucide-rocket",text:"No test runs yet for this project."},{default:t(()=>[n("p",Ul,[o[27]||(o[27]=d(" Point the reporter's ",-1)),o[28]||(o[28]=n("code",{class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},"projectName",-1)),o[29]||(o[29]=d(" at ",-1)),n("code",Il,c(e(i)?.name),1),o[30]||(o[30]=d(" to send results here — see the ",-1)),a(hs,{to:"reporter","no-icon":"",class:"text-primary hover:underline"},{default:t(()=>[...o[26]||(o[26]=[d("reporter docs",-1)])]),_:1}),o[31]||(o[31]=d(" for setup instructions. ",-1))])]),_:1}))]),_:1})]),"failure-clusters":t(()=>[e(q)==="failure-clusters"?(s(),r(X,{key:0},[(s(),f(bs,{key:`sug-${e(de)}`,"project-id":String(e(m)),onMerged:o[4]||(o[4]=l=>de.value++)},null,8,["project-id"])),(s(),f(ks,{key:e(de),"project-id":String(e(m))},null,8,["project-id"]))],64)):R("",!0)]),"flaky-tests":t(()=>[e(q)==="flaky-tests"?(s(),f($s,{key:0,"project-id":String(e(m)),environment:e(F),"project-name":e(i)?.name},null,8,["project-id","environment","project-name"])):R("",!0)]),performance:t(()=>[n("div",Ml,[o[32]||(o[32]=n("span",{class:"text-sm text-muted shrink-0"},"Date range:",-1)),a(Ct,{modelValue:e(Se),"onUpdate:modelValue":o[5]||(o[5]=l=>J(Se)?Se.value=l:null),type:"date",size:"sm",placeholder:"From",class:"w-40"},null,8,["modelValue"]),o[33]||(o[33]=n("span",{class:"text-sm text-muted"},"to",-1)),a(Ct,{modelValue:e(we),"onUpdate:modelValue":o[6]||(o[6]=l=>J(we)?we.value=l:null),type:"date",size:"sm",placeholder:"To",class:"w-40"},null,8,["modelValue"]),e(Se)||e(we)?(s(),f(le,{key:0,size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear",onClick:o[7]||(o[7]=l=>{Se.value="",we.value=""})})):R("",!0)]),a(Pt,{title:"Performance trend",subtitle:"Duration metrics over time",help:"project.performance"},{default:t(()=>[e(as)?(s(),f(Et,{key:0,text:"Loading chart…"})):(s(),f(Cs,{key:1,data:e(yt)||[],height:350,markers:e(Ye),onMarkerClick:je},null,8,["data","markers"]))]),_:1}),a(He,null,{header:t(()=>[n("h2",Fl,[o[34]||(o[34]=d(" Slowest tests ",-1)),a(Fe,{topic:"project.slowest-tests"})]),o[35]||(o[35]=n("p",{class:"text-sm text-gray-600 mt-1"},"Top 20 slowest test cases across recent runs",-1))]),default:t(()=>[e(Ze)&&e(Me)===null?(s(),f(Et,{key:0,text:"Loading…"})):e(Me)&&e(Me).length>0?(s(),f(st,{key:1,data:e(Me),columns:os,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"title-cell":t(({row:l})=>[n("div",null,[n("div",Pl,c(l.original.title),1),n("div",El,[a(Ts,{"file-path":l.original.filePath,"project-key":e(m),"project-name":e(i)?.name,class:"text-xs"},null,8,["file-path","project-key","project-name"])])])]),"trend-cell":t(({row:l})=>[l.original.trend==="slower"?(s(),r("span",Bl,"▲ Slower")):l.original.trend==="faster"?(s(),r("span",Vl,"▼ Faster")):(s(),r("span",Ll,"— Stable"))]),_:1},8,["data"])):e(xt)?(s(),r("div",Nl," Couldn't load the slowest tests — try refreshing. ")):(s(),r("div",Kl,"No slow test data available yet."))]),_:1}),a(js,{"project-id":String(e(m)),"project-name":e(i)?.name},null,8,["project-id","project-name"]),a(He,null,{header:t(()=>[n("div",Ol,[n("div",null,[n("h2",ql,[o[36]||(o[36]=d(" Run comparison ",-1)),a(Fe,{topic:"project.run-compare"})]),o[37]||(o[37]=n("p",{class:"text-sm text-gray-600 mt-1"},"Compare duration changes between two runs",-1))]),e(ce).length>=2?(s(),f(le,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",variant:"outline",label:"Compare latest vs previous",onClick:Mt})):R("",!0)])]),default:t(()=>[n("div",Hl,[n("div",Ql,[n("div",null,[o[38]||(o[38]=n("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run A (baseline)",-1)),a(nt,{modelValue:e(ee),"onUpdate:modelValue":o[8]||(o[8]=l=>J(ee)?ee.value=l:null),items:e(ce),placeholder:"Select run A..."},null,8,["modelValue","items"])]),n("div",null,[o[39]||(o[39]=n("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run B (comparison)",-1)),a(nt,{modelValue:e(te),"onUpdate:modelValue":o[9]||(o[9]=l=>J(te)?te.value=l:null),items:e(ce),placeholder:"Select run B..."},null,8,["modelValue","items"])])]),e(et)?(s(),r("div",Gl,[a($t,{name:"i-lucide-loader-2",class:"animate-spin mr-2"}),o[40]||(o[40]=d(" Loading run data… ",-1))])):e(ee)&&e(te)&&e(tt).length>0?(s(),r("div",Xl,[n("div",Jl,[a(se,{color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).improved)+" improved",1)]),_:1}),a(se,{color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).regressed)+" regressed",1)]),_:1}),a(se,{color:"neutral",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).unchanged)+" unchanged",1)]),_:1})]),a(st,{data:e(tt),columns:Ft,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"statusA-cell":t(({row:l})=>[l.original.statusA?(s(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(at))(l.original.statusA),variant:"subtle",class:"capitalize"},{default:t(()=>[d(c(l.original.statusA),1)]),_:2},1032,["color"])):(s(),r("span",Wl,"—"))]),"statusB-cell":t(({row:l})=>[l.original.statusB?(s(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(at))(l.original.statusB),variant:"subtle",class:"capitalize"},{default:t(()=>[d(c(l.original.statusB),1)]),_:2},1032,["color"])):(s(),r("span",Yl,"—"))]),"durationA-cell":t(({row:l})=>[l.original.durationA!==null?(s(),f(Re,{key:0,ms:l.original.durationA},null,8,["ms"])):(s(),r("span",Zl,"—"))]),"durationB-cell":t(({row:l})=>[l.original.durationB!==null?(s(),f(Re,{key:0,ms:l.original.durationB},null,8,["ms"])):(s(),r("span",er,"—"))]),"delta-cell":t(({row:l})=>[l.original.delta===null?(s(),r("span",tr,"—")):(s(),r("span",{key:1,class:re(l.original.delta>0?"text-red-600":l.original.delta<0?"text-green-600":"text-gray-500")},[d(c(l.original.delta>0?"+":""),1),a(Re,{ms:l.original.delta,"unit-class":"opacity-60"},null,8,["ms"])],2))]),"percentChange-cell":t(({row:l})=>[l.original.percentChange===null?(s(),r("span",sr,"—")):(s(),r("span",{key:1,class:re(l.original.percentChange>10?"text-red-600 font-medium":l.original.percentChange<-10?"text-green-600 font-medium":"text-gray-500")},c(l.original.percentChange>0?"+":"")+c(l.original.percentChange)+"% ",3))]),_:1},8,["data"])])):!e(ee)||!e(te)?(s(),r("div",nr," Select two runs to compare their performance. ")):(s(),r("div",ar," No overlapping test cases found between the selected runs. "))])]),_:1})]),"test-cases":t(()=>[a(Ss,{"project-id":e(m),"project-name":e(i)?.name,"sync-query":"",onTotal:o[10]||(o[10]=l=>qe.value=l)},null,8,["project-id","project-name"])]),compare:t(()=>[a(He,null,{header:t(()=>[n("div",or,[n("p",lr,[o[41]||(o[41]=d(" Compare two test runs side-by-side — status changes and duration deltas ",-1)),a(Fe,{topic:"project.compare"})]),e(ce).length>=2?(s(),f(le,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",variant:"outline",label:"Latest vs previous",onClick:Mt})):R("",!0)])]),default:t(()=>[n("div",rr,[n("div",ir,[n("div",null,[o[42]||(o[42]=n("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run A (baseline)",-1)),a(nt,{modelValue:e(ee),"onUpdate:modelValue":o[11]||(o[11]=l=>J(ee)?ee.value=l:null),items:e(ce),placeholder:"Select run A..."},null,8,["modelValue","items"])]),n("div",null,[o[43]||(o[43]=n("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run B (comparison)",-1)),a(nt,{modelValue:e(te),"onUpdate:modelValue":o[12]||(o[12]=l=>J(te)?te.value=l:null),items:e(ce),placeholder:"Select run B..."},null,8,["modelValue","items"])])]),e(et)?(s(),r("div",cr,[a($t,{name:"i-lucide-loader-2",class:"animate-spin mr-2"}),o[44]||(o[44]=d(" Loading run data… ",-1))])):e(ee)&&e(te)&&e(tt).length>0?(s(),r("div",ur,[n("div",dr,[n("div",mr,[o[45]||(o[45]=n("span",{class:"text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1"},"Status changes",-1)),e(W).newFailures>0?(s(),f(se,{key:0,color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).newFailures)+" new failure"+c(e(W).newFailures>1?"s":""),1)]),_:1})):R("",!0),e(W).recovered>0?(s(),f(se,{key:1,color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).recovered)+" recovered ",1)]),_:1})):R("",!0),e(W).stillFailing>0?(s(),f(se,{key:2,color:"warning",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).stillFailing)+" still failing ",1)]),_:1})):R("",!0),e(W).newFailures===0&&e(W).recovered===0&&e(W).stillFailing===0?(s(),r("span",pr,"No status changes")):R("",!0)]),n("div",gr,[o[46]||(o[46]=n("span",{class:"text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1"},"Duration changes",-1)),e(W).regressed>0?(s(),f(se,{key:0,color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).regressed)+" regressed ",1)]),_:1})):R("",!0),e(W).improved>0?(s(),f(se,{key:1,color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).improved)+" improved ",1)]),_:1})):R("",!0),a(se,{color:"neutral",variant:"soft",size:"lg"},{default:t(()=>[d(c(e(W).unchanged)+" unchanged ",1)]),_:1})])]),a(st,{data:e(tt),columns:Ft,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"statusA-cell":t(({row:l})=>[l.original.statusA?(s(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(at))(l.original.statusA),variant:"subtle",class:"capitalize"},{default:t(()=>[d(c(l.original.statusA),1)]),_:2},1032,["color"])):(s(),r("span",fr,"—"))]),"statusB-cell":t(({row:l})=>[l.original.statusB?(s(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(at))(l.original.statusB),variant:"subtle",class:"capitalize"},{default:t(()=>[d(c(l.original.statusB),1)]),_:2},1032,["color"])):(s(),r("span",_r,"—"))]),"durationA-cell":t(({row:l})=>[l.original.durationA!==null?(s(),f(Re,{key:0,ms:l.original.durationA},null,8,["ms"])):(s(),r("span",vr,"—"))]),"durationB-cell":t(({row:l})=>[l.original.durationB!==null?(s(),f(Re,{key:0,ms:l.original.durationB},null,8,["ms"])):(s(),r("span",yr,"—"))]),"delta-cell":t(({row:l})=>[l.original.delta===null?(s(),r("span",hr,"—")):(s(),r("span",{key:1,class:re(l.original.delta>0?"text-red-600":l.original.delta<0?"text-green-600":"text-gray-500")},[d(c(l.original.delta>0?"+":""),1),a(Re,{ms:l.original.delta,"unit-class":"opacity-60"},null,8,["ms"])],2))]),"percentChange-cell":t(({row:l})=>[l.original.percentChange===null?(s(),r("span",xr,"—")):(s(),r("span",{key:1,class:re(l.original.percentChange>10?"text-red-600 font-medium":l.original.percentChange<-10?"text-green-600 font-medium":"text-gray-500")},c(l.original.percentChange>0?"+":"")+c(l.original.percentChange)+"% ",3))]),_:1},8,["data"])])):!e(ee)||!e(te)?(s(),r("div",br," Select two runs to compare test results. ")):(s(),r("div",kr," No overlapping test cases found between the selected runs. "))])]),_:1})]),"spec-health":t(()=>[a(ws,{"project-id":String(e(m))},null,8,["project-id"])]),quarantine:t(()=>[a(Rs,{"project-id":String(e(m)),"project-name":e(i)?.name},null,8,["project-id","project-name"])]),members:t(()=>[a(He,null,{header:t(()=>[n("div",$r,[n("p",Cr,[o[47]||(o[47]=d(" Users with access to this project ",-1)),a(Fe,{topic:"project.members"})]),a(le,{label:"Save changes",icon:"i-lucide-check",size:"sm",disabled:!e(ge),onClick:j},null,8,["disabled"])])]),default:t(()=>[e(ue).length>0?(s(),r("div",Tr,[(s(!0),r(X,null,ae(e(ue),l=>(s(),r("div",{key:l.id,class:"flex items-center justify-between rounded-lg border border-default px-4 py-3"},[n("div",null,[n("div",jr,c(l.name||l.username),1),n("div",Sr,[n("span",null,"@"+c(l.username),1),a(se,{color:l.role==="administrator"?"primary":l.role==="reporter"?"info":"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(c(l.role),1)]),_:2},1032,["color"]),l.global?(s(),r("span",wr,"Global access")):R("",!0)])]),l.role!=="administrator"?(s(),f(Ds,{key:0,"model-value":e(B).includes(l.id),disabled:l.global,title:l.global?"Has global access — remove global assignment first":"",onChange:De=>h(l.id)},null,8,["model-value","disabled","title","onChange"])):(s(),r("span",Rr,"Admin"))]))),128))])):(s(),r("div",Dr,"Loading members…"))]),_:1})]),timeline:t(()=>[a(As,{"project-id":Number(e(m)),markers:e(Te),environments:e(Ke),"can-edit":e(We),"focus-marker-id":e(Ie),onChanged:e(_t),onClearFocus:o[13]||(o[13]=l=>Ie.value=null)},null,8,["project-id","markers","environments","can-edit","focus-marker-id","onChanged"])]),_:1},8,["modelValue","items"])])]),_:1}),a(Vt,null,{default:t(()=>[a(Bt,{open:e(P),title:"Delete project","onUpdate:open":o[17]||(o[17]=l=>{l||(P.value=!1)})},{body:t(()=>[n("div",Ar,[n("p",zr,[o[48]||(o[48]=d(" This will permanently delete ",-1)),n("strong",null,c(e(i)?.label||e(i)?.name),1),o[49]||(o[49]=d(" and all its test runs, reports, traces, and failure clusters. This action cannot be undone. ",-1))]),n("div",null,[n("label",Ur,[o[50]||(o[50]=d(" Type the project key ",-1)),n("code",Ir,c(e(i)?.name),1),o[51]||(o[51]=d(" to confirm: ",-1))]),a(Ct,{modelValue:e(K),"onUpdate:modelValue":o[15]||(o[15]=l=>J(K)?K.value=l:null),placeholder:e(i)?.name,autofocus:"",onKeydown:Ls(T,["enter"])},null,8,["modelValue","placeholder"])])])]),footer:t(()=>[a(le,{color:"neutral",variant:"ghost",label:"Cancel",onClick:o[16]||(o[16]=l=>P.value=!1)}),a(le,{color:"error",label:"Delete project",icon:"i-lucide-trash-2",disabled:!e(g),loading:e(S),onClick:T},null,8,["disabled","loading"])]),_:1},8,["open"])]),_:1}),a(Vt,null,{default:t(()=>[a(Bt,{open:e(v)!==null,title:"Delete test run","onUpdate:open":o[20]||(o[20]=l=>{l||(v.value=null)})},{body:t(()=>[n("p",null,[o[52]||(o[52]=d(" Are you sure you want to delete ",-1)),n("strong",null,"Run #"+c(e(v)),1),o[53]||(o[53]=d("? This will also remove all associated test results, reports, and traces. This action cannot be undone. ",-1))])]),footer:t(()=>[a(le,{color:"neutral",variant:"ghost",label:"Cancel",onClick:o[18]||(o[18]=l=>v.value=null)}),a(le,{color:"error",label:"Delete",icon:"i-lucide-trash-2",loading:e(A)===e(v),onClick:o[19]||(o[19]=l=>Q(e(v)))},null,8,["loading"])]),_:1},8,["open"])]),_:1})],64)}}});export{Vi as default};