@piwitests/server 0.26.0 → 0.26.1

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 (382) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{BdQ7kfxJ.js → 1QWBzxLM.js} +4 -4
  3. package/.output/public/_nuxt/{CY1UsEbI.js → 4hW9LHwA.js} +1 -1
  4. package/.output/public/_nuxt/96uxfdYT.js +1 -0
  5. package/.output/public/_nuxt/{HGYIpJtg.js → AbnDY6Zr.js} +1 -1
  6. package/.output/public/_nuxt/{CZ6WR7uw.js → B-1zt4pp.js} +1 -1
  7. package/.output/public/_nuxt/{Sx5-c-bZ.js → B1iYmAt_.js} +1 -1
  8. package/.output/public/_nuxt/{CbzgEkmW.js → B2bxEmbR.js} +1 -1
  9. package/.output/public/_nuxt/B3hAvaCe.js +4 -0
  10. package/.output/public/_nuxt/{CyWOerIG.js → B4lvHjBe.js} +1 -1
  11. package/.output/public/_nuxt/B5S7BkC3.js +1 -0
  12. package/.output/public/_nuxt/{Bb_1uAHn.js → B6j5Ornu.js} +1 -1
  13. package/.output/public/_nuxt/{CrsaY0R_.js → B82vqOZe.js} +1 -1
  14. package/.output/public/_nuxt/{CTFUlsXp.js → B9oXlGro.js} +1 -1
  15. package/.output/public/_nuxt/{CsJ9Ce4U.js → BABCH5kE.js} +1 -1
  16. package/.output/public/_nuxt/{Gn1Ns00e.js → BF5qB58w.js} +1 -1
  17. package/.output/public/_nuxt/{CsGsLxHg.js → BFLa9ZEP.js} +1 -1
  18. package/.output/public/_nuxt/BIlohx1E.js +1 -0
  19. package/.output/public/_nuxt/{B6djubIK.js → BM5C-Oec.js} +1 -1
  20. package/.output/public/_nuxt/{CrZhoZuI.js → BOA-I6S9.js} +1 -1
  21. package/.output/public/_nuxt/{Bp2zrrkV.js → BQUhoGCh.js} +1 -1
  22. package/.output/public/_nuxt/{DUC3QnqW.js → BQYLGX9o.js} +1 -1
  23. package/.output/public/_nuxt/{CUjzhXN1.js → BRMeEHXd.js} +1 -1
  24. package/.output/public/_nuxt/{Cf_a8ynB.js → BRtaKOKv.js} +2 -2
  25. package/.output/public/_nuxt/{B7uPoZ7T.js → BS91Og__.js} +1 -1
  26. package/.output/public/_nuxt/{DKgbchez.js → BTGAvMoT.js} +1 -1
  27. package/.output/public/_nuxt/{BIamiwb7.js → BaLX92Wz.js} +1 -1
  28. package/.output/public/_nuxt/{LWIyaZKe.js → Bc6Zr-Xn.js} +1 -1
  29. package/.output/public/_nuxt/{R7AVOWi_.js → BceMEnJt.js} +1 -1
  30. package/.output/public/_nuxt/{Q2oJNyXL.js → BeCAVtCK.js} +1 -1
  31. package/.output/public/_nuxt/{D_SD71Qf.js → Bf119e7x.js} +1 -1
  32. package/.output/public/_nuxt/BfRcdz11.js +9 -0
  33. package/.output/public/_nuxt/{CxwnFFD0.js → Bl0xzETD.js} +1 -1
  34. package/.output/public/_nuxt/{C_eXufkv.js → BnUQ3i5l.js} +1 -1
  35. package/.output/public/_nuxt/{rPG7kzfL.js → Bp1WeQ0_.js} +1 -1
  36. package/.output/public/_nuxt/{BL8cYWsR.js → Bp31ZRcA.js} +1 -1
  37. package/.output/public/_nuxt/{Drh1_ASq.js → BrxUH8qL.js} +1 -1
  38. package/.output/public/_nuxt/{D72Ce8Ff.js → BsdfEbVC.js} +1 -1
  39. package/.output/public/_nuxt/BtGI4ZbP.js +1 -0
  40. package/.output/public/_nuxt/{BV8EzO8q.js → BuMX-4RF.js} +1 -1
  41. package/.output/public/_nuxt/{DPPhFZOr.js → BuXJR5tn.js} +1 -1
  42. package/.output/public/_nuxt/{Bh2WA4IJ.js → Bx_lfKHl.js} +1 -1
  43. package/.output/public/_nuxt/{vcSKeWsW.js → C4UKyPQn.js} +1 -1
  44. package/.output/public/_nuxt/{IoE3eJ9F.js → C9XCTbtQ.js} +1 -1
  45. package/.output/public/_nuxt/{BilJoEne.js → CEPU6VkU.js} +1 -1
  46. package/.output/public/_nuxt/CHz7LJIX.js +1 -0
  47. package/.output/public/_nuxt/{BPhGDGAR.js → CMhd8IBr.js} +1 -1
  48. package/.output/public/_nuxt/{C5X_N4R7.js → CN1M6i4K.js} +33 -33
  49. package/.output/public/_nuxt/CQLkowA3.js +1 -0
  50. package/.output/public/_nuxt/{DTtizz85.js → CU_2YLhT.js} +1 -1
  51. package/.output/public/_nuxt/{CMVTTE_g.js → CXkXHtcx.js} +1 -1
  52. package/.output/public/_nuxt/{igDJCTgt.js → CZeKW-zP.js} +1 -1
  53. package/.output/public/_nuxt/{9oKY4Zb7.js → CapSEET7.js} +1 -1
  54. package/.output/public/_nuxt/{j2eGYaRa.js → CeExxGSu.js} +1 -1
  55. package/.output/public/_nuxt/{CEgRB8H9.js → CfwpqSe7.js} +1 -1
  56. package/.output/public/_nuxt/{CFKbXp6V.js → ChOtLYkd.js} +1 -1
  57. package/.output/public/_nuxt/ChuJzPWz.js +1 -0
  58. package/.output/public/_nuxt/{Bo73sAu8.js → CiCUZGFZ.js} +1 -1
  59. package/.output/public/_nuxt/{C6R4tyud.js → CkL_oDa8.js} +1 -1
  60. package/.output/public/_nuxt/{DtGJeysS.js → CkhOMiiO.js} +1 -1
  61. package/.output/public/_nuxt/ClmHMP65.js +2 -0
  62. package/.output/public/_nuxt/{BtcDY0Du.js → Cnm0d_7S.js} +1 -1
  63. package/.output/public/_nuxt/{CK2AMqz_.js → CtQMagSz.js} +1 -1
  64. package/.output/public/_nuxt/{B1KjIR-q.js → Ctnn3S3-.js} +1 -1
  65. package/.output/public/_nuxt/{DCeZxpxe.js → CywiLuOD.js} +4 -4
  66. package/.output/public/_nuxt/{oA84LLqO.js → CzRkZLB4.js} +1 -1
  67. package/.output/public/_nuxt/CzyCEdYP.js +1 -0
  68. package/.output/public/_nuxt/{D56yp7m9.js → D-F0Rhjj.js} +1 -1
  69. package/.output/public/_nuxt/D4mPjHHR.js +2 -0
  70. package/.output/public/_nuxt/{BsGvSoPC.js → D4v7lLm3.js} +1 -1
  71. package/.output/public/_nuxt/{CxRTKV-K.js → D6B0WKO0.js} +1 -1
  72. package/.output/public/_nuxt/{jv8U_Tup.js → DAg6jtav.js} +1 -1
  73. package/.output/public/_nuxt/DBXXb0w8.js +1 -0
  74. package/.output/public/_nuxt/{ChlP20A5.js → DHN2t5Vt.js} +1 -1
  75. package/.output/public/_nuxt/{B8tezsWe.js → DJKHXfNS.js} +1 -1
  76. package/.output/public/_nuxt/{CFg5qdS0.js → DMqAUHFN.js} +1 -1
  77. package/.output/public/_nuxt/{C9A3sPDo.js → DURme_kn.js} +1 -1
  78. package/.output/public/_nuxt/{C2hIM5f9.js → DVo_e_uj.js} +1 -1
  79. package/.output/public/_nuxt/{DKhqIou2.js → DXh8q5KY.js} +1 -1
  80. package/.output/public/_nuxt/{CZXeJs2k.js → DXz1Kb4-.js} +1 -1
  81. package/.output/public/_nuxt/{CPrVhXJk.js → DYdwHaco.js} +1 -1
  82. package/.output/public/_nuxt/{WZXZeGYt.js → D_ZAGxCQ.js} +1 -1
  83. package/.output/public/_nuxt/{D5SN7rPK.js → D_dhjJvR.js} +1 -1
  84. package/.output/public/_nuxt/{DR1jFptD.js → DamZHy5M.js} +1 -1
  85. package/.output/public/_nuxt/{xKX9IHe3.js → DbtjJCra.js} +1 -1
  86. package/.output/public/_nuxt/{r6zkA1SE.js → DcOlL-oi.js} +1 -1
  87. package/.output/public/_nuxt/{CxspCKpR.js → DeQ9sIia.js} +1 -1
  88. package/.output/public/_nuxt/{BkHJoHpc.js → DjX1bLZD.js} +1 -1
  89. package/.output/public/_nuxt/{Be0bwdsi.js → Dly7wCCl.js} +1 -1
  90. package/.output/public/_nuxt/DmeogbGY.js +1 -0
  91. package/.output/public/_nuxt/{CfV2N201.js → Dn_-RkxP.js} +1 -1
  92. package/.output/public/_nuxt/{dg6uXTyR.js → DoDo3VF2.js} +1 -1
  93. package/.output/public/_nuxt/{BMlKQMjM.js → DoVHTl-K.js} +1 -1
  94. package/.output/public/_nuxt/DpM8IgHL.js +1 -0
  95. package/.output/public/_nuxt/{B4NjylBn.js → Dpwj_1H5.js} +1 -1
  96. package/.output/public/_nuxt/{DzJa19LG.js → DvSHenmZ.js} +1 -1
  97. package/.output/public/_nuxt/DvYU87_a.js +1 -0
  98. package/.output/public/_nuxt/{G2J1dVVb.js → Dx41arC8.js} +1 -1
  99. package/.output/public/_nuxt/DxBrlj7b.js +1 -0
  100. package/.output/public/_nuxt/{r-HZNbp3.js → JNpNdV-o.js} +1 -1
  101. package/.output/public/_nuxt/Lz9MmwKY.js +1 -0
  102. package/.output/public/_nuxt/OMI0cmZ0.js +1 -0
  103. package/.output/public/_nuxt/{CUWrUpTl.js → UAmyrRCI.js} +1 -1
  104. package/.output/public/_nuxt/{EJllK0wm.js → VBTxfbqU.js} +1 -1
  105. package/.output/public/_nuxt/VbedPPFH.js +1 -0
  106. package/.output/public/_nuxt/{BY9A1aOT.js → _okd7MfH.js} +1 -1
  107. package/.output/public/_nuxt/{BOn5q0rT.js → bmAf49LT.js} +1 -1
  108. package/.output/public/_nuxt/builds/latest.json +1 -1
  109. package/.output/public/_nuxt/builds/meta/0174ebd8-8fa5-4698-aa79-7a8dd2f6527f.json +1 -0
  110. package/.output/public/_nuxt/{D0XWJGhG.js → e-GZmCeP.js} +1 -1
  111. package/.output/public/_nuxt/entry.Dv52uAyn.css +1 -0
  112. package/.output/public/_nuxt/{DVIIj6Vv.js → f9TbT3AM.js} +1 -1
  113. package/.output/public/_nuxt/gdlHFfN6.js +1 -0
  114. package/.output/public/_nuxt/{BTG_PmM5.js → huBoAZeM.js} +1 -1
  115. package/.output/public/_nuxt/{DadksxQ9.js → mYw4b7uY.js} +1 -1
  116. package/.output/public/_nuxt/{B0eHOux4.js → mi7tdFxN.js} +1 -1
  117. package/.output/public/_nuxt/sFe4Zr5j.js +1 -0
  118. package/.output/public/_nuxt/{CLrLFf3s.js → uspGXbik.js} +1 -1
  119. package/.output/public/_nuxt/{DLN-CQXF.js → w7KxwWEv.js} +1 -1
  120. package/.output/public/_nuxt/{Bp55g9gr.js → wa4k1aDz.js} +1 -1
  121. package/.output/public/_nuxt/{C2yZcDch.js → xuB8n0QL.js} +1 -1
  122. package/.output/public/favicon.ico +0 -0
  123. package/.output/public/trace-viewer/assets/codeMirrorModule-LEHpjmcn.js +32 -0
  124. package/.output/public/trace-viewer/assets/defaultSettingsView-BNmKHKpQ.js +264 -0
  125. package/.output/public/trace-viewer/assets/urlMatch-BYQrIQwR.js +1 -0
  126. package/.output/public/trace-viewer/assets/xtermModule-CsJ4vdCR.js +9 -0
  127. package/.output/public/trace-viewer/codeMirrorModule.DYBRYzYX.css +1 -0
  128. package/.output/public/trace-viewer/codicon.DCmgc-ay.ttf +0 -0
  129. package/.output/public/trace-viewer/defaultSettingsView.CjdS-WJx.css +1 -0
  130. package/.output/public/trace-viewer/index.CzXZzn5A.css +1 -0
  131. package/.output/public/trace-viewer/index.DMMX1gXU.js +2 -0
  132. package/.output/public/trace-viewer/index.html +44 -0
  133. package/.output/public/trace-viewer/manifest.webmanifest +16 -0
  134. package/.output/public/trace-viewer/playwright-logo.svg +9 -0
  135. package/.output/public/trace-viewer/snapshot.html +10 -0
  136. package/.output/public/trace-viewer/snapshot.v8KI4P3m.js +2 -0
  137. package/.output/public/trace-viewer/sw.bundle.js +5 -0
  138. package/.output/public/trace-viewer/uiMode.BZQ54Kgt.css +1 -0
  139. package/.output/public/trace-viewer/uiMode.Ut8wwJNp.js +6 -0
  140. package/.output/public/trace-viewer/uiMode.html +18 -0
  141. package/.output/public/trace-viewer/xtermModule.DYP7pi_n.css +32 -0
  142. package/.output/server/chunks/_/users.mjs +1 -1
  143. package/.output/server/chunks/build/{BreadcrumbNav-DBnGj5Jq.mjs → BreadcrumbNav-Bg4QGX0k.mjs} +11 -4
  144. package/.output/server/chunks/build/BreadcrumbNav-Bg4QGX0k.mjs.map +1 -0
  145. package/.output/server/chunks/build/{BrowserBadge-vFb1ERG_.mjs → BrowserBadge-yMgLTBUu.mjs} +17 -9
  146. package/.output/server/chunks/build/BrowserBadge-yMgLTBUu.mjs.map +1 -0
  147. package/.output/server/chunks/build/{ChartMarkerLines-BXqUpUcs.mjs → ChartMarkerLines-D0cTRlxF.mjs} +3 -3
  148. package/.output/server/chunks/build/ChartMarkerLines-D0cTRlxF.mjs.map +1 -0
  149. package/.output/server/chunks/build/{ChartTooltip-DoF6Smyc.mjs → ChartTooltip-B2t6VYYH.mjs} +3 -3
  150. package/.output/server/chunks/build/ChartTooltip-B2t6VYYH.mjs.map +1 -0
  151. package/.output/server/chunks/build/Checkbox-ChSYhiUz.mjs +1 -1
  152. package/.output/server/chunks/build/ClientDate-U97Z1p6-.mjs +32 -0
  153. package/.output/server/chunks/build/ClientDate-U97Z1p6-.mjs.map +1 -0
  154. package/.output/server/chunks/build/{CodeBlock-CmvKHaq8.mjs → CodeBlock-DuWhmcI2.mjs} +3 -3
  155. package/.output/server/chunks/build/CodeBlock-DuWhmcI2.mjs.map +1 -0
  156. package/.output/server/chunks/build/DashboardSidebarToggle-a5KYecZ0.mjs +1 -1
  157. package/.output/server/chunks/build/DashboardToolbar-BZoGc0ri.mjs +72 -0
  158. package/.output/server/chunks/build/DashboardToolbar-BZoGc0ri.mjs.map +1 -0
  159. package/.output/server/chunks/build/{DataLocationCard-ChV02QJj.mjs → DataLocationCard-DCdhQBIY.mjs} +2 -2
  160. package/.output/server/chunks/build/DataLocationCard-DCdhQBIY.mjs.map +1 -0
  161. package/.output/server/chunks/build/{DesktopRunLocallyButton-BfmbZpiL.mjs → DesktopRunLocallyButton-ChHg3GqK.mjs} +5 -5
  162. package/.output/server/chunks/build/{DesktopRunLocallyButton-BfmbZpiL.mjs.map → DesktopRunLocallyButton-ChHg3GqK.mjs.map} +1 -1
  163. package/.output/server/chunks/build/{DiagnosisPanel-C_ndadzP.mjs → DiagnosisPanel-DE-r2UV8.mjs} +5 -5
  164. package/.output/server/chunks/build/DiagnosisPanel-DE-r2UV8.mjs.map +1 -0
  165. package/.output/server/chunks/build/{DiagnosisResult-GAjo6Lt3.mjs → DiagnosisResult-CrGK--xh.mjs} +16 -10
  166. package/.output/server/chunks/build/DiagnosisResult-CrGK--xh.mjs.map +1 -0
  167. package/.output/server/chunks/build/{DurationValue-CObiBDnH.mjs → DurationValue-Dn06XQk3.mjs} +2 -2
  168. package/.output/server/chunks/build/DurationValue-Dn06XQk3.mjs.map +1 -0
  169. package/.output/server/chunks/build/EntityLinks-BcpvMt_V.mjs +1 -1
  170. package/.output/server/chunks/build/EnvManagedBadge-_8GfjWjE.mjs +1 -1
  171. package/.output/server/chunks/build/{FeatureUnavailable-Buoyoqx1.mjs → FeatureUnavailable-IaBjVCqQ.mjs} +2 -2
  172. package/.output/server/chunks/build/FeatureUnavailable-IaBjVCqQ.mjs.map +1 -0
  173. package/.output/server/chunks/build/{GetStartedWizard-tL3U_qM1.mjs → GetStartedWizard-BiyxEXWP.mjs} +3 -3
  174. package/.output/server/chunks/build/GetStartedWizard-BiyxEXWP.mjs.map +1 -0
  175. package/.output/server/chunks/build/{HelpHint-C96TlqxY.mjs → HelpHint-CdBz6deq.mjs} +2 -2
  176. package/.output/server/chunks/build/HelpHint-CdBz6deq.mjs.map +1 -0
  177. package/.output/server/chunks/build/{MetaStripGroup-Cp2WCQf7.mjs → MetaStripGroup-CDyGlsNt.mjs} +94 -21
  178. package/.output/server/chunks/build/MetaStripGroup-CDyGlsNt.mjs.map +1 -0
  179. package/.output/server/chunks/build/{NavbarActions-VCHW0u67.mjs → NavbarActions-BTWxKCVI.mjs} +2 -2
  180. package/.output/server/chunks/build/NavbarActions-BTWxKCVI.mjs.map +1 -0
  181. package/.output/server/chunks/build/NavigationMenu-D4ZpdCm_.mjs +1 -1
  182. package/.output/server/chunks/build/OpenInIdeLink-Bnl-_som.mjs +1 -1
  183. package/.output/server/chunks/build/{ProjectTestCasesTable-saHYJoyQ.mjs → ProjectTestCasesTable-DJDAZ9NQ.mjs} +9 -9
  184. package/.output/server/chunks/build/ProjectTestCasesTable-DJDAZ9NQ.mjs.map +1 -0
  185. package/.output/server/chunks/build/{RunReports-CKYYRC59.mjs → RunReports-BSo2cCNx.mjs} +4 -4
  186. package/.output/server/chunks/build/RunReports-BSo2cCNx.mjs.map +1 -0
  187. package/.output/server/chunks/build/{RunStatusBadge-CWhmAmKb.mjs → RunStatusBadge-zfeSwcTx.mjs} +2 -2
  188. package/.output/server/chunks/build/RunStatusBadge-zfeSwcTx.mjs.map +1 -0
  189. package/.output/server/chunks/build/{SectionCard-BB1O3uXd.mjs → SectionCard-CKD1s0eF.mjs} +2 -2
  190. package/.output/server/chunks/build/SectionCard-CKD1s0eF.mjs.map +1 -0
  191. package/.output/server/chunks/build/Select-COU8NARj.mjs +1 -1
  192. package/.output/server/chunks/build/SelectMenu-BUwwc3Qt.mjs +1 -1
  193. package/.output/server/chunks/build/{SettingsField-CEasBHu3.mjs → SettingsField-CDnUtiCM.mjs} +3 -3
  194. package/.output/server/chunks/build/SettingsField-CDnUtiCM.mjs.map +1 -0
  195. package/.output/server/chunks/build/Table-BET-DOtX.mjs +1 -1
  196. package/.output/server/chunks/build/{TestCaseHistoryChart-BgI6P_zS.mjs → TestCaseHistoryChart-Do7WK-ZY.mjs} +16 -17
  197. package/.output/server/chunks/build/TestCaseHistoryChart-Do7WK-ZY.mjs.map +1 -0
  198. package/.output/server/chunks/build/{TestStatusBar-DR8jM5th.mjs → TestStatusBar-BipoEOzd.mjs} +15 -6
  199. package/.output/server/chunks/build/TestStatusBar-BipoEOzd.mjs.map +1 -0
  200. package/.output/server/chunks/build/Tooltip-CK0ucuXC.mjs +1 -1
  201. package/.output/server/chunks/build/{_id_-rQhFY0fN.mjs → _id_-BLPB189b.mjs} +16 -16
  202. package/.output/server/chunks/build/{_id_-rQhFY0fN.mjs.map → _id_-BLPB189b.mjs.map} +1 -1
  203. package/.output/server/chunks/build/{_id_-kkexEH_q.mjs → _id_-BeGJOSxY.mjs} +16 -16
  204. package/.output/server/chunks/build/_id_-BeGJOSxY.mjs.map +1 -0
  205. package/.output/server/chunks/build/{_id_-B7Dw490u.mjs → _id_-CfLEW45H.mjs} +472 -304
  206. package/.output/server/chunks/build/_id_-CfLEW45H.mjs.map +1 -0
  207. package/.output/server/chunks/build/{_id_-DVPb1S93.mjs → _id_-DxHe32cW.mjs} +654 -453
  208. package/.output/server/chunks/build/_id_-DxHe32cW.mjs.map +1 -0
  209. package/.output/server/chunks/build/{about-C4AbyQ4q.mjs → about-FLAssVsA.mjs} +5 -5
  210. package/.output/server/chunks/build/about-FLAssVsA.mjs.map +1 -0
  211. package/.output/server/chunks/build/{account-B45bYZd1.mjs → account-Cvz6KkYu.mjs} +4 -4
  212. package/.output/server/chunks/build/account-Cvz6KkYu.mjs.map +1 -0
  213. package/.output/server/chunks/build/{ai-CgN9xXFf.mjs → ai-DR9Zry7B.mjs} +8 -8
  214. package/.output/server/chunks/build/{ai-CgN9xXFf.mjs.map → ai-DR9Zry7B.mjs.map} +1 -1
  215. package/.output/server/chunks/build/{analytics-BRkiUpwa.mjs → analytics-CCAQayhv.mjs} +9 -9
  216. package/.output/server/chunks/build/{analytics-BRkiUpwa.mjs.map → analytics-CCAQayhv.mjs.map} +1 -1
  217. package/.output/server/chunks/build/{auto-heal-BnTdKHQq.mjs → auto-heal-ngiiiVmq.mjs} +4 -4
  218. package/.output/server/chunks/build/auto-heal-ngiiiVmq.mjs.map +1 -0
  219. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  220. package/.output/server/chunks/build/{default-BGOdM_zA.mjs → default-wYpdMMvh.mjs} +15 -13
  221. package/.output/server/chunks/build/{default-BGOdM_zA.mjs.map → default-wYpdMMvh.mjs.map} +1 -1
  222. package/.output/server/chunks/build/{docs-D7R5eJ1Z.mjs → docs-BX9DoKOI.mjs} +4 -4
  223. package/.output/server/chunks/build/{docs-D7R5eJ1Z.mjs.map → docs-BX9DoKOI.mjs.map} +1 -1
  224. package/.output/server/chunks/build/{edit-BbL3k6c3.mjs → edit-DnyBC4uC.mjs} +7 -7
  225. package/.output/server/chunks/build/{edit-BbL3k6c3.mjs.map → edit-DnyBC4uC.mjs.map} +1 -1
  226. package/.output/server/chunks/build/fetch-DOcN2mHf.mjs +1 -1
  227. package/.output/server/chunks/build/{help-content-BK3jcgLw.mjs → help-content-3QLSe6Vd.mjs} +3 -3
  228. package/.output/server/chunks/build/help-content-3QLSe6Vd.mjs.map +1 -0
  229. package/.output/server/chunks/build/{import-ibAn_HB9.mjs → import-S-w3MXez.mjs} +8 -8
  230. package/.output/server/chunks/build/import-S-w3MXez.mjs.map +1 -0
  231. package/.output/server/chunks/build/{index-D5A0DW7Y.mjs → index-BFr7JW_2.mjs} +4 -4
  232. package/.output/server/chunks/build/index-BFr7JW_2.mjs.map +1 -0
  233. package/.output/server/chunks/build/{index-CqinXTVs.mjs → index-CdzYiYiu.mjs} +9 -9
  234. package/.output/server/chunks/build/{index-CqinXTVs.mjs.map → index-CdzYiYiu.mjs.map} +1 -1
  235. package/.output/server/chunks/build/{index-DreB_S-d.mjs → index-CgYJur1z.mjs} +31 -23
  236. package/.output/server/chunks/build/index-CgYJur1z.mjs.map +1 -0
  237. package/.output/server/chunks/build/{index-2GmuPNF-.mjs → index-CjnZ521K.mjs} +22 -4
  238. package/.output/server/chunks/build/index-CjnZ521K.mjs.map +1 -0
  239. package/.output/server/chunks/build/{index-KsRegEjT.mjs → index-xgA4P1ht.mjs} +3218 -4087
  240. package/.output/server/chunks/build/index-xgA4P1ht.mjs.map +1 -0
  241. package/.output/server/chunks/build/isValueEqualOrExist-D4lZ8uRY.mjs +1 -1
  242. package/.output/server/chunks/build/login-DueFS2RU.mjs +1 -1
  243. package/.output/server/chunks/build/{mcp-Dwj29-uG.mjs → mcp-DlZzubUF.mjs} +7 -7
  244. package/.output/server/chunks/build/mcp-DlZzubUF.mjs.map +1 -0
  245. package/.output/server/chunks/build/{notifications-CjAn5FJj.mjs → notifications-ByPVhyPX.mjs} +6 -6
  246. package/.output/server/chunks/build/notifications-ByPVhyPX.mjs.map +1 -0
  247. package/.output/server/chunks/build/{performance-DRzcu_c7.mjs → performance-Dc9FhaJr.mjs} +6 -6
  248. package/.output/server/chunks/build/performance-Dc9FhaJr.mjs.map +1 -0
  249. package/.output/server/chunks/build/{pr-feedback-DR60oGBf.mjs → pr-feedback-5kC_UmKG.mjs} +4 -4
  250. package/.output/server/chunks/build/pr-feedback-5kC_UmKG.mjs.map +1 -0
  251. package/.output/server/chunks/build/{selections-BjjolRZ9.mjs → selections-C6J9mI0s.mjs} +9 -9
  252. package/.output/server/chunks/build/selections-C6J9mI0s.mjs.map +1 -0
  253. package/.output/server/chunks/build/server.mjs +33 -33
  254. package/.output/server/chunks/build/{settings-B3NWV9tu.mjs → settings-DcCAv0U4.mjs} +17 -81
  255. package/.output/server/chunks/build/settings-DcCAv0U4.mjs.map +1 -0
  256. package/.output/server/chunks/build/{settings-metadata-DwJk8uSt.mjs → settings-metadata-B684YiW4.mjs} +2 -2
  257. package/.output/server/chunks/build/settings-metadata-B684YiW4.mjs.map +1 -0
  258. package/.output/server/chunks/build/{setup-BlgFTixN.mjs → setup-Cf3Mzf-W.mjs} +8 -8
  259. package/.output/server/chunks/build/{setup-BlgFTixN.mjs.map → setup-Cf3Mzf-W.mjs.map} +1 -1
  260. package/.output/server/chunks/build/{storage-C1O-FC0U.mjs → storage-B4VySiv3.mjs} +7 -7
  261. package/.output/server/chunks/build/storage-B4VySiv3.mjs.map +1 -0
  262. package/.output/server/chunks/build/{tags-dsvYrnii.mjs → tags-BvWdsd1F.mjs} +25 -11
  263. package/.output/server/chunks/build/tags-BvWdsd1F.mjs.map +1 -0
  264. package/.output/server/chunks/build/{test-cases-CFiOuyK6.mjs → test-cases-LIIu7dMu.mjs} +11 -11
  265. package/.output/server/chunks/build/test-cases-LIIu7dMu.mjs.map +1 -0
  266. package/.output/server/chunks/build/{test-functions-CbmBi6az.mjs → test-functions-Dv8nezrM.mjs} +8 -8
  267. package/.output/server/chunks/build/test-functions-Dv8nezrM.mjs.map +1 -0
  268. package/.output/server/chunks/build/{useCopyRich-DPKZKHvZ.mjs → useCopyRich-DRRKIts2.mjs} +17 -14
  269. package/.output/server/chunks/build/{useCopyRich-DPKZKHvZ.mjs.map → useCopyRich-DRRKIts2.mjs.map} +1 -1
  270. package/.output/server/chunks/build/{useDesktopDownload-R_RWSgUV.mjs → useDesktopDownload-CK-5nATq.mjs} +2 -2
  271. package/.output/server/chunks/build/useDesktopDownload-CK-5nATq.mjs.map +1 -0
  272. package/.output/server/chunks/build/{useDesktopLocalRuns-BdELBy0Y.mjs → useDesktopLocalRuns-BHZic4MJ.mjs} +3 -3
  273. package/.output/server/chunks/build/useDesktopLocalRuns-BHZic4MJ.mjs.map +1 -0
  274. package/.output/server/chunks/build/{useDesktopProjectLink-IUN7SIP2.mjs → useDesktopProjectLink-CqBvnXwG.mjs} +2 -2
  275. package/.output/server/chunks/build/useDesktopProjectLink-CqBvnXwG.mjs.map +1 -0
  276. package/.output/server/chunks/build/useOpenInIde-DS4YXevu.mjs +1 -1
  277. package/.output/server/chunks/build/{useSettingsNav-Dg87E7kY.mjs → useSettingsNav-dyHz-2Bz.mjs} +2 -2
  278. package/.output/server/chunks/build/useSettingsNav-dyHz-2Bz.mjs.map +1 -0
  279. package/.output/server/chunks/build/{users-DgsoiXxQ.mjs → users-CluLB8DL.mjs} +31 -13
  280. package/.output/server/chunks/build/users-CluLB8DL.mjs.map +1 -0
  281. package/.output/server/chunks/nitro/nitro.mjs +839 -680
  282. package/.output/server/chunks/routes/__piwi/session.get.mjs +1 -1
  283. package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs +5 -2
  284. package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs.map +1 -1
  285. package/.output/server/chunks/routes/api/test-runs/_id/events.post.mjs +1 -1
  286. package/.output/server/chunks/routes/api/test-runs/_id/failure-groups.get.mjs +1 -1
  287. package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs +42 -26
  288. package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs.map +1 -1
  289. package/.output/server/chunks/routes/api/test-runs/_id/gate.post.mjs +1 -1
  290. package/.output/server/chunks/routes/api/test-runs/_id/heartbeat.post.mjs +1 -1
  291. package/.output/server/chunks/routes/api/test-runs/_id/insights.get.mjs +1 -1
  292. package/.output/server/chunks/routes/api/test-runs/_id/network-requests.get.mjs +1 -1
  293. package/.output/server/chunks/routes/api/test-runs/_id/regression-context.get.mjs +1 -1
  294. package/.output/server/chunks/routes/api/test-runs/_id/summary.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/test-runs/import/check.post.mjs +1 -1
  296. package/.output/server/chunks/routes/api/test-runs/recent.get.mjs +1 -1
  297. package/.output/server/chunks/routes/api/test-runs/submit.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/test-runs/upload.post.mjs +1 -1
  299. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs +1 -0
  300. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs.map +1 -1
  301. package/.output/server/chunks/routes/api/traces/check.post.mjs +1 -1
  302. package/.output/server/chunks/routes/api/users/_id/index.post.mjs +1 -1
  303. package/.output/server/chunks/routes/api/users/_id/invite.post.mjs +1 -1
  304. package/.output/server/chunks/routes/api/users/_id/projects.get.mjs +1 -1
  305. package/.output/server/chunks/routes/api/users/_id/projects.put.mjs +1 -1
  306. package/.output/server/chunks/routes/mcp.post.mjs +1 -1
  307. package/.output/server/chunks/routes/renderer.mjs +1 -1
  308. package/.output/server/chunks/routes/share/_token_.get.mjs +1 -1
  309. package/.output/server/index.mjs +1 -1
  310. package/.output/server/package.json +1 -1
  311. package/package.json +1 -1
  312. package/.output/public/_nuxt/3HmftUHT.js +0 -1
  313. package/.output/public/_nuxt/B7zo6PK8.js +0 -1
  314. package/.output/public/_nuxt/BO4sfkbw.js +0 -1
  315. package/.output/public/_nuxt/BdyXNI2_.js +0 -1
  316. package/.output/public/_nuxt/Bg63qh8W.js +0 -1
  317. package/.output/public/_nuxt/BnhWd06P.js +0 -1
  318. package/.output/public/_nuxt/CHWW6xiX.js +0 -1
  319. package/.output/public/_nuxt/CIPvUOic.js +0 -2
  320. package/.output/public/_nuxt/CVcFbORW.js +0 -9
  321. package/.output/public/_nuxt/CZlz5y13.js +0 -1
  322. package/.output/public/_nuxt/CkV_UG8j.js +0 -1
  323. package/.output/public/_nuxt/D0TpBpCc.js +0 -1
  324. package/.output/public/_nuxt/D3LyIeiJ.js +0 -1
  325. package/.output/public/_nuxt/DcccidY5.js +0 -4
  326. package/.output/public/_nuxt/DqkCbAzo.js +0 -1
  327. package/.output/public/_nuxt/DwH4SIZE.js +0 -1
  328. package/.output/public/_nuxt/DwZS0oRm.js +0 -2
  329. package/.output/public/_nuxt/DxPZIuWy.js +0 -1
  330. package/.output/public/_nuxt/Dyb1FouX.js +0 -1
  331. package/.output/public/_nuxt/builds/meta/a5fb24cc-65e3-4e55-aa12-038fe2de4754.json +0 -1
  332. package/.output/public/_nuxt/entry.BFe0Ua9k.css +0 -1
  333. package/.output/public/_nuxt/i7znB42v.js +0 -1
  334. package/.output/server/chunks/build/BreadcrumbNav-DBnGj5Jq.mjs.map +0 -1
  335. package/.output/server/chunks/build/BrowserBadge-vFb1ERG_.mjs.map +0 -1
  336. package/.output/server/chunks/build/ChartMarkerLines-BXqUpUcs.mjs.map +0 -1
  337. package/.output/server/chunks/build/ChartTooltip-DoF6Smyc.mjs.map +0 -1
  338. package/.output/server/chunks/build/CodeBlock-CmvKHaq8.mjs.map +0 -1
  339. package/.output/server/chunks/build/DataLocationCard-ChV02QJj.mjs.map +0 -1
  340. package/.output/server/chunks/build/DiagnosisPanel-C_ndadzP.mjs.map +0 -1
  341. package/.output/server/chunks/build/DiagnosisResult-GAjo6Lt3.mjs.map +0 -1
  342. package/.output/server/chunks/build/DurationValue-CObiBDnH.mjs.map +0 -1
  343. package/.output/server/chunks/build/FeatureUnavailable-Buoyoqx1.mjs.map +0 -1
  344. package/.output/server/chunks/build/GetStartedWizard-tL3U_qM1.mjs.map +0 -1
  345. package/.output/server/chunks/build/HelpHint-C96TlqxY.mjs.map +0 -1
  346. package/.output/server/chunks/build/MetaStripGroup-Cp2WCQf7.mjs.map +0 -1
  347. package/.output/server/chunks/build/NavbarActions-VCHW0u67.mjs.map +0 -1
  348. package/.output/server/chunks/build/ProjectTestCasesTable-saHYJoyQ.mjs.map +0 -1
  349. package/.output/server/chunks/build/RunReports-CKYYRC59.mjs.map +0 -1
  350. package/.output/server/chunks/build/RunStatusBadge-CWhmAmKb.mjs.map +0 -1
  351. package/.output/server/chunks/build/SectionCard-BB1O3uXd.mjs.map +0 -1
  352. package/.output/server/chunks/build/SettingsField-CEasBHu3.mjs.map +0 -1
  353. package/.output/server/chunks/build/TestCaseHistoryChart-BgI6P_zS.mjs.map +0 -1
  354. package/.output/server/chunks/build/TestStatusBar-DR8jM5th.mjs.map +0 -1
  355. package/.output/server/chunks/build/_id_-B7Dw490u.mjs.map +0 -1
  356. package/.output/server/chunks/build/_id_-DVPb1S93.mjs.map +0 -1
  357. package/.output/server/chunks/build/_id_-kkexEH_q.mjs.map +0 -1
  358. package/.output/server/chunks/build/about-C4AbyQ4q.mjs.map +0 -1
  359. package/.output/server/chunks/build/account-B45bYZd1.mjs.map +0 -1
  360. package/.output/server/chunks/build/auto-heal-BnTdKHQq.mjs.map +0 -1
  361. package/.output/server/chunks/build/help-content-BK3jcgLw.mjs.map +0 -1
  362. package/.output/server/chunks/build/import-ibAn_HB9.mjs.map +0 -1
  363. package/.output/server/chunks/build/index-2GmuPNF-.mjs.map +0 -1
  364. package/.output/server/chunks/build/index-D5A0DW7Y.mjs.map +0 -1
  365. package/.output/server/chunks/build/index-DreB_S-d.mjs.map +0 -1
  366. package/.output/server/chunks/build/index-KsRegEjT.mjs.map +0 -1
  367. package/.output/server/chunks/build/mcp-Dwj29-uG.mjs.map +0 -1
  368. package/.output/server/chunks/build/notifications-CjAn5FJj.mjs.map +0 -1
  369. package/.output/server/chunks/build/performance-DRzcu_c7.mjs.map +0 -1
  370. package/.output/server/chunks/build/pr-feedback-DR60oGBf.mjs.map +0 -1
  371. package/.output/server/chunks/build/selections-BjjolRZ9.mjs.map +0 -1
  372. package/.output/server/chunks/build/settings-B3NWV9tu.mjs.map +0 -1
  373. package/.output/server/chunks/build/settings-metadata-DwJk8uSt.mjs.map +0 -1
  374. package/.output/server/chunks/build/storage-C1O-FC0U.mjs.map +0 -1
  375. package/.output/server/chunks/build/tags-dsvYrnii.mjs.map +0 -1
  376. package/.output/server/chunks/build/test-cases-CFiOuyK6.mjs.map +0 -1
  377. package/.output/server/chunks/build/test-functions-CbmBi6az.mjs.map +0 -1
  378. package/.output/server/chunks/build/useDesktopDownload-R_RWSgUV.mjs.map +0 -1
  379. package/.output/server/chunks/build/useDesktopLocalRuns-BdELBy0Y.mjs.map +0 -1
  380. package/.output/server/chunks/build/useDesktopProjectLink-IUN7SIP2.mjs.map +0 -1
  381. package/.output/server/chunks/build/useSettingsNav-Dg87E7kY.mjs.map +0 -1
  382. package/.output/server/chunks/build/users-DgsoiXxQ.mjs.map +0 -1
@@ -1,22 +1,22 @@
1
- import { _ as _sfc_main$1$1, a as _sfc_main$i } from './DashboardNavbar-C3PsNVJt.mjs';
1
+ import { _ as _sfc_main$1$1, a as _sfc_main$j } from './DashboardNavbar-C3PsNVJt.mjs';
2
2
  import { _ as _sfc_main$1$2 } from './Breadcrumb-DtV_L8Gt.mjs';
3
- import { _ as __nuxt_component_3$1 } from './BreadcrumbNav-DBnGj5Jq.mjs';
4
- import { u as useRoute, n as useRouter, r as useRuntimeConfig, o as useHead, j as useToast, m as _sfc_main$7$1, l as _sfc_main$k, v as __nuxt_component_12$1, k as _sfc_main$p, w as __nuxt_component_7$1, _ as _sfc_main$d$1, s as _sfc_main$8$1, p as _sfc_main$j$1 } from './server.mjs';
5
- import { _ as _sfc_main$j } from './Tooltip-CK0ucuXC.mjs';
6
- import { _ as __nuxt_component_4$1 } from './NavbarActions-VCHW0u67.mjs';
7
- import { _ as __nuxt_component_8, a as __nuxt_component_1$1, b as __nuxt_component_16$1, c as __nuxt_component_17$1 } from './MetaStripGroup-Cp2WCQf7.mjs';
8
- import { _ as __nuxt_component_0$1 } from './DiagnosisResult-GAjo6Lt3.mjs';
9
- import { _ as __nuxt_component_14$3 } from './TestStatusBar-DR8jM5th.mjs';
10
- import { _ as __nuxt_component_14$1 } from './DurationValue-CObiBDnH.mjs';
3
+ import { _ as __nuxt_component_3$1 } from './BreadcrumbNav-Bg4QGX0k.mjs';
4
+ import { u as useRoute, n as useRouter, r as useRuntimeConfig, o as useHead, j as useToast, m as _sfc_main$7$1, l as _sfc_main$k, v as __nuxt_component_12$1, w as __nuxt_component_8$1, k as _sfc_main$p, _ as _sfc_main$d$1, s as _sfc_main$8$1, p as _sfc_main$j$1 } from './server.mjs';
5
+ import { defineComponent, withAsyncContext, ref, computed, watch, withCtx, isRef, unref, createVNode, createTextVNode, toDisplayString, openBlock, createBlock, createCommentVNode, nextTick, mergeProps, Fragment, renderList, useModel, mergeModels, withDirectives, vModelText, withKeys, withModifiers, useSSRContext } from 'vue';
6
+ import { ssrRenderComponent, ssrInterpolate, ssrRenderAttrs, ssrRenderClass, ssrRenderList, ssrRenderStyle, ssrRenderAttr, ssrIncludeBooleanAttr, ssrRenderTeleport } from 'vue/server-renderer';
7
+ import { _ as __nuxt_component_4$1 } from './NavbarActions-BTWxKCVI.mjs';
8
+ import { _ as __nuxt_component_7$1, a as __nuxt_component_1$1, b as __nuxt_component_16$1, c as __nuxt_component_17$1 } from './MetaStripGroup-CDyGlsNt.mjs';
9
+ import { _ as __nuxt_component_0$1 } from './DiagnosisResult-CrGK--xh.mjs';
10
+ import { _ as __nuxt_component_15$1 } from './TestStatusBar-BipoEOzd.mjs';
11
+ import { _ as __nuxt_component_14$1 } from './DurationValue-Dn06XQk3.mjs';
11
12
  import { _ as _sfc_main$o } from './Card--Ike7sYc.mjs';
12
- import { _ as __nuxt_component_2$2 } from './HelpHint-C96TlqxY.mjs';
13
- import { _ as __nuxt_component_5 } from './MarkerBadge-DmubzeuF.mjs';
14
- import { _ as __nuxt_component_14$2 } from './DesktopRunLocallyButton-BfmbZpiL.mjs';
13
+ import { _ as __nuxt_component_2$2 } from './HelpHint-CdBz6deq.mjs';
14
+ import { _ as _sfc_main$t } from './Tooltip-CK0ucuXC.mjs';
15
+ import { _ as __nuxt_component_5$1 } from './MarkerBadge-DmubzeuF.mjs';
16
+ import { _ as __nuxt_component_14$2 } from './DesktopRunLocallyButton-ChHg3GqK.mjs';
15
17
  import { _ as __nuxt_component_1$2 } from './StatTileGrid-7zOFUQ6j.mjs';
16
- import { p as prettyDateFormat, w as getStatusColor, a as formatRelativeTime, c as copyPreview, k as clusterStatusColor, i as clusterErrorTypeColor, A as reportIcon, o as fileApiUrl, x as createSortHeader, f as formatDuration, H as getStatusTextClass, G as getStatusIcon, b as formatStatusLabel, F as isStatusInFlight, D as isPiwiAnnotation } from './index-2GmuPNF-.mjs';
17
- import { eM as buildRetryCommand, am as formatBytes, cC as DEFAULT_WASTED_WAIT_PATTERNS, f1 as isWastedWait } from '../nitro/nitro.mjs';
18
- import { defineComponent, withAsyncContext, ref, computed, watch, withCtx, isRef, unref, createVNode, createTextVNode, openBlock, createBlock, createCommentVNode, toDisplayString, nextTick, mergeProps, Fragment, renderList, useModel, mergeModels, withDirectives, vModelText, useSSRContext } from 'vue';
19
- import { ssrRenderComponent, ssrInterpolate, ssrRenderAttrs, ssrRenderClass, ssrRenderList, ssrRenderStyle, ssrRenderAttr, ssrRenderTeleport, ssrIncludeBooleanAttr } from 'vue/server-renderer';
18
+ import { w as getStatusColor, a as formatRelativeTime, c as copyPreview, k as clusterStatusColor, E as formatTriageStatus, i as clusterErrorTypeColor, B as isFailedStatus, J as failureFirstCompare, A as reportIcon, o as fileApiUrl, p as prettyDateFormat, x as createSortHeader, f as formatDuration, K as getStatusTextClass, I as getStatusIcon, b as formatStatusLabel, H as isStatusInFlight, F as isPiwiAnnotation } from './index-CjnZ521K.mjs';
19
+ import { eN as buildRetryCommand, am as formatBytes, cC as DEFAULT_WASTED_WAIT_PATTERNS, f2 as isWastedWait } from '../nitro/nitro.mjs';
20
20
  import { _ as __nuxt_component_19 } from './EntityLinks-BcpvMt_V.mjs';
21
21
  import { u as useFetch, a as useCopy } from './fetch-DOcN2mHf.mjs';
22
22
  import { _ as __nuxt_component_4$4 } from './FilterToolbar-BwXy8xSk.mjs';
@@ -24,21 +24,21 @@ import { _ as _sfc_main$r } from './Select-COU8NARj.mjs';
24
24
  import { _ as _sfc_main$s } from './Checkbox-ChSYhiUz.mjs';
25
25
  import { _ as __nuxt_component_1$3 } from './OpenInIdeLink-Bnl-_som.mjs';
26
26
  import { _ as __nuxt_component_2$3 } from './TestMetaBadges-G2dAHnT-.mjs';
27
- import { _ as __nuxt_component_3$3 } from './BrowserBadge-vFb1ERG_.mjs';
27
+ import { _ as __nuxt_component_3$3 } from './BrowserBadge-yMgLTBUu.mjs';
28
+ import { _ as __nuxt_component_4$3 } from './EmptyState-C-mCzGhO.mjs';
28
29
  import { u as useTreeViewCookie } from './useTreeViewCookie-BvoH7a_X.mjs';
29
- import { _ as __nuxt_component_5$1 } from './ErrorState-9UPssp7w.mjs';
30
+ import { _ as __nuxt_component_5$2 } from './ErrorState-9UPssp7w.mjs';
30
31
  import { _ as __nuxt_component_13$2 } from './LoadingState-CxfFwac9.mjs';
31
- import { _ as __nuxt_component_4$3 } from './EmptyState-C-mCzGhO.mjs';
32
- import { _ as __nuxt_component_11 } from './SectionCard-BB1O3uXd.mjs';
32
+ import { _ as __nuxt_component_11$1 } from './SectionCard-CKD1s0eF.mjs';
33
33
  import { _ as __nuxt_component_3$2 } from './TableScroller-DMcdCVrH.mjs';
34
34
  import { _ as _sfc_main$l } from './Table-BET-DOtX.mjs';
35
35
  import { _ as _sfc_main$q } from './Modal-BGBGJtVH.mjs';
36
- import { _ as __nuxt_component_0$2 } from './DiagnosisPanel-C_ndadzP.mjs';
36
+ import { _ as __nuxt_component_0$2 } from './DiagnosisPanel-DE-r2UV8.mjs';
37
37
  import { _ as _sfc_main$m } from './SelectMenu-BUwwc3Qt.mjs';
38
- import { _ as __nuxt_component_13$1 } from './RunStatusBadge-CWhmAmKb.mjs';
38
+ import { _ as __nuxt_component_13$1 } from './RunStatusBadge-zfeSwcTx.mjs';
39
39
  import { _ as _sfc_main$n } from './Alert-gs8RgKxH.mjs';
40
40
  import { u as useRunComparison } from './useRunComparison-CiMBLpe2.mjs';
41
- import { _ as __nuxt_component_4$2 } from './FeatureUnavailable-Buoyoqx1.mjs';
41
+ import { _ as __nuxt_component_4$2 } from './FeatureUnavailable-IaBjVCqQ.mjs';
42
42
  import './DashboardSidebarToggle-a5KYecZ0.mjs';
43
43
  import 'vue-router';
44
44
  import '@iconify/vue';
@@ -98,13 +98,14 @@ import 'node:zlib';
98
98
  import 'consola';
99
99
  import 'node:url';
100
100
  import '@iconify/utils';
101
- import './Tabs-CC34LIUz.mjs';
102
- import './RovingFocusItem-CLjuqlIR.mjs';
103
- import './CodeBlock-CmvKHaq8.mjs';
101
+ import './DashboardToolbar-BZoGc0ri.mjs';
102
+ import './NavigationMenu-D4ZpdCm_.mjs';
103
+ import './isValueEqualOrExist-D4lZ8uRY.mjs';
104
+ import './CodeBlock-DuWhmcI2.mjs';
104
105
  import './Textarea-CmjqdiIA.mjs';
105
- import './help-content-BK3jcgLw.mjs';
106
+ import './help-content-3QLSe6Vd.mjs';
106
107
  import '../_/marker-categories.mjs';
107
- import './useDesktopLocalRuns-BdELBy0Y.mjs';
108
+ import './useDesktopLocalRuns-BHZic4MJ.mjs';
108
109
  import './useTauri-Kf3HE_42.mjs';
109
110
  import './FormField-GYHKiSI6.mjs';
110
111
  import './Label-DYDR1Oeh.mjs';
@@ -112,17 +113,74 @@ import './Switch-_NJhWmI9.mjs';
112
113
  import './useFormControl-8skMOTIf.mjs';
113
114
  import './useForwardScopeId-D0ameaSU.mjs';
114
115
  import './VisuallyHiddenInput-D4E5aJCQ.mjs';
115
- import './useDesktopProjectLink-IUN7SIP2.mjs';
116
+ import './useDesktopProjectLink-CqBvnXwG.mjs';
116
117
  import 'date-fns';
117
118
  import '@vue/shared';
118
119
  import './handleAndDispatchCustomEvent-Bk_AVSSo.mjs';
119
- import './isValueEqualOrExist-D4lZ8uRY.mjs';
120
+ import './RovingFocusItem-CLjuqlIR.mjs';
120
121
  import './Separator-CQsq6WA9.mjs';
121
122
  import './useOpenInIde-DS4YXevu.mjs';
122
123
  import '@tanstack/vue-table';
123
124
  import '@tanstack/vue-virtual';
124
125
  import './useAiStatus-CiK1MZbH.mjs';
125
126
 
127
+ const _sfc_main$i = /* @__PURE__ */ defineComponent({
128
+ __name: "RunFreshnessPill",
129
+ __ssrInlineRender: true,
130
+ props: {
131
+ latestRunId: {},
132
+ currentRunId: {},
133
+ isActive: { type: Boolean }
134
+ },
135
+ setup(__props) {
136
+ return (_ctx, _push, _parent, _attrs) => {
137
+ const _component_NuxtLink = __nuxt_component_12$1;
138
+ const _component_UIcon = _sfc_main$p;
139
+ if (__props.latestRunId && __props.latestRunId !== __props.currentRunId) {
140
+ _push(ssrRenderComponent(_component_NuxtLink, mergeProps({
141
+ to: `/test-runs/${__props.latestRunId}`,
142
+ "aria-label": __props.isActive ? `Go to running run #${__props.latestRunId}` : `Go to latest run #${__props.latestRunId}`,
143
+ class: "shrink-0 inline-flex items-center gap-1 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors px-2 py-0.5 text-xs text-blue-500"
144
+ }, _attrs), {
145
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
146
+ if (_push2) {
147
+ _push2(ssrRenderComponent(_component_UIcon, {
148
+ name: "i-lucide-circle-play",
149
+ class: ["size-3.5", { "animate-pulse": __props.isActive }]
150
+ }, null, _parent2, _scopeId));
151
+ _push2(` ${ssrInterpolate(__props.isActive ? "Running" : "Newer run")} → #${ssrInterpolate(__props.latestRunId)}`);
152
+ } else {
153
+ return [
154
+ createVNode(_component_UIcon, {
155
+ name: "i-lucide-circle-play",
156
+ class: ["size-3.5", { "animate-pulse": __props.isActive }]
157
+ }, null, 8, ["class"]),
158
+ createTextVNode(" " + toDisplayString(__props.isActive ? "Running" : "Newer run") + " → #" + toDisplayString(__props.latestRunId), 1)
159
+ ];
160
+ }
161
+ }),
162
+ _: 1
163
+ }, _parent));
164
+ } else if (__props.latestRunId) {
165
+ _push(`<span${ssrRenderAttrs(mergeProps({ class: "shrink-0 inline-flex items-center gap-1 rounded-full bg-emerald-500/10 px-2 py-0.5 text-xs text-emerald-600 dark:text-emerald-400" }, _attrs))}>`);
166
+ _push(ssrRenderComponent(_component_UIcon, {
167
+ name: "i-lucide-check-circle-2",
168
+ class: "size-3.5"
169
+ }, null, _parent));
170
+ _push(` Latest run </span>`);
171
+ } else {
172
+ _push(`<!---->`);
173
+ }
174
+ };
175
+ }
176
+ });
177
+ const _sfc_setup$i = _sfc_main$i.setup;
178
+ _sfc_main$i.setup = (props, ctx) => {
179
+ const ssrContext = useSSRContext();
180
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/RunFreshnessPill.vue");
181
+ return _sfc_setup$i ? _sfc_setup$i(props, ctx) : void 0;
182
+ };
183
+ const __nuxt_component_5 = Object.assign(_sfc_main$i, { __name: "RunFreshnessPill" });
126
184
  const _sfc_main$h = /* @__PURE__ */ defineComponent({
127
185
  __name: "RunStorageChip",
128
186
  __ssrInlineRender: true,
@@ -281,7 +339,7 @@ _sfc_main$h.setup = (props, ctx) => {
281
339
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/RunStorageChip.vue");
282
340
  return _sfc_setup$h ? _sfc_setup$h(props, ctx) : void 0;
283
341
  };
284
- const __nuxt_component_18$1 = Object.assign(_sfc_main$h, { __name: "RunStorageChip" });
342
+ const __nuxt_component_18 = Object.assign(_sfc_main$h, { __name: "RunStorageChip" });
285
343
  const _sfc_main$g = /* @__PURE__ */ defineComponent({
286
344
  __name: "RunSummary",
287
345
  __ssrInlineRender: true,
@@ -291,10 +349,10 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
291
349
  allReports: {},
292
350
  showCustomData: { type: Boolean },
293
351
  finalizing: { type: Boolean },
294
- activeFilter: {},
352
+ activeStatuses: {},
295
353
  totalWastedTime: {}
296
354
  },
297
- emits: ["update:showCustomData", "filter-status", "label-updated"],
355
+ emits: ["update:showCustomData", "toggle-status", "label-updated"],
298
356
  setup(__props, { emit: __emit }) {
299
357
  const props = __props;
300
358
  const emit = __emit;
@@ -407,21 +465,21 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
407
465
  const _component_StatusChip = __nuxt_component_1$1;
408
466
  const _component_UIcon = _sfc_main$p;
409
467
  const _component_UBadge = _sfc_main$7$1;
410
- const _component_TestStatusBar = __nuxt_component_14$3;
468
+ const _component_TestStatusBar = __nuxt_component_15$1;
411
469
  const _component_DurationValue = __nuxt_component_14$1;
412
470
  const _component_UCard = _sfc_main$o;
413
471
  const _component_HelpHint = __nuxt_component_2$2;
414
- const _component_UTooltip = _sfc_main$j;
472
+ const _component_UTooltip = _sfc_main$t;
415
473
  const _component_NuxtLink = __nuxt_component_12$1;
416
- const _component_MarkerBadge = __nuxt_component_5;
417
- const _component_ClientOnly = __nuxt_component_7$1;
474
+ const _component_MarkerBadge = __nuxt_component_5$1;
475
+ const _component_ClientOnly = __nuxt_component_8$1;
418
476
  const _component_UButton = _sfc_main$k;
419
477
  const _component_UPopover = _sfc_main$8$1;
420
478
  const _component_DesktopRunLocallyButton = __nuxt_component_14$2;
421
479
  const _component_StatTileGrid = __nuxt_component_1$2;
422
480
  const _component_SummaryMetaStrip = __nuxt_component_16$1;
423
481
  const _component_MetaStripGroup = __nuxt_component_17$1;
424
- const _component_RunStorageChip = __nuxt_component_18$1;
482
+ const _component_RunStorageChip = __nuxt_component_18;
425
483
  const _component_EntityLinks = __nuxt_component_19;
426
484
  _push(ssrRenderComponent(_component_FoldableSummary, mergeProps({ "storage-key": "test-run" }, _attrs), {
427
485
  folded: withCtx((_, _push2, _parent2, _scopeId) => {
@@ -446,7 +504,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
446
504
  } else {
447
505
  _push2(`<!--[-->`);
448
506
  if (__props.testRun?.label) {
449
- _push2(`<span class="font-normal text-zinc-500 ml-1.5 cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-300 border-b border-dashed border-transparent hover:border-zinc-400"${_scopeId}>— ${ssrInterpolate(__props.testRun.label)}</span>`);
507
+ _push2(`<span role="button" tabindex="0" class="font-normal text-zinc-500 ml-1.5 cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-300 border-b border-dashed border-transparent hover:border-zinc-400"${_scopeId}>— ${ssrInterpolate(__props.testRun.label)}</span>`);
450
508
  } else {
451
509
  _push2(`<button class="text-xs text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 border-b border-dashed border-transparent hover:border-zinc-400 ml-1" title="Add a label"${_scopeId}> + label </button>`);
452
510
  }
@@ -528,9 +586,12 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
528
586
  ], 64)) : (openBlock(), createBlock(Fragment, { key: 1 }, [
529
587
  __props.testRun?.label ? (openBlock(), createBlock("span", {
530
588
  key: 0,
589
+ role: "button",
590
+ tabindex: "0",
531
591
  class: "font-normal text-zinc-500 ml-1.5 cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-300 border-b border-dashed border-transparent hover:border-zinc-400",
532
- onClick: startEditLabel
533
- }, "— " + toDisplayString(__props.testRun.label), 1)) : (openBlock(), createBlock("button", {
592
+ onClick: withModifiers(startEditLabel, ["stop"]),
593
+ onKeydown: withKeys(withModifiers(startEditLabel, ["stop"]), ["enter"])
594
+ }, "— " + toDisplayString(__props.testRun.label), 41, ["onKeydown"])) : (openBlock(), createBlock("button", {
534
595
  key: 1,
535
596
  class: "text-xs text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 border-b border-dashed border-transparent hover:border-zinc-400 ml-1",
536
597
  title: "Add a label",
@@ -1331,6 +1392,11 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1331
1392
  _push3(ssrRenderComponent(_component_StatusChip, {
1332
1393
  status: __props.testRun?.status ?? ""
1333
1394
  }, null, _parent3, _scopeId2));
1395
+ if (__props.testRun?.status === "interrupted" || __props.testRun?.shardTotal && __props.testRun.shardTotal > 1) {
1396
+ _push3(ssrRenderComponent(_component_HelpHint, { topic: "run.partial" }, null, _parent3, _scopeId2));
1397
+ } else {
1398
+ _push3(`<!---->`);
1399
+ }
1334
1400
  _push3(`<h2 class="text-base font-bold shrink-0 flex items-center gap-1"${_scopeId2}> Run #${ssrInterpolate(__props.testRun?.id)} `);
1335
1401
  if (unref(editingLabel)) {
1336
1402
  _push3(`<!--[--><input${ssrRenderAttr("value", unref(labelInput))} type="text" placeholder="Add a label..." class="inline-block w-48 text-sm font-normal border-b border-dashed border-zinc-400 bg-transparent outline-none focus:border-primary px-0.5 py-0"${_scopeId2}>`);
@@ -1436,8 +1502,15 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1436
1502
  } else {
1437
1503
  _push3(`<!---->`);
1438
1504
  }
1439
- _push3(`</div><p class="mt-1 text-xs text-muted flex items-center gap-1.5 flex-wrap"${_scopeId2}><span${_scopeId2}>Started ${ssrInterpolate(("prettyDateFormat" in _ctx ? _ctx.prettyDateFormat : unref(prettyDateFormat))(__props.testRun?.startTime))}</span>`);
1505
+ _push3(`</div><p class="mt-1 text-xs text-muted flex items-center gap-1.5 flex-wrap"${_scopeId2}>`);
1440
1506
  _push3(ssrRenderComponent(_component_ClientOnly, null, {}, _parent3, _scopeId2));
1507
+ if (__props.testRun?.shardTotal && __props.testRun.shardTotal > 1) {
1508
+ _push3(`<!--[--><span class="text-dimmed"${_scopeId2}>·</span>`);
1509
+ _push3(ssrRenderComponent(_component_HelpHint, { topic: "run.partial" }, null, _parent3, _scopeId2));
1510
+ _push3(`<!--]-->`);
1511
+ } else {
1512
+ _push3(`<!---->`);
1513
+ }
1441
1514
  _push3(`</p></div><div class="flex items-center gap-1.5 shrink-0"${_scopeId2}>`);
1442
1515
  _push3(ssrRenderComponent(_component_UTooltip, {
1443
1516
  text: unref(copied) ? "Copied!" : "Copy run summary"
@@ -1499,17 +1572,17 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1499
1572
  size: "xs",
1500
1573
  color: "warning",
1501
1574
  variant: "subtle",
1502
- icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-play",
1575
+ icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-clipboard",
1503
1576
  title: unref(retryTitle),
1504
- "aria-label": "Retry",
1577
+ "aria-label": "Copy retry command",
1505
1578
  onClick: ($event) => copyRetryCommand()
1506
1579
  }, {
1507
1580
  default: withCtx((_4, _push5, _parent5, _scopeId4) => {
1508
1581
  if (_push5) {
1509
- _push5(`<span class="hidden @2xl:inline"${_scopeId4}>Retry</span>`);
1582
+ _push5(`<span class="hidden @2xl:inline"${_scopeId4}>Copy retry command</span>`);
1510
1583
  } else {
1511
1584
  return [
1512
- createVNode("span", { class: "hidden @2xl:inline" }, "Retry")
1585
+ createVNode("span", { class: "hidden @2xl:inline" }, "Copy retry command")
1513
1586
  ];
1514
1587
  }
1515
1588
  }),
@@ -1521,13 +1594,13 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1521
1594
  size: "xs",
1522
1595
  color: "warning",
1523
1596
  variant: "subtle",
1524
- icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-play",
1597
+ icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-clipboard",
1525
1598
  title: unref(retryTitle),
1526
- "aria-label": "Retry",
1599
+ "aria-label": "Copy retry command",
1527
1600
  onClick: ($event) => copyRetryCommand()
1528
1601
  }, {
1529
1602
  default: withCtx(() => [
1530
- createVNode("span", { class: "hidden @2xl:inline" }, "Retry")
1603
+ createVNode("span", { class: "hidden @2xl:inline" }, "Copy retry command")
1531
1604
  ]),
1532
1605
  _: 1
1533
1606
  }, 8, ["icon", "title", "onClick"])
@@ -1578,17 +1651,17 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1578
1651
  default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1579
1652
  if (_push4) {
1580
1653
  _push4(`<button class="${ssrRenderClass([
1581
- __props.activeFilter === "all" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated",
1582
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer"
1583
- ])}"${_scopeId3}><p class="text-xs font-medium text-zinc-500 uppercase tracking-wider"${_scopeId3}>Total</p><p class="text-xl font-bold mt-0.5"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0)}</p></button><div class="relative"${_scopeId3}><button class="${ssrRenderClass([
1584
- __props.activeFilter === "passed" ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30",
1585
- "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer"
1586
- ])}"${_scopeId3}><p class="text-xs font-medium text-emerald-700 dark:text-emerald-400 uppercase tracking-wider"${_scopeId3}> Passed </p><p class="text-xl font-bold mt-0.5 text-emerald-600 dark:text-emerald-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0)}</p></button>`);
1654
+ __props.activeStatuses.length === 0 ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated",
1655
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
1656
+ ])}"${ssrRenderAttr("aria-pressed", __props.activeStatuses.length === 0)}${ssrIncludeBooleanAttr((__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0) === 0) ? " disabled" : ""}${_scopeId3}><p class="text-xs font-medium text-zinc-500 uppercase tracking-wider"${_scopeId3}>Total</p><p class="text-xl font-bold mt-0.5"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0)}</p></button><div class="relative"${_scopeId3}><button class="${ssrRenderClass([
1657
+ __props.activeStatuses.includes("passed") ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30",
1658
+ "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
1659
+ ])}"${ssrRenderAttr("aria-pressed", __props.activeStatuses.includes("passed"))}${ssrIncludeBooleanAttr((__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0) === 0) ? " disabled" : ""}${_scopeId3}><p class="text-xs font-medium text-emerald-700 dark:text-emerald-400 uppercase tracking-wider"${_scopeId3}> Passed </p><p class="text-xl font-bold mt-0.5 text-emerald-600 dark:text-emerald-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0)}</p></button>`);
1587
1660
  if ((__props.testRun?.flakyTests ?? 0) > 0) {
1588
1661
  _push4(`<button class="${ssrRenderClass([
1589
- __props.activeFilter === "flaky" ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60",
1662
+ __props.activeStatuses.includes("flaky") ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60",
1590
1663
  "absolute top-1.5 right-1.5 inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-semibold leading-none tabular-nums transition-colors cursor-pointer"
1591
- ])}" title="Flaky — passed only after a retry (a subset of passed). Click to filter."${_scopeId3}>`);
1664
+ ])}" title="Flaky — passed only after a retry (a subset of passed). Click to filter."${ssrRenderAttr("aria-pressed", __props.activeStatuses.includes("flaky"))}${_scopeId3}>`);
1592
1665
  _push4(ssrRenderComponent(_component_UIcon, {
1593
1666
  name: "i-lucide-shuffle",
1594
1667
  class: "size-3"
@@ -1598,85 +1671,96 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1598
1671
  _push4(`<!---->`);
1599
1672
  }
1600
1673
  _push4(`</div><button class="${ssrRenderClass([
1601
- __props.activeFilter === "failed" ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30",
1602
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer"
1603
- ])}"${_scopeId3}><p class="text-xs font-medium text-rose-700 dark:text-rose-400 uppercase tracking-wider"${_scopeId3}>Failed</p><p class="text-xl font-bold mt-0.5 text-rose-600 dark:text-rose-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0)}</p></button><button class="${ssrRenderClass([
1604
- __props.activeFilter === "skipped" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated",
1605
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer"
1606
- ])}"${_scopeId3}><p class="text-xs font-medium text-zinc-500 uppercase tracking-wider"${_scopeId3}>Skipped</p><p class="text-xl font-bold mt-0.5 text-zinc-600 dark:text-zinc-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0)}</p></button><button class="${ssrRenderClass([
1607
- __props.activeFilter === "didnotrun" ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30",
1608
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer"
1609
- ])}" title="Tests that never ran (maxFailures cutoff or a serial-group failure)"${_scopeId3}><p class="text-xs font-medium text-amber-700 dark:text-amber-400 uppercase tracking-wider"${_scopeId3}>Didn&#39;t run</p><p class="text-xl font-bold mt-0.5 text-amber-600 dark:text-amber-400"${_scopeId3}>${ssrInterpolate(__props.testRun?.didNotRunTests ?? 0)}</p></button>`);
1674
+ __props.activeStatuses.includes("failed") ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30",
1675
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
1676
+ ])}"${ssrRenderAttr("aria-pressed", __props.activeStatuses.includes("failed"))}${ssrIncludeBooleanAttr((__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0) === 0) ? " disabled" : ""}${_scopeId3}><p class="text-xs font-medium text-rose-700 dark:text-rose-400 uppercase tracking-wider"${_scopeId3}>Failed</p><p class="text-xl font-bold mt-0.5 text-rose-600 dark:text-rose-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0)}</p></button><button class="${ssrRenderClass([
1677
+ __props.activeStatuses.includes("skipped") ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated",
1678
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
1679
+ ])}"${ssrRenderAttr("aria-pressed", __props.activeStatuses.includes("skipped"))}${ssrIncludeBooleanAttr((__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0) === 0) ? " disabled" : ""}${_scopeId3}><p class="text-xs font-medium text-zinc-500 uppercase tracking-wider"${_scopeId3}>Skipped</p><p class="text-xl font-bold mt-0.5 text-zinc-600 dark:text-zinc-400"${_scopeId3}>${ssrInterpolate(__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0)}</p></button><button class="${ssrRenderClass([
1680
+ __props.activeStatuses.includes("didnotrun") ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30",
1681
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
1682
+ ])}" title="Tests that never ran (maxFailures cutoff or a serial-group failure)"${ssrRenderAttr("aria-pressed", __props.activeStatuses.includes("didnotrun"))}${ssrIncludeBooleanAttr((__props.testRun?.didNotRunTests ?? 0) === 0) ? " disabled" : ""}${_scopeId3}><p class="text-xs font-medium text-amber-700 dark:text-amber-400 uppercase tracking-wider"${_scopeId3}>Didn&#39;t run</p><p class="text-xl font-bold mt-0.5 text-amber-600 dark:text-amber-400"${_scopeId3}>${ssrInterpolate(__props.testRun?.didNotRunTests ?? 0)}</p></button>`);
1610
1683
  } else {
1611
1684
  return [
1612
1685
  createVNode("button", {
1613
1686
  class: [
1614
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1615
- __props.activeFilter === "all" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1687
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
1688
+ __props.activeStatuses.length === 0 ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1616
1689
  ],
1617
- onClick: ($event) => emit("filter-status", "all")
1690
+ "aria-pressed": __props.activeStatuses.length === 0,
1691
+ disabled: (__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0) === 0,
1692
+ onClick: ($event) => emit("toggle-status", "all")
1618
1693
  }, [
1619
1694
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Total"),
1620
1695
  createVNode("p", { class: "text-xl font-bold mt-0.5" }, toDisplayString(__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0), 1)
1621
- ], 10, ["onClick"]),
1696
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1622
1697
  createVNode("div", { class: "relative" }, [
1623
1698
  createVNode("button", {
1624
1699
  class: [
1625
- "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer",
1626
- __props.activeFilter === "passed" ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
1700
+ "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
1701
+ __props.activeStatuses.includes("passed") ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
1627
1702
  ],
1628
- onClick: ($event) => emit("filter-status", "passed")
1703
+ "aria-pressed": __props.activeStatuses.includes("passed"),
1704
+ disabled: (__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0) === 0,
1705
+ onClick: ($event) => emit("toggle-status", "passed")
1629
1706
  }, [
1630
1707
  createVNode("p", { class: "text-xs font-medium text-emerald-700 dark:text-emerald-400 uppercase tracking-wider" }, " Passed "),
1631
1708
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-emerald-600 dark:text-emerald-400" }, toDisplayString(__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0), 1)
1632
- ], 10, ["onClick"]),
1709
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1633
1710
  (__props.testRun?.flakyTests ?? 0) > 0 ? (openBlock(), createBlock("button", {
1634
1711
  key: 0,
1635
1712
  class: [
1636
1713
  "absolute top-1.5 right-1.5 inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-semibold leading-none tabular-nums transition-colors cursor-pointer",
1637
- __props.activeFilter === "flaky" ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
1714
+ __props.activeStatuses.includes("flaky") ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
1638
1715
  ],
1639
1716
  title: "Flaky — passed only after a retry (a subset of passed). Click to filter.",
1640
- onClick: ($event) => emit("filter-status", "flaky")
1717
+ "aria-pressed": __props.activeStatuses.includes("flaky"),
1718
+ onClick: ($event) => emit("toggle-status", "flaky")
1641
1719
  }, [
1642
1720
  createVNode(_component_UIcon, {
1643
1721
  name: "i-lucide-shuffle",
1644
1722
  class: "size-3"
1645
1723
  }),
1646
1724
  createTextVNode(" " + toDisplayString(__props.testRun?.flakyTests ?? 0), 1)
1647
- ], 10, ["onClick"])) : createCommentVNode("", true)
1725
+ ], 10, ["aria-pressed", "onClick"])) : createCommentVNode("", true)
1648
1726
  ]),
1649
1727
  createVNode("button", {
1650
1728
  class: [
1651
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1652
- __props.activeFilter === "failed" ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
1729
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
1730
+ __props.activeStatuses.includes("failed") ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
1653
1731
  ],
1654
- onClick: ($event) => emit("filter-status", "failed")
1732
+ "aria-pressed": __props.activeStatuses.includes("failed"),
1733
+ disabled: (__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0) === 0,
1734
+ onClick: ($event) => emit("toggle-status", "failed")
1655
1735
  }, [
1656
1736
  createVNode("p", { class: "text-xs font-medium text-rose-700 dark:text-rose-400 uppercase tracking-wider" }, "Failed"),
1657
1737
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-rose-600 dark:text-rose-400" }, toDisplayString(__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0), 1)
1658
- ], 10, ["onClick"]),
1738
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1659
1739
  createVNode("button", {
1660
1740
  class: [
1661
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1662
- __props.activeFilter === "skipped" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1741
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
1742
+ __props.activeStatuses.includes("skipped") ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1663
1743
  ],
1664
- onClick: ($event) => emit("filter-status", "skipped")
1744
+ "aria-pressed": __props.activeStatuses.includes("skipped"),
1745
+ disabled: (__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0) === 0,
1746
+ onClick: ($event) => emit("toggle-status", "skipped")
1665
1747
  }, [
1666
1748
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Skipped"),
1667
1749
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-zinc-600 dark:text-zinc-400" }, toDisplayString(__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0), 1)
1668
- ], 10, ["onClick"]),
1750
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1669
1751
  createVNode("button", {
1670
1752
  class: [
1671
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1672
- __props.activeFilter === "didnotrun" ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
1753
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
1754
+ __props.activeStatuses.includes("didnotrun") ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
1673
1755
  ],
1674
1756
  title: "Tests that never ran (maxFailures cutoff or a serial-group failure)",
1675
- onClick: ($event) => emit("filter-status", "didnotrun")
1757
+ "aria-pressed": __props.activeStatuses.includes("didnotrun"),
1758
+ disabled: (__props.testRun?.didNotRunTests ?? 0) === 0,
1759
+ onClick: ($event) => emit("toggle-status", "didnotrun")
1676
1760
  }, [
1677
1761
  createVNode("p", { class: "text-xs font-medium text-amber-700 dark:text-amber-400 uppercase tracking-wider" }, "Didn't run"),
1678
1762
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-amber-600 dark:text-amber-400" }, toDisplayString(__props.testRun?.didNotRunTests ?? 0), 1)
1679
- ], 10, ["onClick"])
1763
+ ], 10, ["aria-pressed", "disabled", "onClick"])
1680
1764
  ];
1681
1765
  }
1682
1766
  }),
@@ -1697,6 +1781,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1697
1781
  name: "i-lucide-clock",
1698
1782
  class: "size-3.5 text-zinc-400"
1699
1783
  }, null, _parent3, _scopeId2));
1784
+ _push3(`<span class="text-zinc-500"${_scopeId2}>Duration</span>`);
1700
1785
  _push3(ssrRenderComponent(_component_DurationValue, {
1701
1786
  ms: __props.testRun?.duration,
1702
1787
  class: "font-medium"
@@ -1734,7 +1819,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1734
1819
  _push3(`<!---->`);
1735
1820
  }
1736
1821
  if (__props.totalWastedTime && __props.totalWastedTime > 0) {
1737
- _push3(`<div class="flex items-center gap-1"${_scopeId2}>`);
1822
+ _push3(`<div class="flex items-center gap-1" title="Wasted in fixed waits"${_scopeId2}>`);
1738
1823
  _push3(ssrRenderComponent(_component_UIcon, {
1739
1824
  name: "i-lucide-clock",
1740
1825
  class: "size-3.5 text-amber-500"
@@ -1763,6 +1848,10 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1763
1848
  createVNode(_component_StatusChip, {
1764
1849
  status: __props.testRun?.status ?? ""
1765
1850
  }, null, 8, ["status"]),
1851
+ __props.testRun?.status === "interrupted" || __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(_component_HelpHint, {
1852
+ key: 0,
1853
+ topic: "run.partial"
1854
+ })) : createCommentVNode("", true),
1766
1855
  createVNode("h2", { class: "text-base font-bold shrink-0 flex items-center gap-1" }, [
1767
1856
  createTextVNode(" Run #" + toDisplayString(__props.testRun?.id) + " ", 1),
1768
1857
  unref(editingLabel) ? (openBlock(), createBlock(Fragment, { key: 0 }, [
@@ -1798,7 +1887,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1798
1887
  createVNode(_component_HelpHint, { topic: "run.summary" })
1799
1888
  ]),
1800
1889
  __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(_component_UBadge, {
1801
- key: 0,
1890
+ key: 1,
1802
1891
  color: "neutral",
1803
1892
  variant: "soft",
1804
1893
  size: "sm",
@@ -1815,7 +1904,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1815
1904
  _: 1
1816
1905
  }, 8, ["title"])) : createCommentVNode("", true),
1817
1906
  __props.testRun?.precedingMarker ? (openBlock(), createBlock(_component_UTooltip, {
1818
- key: 1,
1907
+ key: 2,
1819
1908
  text: `This run started after: ${__props.testRun.precedingMarker.label}`
1820
1909
  }, {
1821
1910
  default: withCtx(() => [
@@ -1837,13 +1926,18 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1837
1926
  }, 8, ["text"])) : createCommentVNode("", true)
1838
1927
  ]),
1839
1928
  createVNode("p", { class: "mt-1 text-xs text-muted flex items-center gap-1.5 flex-wrap" }, [
1840
- createVNode("span", null, "Started " + toDisplayString(("prettyDateFormat" in _ctx ? _ctx.prettyDateFormat : unref(prettyDateFormat))(__props.testRun?.startTime)), 1),
1841
1929
  createVNode(_component_ClientOnly, null, {
1842
1930
  default: withCtx(() => [
1843
- createVNode("span", { class: "text-dimmed" }, "· " + toDisplayString(("formatRelativeTime" in _ctx ? _ctx.formatRelativeTime : unref(formatRelativeTime))(__props.testRun?.startTime)), 1)
1931
+ createVNode("span", {
1932
+ title: ("prettyDateFormat" in _ctx ? _ctx.prettyDateFormat : unref(prettyDateFormat))(__props.testRun?.startTime)
1933
+ }, " Started " + toDisplayString(("formatRelativeTime" in _ctx ? _ctx.formatRelativeTime : unref(formatRelativeTime))(__props.testRun?.startTime)), 9, ["title"])
1844
1934
  ]),
1845
1935
  _: 1
1846
- })
1936
+ }),
1937
+ __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(Fragment, { key: 0 }, [
1938
+ createVNode("span", { class: "text-dimmed" }, "·"),
1939
+ createVNode(_component_HelpHint, { topic: "run.partial" })
1940
+ ], 64)) : createCommentVNode("", true)
1847
1941
  ])
1848
1942
  ]),
1849
1943
  createVNode("div", { class: "flex items-center gap-1.5 shrink-0" }, [
@@ -1881,13 +1975,13 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1881
1975
  size: "xs",
1882
1976
  color: "warning",
1883
1977
  variant: "subtle",
1884
- icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-play",
1978
+ icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-clipboard",
1885
1979
  title: unref(retryTitle),
1886
- "aria-label": "Retry",
1980
+ "aria-label": "Copy retry command",
1887
1981
  onClick: ($event) => copyRetryCommand()
1888
1982
  }, {
1889
1983
  default: withCtx(() => [
1890
- createVNode("span", { class: "hidden @2xl:inline" }, "Retry")
1984
+ createVNode("span", { class: "hidden @2xl:inline" }, "Copy retry command")
1891
1985
  ]),
1892
1986
  _: 1
1893
1987
  }, 8, ["icon", "title", "onClick"])
@@ -1922,72 +2016,83 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1922
2016
  default: withCtx(() => [
1923
2017
  createVNode("button", {
1924
2018
  class: [
1925
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1926
- __props.activeFilter === "all" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2019
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2020
+ __props.activeStatuses.length === 0 ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1927
2021
  ],
1928
- onClick: ($event) => emit("filter-status", "all")
2022
+ "aria-pressed": __props.activeStatuses.length === 0,
2023
+ disabled: (__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0) === 0,
2024
+ onClick: ($event) => emit("toggle-status", "all")
1929
2025
  }, [
1930
2026
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Total"),
1931
2027
  createVNode("p", { class: "text-xl font-bold mt-0.5" }, toDisplayString(__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0), 1)
1932
- ], 10, ["onClick"]),
2028
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1933
2029
  createVNode("div", { class: "relative" }, [
1934
2030
  createVNode("button", {
1935
2031
  class: [
1936
- "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer",
1937
- __props.activeFilter === "passed" ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
2032
+ "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2033
+ __props.activeStatuses.includes("passed") ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
1938
2034
  ],
1939
- onClick: ($event) => emit("filter-status", "passed")
2035
+ "aria-pressed": __props.activeStatuses.includes("passed"),
2036
+ disabled: (__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0) === 0,
2037
+ onClick: ($event) => emit("toggle-status", "passed")
1940
2038
  }, [
1941
2039
  createVNode("p", { class: "text-xs font-medium text-emerald-700 dark:text-emerald-400 uppercase tracking-wider" }, " Passed "),
1942
2040
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-emerald-600 dark:text-emerald-400" }, toDisplayString(__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0), 1)
1943
- ], 10, ["onClick"]),
2041
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1944
2042
  (__props.testRun?.flakyTests ?? 0) > 0 ? (openBlock(), createBlock("button", {
1945
2043
  key: 0,
1946
2044
  class: [
1947
2045
  "absolute top-1.5 right-1.5 inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-semibold leading-none tabular-nums transition-colors cursor-pointer",
1948
- __props.activeFilter === "flaky" ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
2046
+ __props.activeStatuses.includes("flaky") ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
1949
2047
  ],
1950
2048
  title: "Flaky — passed only after a retry (a subset of passed). Click to filter.",
1951
- onClick: ($event) => emit("filter-status", "flaky")
2049
+ "aria-pressed": __props.activeStatuses.includes("flaky"),
2050
+ onClick: ($event) => emit("toggle-status", "flaky")
1952
2051
  }, [
1953
2052
  createVNode(_component_UIcon, {
1954
2053
  name: "i-lucide-shuffle",
1955
2054
  class: "size-3"
1956
2055
  }),
1957
2056
  createTextVNode(" " + toDisplayString(__props.testRun?.flakyTests ?? 0), 1)
1958
- ], 10, ["onClick"])) : createCommentVNode("", true)
2057
+ ], 10, ["aria-pressed", "onClick"])) : createCommentVNode("", true)
1959
2058
  ]),
1960
2059
  createVNode("button", {
1961
2060
  class: [
1962
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1963
- __props.activeFilter === "failed" ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
2061
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2062
+ __props.activeStatuses.includes("failed") ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
1964
2063
  ],
1965
- onClick: ($event) => emit("filter-status", "failed")
2064
+ "aria-pressed": __props.activeStatuses.includes("failed"),
2065
+ disabled: (__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0) === 0,
2066
+ onClick: ($event) => emit("toggle-status", "failed")
1966
2067
  }, [
1967
2068
  createVNode("p", { class: "text-xs font-medium text-rose-700 dark:text-rose-400 uppercase tracking-wider" }, "Failed"),
1968
2069
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-rose-600 dark:text-rose-400" }, toDisplayString(__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0), 1)
1969
- ], 10, ["onClick"]),
2070
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1970
2071
  createVNode("button", {
1971
2072
  class: [
1972
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1973
- __props.activeFilter === "skipped" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2073
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2074
+ __props.activeStatuses.includes("skipped") ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
1974
2075
  ],
1975
- onClick: ($event) => emit("filter-status", "skipped")
2076
+ "aria-pressed": __props.activeStatuses.includes("skipped"),
2077
+ disabled: (__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0) === 0,
2078
+ onClick: ($event) => emit("toggle-status", "skipped")
1976
2079
  }, [
1977
2080
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Skipped"),
1978
2081
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-zinc-600 dark:text-zinc-400" }, toDisplayString(__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0), 1)
1979
- ], 10, ["onClick"]),
2082
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
1980
2083
  createVNode("button", {
1981
2084
  class: [
1982
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
1983
- __props.activeFilter === "didnotrun" ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
2085
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2086
+ __props.activeStatuses.includes("didnotrun") ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
1984
2087
  ],
1985
2088
  title: "Tests that never ran (maxFailures cutoff or a serial-group failure)",
1986
- onClick: ($event) => emit("filter-status", "didnotrun")
2089
+ "aria-pressed": __props.activeStatuses.includes("didnotrun"),
2090
+ disabled: (__props.testRun?.didNotRunTests ?? 0) === 0,
2091
+ onClick: ($event) => emit("toggle-status", "didnotrun")
1987
2092
  }, [
1988
2093
  createVNode("p", { class: "text-xs font-medium text-amber-700 dark:text-amber-400 uppercase tracking-wider" }, "Didn't run"),
1989
2094
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-amber-600 dark:text-amber-400" }, toDisplayString(__props.testRun?.didNotRunTests ?? 0), 1)
1990
- ], 10, ["onClick"])
2095
+ ], 10, ["aria-pressed", "disabled", "onClick"])
1991
2096
  ]),
1992
2097
  _: 1
1993
2098
  }),
@@ -2011,6 +2116,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2011
2116
  name: "i-lucide-clock",
2012
2117
  class: "size-3.5 text-zinc-400"
2013
2118
  }),
2119
+ createVNode("span", { class: "text-zinc-500" }, "Duration"),
2014
2120
  createVNode(_component_DurationValue, {
2015
2121
  ms: __props.testRun?.duration,
2016
2122
  class: "font-medium"
@@ -2047,7 +2153,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2047
2153
  ])) : createCommentVNode("", true),
2048
2154
  __props.totalWastedTime && __props.totalWastedTime > 0 ? (openBlock(), createBlock("div", {
2049
2155
  key: 2,
2050
- class: "flex items-center gap-1"
2156
+ class: "flex items-center gap-1",
2157
+ title: "Wasted in fixed waits"
2051
2158
  }, [
2052
2159
  createVNode(_component_UIcon, {
2053
2160
  name: "i-lucide-clock",
@@ -2264,6 +2371,10 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2264
2371
  createVNode(_component_StatusChip, {
2265
2372
  status: __props.testRun?.status ?? ""
2266
2373
  }, null, 8, ["status"]),
2374
+ __props.testRun?.status === "interrupted" || __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(_component_HelpHint, {
2375
+ key: 0,
2376
+ topic: "run.partial"
2377
+ })) : createCommentVNode("", true),
2267
2378
  createVNode("h2", { class: "text-base font-bold shrink-0 flex items-center gap-1" }, [
2268
2379
  createTextVNode(" Run #" + toDisplayString(__props.testRun?.id) + " ", 1),
2269
2380
  unref(editingLabel) ? (openBlock(), createBlock(Fragment, { key: 0 }, [
@@ -2299,7 +2410,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2299
2410
  createVNode(_component_HelpHint, { topic: "run.summary" })
2300
2411
  ]),
2301
2412
  __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(_component_UBadge, {
2302
- key: 0,
2413
+ key: 1,
2303
2414
  color: "neutral",
2304
2415
  variant: "soft",
2305
2416
  size: "sm",
@@ -2316,7 +2427,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2316
2427
  _: 1
2317
2428
  }, 8, ["title"])) : createCommentVNode("", true),
2318
2429
  __props.testRun?.precedingMarker ? (openBlock(), createBlock(_component_UTooltip, {
2319
- key: 1,
2430
+ key: 2,
2320
2431
  text: `This run started after: ${__props.testRun.precedingMarker.label}`
2321
2432
  }, {
2322
2433
  default: withCtx(() => [
@@ -2338,13 +2449,18 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2338
2449
  }, 8, ["text"])) : createCommentVNode("", true)
2339
2450
  ]),
2340
2451
  createVNode("p", { class: "mt-1 text-xs text-muted flex items-center gap-1.5 flex-wrap" }, [
2341
- createVNode("span", null, "Started " + toDisplayString(("prettyDateFormat" in _ctx ? _ctx.prettyDateFormat : unref(prettyDateFormat))(__props.testRun?.startTime)), 1),
2342
2452
  createVNode(_component_ClientOnly, null, {
2343
2453
  default: withCtx(() => [
2344
- createVNode("span", { class: "text-dimmed" }, "· " + toDisplayString(("formatRelativeTime" in _ctx ? _ctx.formatRelativeTime : unref(formatRelativeTime))(__props.testRun?.startTime)), 1)
2454
+ createVNode("span", {
2455
+ title: ("prettyDateFormat" in _ctx ? _ctx.prettyDateFormat : unref(prettyDateFormat))(__props.testRun?.startTime)
2456
+ }, " Started " + toDisplayString(("formatRelativeTime" in _ctx ? _ctx.formatRelativeTime : unref(formatRelativeTime))(__props.testRun?.startTime)), 9, ["title"])
2345
2457
  ]),
2346
2458
  _: 1
2347
- })
2459
+ }),
2460
+ __props.testRun?.shardTotal && __props.testRun.shardTotal > 1 ? (openBlock(), createBlock(Fragment, { key: 0 }, [
2461
+ createVNode("span", { class: "text-dimmed" }, "·"),
2462
+ createVNode(_component_HelpHint, { topic: "run.partial" })
2463
+ ], 64)) : createCommentVNode("", true)
2348
2464
  ])
2349
2465
  ]),
2350
2466
  createVNode("div", { class: "flex items-center gap-1.5 shrink-0" }, [
@@ -2382,13 +2498,13 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2382
2498
  size: "xs",
2383
2499
  color: "warning",
2384
2500
  variant: "subtle",
2385
- icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-play",
2501
+ icon: unref(retryCopied) ? "i-lucide-check" : "i-lucide-clipboard",
2386
2502
  title: unref(retryTitle),
2387
- "aria-label": "Retry",
2503
+ "aria-label": "Copy retry command",
2388
2504
  onClick: ($event) => copyRetryCommand()
2389
2505
  }, {
2390
2506
  default: withCtx(() => [
2391
- createVNode("span", { class: "hidden @2xl:inline" }, "Retry")
2507
+ createVNode("span", { class: "hidden @2xl:inline" }, "Copy retry command")
2392
2508
  ]),
2393
2509
  _: 1
2394
2510
  }, 8, ["icon", "title", "onClick"])
@@ -2423,72 +2539,83 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2423
2539
  default: withCtx(() => [
2424
2540
  createVNode("button", {
2425
2541
  class: [
2426
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
2427
- __props.activeFilter === "all" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2542
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2543
+ __props.activeStatuses.length === 0 ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2428
2544
  ],
2429
- onClick: ($event) => emit("filter-status", "all")
2545
+ "aria-pressed": __props.activeStatuses.length === 0,
2546
+ disabled: (__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0) === 0,
2547
+ onClick: ($event) => emit("toggle-status", "all")
2430
2548
  }, [
2431
2549
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Total"),
2432
2550
  createVNode("p", { class: "text-xl font-bold mt-0.5" }, toDisplayString(__props.displayProgress?.totalTests ?? __props.testRun?.totalTests ?? 0), 1)
2433
- ], 10, ["onClick"]),
2551
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
2434
2552
  createVNode("div", { class: "relative" }, [
2435
2553
  createVNode("button", {
2436
2554
  class: [
2437
- "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer",
2438
- __props.activeFilter === "passed" ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
2555
+ "rounded-lg p-3 text-left w-full h-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2556
+ __props.activeStatuses.includes("passed") ? "bg-emerald-100 dark:bg-emerald-900/30 ring-2 ring-emerald-400 dark:ring-emerald-600" : "bg-emerald-50 dark:bg-emerald-900/20 hover:bg-emerald-100 dark:hover:bg-emerald-900/30"
2439
2557
  ],
2440
- onClick: ($event) => emit("filter-status", "passed")
2558
+ "aria-pressed": __props.activeStatuses.includes("passed"),
2559
+ disabled: (__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0) === 0,
2560
+ onClick: ($event) => emit("toggle-status", "passed")
2441
2561
  }, [
2442
2562
  createVNode("p", { class: "text-xs font-medium text-emerald-700 dark:text-emerald-400 uppercase tracking-wider" }, " Passed "),
2443
2563
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-emerald-600 dark:text-emerald-400" }, toDisplayString(__props.displayProgress?.passedTests ?? __props.testRun?.passedTests ?? 0), 1)
2444
- ], 10, ["onClick"]),
2564
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
2445
2565
  (__props.testRun?.flakyTests ?? 0) > 0 ? (openBlock(), createBlock("button", {
2446
2566
  key: 0,
2447
2567
  class: [
2448
2568
  "absolute top-1.5 right-1.5 inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-semibold leading-none tabular-nums transition-colors cursor-pointer",
2449
- __props.activeFilter === "flaky" ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
2569
+ __props.activeStatuses.includes("flaky") ? "bg-orange-200 dark:bg-orange-800/60 text-orange-800 dark:text-orange-200 ring-2 ring-orange-400 dark:ring-orange-600" : "bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300 hover:bg-orange-200 dark:hover:bg-orange-800/60"
2450
2570
  ],
2451
2571
  title: "Flaky — passed only after a retry (a subset of passed). Click to filter.",
2452
- onClick: ($event) => emit("filter-status", "flaky")
2572
+ "aria-pressed": __props.activeStatuses.includes("flaky"),
2573
+ onClick: ($event) => emit("toggle-status", "flaky")
2453
2574
  }, [
2454
2575
  createVNode(_component_UIcon, {
2455
2576
  name: "i-lucide-shuffle",
2456
2577
  class: "size-3"
2457
2578
  }),
2458
2579
  createTextVNode(" " + toDisplayString(__props.testRun?.flakyTests ?? 0), 1)
2459
- ], 10, ["onClick"])) : createCommentVNode("", true)
2580
+ ], 10, ["aria-pressed", "onClick"])) : createCommentVNode("", true)
2460
2581
  ]),
2461
2582
  createVNode("button", {
2462
2583
  class: [
2463
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
2464
- __props.activeFilter === "failed" ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
2584
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2585
+ __props.activeStatuses.includes("failed") ? "bg-rose-100 dark:bg-rose-900/30 ring-2 ring-rose-400 dark:ring-rose-600" : "bg-rose-50 dark:bg-rose-900/20 hover:bg-rose-100 dark:hover:bg-rose-900/30"
2465
2586
  ],
2466
- onClick: ($event) => emit("filter-status", "failed")
2587
+ "aria-pressed": __props.activeStatuses.includes("failed"),
2588
+ disabled: (__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0) === 0,
2589
+ onClick: ($event) => emit("toggle-status", "failed")
2467
2590
  }, [
2468
2591
  createVNode("p", { class: "text-xs font-medium text-rose-700 dark:text-rose-400 uppercase tracking-wider" }, "Failed"),
2469
2592
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-rose-600 dark:text-rose-400" }, toDisplayString(__props.displayProgress?.failedTests ?? __props.testRun?.failedTests ?? 0), 1)
2470
- ], 10, ["onClick"]),
2593
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
2471
2594
  createVNode("button", {
2472
2595
  class: [
2473
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
2474
- __props.activeFilter === "skipped" ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2596
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2597
+ __props.activeStatuses.includes("skipped") ? "bg-accented ring-2 ring-zinc-400 dark:ring-zinc-500" : "bg-elevated/60 hover:bg-elevated"
2475
2598
  ],
2476
- onClick: ($event) => emit("filter-status", "skipped")
2599
+ "aria-pressed": __props.activeStatuses.includes("skipped"),
2600
+ disabled: (__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0) === 0,
2601
+ onClick: ($event) => emit("toggle-status", "skipped")
2477
2602
  }, [
2478
2603
  createVNode("p", { class: "text-xs font-medium text-zinc-500 uppercase tracking-wider" }, "Skipped"),
2479
2604
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-zinc-600 dark:text-zinc-400" }, toDisplayString(__props.displayProgress?.skippedTests ?? __props.testRun?.skippedTests ?? 0), 1)
2480
- ], 10, ["onClick"]),
2605
+ ], 10, ["aria-pressed", "disabled", "onClick"]),
2481
2606
  createVNode("button", {
2482
2607
  class: [
2483
- "rounded-lg p-3 text-left w-full transition-colors cursor-pointer",
2484
- __props.activeFilter === "didnotrun" ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
2608
+ "rounded-lg p-3 text-left w-full transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
2609
+ __props.activeStatuses.includes("didnotrun") ? "bg-amber-100 dark:bg-amber-900/30 ring-2 ring-amber-400 dark:ring-amber-600" : "bg-amber-50 dark:bg-amber-900/20 hover:bg-amber-100 dark:hover:bg-amber-900/30"
2485
2610
  ],
2486
2611
  title: "Tests that never ran (maxFailures cutoff or a serial-group failure)",
2487
- onClick: ($event) => emit("filter-status", "didnotrun")
2612
+ "aria-pressed": __props.activeStatuses.includes("didnotrun"),
2613
+ disabled: (__props.testRun?.didNotRunTests ?? 0) === 0,
2614
+ onClick: ($event) => emit("toggle-status", "didnotrun")
2488
2615
  }, [
2489
2616
  createVNode("p", { class: "text-xs font-medium text-amber-700 dark:text-amber-400 uppercase tracking-wider" }, "Didn't run"),
2490
2617
  createVNode("p", { class: "text-xl font-bold mt-0.5 text-amber-600 dark:text-amber-400" }, toDisplayString(__props.testRun?.didNotRunTests ?? 0), 1)
2491
- ], 10, ["onClick"])
2618
+ ], 10, ["aria-pressed", "disabled", "onClick"])
2492
2619
  ]),
2493
2620
  _: 1
2494
2621
  }),
@@ -2512,6 +2639,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2512
2639
  name: "i-lucide-clock",
2513
2640
  class: "size-3.5 text-zinc-400"
2514
2641
  }),
2642
+ createVNode("span", { class: "text-zinc-500" }, "Duration"),
2515
2643
  createVNode(_component_DurationValue, {
2516
2644
  ms: __props.testRun?.duration,
2517
2645
  class: "font-medium"
@@ -2548,7 +2676,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2548
2676
  ])) : createCommentVNode("", true),
2549
2677
  __props.totalWastedTime && __props.totalWastedTime > 0 ? (openBlock(), createBlock("div", {
2550
2678
  key: 2,
2551
- class: "flex items-center gap-1"
2679
+ class: "flex items-center gap-1",
2680
+ title: "Wasted in fixed waits"
2552
2681
  }, [
2553
2682
  createVNode(_component_UIcon, {
2554
2683
  name: "i-lucide-clock",
@@ -2582,7 +2711,7 @@ _sfc_main$g.setup = (props, ctx) => {
2582
2711
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/RunSummary.vue");
2583
2712
  return _sfc_setup$g ? _sfc_setup$g(props, ctx) : void 0;
2584
2713
  };
2585
- const __nuxt_component_9$1 = Object.assign(_sfc_main$g, { __name: "RunSummary" });
2714
+ const __nuxt_component_8 = Object.assign(_sfc_main$g, { __name: "RunSummary" });
2586
2715
  const _sfc_main$f = /* @__PURE__ */ defineComponent({
2587
2716
  __name: "TestRowBadges",
2588
2717
  __ssrInlineRender: true,
@@ -2982,14 +3111,12 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
2982
3111
  browser: row.test.browser,
2983
3112
  size: "sm"
2984
3113
  }, null, _parent));
3114
+ _push(`<span class="size-4 shrink-0" role="img"${ssrRenderAttr("aria-label", `Status: ${("formatStatusLabel" in _ctx ? _ctx.formatStatusLabel : unref(formatStatusLabel))(row.test.status)}`)}${ssrRenderAttr("title", ("formatStatusLabel" in _ctx ? _ctx.formatStatusLabel : unref(formatStatusLabel))(row.test.status))}>`);
2985
3115
  _push(ssrRenderComponent(_component_UIcon, {
2986
3116
  name: ("getStatusIcon" in _ctx ? _ctx.getStatusIcon : unref(getStatusIcon))(row.test.status),
2987
- class: ["size-4 shrink-0", [("getStatusTextClass" in _ctx ? _ctx.getStatusTextClass : unref(getStatusTextClass))(row.test.status), ("isStatusInFlight" in _ctx ? _ctx.isStatusInFlight : unref(isStatusInFlight))(row.test.status) ? "animate-spin" : ""]],
2988
- role: "img",
2989
- "aria-label": `Status: ${("formatStatusLabel" in _ctx ? _ctx.formatStatusLabel : unref(formatStatusLabel))(row.test.status)}`,
2990
- title: ("formatStatusLabel" in _ctx ? _ctx.formatStatusLabel : unref(formatStatusLabel))(row.test.status)
3117
+ class: ["size-4", [("getStatusTextClass" in _ctx ? _ctx.getStatusTextClass : unref(getStatusTextClass))(row.test.status), ("isStatusInFlight" in _ctx ? _ctx.isStatusInFlight : unref(isStatusInFlight))(row.test.status) ? "animate-spin" : ""]]
2991
3118
  }, null, _parent));
2992
- _push(`<a${ssrRenderAttr("href", `/test-run-cases/${row.test.executionId}`)} class="text-highlighted hover:text-primary hover:underline min-w-32 self-stretch flex items-center"${ssrRenderAttr("title", row.test.title)}><span class="truncate">${ssrInterpolate(row.test.title)}</span></a>`);
3119
+ _push(`</span><a${ssrRenderAttr("href", `/test-run-cases/${row.test.executionId}`)} class="text-highlighted hover:text-primary hover:underline min-w-32 self-stretch flex items-center"${ssrRenderAttr("title", row.test.title)}><span class="truncate">${ssrInterpolate(row.test.title)}</span></a>`);
2993
3120
  _push(ssrRenderComponent(_component_TestRowBadges, {
2994
3121
  "is-new-regression": Boolean(row.test.isNewRegression),
2995
3122
  "is-new-flaky": Boolean(row.test.isNewFlaky),
@@ -3112,6 +3239,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3112
3239
  isLive: { type: Boolean },
3113
3240
  liveSteps: {},
3114
3241
  failureClusterFilter: {},
3242
+ clusterNames: {},
3115
3243
  projectKey: {},
3116
3244
  projectName: {}
3117
3245
  }, {
@@ -3125,6 +3253,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3125
3253
  emits: ["update:search", "update:activeStatuses", "update:browserFilter"],
3126
3254
  setup(__props, { expose: __expose }) {
3127
3255
  const { treeView, setTreeView } = useTreeViewCookie("test-cases");
3256
+ const flatViewOverride = ref(false);
3257
+ const effectiveTreeView = computed(() => treeView.value && !flatViewOverride.value);
3128
3258
  const props = __props;
3129
3259
  const testCaseSearch = useModel(__props, "search");
3130
3260
  const activeStatuses = useModel(__props, "activeStatuses");
@@ -3159,8 +3289,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3159
3289
  return items;
3160
3290
  });
3161
3291
  function matchesStatus(tc, filter) {
3162
- if (filter === "failed") return tc.status === "failed" || tc.status === "timedOut" || tc.status === "timedout";
3163
- if (filter === "flaky") return (tc.retries ?? 0) > 0;
3292
+ if (filter === "failed") return isFailedStatus(tc.status);
3293
+ if (filter === "flaky") return tc.status === "passed" && (tc.retries ?? 0) > 0;
3164
3294
  return tc.status === filter;
3165
3295
  }
3166
3296
  const filteredTestCases = computed(() => {
@@ -3201,7 +3331,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3201
3331
  case "title":
3202
3332
  return tc.title ?? "";
3203
3333
  case "status":
3204
- return tc.status ?? "";
3334
+ return isFailedStatus(tc.status ?? "") ? "failed" : tc.status ?? "";
3205
3335
  case "duration":
3206
3336
  return tc.duration ?? 0;
3207
3337
  case "workerIndex":
@@ -3214,10 +3344,14 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3214
3344
  return "";
3215
3345
  }
3216
3346
  }
3347
+ const failedCount = computed(() => props.testCases.filter((tc) => isFailedStatus(tc.status)).length);
3217
3348
  const sortedTestCases = computed(() => {
3218
3349
  const cases = filteredTestCases.value;
3219
3350
  const key = sortKey.value;
3220
- if (!key) return cases;
3351
+ if (!key) {
3352
+ if (failedCount.value === 0) return cases;
3353
+ return [...cases].sort((a, b) => failureFirstCompare(a.status, b.status));
3354
+ }
3221
3355
  const dir = sortDir.value === "asc" ? 1 : -1;
3222
3356
  return [...cases].sort((a, b) => {
3223
3357
  const va = sortValue(a, key);
@@ -3227,6 +3361,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3227
3361
  });
3228
3362
  });
3229
3363
  const hasWastedTime = computed(() => props.testCases.some((tc) => (tc.wastedTimeMs ?? 0) > 0));
3364
+ const finishedCount = computed(() => props.testCases.filter((tc) => tc.status !== "running").length);
3230
3365
  const columns = computed(() => {
3231
3366
  const cols = [
3232
3367
  { key: "browser", label: "Browser", sortable: true, width: "3.25rem", align: "left", icon: "i-lucide-monitor" },
@@ -3242,7 +3377,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3242
3377
  return cols;
3243
3378
  });
3244
3379
  const sortOptions = computed(() => [
3245
- { label: "Run order", value: NATURAL_ORDER },
3380
+ { label: failedCount.value > 0 ? "Failures first" : "Run order", value: NATURAL_ORDER },
3246
3381
  ...columns.value.map((c) => ({ label: c.label, value: c.key }))
3247
3382
  ]);
3248
3383
  const mobileSortKey = computed({
@@ -3255,7 +3390,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3255
3390
  const gridTemplate = computed(() => columns.value.map((c) => c.width).join(" "));
3256
3391
  const gridMinWidth = computed(() => hasWastedTime.value ? "47.5rem" : "41.5rem");
3257
3392
  const hasFilter = computed(
3258
- () => testCaseSearch.value !== "" || activeStatuses.value.length > 0 || testCaseBrowserFilter.value !== "all" || props.failureClusterFilter != null
3393
+ () => testCaseSearch.value !== "" || activeStatuses.value.length > 0 || testCaseBrowserFilter.value !== "all"
3259
3394
  );
3260
3395
  const scrollerRef = ref(null);
3261
3396
  const userScrolledAway = ref(false);
@@ -3274,7 +3409,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3274
3409
  }
3275
3410
  );
3276
3411
  function scrollToCase(id) {
3277
- setTreeView(false);
3412
+ flatViewOverride.value = true;
3278
3413
  highlightedCaseId.value = id;
3279
3414
  const doScroll = () => {
3280
3415
  const index = sortedTestCases.value.findIndex((tc) => tc.executionId === id);
@@ -3288,6 +3423,11 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3288
3423
  }, 3e3);
3289
3424
  });
3290
3425
  }
3426
+ function selectView(tree) {
3427
+ flatViewOverride.value = false;
3428
+ setTreeView(tree);
3429
+ }
3430
+ const isDesktopList = ref(false);
3291
3431
  __expose({ scrollToCase });
3292
3432
  return (_ctx, _push, _parent, _attrs) => {
3293
3433
  const _component_FilterToolbar = __nuxt_component_4$4;
@@ -3298,24 +3438,25 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3298
3438
  const _component_UCheckbox = _sfc_main$s;
3299
3439
  const _component_UButton = _sfc_main$k;
3300
3440
  const _component_TestCasesTree = __nuxt_component_7;
3301
- const _component_ClientOnly = __nuxt_component_7$1;
3441
+ const _component_ClientOnly = __nuxt_component_8$1;
3442
+ const _component_EmptyState = __nuxt_component_4$3;
3302
3443
  _push(`<div${ssrRenderAttrs(mergeProps({ class: "flex flex-col min-h-0" }, _attrs))}>`);
3303
3444
  _push(ssrRenderComponent(_component_FilterToolbar, { class: "mb-4 shrink-0" }, {
3304
3445
  start: withCtx((_, _push2, _parent2, _scopeId) => {
3305
3446
  if (_push2) {
3306
- _push2(`<div class="flex items-center rounded-md border border-default overflow-hidden"${_scopeId}><button class="${ssrRenderClass([!unref(treeView) ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60", "px-2 py-1 text-xs transition-colors"])}" title="Flat list"${_scopeId}>`);
3447
+ _push2(`<div class="flex items-center rounded-md border border-default overflow-hidden"${_scopeId}><button class="${ssrRenderClass([!effectiveTreeView.value ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60", "px-2 py-1 text-xs transition-colors"])}" title="Flat list"${ssrRenderAttr("aria-pressed", !effectiveTreeView.value)}${_scopeId}>`);
3307
3448
  _push2(ssrRenderComponent(_component_UIcon, {
3308
3449
  name: "i-lucide-list",
3309
3450
  class: "size-3.5"
3310
3451
  }, null, _parent2, _scopeId));
3311
- _push2(`</button><button class="${ssrRenderClass([unref(treeView) ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60", "px-2 py-1 text-xs transition-colors"])}" title="Tree view"${_scopeId}>`);
3452
+ _push2(`</button><button class="${ssrRenderClass([effectiveTreeView.value ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60", "px-2 py-1 text-xs transition-colors"])}" title="Tree view"${ssrRenderAttr("aria-pressed", effectiveTreeView.value)}${_scopeId}>`);
3312
3453
  _push2(ssrRenderComponent(_component_UIcon, {
3313
3454
  name: "i-lucide-folder-tree",
3314
3455
  class: "size-3.5"
3315
3456
  }, null, _parent2, _scopeId));
3316
3457
  _push2(`</button></div>`);
3317
3458
  if (__props.isLive) {
3318
- _push2(`<span class="text-sm text-zinc-500 tabular-nums inline-flex items-center gap-1"${_scopeId}>${ssrInterpolate(__props.testCases.length)} completed `);
3459
+ _push2(`<span aria-live="polite" class="text-sm text-zinc-500 tabular-nums inline-flex items-center gap-1"${_scopeId}>${ssrInterpolate(finishedCount.value)} / ${ssrInterpolate(__props.testCases.length)} completed `);
3319
3460
  _push2(ssrRenderComponent(_component_HelpHint, { topic: "run.live" }, null, _parent2, _scopeId));
3320
3461
  _push2(`</span>`);
3321
3462
  } else {
@@ -3327,31 +3468,34 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3327
3468
  return [
3328
3469
  createVNode("div", { class: "flex items-center rounded-md border border-default overflow-hidden" }, [
3329
3470
  createVNode("button", {
3330
- class: ["px-2 py-1 text-xs transition-colors", !unref(treeView) ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60"],
3471
+ class: ["px-2 py-1 text-xs transition-colors", !effectiveTreeView.value ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60"],
3331
3472
  title: "Flat list",
3332
- onClick: ($event) => unref(setTreeView)(false)
3473
+ "aria-pressed": !effectiveTreeView.value,
3474
+ onClick: ($event) => selectView(false)
3333
3475
  }, [
3334
3476
  createVNode(_component_UIcon, {
3335
3477
  name: "i-lucide-list",
3336
3478
  class: "size-3.5"
3337
3479
  })
3338
- ], 10, ["onClick"]),
3480
+ ], 10, ["aria-pressed", "onClick"]),
3339
3481
  createVNode("button", {
3340
- class: ["px-2 py-1 text-xs transition-colors", unref(treeView) ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60"],
3482
+ class: ["px-2 py-1 text-xs transition-colors", effectiveTreeView.value ? "bg-primary text-white dark:text-white" : "text-muted hover:bg-elevated/60"],
3341
3483
  title: "Tree view",
3342
- onClick: ($event) => unref(setTreeView)(true)
3484
+ "aria-pressed": effectiveTreeView.value,
3485
+ onClick: ($event) => selectView(true)
3343
3486
  }, [
3344
3487
  createVNode(_component_UIcon, {
3345
3488
  name: "i-lucide-folder-tree",
3346
3489
  class: "size-3.5"
3347
3490
  })
3348
- ], 10, ["onClick"])
3491
+ ], 10, ["aria-pressed", "onClick"])
3349
3492
  ]),
3350
3493
  __props.isLive ? (openBlock(), createBlock("span", {
3351
3494
  key: 0,
3495
+ "aria-live": "polite",
3352
3496
  class: "text-sm text-zinc-500 tabular-nums inline-flex items-center gap-1"
3353
3497
  }, [
3354
- createTextVNode(toDisplayString(__props.testCases.length) + " completed ", 1),
3498
+ createTextVNode(toDisplayString(finishedCount.value) + " / " + toDisplayString(__props.testCases.length) + " completed ", 1),
3355
3499
  createVNode(_component_HelpHint, { topic: "run.live" })
3356
3500
  ])) : (openBlock(), createBlock("span", {
3357
3501
  key: 1,
@@ -3378,7 +3522,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3378
3522
  _push2(`<button class="${ssrRenderClass([
3379
3523
  activeStatuses.value.includes(opt.value) ? opt.color === "green" ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400" : opt.color === "red" ? "bg-rose-100 text-rose-700 dark:bg-rose-900/30 dark:text-rose-400" : opt.color === "orange" ? "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400" : "bg-zinc-200 text-zinc-700 dark:bg-zinc-700 dark:text-zinc-300" : "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700",
3380
3524
  "inline-flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium transition-colors whitespace-nowrap"
3381
- ])}"${_scopeId}><span class="${ssrRenderClass([
3525
+ ])}"${ssrRenderAttr("aria-pressed", activeStatuses.value.includes(opt.value))}${_scopeId}><span class="${ssrRenderClass([
3382
3526
  opt.color === "green" ? "bg-emerald-500" : opt.color === "red" ? "bg-rose-500" : opt.color === "orange" ? "bg-orange-500" : "bg-zinc-400",
3383
3527
  "size-2 rounded-full shrink-0"
3384
3528
  ])}"${_scopeId}></span> ${ssrInterpolate(opt.label)}</button>`);
@@ -3389,7 +3533,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3389
3533
  "onUpdate:modelValue": ($event) => testCaseBrowserFilter.value = $event,
3390
3534
  items: testCaseBrowserOptions.value,
3391
3535
  size: "sm",
3392
- class: "w-36"
3536
+ class: "w-36",
3537
+ "aria-label": "Filter by browser"
3393
3538
  }, null, _parent2, _scopeId));
3394
3539
  if (!__props.isLive) {
3395
3540
  _push2(ssrRenderComponent(_component_UCheckbox, {
@@ -3411,7 +3556,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3411
3556
  } else {
3412
3557
  _push2(`<!---->`);
3413
3558
  }
3414
- if (!unref(treeView)) {
3559
+ if (!effectiveTreeView.value) {
3415
3560
  _push2(`<div class="flex items-center gap-1 md:hidden"${_scopeId}>`);
3416
3561
  _push2(ssrRenderComponent(_component_USelect, {
3417
3562
  modelValue: mobileSortKey.value,
@@ -3453,6 +3598,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3453
3598
  "inline-flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium transition-colors whitespace-nowrap",
3454
3599
  activeStatuses.value.includes(opt.value) ? opt.color === "green" ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400" : opt.color === "red" ? "bg-rose-100 text-rose-700 dark:bg-rose-900/30 dark:text-rose-400" : opt.color === "orange" ? "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400" : "bg-zinc-200 text-zinc-700 dark:bg-zinc-700 dark:text-zinc-300" : "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700"
3455
3600
  ],
3601
+ "aria-pressed": activeStatuses.value.includes(opt.value),
3456
3602
  onClick: ($event) => toggleStatus(opt.value)
3457
3603
  }, [
3458
3604
  createVNode("span", {
@@ -3462,7 +3608,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3462
3608
  ]
3463
3609
  }, null, 2),
3464
3610
  createTextVNode(" " + toDisplayString(opt.label), 1)
3465
- ], 10, ["onClick"]);
3611
+ ], 10, ["aria-pressed", "onClick"]);
3466
3612
  }), 64))
3467
3613
  ]),
3468
3614
  createVNode(_component_USelect, {
@@ -3470,7 +3616,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3470
3616
  "onUpdate:modelValue": ($event) => testCaseBrowserFilter.value = $event,
3471
3617
  items: testCaseBrowserOptions.value,
3472
3618
  size: "sm",
3473
- class: "w-36"
3619
+ class: "w-36",
3620
+ "aria-label": "Filter by browser"
3474
3621
  }, null, 8, ["modelValue", "onUpdate:modelValue", "items"]),
3475
3622
  !__props.isLive ? (openBlock(), createBlock(_component_UCheckbox, {
3476
3623
  key: 0,
@@ -3486,7 +3633,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3486
3633
  label: "New flaky",
3487
3634
  size: "sm"
3488
3635
  }, null, 8, ["modelValue", "onUpdate:modelValue"])) : createCommentVNode("", true),
3489
- !unref(treeView) ? (openBlock(), createBlock("div", {
3636
+ !effectiveTreeView.value ? (openBlock(), createBlock("div", {
3490
3637
  key: 2,
3491
3638
  class: "flex items-center gap-1 md:hidden"
3492
3639
  }, [
@@ -3514,7 +3661,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3514
3661
  }),
3515
3662
  _: 1
3516
3663
  }, _parent));
3517
- if (unref(treeView) && __props.testCases.length > 0) {
3664
+ if (effectiveTreeView.value) {
3518
3665
  _push(ssrRenderComponent(_component_TestCasesTree, {
3519
3666
  "test-cases": sortedTestCases.value,
3520
3667
  suites: __props.suites,
@@ -3525,10 +3672,10 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3525
3672
  "project-name": __props.projectName,
3526
3673
  class: "flex-1 min-h-0"
3527
3674
  }, null, _parent));
3528
- } else if (!unref(treeView)) {
3675
+ } else if (!effectiveTreeView.value) {
3529
3676
  _push(`<!--[-->`);
3530
3677
  if (sortedTestCases.value.length > 0) {
3531
- _push(`<div class="flex-1 min-h-0 max-lg:h-[70dvh] md:overflow-x-auto overflow-y-hidden rounded-lg border border-default bg-default"><div class="flex flex-col h-full md:min-w-(--grid-min-width)" role="table" aria-label="Test cases"${ssrRenderAttr("aria-rowcount", sortedTestCases.value.length + 1)} style="${ssrRenderStyle({ "--grid-min-width": gridMinWidth.value })}"><div class="hidden md:grid shrink-0 bg-elevated/50 border-b border-default" role="row" style="${ssrRenderStyle({ gridTemplateColumns: gridTemplate.value })}"><!--[-->`);
3678
+ _push(`<div class="flex-1 min-h-0 md:overflow-x-auto overflow-y-hidden rounded-lg border border-default bg-default"><div class="flex flex-col h-full md:min-w-(--grid-min-width)"${ssrRenderAttr("role", isDesktopList.value ? "table" : void 0)}${ssrRenderAttr("aria-label", isDesktopList.value ? "Test cases" : void 0)}${ssrRenderAttr("aria-rowcount", isDesktopList.value ? sortedTestCases.value.length + 1 : void 0)} style="${ssrRenderStyle({ "--grid-min-width": gridMinWidth.value })}"><div class="hidden md:grid shrink-0 bg-elevated/50 border-b border-default" role="row" style="${ssrRenderStyle({ gridTemplateColumns: gridTemplate.value })}"><!--[-->`);
3532
3679
  ssrRenderList(columns.value, (col) => {
3533
3680
  _push(`<!--[-->`);
3534
3681
  if (col.sortable) {
@@ -3576,19 +3723,46 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
3576
3723
  }, _parent));
3577
3724
  _push(`</div></div>`);
3578
3725
  } else if (__props.testCases.length === 0) {
3579
- _push(`<div class="text-center py-10 text-zinc-500">`);
3580
- _push(ssrRenderComponent(_component_UIcon, {
3581
- name: "i-lucide-beaker",
3582
- class: "size-8 mx-auto mb-2 text-zinc-300 dark:text-zinc-600"
3726
+ _push(ssrRenderComponent(_component_EmptyState, {
3727
+ icon: "i-lucide-beaker",
3728
+ text: "No test cases recorded for this run."
3583
3729
  }, null, _parent));
3584
- _push(`<p>No test cases recorded for this run.</p></div>`);
3585
3730
  } else {
3586
- _push(`<div class="text-center py-10 text-zinc-500">`);
3587
- _push(ssrRenderComponent(_component_UIcon, {
3588
- name: "i-lucide-search-x",
3589
- class: "size-8 mx-auto mb-2 text-zinc-300 dark:text-zinc-600"
3590
- }, null, _parent));
3591
- _push(`<p>No test cases match your filters.</p></div>`);
3731
+ _push(ssrRenderComponent(_component_EmptyState, {
3732
+ icon: "i-lucide-search-x",
3733
+ text: "No test cases match your filters."
3734
+ }, {
3735
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
3736
+ if (_push2) {
3737
+ _push2(ssrRenderComponent(_component_UButton, {
3738
+ size: "xs",
3739
+ variant: "outline",
3740
+ color: "neutral",
3741
+ label: "Clear filters",
3742
+ onClick: ($event) => {
3743
+ testCaseSearch.value = "";
3744
+ activeStatuses.value = [];
3745
+ testCaseBrowserFilter.value = "all";
3746
+ }
3747
+ }, null, _parent2, _scopeId));
3748
+ } else {
3749
+ return [
3750
+ createVNode(_component_UButton, {
3751
+ size: "xs",
3752
+ variant: "outline",
3753
+ color: "neutral",
3754
+ label: "Clear filters",
3755
+ onClick: ($event) => {
3756
+ testCaseSearch.value = "";
3757
+ activeStatuses.value = [];
3758
+ testCaseBrowserFilter.value = "all";
3759
+ }
3760
+ }, null, 8, ["onClick"])
3761
+ ];
3762
+ }
3763
+ }),
3764
+ _: 1
3765
+ }, _parent));
3592
3766
  }
3593
3767
  _push(`<!--]-->`);
3594
3768
  } else {
@@ -3604,7 +3778,7 @@ _sfc_main$c.setup = (props, ctx) => {
3604
3778
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/TestCasesList.vue");
3605
3779
  return _sfc_setup$c ? _sfc_setup$c(props, ctx) : void 0;
3606
3780
  };
3607
- const __nuxt_component_12 = Object.assign(_sfc_main$c, { __name: "TestCasesList" });
3781
+ const __nuxt_component_11 = Object.assign(_sfc_main$c, { __name: "TestCasesList" });
3608
3782
  const _sfc_main$b = /* @__PURE__ */ defineComponent({
3609
3783
  __name: "RunInsights",
3610
3784
  __ssrInlineRender: true,
@@ -3673,13 +3847,13 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
3673
3847
  return `${(ms / 1e3).toFixed(1)}s`;
3674
3848
  }
3675
3849
  return (_ctx, _push, _parent, _attrs) => {
3676
- const _component_ErrorState = __nuxt_component_5$1;
3850
+ const _component_ErrorState = __nuxt_component_5$2;
3677
3851
  const _component_UButton = _sfc_main$k;
3678
3852
  const _component_LoadingState = __nuxt_component_13$2;
3679
3853
  const _component_EmptyState = __nuxt_component_4$3;
3680
3854
  const _component_UIcon = _sfc_main$p;
3681
3855
  const _component_HelpHint = __nuxt_component_2$2;
3682
- const _component_SectionCard = __nuxt_component_11;
3856
+ const _component_SectionCard = __nuxt_component_11$1;
3683
3857
  const _component_NuxtLink = __nuxt_component_12$1;
3684
3858
  const _component_UBadge = _sfc_main$7$1;
3685
3859
  if (unref(error)) {
@@ -4338,7 +4512,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
4338
4512
  if (_push2) {
4339
4513
  _push2(`<div class="grid grid-cols-2 gap-4"${_scopeId}>`);
4340
4514
  if (unref(data).mostRegressed.length > 0) {
4341
- _push2(`<div${_scopeId}><p class="text-xs font-medium text-red-500 mb-2"${_scopeId}>Most regressed</p><div class="space-y-1"${_scopeId}><!--[-->`);
4515
+ _push2(`<div${_scopeId}><p class="text-xs font-medium text-red-500 mb-2"${_scopeId}>Slower</p><div class="space-y-1"${_scopeId}><!--[-->`);
4342
4516
  ssrRenderList(unref(data).mostRegressed, (r) => {
4343
4517
  _push2(ssrRenderComponent(_component_NuxtLink, {
4344
4518
  key: r.executionId,
@@ -4392,7 +4566,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
4392
4566
  return [
4393
4567
  createVNode("div", { class: "grid grid-cols-2 gap-4" }, [
4394
4568
  unref(data).mostRegressed.length > 0 ? (openBlock(), createBlock("div", { key: 0 }, [
4395
- createVNode("p", { class: "text-xs font-medium text-red-500 mb-2" }, "Most regressed"),
4569
+ createVNode("p", { class: "text-xs font-medium text-red-500 mb-2" }, "Slower"),
4396
4570
  createVNode("div", { class: "space-y-1" }, [
4397
4571
  (openBlock(true), createBlock(Fragment, null, renderList(unref(data).mostRegressed, (r) => {
4398
4572
  return openBlock(), createBlock(_component_NuxtLink, {
@@ -4628,7 +4802,7 @@ _sfc_main$b.setup = (props, ctx) => {
4628
4802
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/RunInsights.vue");
4629
4803
  return _sfc_setup$b ? _sfc_setup$b(props, ctx) : void 0;
4630
4804
  };
4631
- const __nuxt_component_13 = Object.assign(_sfc_main$b, { __name: "RunInsights" });
4805
+ const __nuxt_component_12 = Object.assign(_sfc_main$b, { __name: "RunInsights" });
4632
4806
  const _sfc_main$a = /* @__PURE__ */ defineComponent({
4633
4807
  __name: "ClusterDiagnosis",
4634
4808
  __ssrInlineRender: true,
@@ -4648,7 +4822,7 @@ _sfc_main$a.setup = (props, ctx) => {
4648
4822
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/cluster/ClusterDiagnosis.vue");
4649
4823
  return _sfc_setup$a ? _sfc_setup$a(props, ctx) : void 0;
4650
4824
  };
4651
- const __nuxt_component_9 = Object.assign(_sfc_main$a, { __name: "ClusterDiagnosis" });
4825
+ const __nuxt_component_10 = Object.assign(_sfc_main$a, { __name: "ClusterDiagnosis" });
4652
4826
  const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4653
4827
  __name: "FailureGroups",
4654
4828
  __ssrInlineRender: true,
@@ -4703,7 +4877,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4703
4877
  const columns = [
4704
4878
  { accessorKey: "signature", header: createSortHeader("Signature") },
4705
4879
  { accessorKey: "errorType", header: createSortHeader("Type") },
4706
- { accessorKey: "status", header: createSortHeader("Status") },
4880
+ { accessorKey: "status", header: createSortHeader("Triage") },
4707
4881
  { accessorKey: "caseCount", header: createSortHeader("Tests") },
4708
4882
  { accessorKey: "signals", header: "Signals" },
4709
4883
  { accessorKey: "diagnosis", header: "AI" },
@@ -4720,8 +4894,9 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4720
4894
  const _component_UTable = _sfc_main$l;
4721
4895
  const _component_UBadge = _sfc_main$7$1;
4722
4896
  const _component_NuxtLink = __nuxt_component_12$1;
4897
+ const _component_EmptyState = __nuxt_component_4$3;
4723
4898
  const _component_UModal = _sfc_main$q;
4724
- const _component_ClusterDiagnosis = __nuxt_component_9;
4899
+ const _component_ClusterDiagnosis = __nuxt_component_10;
4725
4900
  _push(`<!--[--><div class="pt-4 space-y-3">`);
4726
4901
  if (unref(loading)) {
4727
4902
  _push(`<div class="flex items-center justify-center py-8 text-gray-500 gap-2">`);
@@ -4731,7 +4906,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4731
4906
  }, null, _parent));
4732
4907
  _push(`<span>Grouping failures...</span></div>`);
4733
4908
  } else if (unref(groups) && unref(groups).length) {
4734
- _push(`<!--[--><div class="flex items-center justify-between gap-3"><p class="text-sm text-gray-500 dark:text-gray-400 inline-flex items-center gap-1">${ssrInterpolate(unref(totalCases))} failing ${ssrInterpolate(unref(totalCases) === 1 ? "test" : "tests")} across ${ssrInterpolate(unref(groups).length)} ${ssrInterpolate(unref(groups).length === 1 ? "group" : "groups")} `);
4909
+ _push(`<!--[--><div class="flex items-center justify-between gap-3"><p class="text-sm text-gray-500 dark:text-gray-400 inline-flex items-center gap-1">${ssrInterpolate(unref(totalCases))} failing ${ssrInterpolate(unref(totalCases) === 1 ? "test" : "tests")} across ${ssrInterpolate(unref(groups).length)} ${ssrInterpolate(unref(groups).length === 1 ? "cluster" : "clusters")} `);
4735
4910
  _push(ssrRenderComponent(_component_HelpHint, { topic: "cluster.concept" }, null, _parent));
4736
4911
  _push(`</p>`);
4737
4912
  if (unref(allFailedCases).length > 0) {
@@ -4769,7 +4944,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4769
4944
  if (_push3) {
4770
4945
  _push3(ssrRenderComponent(_component_UTable, {
4771
4946
  data: unref(groups),
4772
- columns
4947
+ columns,
4948
+ "aria-label": "Failure clusters"
4773
4949
  }, {
4774
4950
  "actions-header": withCtx((_3, _push4, _parent4, _scopeId3) => {
4775
4951
  if (_push4) {
@@ -4858,10 +5034,10 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4858
5034
  }, {
4859
5035
  default: withCtx((_3, _push5, _parent5, _scopeId4) => {
4860
5036
  if (_push5) {
4861
- _push5(`${ssrInterpolate(row.original.status)}`);
5037
+ _push5(`${ssrInterpolate(("formatTriageStatus" in _ctx ? _ctx.formatTriageStatus : unref(formatTriageStatus))(row.original.status))}`);
4862
5038
  } else {
4863
5039
  return [
4864
- createTextVNode(toDisplayString(row.original.status), 1)
5040
+ createTextVNode(toDisplayString(("formatTriageStatus" in _ctx ? _ctx.formatTriageStatus : unref(formatTriageStatus))(row.original.status)), 1)
4865
5041
  ];
4866
5042
  }
4867
5043
  }),
@@ -4879,7 +5055,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
4879
5055
  size: "sm"
4880
5056
  }, {
4881
5057
  default: withCtx(() => [
4882
- createTextVNode(toDisplayString(row.original.status), 1)
5058
+ createTextVNode(toDisplayString(("formatTriageStatus" in _ctx ? _ctx.formatTriageStatus : unref(formatTriageStatus))(row.original.status)), 1)
4883
5059
  ]),
4884
5060
  _: 2
4885
5061
  }, 1032, ["color"])) : (openBlock(), createBlock("span", {
@@ -5216,10 +5392,10 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5216
5392
  }, {
5217
5393
  default: withCtx((_3, _push5, _parent5, _scopeId4) => {
5218
5394
  if (_push5) {
5219
- _push5(` Filter `);
5395
+ _push5(` Show failing tests `);
5220
5396
  } else {
5221
5397
  return [
5222
- createTextVNode(" Filter ")
5398
+ createTextVNode(" Show failing tests ")
5223
5399
  ];
5224
5400
  }
5225
5401
  }),
@@ -5271,7 +5447,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5271
5447
  onClick: ($event) => emit("selectCluster", row.original.clusterId)
5272
5448
  }, {
5273
5449
  default: withCtx(() => [
5274
- createTextVNode(" Filter ")
5450
+ createTextVNode(" Show failing tests ")
5275
5451
  ]),
5276
5452
  _: 1
5277
5453
  }, 8, ["onClick"]),
@@ -5308,7 +5484,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5308
5484
  return [
5309
5485
  createVNode(_component_UTable, {
5310
5486
  data: unref(groups),
5311
- columns
5487
+ columns,
5488
+ "aria-label": "Failure clusters"
5312
5489
  }, {
5313
5490
  "actions-header": withCtx(() => [
5314
5491
  createVNode("div", { class: "text-right" }, "Actions")
@@ -5352,7 +5529,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5352
5529
  size: "sm"
5353
5530
  }, {
5354
5531
  default: withCtx(() => [
5355
- createTextVNode(toDisplayString(row.original.status), 1)
5532
+ createTextVNode(toDisplayString(("formatTriageStatus" in _ctx ? _ctx.formatTriageStatus : unref(formatTriageStatus))(row.original.status)), 1)
5356
5533
  ]),
5357
5534
  _: 2
5358
5535
  }, 1032, ["color"])) : (openBlock(), createBlock("span", {
@@ -5494,7 +5671,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5494
5671
  onClick: ($event) => emit("selectCluster", row.original.clusterId)
5495
5672
  }, {
5496
5673
  default: withCtx(() => [
5497
- createTextVNode(" Filter ")
5674
+ createTextVNode(" Show failing tests ")
5498
5675
  ]),
5499
5676
  _: 1
5500
5677
  }, 8, ["onClick"]),
@@ -5539,7 +5716,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5539
5716
  default: withCtx(() => [
5540
5717
  createVNode(_component_UTable, {
5541
5718
  data: unref(groups),
5542
- columns
5719
+ columns,
5720
+ "aria-label": "Failure clusters"
5543
5721
  }, {
5544
5722
  "actions-header": withCtx(() => [
5545
5723
  createVNode("div", { class: "text-right" }, "Actions")
@@ -5583,7 +5761,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5583
5761
  size: "sm"
5584
5762
  }, {
5585
5763
  default: withCtx(() => [
5586
- createTextVNode(toDisplayString(row.original.status), 1)
5764
+ createTextVNode(toDisplayString(("formatTriageStatus" in _ctx ? _ctx.formatTriageStatus : unref(formatTriageStatus))(row.original.status)), 1)
5587
5765
  ]),
5588
5766
  _: 2
5589
5767
  }, 1032, ["color"])) : (openBlock(), createBlock("span", {
@@ -5725,7 +5903,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5725
5903
  onClick: ($event) => emit("selectCluster", row.original.clusterId)
5726
5904
  }, {
5727
5905
  default: withCtx(() => [
5728
- createTextVNode(" Filter ")
5906
+ createTextVNode(" Show failing tests ")
5729
5907
  ]),
5730
5908
  _: 1
5731
5909
  }, 8, ["onClick"]),
@@ -5766,17 +5944,15 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5766
5944
  }, _parent));
5767
5945
  _push(`<!--]-->`);
5768
5946
  } else {
5769
- _push(`<div class="flex flex-col items-center justify-center py-8 text-gray-500 gap-2">`);
5770
- _push(ssrRenderComponent(_component_UIcon, {
5771
- name: "i-lucide-party-popper",
5772
- class: "size-6"
5947
+ _push(ssrRenderComponent(_component_EmptyState, {
5948
+ icon: "i-lucide-shield-check",
5949
+ text: "No failure clusters — failed tests without error details are not grouped"
5773
5950
  }, null, _parent));
5774
- _push(`<span>No failure groups — failed tests without error details are not grouped</span></div>`);
5775
5951
  }
5776
5952
  _push(`</div>`);
5777
5953
  _push(ssrRenderComponent(_component_UModal, {
5778
5954
  open: unref(diagnosisClusterId) !== null,
5779
- title: "AI Diagnosis",
5955
+ title: "AI diagnosis",
5780
5956
  ui: { content: "max-w-2xl" },
5781
5957
  "onUpdate:open": (v) => {
5782
5958
  if (!v) diagnosisClusterId.value = null;
@@ -5810,7 +5986,7 @@ _sfc_main$9.setup = (props, ctx) => {
5810
5986
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/FailureGroups.vue");
5811
5987
  return _sfc_setup$9 ? _sfc_setup$9(props, ctx) : void 0;
5812
5988
  };
5813
- const __nuxt_component_14 = Object.assign(_sfc_main$9, { __name: "FailureGroups" });
5989
+ const __nuxt_component_13 = Object.assign(_sfc_main$9, { __name: "FailureGroups" });
5814
5990
  const _sfc_main$8 = /* @__PURE__ */ defineComponent({
5815
5991
  __name: "RegressionContext",
5816
5992
  __ssrInlineRender: true,
@@ -5828,7 +6004,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
5828
6004
  refresh: refreshContext
5829
6005
  } = ([__temp, __restore] = withAsyncContext(() => useFetch(
5830
6006
  `/api/test-runs/${runId}/regression-context`,
5831
- { lazy: true, server: false },
6007
+ { lazy: true },
5832
6008
  "$bK54nhbSza"
5833
6009
  /* nuxt-injected */
5834
6010
  )), __temp = await __temp, __restore(), __temp);
@@ -6192,7 +6368,7 @@ _sfc_main$8.setup = (props, ctx) => {
6192
6368
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/cluster/RegressionContext.vue");
6193
6369
  return _sfc_setup$8 ? _sfc_setup$8(props, ctx) : void 0;
6194
6370
  };
6195
- const __nuxt_component_15 = Object.assign(_sfc_main$8, { __name: "RegressionContext" });
6371
+ const __nuxt_component_14 = Object.assign(_sfc_main$8, { __name: "RegressionContext" });
6196
6372
  const _sfc_main$7 = /* @__PURE__ */ defineComponent({
6197
6373
  __name: "TimelineHeader",
6198
6374
  __ssrInlineRender: true,
@@ -6934,7 +7110,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
6934
7110
  const _component_TimelineGrid = __nuxt_component_1;
6935
7111
  const _component_TimelineBar = __nuxt_component_2;
6936
7112
  const _component_TimelineTooltip = __nuxt_component_3;
6937
- const _component_UIcon = _sfc_main$p;
7113
+ const _component_EmptyState = __nuxt_component_4$3;
6938
7114
  if (unref(timelineData).length > 0) {
6939
7115
  _push(`<div${ssrRenderAttrs(mergeProps({
6940
7116
  class: "relative select-none",
@@ -6980,12 +7156,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
6980
7156
  }, null, _parent));
6981
7157
  _push(`</div>`);
6982
7158
  } else {
6983
- _push(`<div${ssrRenderAttrs(mergeProps({ class: "text-center py-10 text-gray-500" }, _attrs))}>`);
6984
- _push(ssrRenderComponent(_component_UIcon, {
6985
- name: "i-lucide-rows-3",
6986
- class: "size-8 mx-auto mb-2 text-gray-300 dark:text-gray-600"
6987
- }, null, _parent));
6988
- _push(`<p>No worker data available for this run.</p></div>`);
7159
+ _push(ssrRenderComponent(_component_EmptyState, mergeProps({
7160
+ icon: "i-lucide-rows-3",
7161
+ text: "No worker data available for this run."
7162
+ }, _attrs), null, _parent));
6989
7163
  }
6990
7164
  };
6991
7165
  }
@@ -6996,7 +7170,7 @@ _sfc_main$3.setup = (props, ctx) => {
6996
7170
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/WorkersTimeline.vue");
6997
7171
  return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0;
6998
7172
  };
6999
- const __nuxt_component_16 = Object.assign(_sfc_main$3, { __name: "WorkersTimeline" });
7173
+ const __nuxt_component_15 = Object.assign(_sfc_main$3, { __name: "WorkersTimeline" });
7000
7174
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
7001
7175
  __name: "RunCompare",
7002
7176
  __ssrInlineRender: true,
@@ -7042,12 +7216,33 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
7042
7216
  return m.environment == null || envs.has(m.environment);
7043
7217
  });
7044
7218
  });
7045
- const projectRunOptions = computed(() => {
7046
- if (!projectData.value?.testRuns) return [];
7047
- return projectData.value.testRuns.filter((r) => r.id !== Number(runId)).slice(0, 50).map((r) => ({
7219
+ function runToOption(r) {
7220
+ return {
7048
7221
  label: `Run #${r.id} — ${prettyDateFormat(r.startTime, { dateOnly: true })} (${r.status})`,
7049
- value: r.id
7050
- }));
7222
+ value: r.id,
7223
+ status: r.status,
7224
+ startTime: new Date(r.startTime).getTime()
7225
+ };
7226
+ }
7227
+ const defaultBaselineOption = computed(() => {
7228
+ const runs = projectData.value?.testRuns;
7229
+ if (!runs || !props.testRun) return null;
7230
+ const currentStart = new Date(props.testRun.startTime).getTime();
7231
+ const earlier = runs.filter((r) => r.id !== Number(runId) && new Date(r.startTime).getTime() < currentStart).sort((a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime());
7232
+ const pick = earlier.find((r) => r.status === "passed") ?? earlier[0];
7233
+ return pick ? runToOption(pick) : null;
7234
+ });
7235
+ const projectRunOptions = computed(() => {
7236
+ const runs = projectData.value?.testRuns;
7237
+ if (!runs) return [];
7238
+ const options = runs.filter((r) => r.id !== Number(runId)).slice(0, 50).map(runToOption);
7239
+ const baseline = defaultBaselineOption.value;
7240
+ if (baseline && !options.some((o) => o.value === baseline.value)) options.push(baseline);
7241
+ return options;
7242
+ });
7243
+ watch([projectRunOptions, defaultBaselineOption], ([options, baseline]) => {
7244
+ if (compareRunA.value || !baseline) return;
7245
+ compareRunA.value = options.find((o) => o.value === baseline.value) ?? baseline;
7051
7246
  });
7052
7247
  const previousRunId = computed(() => {
7053
7248
  if (!projectData.value?.testRuns) return null;
@@ -7120,15 +7315,17 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
7120
7315
  const _component_UButton = _sfc_main$k;
7121
7316
  const _component_UIcon = _sfc_main$p;
7122
7317
  const _component_UAlert = _sfc_main$n;
7123
- const _component_MarkerBadge = __nuxt_component_5;
7318
+ const _component_MarkerBadge = __nuxt_component_5$1;
7124
7319
  const _component_UBadge = _sfc_main$7$1;
7125
7320
  const _component_TableScroller = __nuxt_component_3$2;
7126
7321
  const _component_UTable = _sfc_main$l;
7127
7322
  const _component_DurationValue = __nuxt_component_14$1;
7323
+ const _component_EmptyState = __nuxt_component_4$3;
7128
7324
  _push(`<div${ssrRenderAttrs(_attrs)}>`);
7129
7325
  if (__props.testRun && !isLive.value) {
7130
- _push(`<div class="space-y-4"><div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Run A (baseline)</label>`);
7326
+ _push(`<div class="space-y-4"><div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" for="compare-baseline-select">Run A (baseline)</label>`);
7131
7327
  _push(ssrRenderComponent(_component_USelectMenu, {
7328
+ id: "compare-baseline-select",
7132
7329
  modelValue: compareRunA.value,
7133
7330
  "onUpdate:modelValue": ($event) => compareRunA.value = $event,
7134
7331
  items: projectRunOptions.value,
@@ -7610,19 +7807,15 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
7610
7807
  }, _parent));
7611
7808
  _push(`<!--]-->`);
7612
7809
  } else if (compareRunA.value && !loadingBaseline.value) {
7613
- _push(`<div class="text-center py-8 text-gray-500">`);
7614
- _push(ssrRenderComponent(_component_UIcon, {
7615
- name: "i-lucide-git-compare-arrows",
7616
- class: "size-8 mx-auto mb-2 text-gray-300 dark:text-gray-600"
7810
+ _push(ssrRenderComponent(_component_EmptyState, {
7811
+ icon: "i-lucide-git-compare-arrows",
7812
+ text: "No comparison data available."
7617
7813
  }, null, _parent));
7618
- _push(`<p>No comparison data available.</p></div>`);
7619
7814
  } else {
7620
- _push(`<div class="text-center py-8 text-gray-500">`);
7621
- _push(ssrRenderComponent(_component_UIcon, {
7622
- name: "i-lucide-arrow-left-right",
7623
- class: "size-8 mx-auto mb-2 text-gray-300 dark:text-gray-600"
7815
+ _push(ssrRenderComponent(_component_EmptyState, {
7816
+ icon: "i-lucide-arrow-left-right",
7817
+ text: "Select a baseline run to compare."
7624
7818
  }, null, _parent));
7625
- _push(`<p>Select a baseline run to compare.</p></div>`);
7626
7819
  }
7627
7820
  _push(`</div>`);
7628
7821
  } else if (isLive.value) {
@@ -7645,7 +7838,7 @@ _sfc_main$2.setup = (props, ctx) => {
7645
7838
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/RunCompare.vue");
7646
7839
  return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0;
7647
7840
  };
7648
- const __nuxt_component_17 = Object.assign(_sfc_main$2, { __name: "RunCompare" });
7841
+ const __nuxt_component_16 = Object.assign(_sfc_main$2, { __name: "RunCompare" });
7649
7842
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7650
7843
  __name: "SlowEndpoints",
7651
7844
  __ssrInlineRender: true,
@@ -7731,6 +7924,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7731
7924
  sticky: "",
7732
7925
  data: unref(endpoints),
7733
7926
  columns: endpointColumns,
7927
+ "aria-label": "Slow endpoints",
7734
7928
  class: "flex-1 min-h-0",
7735
7929
  ui: {
7736
7930
  base: "table-fixed border-separate border-spacing-0 min-w-[44rem]",
@@ -7828,6 +8022,29 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
7828
8022
  ];
7829
8023
  }
7830
8024
  }),
8025
+ "maxDuration-cell": withCtx(({ row }, _push2, _parent2, _scopeId) => {
8026
+ if (_push2) {
8027
+ _push2(`<span class="${ssrRenderClass(
8028
+ row.original.maxDuration > 2e3 ? "text-red-600 font-medium" : row.original.maxDuration > 1e3 ? "text-orange-500" : ""
8029
+ )}"${_scopeId}>`);
8030
+ _push2(ssrRenderComponent(_component_DurationValue, {
8031
+ ms: row.original.maxDuration,
8032
+ "unit-class": "opacity-60"
8033
+ }, null, _parent2, _scopeId));
8034
+ _push2(`</span>`);
8035
+ } else {
8036
+ return [
8037
+ createVNode("span", {
8038
+ class: row.original.maxDuration > 2e3 ? "text-red-600 font-medium" : row.original.maxDuration > 1e3 ? "text-orange-500" : ""
8039
+ }, [
8040
+ createVNode(_component_DurationValue, {
8041
+ ms: row.original.maxDuration,
8042
+ "unit-class": "opacity-60"
8043
+ }, null, 8, ["ms"])
8044
+ ], 2)
8045
+ ];
8046
+ }
8047
+ }),
7831
8048
  "errorRate-cell": withCtx(({ row }, _push2, _parent2, _scopeId) => {
7832
8049
  if (_push2) {
7833
8050
  if (row.original.errorRate === 0) {
@@ -7868,7 +8085,7 @@ _sfc_main$1.setup = (props, ctx) => {
7868
8085
  (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/run/SlowEndpoints.vue");
7869
8086
  return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0;
7870
8087
  };
7871
- const __nuxt_component_18 = Object.assign(_sfc_main$1, { __name: "SlowEndpoints" });
8088
+ const __nuxt_component_17 = Object.assign(_sfc_main$1, { __name: "SlowEndpoints" });
7872
8089
  const _sfc_main = /* @__PURE__ */ defineComponent({
7873
8090
  __name: "[id]",
7874
8091
  __ssrInlineRender: true,
@@ -7894,10 +8111,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
7894
8111
  const latestRunId = computed(() => latestRunInfo.value?.id ?? testRun.value?.project?.latestRunId ?? null);
7895
8112
  const latestRunStatus = computed(() => latestRunInfo.value?.status ?? testRun.value?.project?.latestRunStatus ?? null);
7896
8113
  const isLatestRunActive = computed(() => latestRunStatus.value === "running" || latestRunStatus.value === "finalizing");
8114
+ const navbarTitle = computed(() => {
8115
+ const project = testRun.value?.project?.label || testRun.value?.project?.name;
8116
+ return project ? `Run #${runId} — ${project}` : `Run #${runId}`;
8117
+ });
7897
8118
  useHead(
7898
- computed(() => ({
7899
- title: `Test run #${runId}${testRun.value?.project ? ` — ${testRun.value.project.name}` : ""} — Piwi Dashboard`
7900
- }))
8119
+ computed(() => {
8120
+ const project = testRun.value?.project?.label || testRun.value?.project?.name;
8121
+ return {
8122
+ title: `Test run #${runId}${project ? ` — ${project}` : ""} — Piwi Dashboard`
8123
+ };
8124
+ })
7901
8125
  );
7902
8126
  useToast();
7903
8127
  const isDeleteConfirmOpen = ref(false);
@@ -7957,11 +8181,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
7957
8181
  const testCaseSearch = ref("");
7958
8182
  const testCaseActiveStatuses = ref([]);
7959
8183
  const testCaseBrowserFilter = ref("all");
7960
- const statusFilterForSummary = computed(
7961
- () => testCaseActiveStatuses.value.length === 1 ? testCaseActiveStatuses.value[0] : "all"
7962
- );
7963
8184
  function handleFilterStatus(status) {
7964
- testCaseActiveStatuses.value = !status || status === "all" ? [] : [status];
8185
+ if (!status || status === "all") {
8186
+ testCaseActiveStatuses.value = [];
8187
+ return;
8188
+ }
8189
+ testCaseActiveStatuses.value = testCaseActiveStatuses.value.includes(status) ? testCaseActiveStatuses.value.filter((s) => s !== status) : [...testCaseActiveStatuses.value, status];
7965
8190
  }
7966
8191
  const allReports = computed(() => testRun.value?.reports || []);
7967
8192
  const totalWastedTime = computed(() => {
@@ -7970,13 +8195,49 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
7970
8195
  return cases.reduce((sum, tc) => sum + (tc.wastedTimeMs ?? 0), 0);
7971
8196
  });
7972
8197
  const activeTab = ref("test-cases");
8198
+ const hasFailures = computed(() => (displayProgress.value?.failedTests ?? 0) > 0);
8199
+ const showFailureTabs = computed(() => hasFailures.value || (testRun.value?.flakyTests ?? 0) > 0);
7973
8200
  const selectedClusterFilter = ref(null);
8201
+ const clusterNames = ref({});
8202
+ async function fetchClusterNames() {
8203
+ return;
8204
+ }
8205
+ watch(
8206
+ showFailureTabs,
8207
+ (show) => {
8208
+ if (show) fetchClusterNames();
8209
+ },
8210
+ { immediate: true }
8211
+ );
8212
+ const clusterFilterName = computed(() => {
8213
+ const f = selectedClusterFilter.value;
8214
+ if (!f) return "";
8215
+ return f.title ?? clusterNames.value[f.id] ?? `Cluster #${f.id}`;
8216
+ });
8217
+ const clusterFilterCount = computed(() => {
8218
+ const f = selectedClusterFilter.value;
8219
+ if (!f) return 0;
8220
+ return displayTestCases.value.filter((tc) => tc.failureClusterId === f.id).length;
8221
+ });
8222
+ const clusterQuery = typeof route.query.cluster === "string" ? Number(route.query.cluster) : null;
8223
+ if (clusterQuery && !Number.isNaN(clusterQuery)) {
8224
+ selectedClusterFilter.value = { id: clusterQuery, title: null };
8225
+ activeTab.value = "test-cases";
8226
+ }
7974
8227
  const runRefreshKey = ref(0);
7975
- const endpointsCount = ref(0);
8228
+ watch(runRefreshKey, () => {
8229
+ if (showFailureTabs.value) fetchClusterNames();
8230
+ });
8231
+ const endpointsCount = ref(testRun.value?.networkRequestCount ?? 0);
8232
+ watch(
8233
+ () => testRun.value?.networkRequestCount,
8234
+ (count) => {
8235
+ if (count != null) endpointsCount.value = count;
8236
+ }
8237
+ );
7976
8238
  function clearClusterFilter() {
7977
8239
  selectedClusterFilter.value = null;
7978
8240
  }
7979
- const hasFailures = computed(() => testRun.value && testRun.value.failedTests > 0);
7980
8241
  const failureGroupCount = computed(() => {
7981
8242
  if (!testRun.value?.testCases) return 0;
7982
8243
  const clusterIds = /* @__PURE__ */ new Set();
@@ -7996,7 +8257,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
7996
8257
  });
7997
8258
  const tabItems = computed(() => [
7998
8259
  {
7999
- label: `Test cases (${displayTestCases.value.length})`,
8260
+ label: `Executions (${displayTestCases.value.length})`,
8000
8261
  icon: "i-lucide-beaker",
8001
8262
  value: "test-cases",
8002
8263
  slot: "test-cases"
@@ -8010,18 +8271,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8010
8271
  // Failure-only tabs stay visible but disabled on a green run: tabs that
8011
8272
  // appear and disappear shift every other tab's position between runs.
8012
8273
  {
8013
- label: hasFailures.value ? `Failure groups (${failureGroupCount.value})` : "Failure groups",
8274
+ label: hasFailures.value ? `Failure clusters (${failureGroupCount.value})` : "Failure clusters",
8014
8275
  icon: "i-lucide-layers",
8015
8276
  value: "failure-groups",
8016
8277
  slot: "failure-groups",
8017
- disabled: !hasFailures.value
8278
+ disabled: !showFailureTabs.value,
8279
+ disabledReason: "no failing tests in this run"
8018
8280
  },
8019
8281
  {
8020
- label: "Regression",
8282
+ label: "Since last pass",
8021
8283
  icon: "i-lucide-git-pull-request-arrow",
8022
8284
  value: "regression",
8023
8285
  slot: "regression",
8024
- disabled: !hasFailures.value
8286
+ disabled: !showFailureTabs.value,
8287
+ disabledReason: "no failing tests in this run"
8025
8288
  },
8026
8289
  {
8027
8290
  label: `Timeline${uniqueWorkerCount.value > 0 ? ` (${uniqueWorkerCount.value})` : ""}`,
@@ -8048,9 +8311,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8048
8311
  watch(runTabValues, (vals) => {
8049
8312
  if (!vals.includes(activeTab.value)) activeTab.value = "test-cases";
8050
8313
  });
8051
- watch(activeTab, (tab) => {
8052
- if (route.query.tab === tab) return;
8053
- router.replace({ query: { ...route.query, tab } });
8314
+ watch([activeTab, selectedClusterFilter], ([tab, f]) => {
8315
+ const query = { ...route.query };
8316
+ if (f) query.cluster = String(f.id);
8317
+ else delete query.cluster;
8318
+ query.tab = tab;
8319
+ if (JSON.stringify(query) === JSON.stringify({ ...route.query })) return;
8320
+ router.replace({ query });
8054
8321
  });
8055
8322
  const testCasesListRef = ref(null);
8056
8323
  function handleSelectTestCase(id) {
@@ -8060,35 +8327,34 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8060
8327
  });
8061
8328
  }
8062
8329
  function handleSelectCluster(clusterId) {
8063
- selectedClusterFilter.value = clusterId;
8330
+ selectedClusterFilter.value = { id: clusterId, title: null };
8064
8331
  activeTab.value = "test-cases";
8065
8332
  }
8066
8333
  return (_ctx, _push, _parent, _attrs) => {
8067
8334
  const _component_UDashboardPanel = _sfc_main$1$1;
8068
- const _component_UDashboardNavbar = _sfc_main$i;
8335
+ const _component_UDashboardNavbar = _sfc_main$j;
8069
8336
  const _component_UDashboardSidebarCollapse = _sfc_main$1$2;
8070
8337
  const _component_BreadcrumbNav = __nuxt_component_3$1;
8071
8338
  const _component_NuxtLink = __nuxt_component_12$1;
8072
- const _component_UTooltip = _sfc_main$j;
8073
- const _component_UIcon = _sfc_main$p;
8339
+ const _component_RunFreshnessPill = __nuxt_component_5;
8074
8340
  const _component_NavbarActions = __nuxt_component_4$1;
8075
- const _component_DetailPageLayout = __nuxt_component_8;
8076
- const _component_RunSummary = __nuxt_component_9$1;
8341
+ const _component_DetailPageLayout = __nuxt_component_7$1;
8342
+ const _component_RunSummary = __nuxt_component_8;
8077
8343
  const _component_UBadge = _sfc_main$7$1;
8078
8344
  const _component_UButton = _sfc_main$k;
8079
- const _component_TestCasesList = __nuxt_component_12;
8080
- const _component_RunInsights = __nuxt_component_13;
8081
- const _component_FailureGroups = __nuxt_component_14;
8082
- const _component_RegressionContext = __nuxt_component_15;
8083
- const _component_WorkersTimeline = __nuxt_component_16;
8084
- const _component_RunCompare = __nuxt_component_17;
8085
- const _component_SlowEndpoints = __nuxt_component_18;
8086
- const _component_ClientOnly = __nuxt_component_7$1;
8345
+ const _component_TestCasesList = __nuxt_component_11;
8346
+ const _component_RunInsights = __nuxt_component_12;
8347
+ const _component_FailureGroups = __nuxt_component_13;
8348
+ const _component_RegressionContext = __nuxt_component_14;
8349
+ const _component_WorkersTimeline = __nuxt_component_15;
8350
+ const _component_RunCompare = __nuxt_component_16;
8351
+ const _component_SlowEndpoints = __nuxt_component_17;
8352
+ const _component_ClientOnly = __nuxt_component_8$1;
8087
8353
  _push(`<!--[-->`);
8088
8354
  _push(ssrRenderComponent(_component_UDashboardPanel, { id: "test-run-detail" }, {
8089
8355
  header: withCtx((_, _push2, _parent2, _scopeId) => {
8090
8356
  if (_push2) {
8091
- _push2(ssrRenderComponent(_component_UDashboardNavbar, null, {
8357
+ _push2(ssrRenderComponent(_component_UDashboardNavbar, { title: navbarTitle.value }, {
8092
8358
  leading: withCtx((_2, _push3, _parent3, _scopeId2) => {
8093
8359
  if (_push3) {
8094
8360
  _push3(ssrRenderComponent(_component_UDashboardSidebarCollapse, null, null, _parent3, _scopeId2));
@@ -8123,59 +8389,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8123
8389
  }),
8124
8390
  _: 2
8125
8391
  }, _parent4, _scopeId3));
8126
- if (latestRunId.value && latestRunId.value !== Number(unref(runId))) {
8127
- _push4(ssrRenderComponent(_component_UTooltip, {
8128
- text: isLatestRunActive.value ? "Go to running run" : "Go to latest run"
8129
- }, {
8130
- default: withCtx((_3, _push5, _parent5, _scopeId4) => {
8131
- if (_push5) {
8132
- _push5(ssrRenderComponent(_component_NuxtLink, {
8133
- to: `/test-runs/${latestRunId.value}`
8134
- }, {
8135
- default: withCtx((_4, _push6, _parent6, _scopeId5) => {
8136
- if (_push6) {
8137
- _push6(`<span class="inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1"${_scopeId5}>`);
8138
- _push6(ssrRenderComponent(_component_UIcon, {
8139
- name: "i-lucide-circle-play",
8140
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8141
- }, null, _parent6, _scopeId5));
8142
- _push6(`</span>`);
8143
- } else {
8144
- return [
8145
- createVNode("span", { class: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1" }, [
8146
- createVNode(_component_UIcon, {
8147
- name: "i-lucide-circle-play",
8148
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8149
- }, null, 8, ["class"])
8150
- ])
8151
- ];
8152
- }
8153
- }),
8154
- _: 2
8155
- }, _parent5, _scopeId4));
8156
- } else {
8157
- return [
8158
- createVNode(_component_NuxtLink, {
8159
- to: `/test-runs/${latestRunId.value}`
8160
- }, {
8161
- default: withCtx(() => [
8162
- createVNode("span", { class: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1" }, [
8163
- createVNode(_component_UIcon, {
8164
- name: "i-lucide-circle-play",
8165
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8166
- }, null, 8, ["class"])
8167
- ])
8168
- ]),
8169
- _: 1
8170
- }, 8, ["to"])
8171
- ];
8172
- }
8173
- }),
8174
- _: 2
8175
- }, _parent4, _scopeId3));
8176
- } else {
8177
- _push4(`<!---->`);
8178
- }
8392
+ _push4(ssrRenderComponent(_component_RunFreshnessPill, {
8393
+ class: "ml-1",
8394
+ "latest-run-id": latestRunId.value,
8395
+ "current-run-id": Number(unref(runId)),
8396
+ "is-active": isLatestRunActive.value
8397
+ }, null, _parent4, _scopeId3));
8179
8398
  } else {
8180
8399
  return [
8181
8400
  createVNode(_component_NuxtLink, {
@@ -8187,32 +8406,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8187
8406
  ]),
8188
8407
  _: 2
8189
8408
  }, 1032, ["to"]),
8190
- latestRunId.value && latestRunId.value !== Number(unref(runId)) ? (openBlock(), createBlock(_component_UTooltip, {
8191
- key: 0,
8192
- text: isLatestRunActive.value ? "Go to running run" : "Go to latest run"
8193
- }, {
8194
- default: withCtx(() => [
8195
- createVNode(_component_NuxtLink, {
8196
- to: `/test-runs/${latestRunId.value}`
8197
- }, {
8198
- default: withCtx(() => [
8199
- createVNode("span", { class: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1" }, [
8200
- createVNode(_component_UIcon, {
8201
- name: "i-lucide-circle-play",
8202
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8203
- }, null, 8, ["class"])
8204
- ])
8205
- ]),
8206
- _: 1
8207
- }, 8, ["to"])
8208
- ]),
8209
- _: 1
8210
- }, 8, ["text"])) : createCommentVNode("", true)
8409
+ createVNode(_component_RunFreshnessPill, {
8410
+ class: "ml-1",
8411
+ "latest-run-id": latestRunId.value,
8412
+ "current-run-id": Number(unref(runId)),
8413
+ "is-active": isLatestRunActive.value
8414
+ }, null, 8, ["latest-run-id", "current-run-id", "is-active"])
8211
8415
  ];
8212
8416
  }
8213
8417
  }),
8214
8418
  _: 1
8215
8419
  }, _parent3, _scopeId2));
8420
+ _push3(ssrRenderComponent(_component_RunFreshnessPill, {
8421
+ class: "ml-1 sm:hidden",
8422
+ "latest-run-id": latestRunId.value,
8423
+ "current-run-id": Number(unref(runId)),
8424
+ "is-active": isLatestRunActive.value
8425
+ }, null, _parent3, _scopeId2));
8216
8426
  } else {
8217
8427
  return [
8218
8428
  createVNode(_component_UDashboardSidebarCollapse),
@@ -8240,35 +8450,27 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8240
8450
  ]),
8241
8451
  _: 2
8242
8452
  }, 1032, ["to"]),
8243
- latestRunId.value && latestRunId.value !== Number(unref(runId)) ? (openBlock(), createBlock(_component_UTooltip, {
8244
- key: 0,
8245
- text: isLatestRunActive.value ? "Go to running run" : "Go to latest run"
8246
- }, {
8247
- default: withCtx(() => [
8248
- createVNode(_component_NuxtLink, {
8249
- to: `/test-runs/${latestRunId.value}`
8250
- }, {
8251
- default: withCtx(() => [
8252
- createVNode("span", { class: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1" }, [
8253
- createVNode(_component_UIcon, {
8254
- name: "i-lucide-circle-play",
8255
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8256
- }, null, 8, ["class"])
8257
- ])
8258
- ]),
8259
- _: 1
8260
- }, 8, ["to"])
8261
- ]),
8262
- _: 1
8263
- }, 8, ["text"])) : createCommentVNode("", true)
8453
+ createVNode(_component_RunFreshnessPill, {
8454
+ class: "ml-1",
8455
+ "latest-run-id": latestRunId.value,
8456
+ "current-run-id": Number(unref(runId)),
8457
+ "is-active": isLatestRunActive.value
8458
+ }, null, 8, ["latest-run-id", "current-run-id", "is-active"])
8264
8459
  ]),
8265
8460
  _: 1
8266
- }, 8, ["items"])
8461
+ }, 8, ["items"]),
8462
+ createVNode(_component_RunFreshnessPill, {
8463
+ class: "ml-1 sm:hidden",
8464
+ "latest-run-id": latestRunId.value,
8465
+ "current-run-id": Number(unref(runId)),
8466
+ "is-active": isLatestRunActive.value
8467
+ }, null, 8, ["latest-run-id", "current-run-id", "is-active"])
8267
8468
  ];
8268
8469
  }
8269
8470
  }),
8270
8471
  right: withCtx((_2, _push3, _parent3, _scopeId2) => {
8271
8472
  if (_push3) {
8473
+ _push3(`<div class="flex items-center shrink-0 min-w-0"${_scopeId2}>`);
8272
8474
  _push3(ssrRenderComponent(_component_NavbarActions, {
8273
8475
  actions: [
8274
8476
  { label: "Refresh", icon: "i-lucide-refresh-cw", onClick: () => unref(refresh)() },
@@ -8282,21 +8484,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8282
8484
  }
8283
8485
  ]
8284
8486
  }, null, _parent3, _scopeId2));
8487
+ _push3(`</div>`);
8285
8488
  } else {
8286
8489
  return [
8287
- createVNode(_component_NavbarActions, {
8288
- actions: [
8289
- { label: "Refresh", icon: "i-lucide-refresh-cw", onClick: () => unref(refresh)() },
8290
- {
8291
- label: "Delete",
8292
- icon: "i-lucide-trash-2",
8293
- color: "error",
8294
- variant: "soft",
8295
- loading: unref(deleting),
8296
- onClick: () => isDeleteConfirmOpen.value = true
8297
- }
8298
- ]
8299
- }, null, 8, ["actions"])
8490
+ createVNode("div", { class: "flex items-center shrink-0 min-w-0" }, [
8491
+ createVNode(_component_NavbarActions, {
8492
+ actions: [
8493
+ { label: "Refresh", icon: "i-lucide-refresh-cw", onClick: () => unref(refresh)() },
8494
+ {
8495
+ label: "Delete",
8496
+ icon: "i-lucide-trash-2",
8497
+ color: "error",
8498
+ variant: "soft",
8499
+ loading: unref(deleting),
8500
+ onClick: () => isDeleteConfirmOpen.value = true
8501
+ }
8502
+ ]
8503
+ }, null, 8, ["actions"])
8504
+ ])
8300
8505
  ];
8301
8506
  }
8302
8507
  }),
@@ -8304,7 +8509,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8304
8509
  }, _parent2, _scopeId));
8305
8510
  } else {
8306
8511
  return [
8307
- createVNode(_component_UDashboardNavbar, null, {
8512
+ createVNode(_component_UDashboardNavbar, { title: navbarTitle.value }, {
8308
8513
  leading: withCtx(() => [
8309
8514
  createVNode(_component_UDashboardSidebarCollapse),
8310
8515
  createVNode(_component_BreadcrumbNav, {
@@ -8331,48 +8536,41 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8331
8536
  ]),
8332
8537
  _: 2
8333
8538
  }, 1032, ["to"]),
8334
- latestRunId.value && latestRunId.value !== Number(unref(runId)) ? (openBlock(), createBlock(_component_UTooltip, {
8335
- key: 0,
8336
- text: isLatestRunActive.value ? "Go to running run" : "Go to latest run"
8337
- }, {
8338
- default: withCtx(() => [
8339
- createVNode(_component_NuxtLink, {
8340
- to: `/test-runs/${latestRunId.value}`
8341
- }, {
8342
- default: withCtx(() => [
8343
- createVNode("span", { class: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-blue-500/10 hover:bg-blue-500/20 transition-colors ml-1" }, [
8344
- createVNode(_component_UIcon, {
8345
- name: "i-lucide-circle-play",
8346
- class: ["w-3.5 h-3.5 text-blue-500", { "animate-pulse": isLatestRunActive.value }]
8347
- }, null, 8, ["class"])
8348
- ])
8349
- ]),
8350
- _: 1
8351
- }, 8, ["to"])
8352
- ]),
8353
- _: 1
8354
- }, 8, ["text"])) : createCommentVNode("", true)
8539
+ createVNode(_component_RunFreshnessPill, {
8540
+ class: "ml-1",
8541
+ "latest-run-id": latestRunId.value,
8542
+ "current-run-id": Number(unref(runId)),
8543
+ "is-active": isLatestRunActive.value
8544
+ }, null, 8, ["latest-run-id", "current-run-id", "is-active"])
8355
8545
  ]),
8356
8546
  _: 1
8357
- }, 8, ["items"])
8547
+ }, 8, ["items"]),
8548
+ createVNode(_component_RunFreshnessPill, {
8549
+ class: "ml-1 sm:hidden",
8550
+ "latest-run-id": latestRunId.value,
8551
+ "current-run-id": Number(unref(runId)),
8552
+ "is-active": isLatestRunActive.value
8553
+ }, null, 8, ["latest-run-id", "current-run-id", "is-active"])
8358
8554
  ]),
8359
8555
  right: withCtx(() => [
8360
- createVNode(_component_NavbarActions, {
8361
- actions: [
8362
- { label: "Refresh", icon: "i-lucide-refresh-cw", onClick: () => unref(refresh)() },
8363
- {
8364
- label: "Delete",
8365
- icon: "i-lucide-trash-2",
8366
- color: "error",
8367
- variant: "soft",
8368
- loading: unref(deleting),
8369
- onClick: () => isDeleteConfirmOpen.value = true
8370
- }
8371
- ]
8372
- }, null, 8, ["actions"])
8556
+ createVNode("div", { class: "flex items-center shrink-0 min-w-0" }, [
8557
+ createVNode(_component_NavbarActions, {
8558
+ actions: [
8559
+ { label: "Refresh", icon: "i-lucide-refresh-cw", onClick: () => unref(refresh)() },
8560
+ {
8561
+ label: "Delete",
8562
+ icon: "i-lucide-trash-2",
8563
+ color: "error",
8564
+ variant: "soft",
8565
+ loading: unref(deleting),
8566
+ onClick: () => isDeleteConfirmOpen.value = true
8567
+ }
8568
+ ]
8569
+ }, null, 8, ["actions"])
8570
+ ])
8373
8571
  ]),
8374
8572
  _: 1
8375
- })
8573
+ }, 8, ["title"])
8376
8574
  ];
8377
8575
  }
8378
8576
  }),
@@ -8393,10 +8591,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8393
8591
  "all-reports": allReports.value,
8394
8592
  "show-custom-data": unref(showCustomData),
8395
8593
  finalizing: unref(isFinalizing),
8396
- "active-filter": statusFilterForSummary.value,
8594
+ "active-statuses": unref(testCaseActiveStatuses),
8397
8595
  "total-wasted-time": totalWastedTime.value,
8398
8596
  "onUpdate:showCustomData": ($event) => showCustomData.value = $event,
8399
- onFilterStatus: handleFilterStatus,
8597
+ onToggleStatus: handleFilterStatus,
8400
8598
  onLabelUpdated: unref(refresh)
8401
8599
  }, null, _parent3, _scopeId2));
8402
8600
  } else {
@@ -8411,12 +8609,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8411
8609
  "all-reports": allReports.value,
8412
8610
  "show-custom-data": unref(showCustomData),
8413
8611
  finalizing: unref(isFinalizing),
8414
- "active-filter": statusFilterForSummary.value,
8612
+ "active-statuses": unref(testCaseActiveStatuses),
8415
8613
  "total-wasted-time": totalWastedTime.value,
8416
8614
  "onUpdate:showCustomData": ($event) => showCustomData.value = $event,
8417
- onFilterStatus: handleFilterStatus,
8615
+ onToggleStatus: handleFilterStatus,
8418
8616
  onLabelUpdated: unref(refresh)
8419
- }, null, 8, ["test-run", "display-progress", "all-reports", "show-custom-data", "finalizing", "active-filter", "total-wasted-time", "onUpdate:showCustomData", "onLabelUpdated"])) : createCommentVNode("", true)
8617
+ }, null, 8, ["test-run", "display-progress", "all-reports", "show-custom-data", "finalizing", "active-statuses", "total-wasted-time", "onUpdate:showCustomData", "onLabelUpdated"])) : createCommentVNode("", true)
8420
8618
  ];
8421
8619
  }
8422
8620
  }),
@@ -8431,10 +8629,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8431
8629
  }, {
8432
8630
  default: withCtx((_3, _push4, _parent4, _scopeId3) => {
8433
8631
  if (_push4) {
8434
- _push4(` Filtered by failure group `);
8632
+ _push4(` Cluster: ${ssrInterpolate(clusterFilterName.value)} · ${ssrInterpolate(clusterFilterCount.value)} ${ssrInterpolate(clusterFilterCount.value === 1 ? "test" : "tests")}`);
8435
8633
  } else {
8436
8634
  return [
8437
- createTextVNode(" Filtered by failure group ")
8635
+ createTextVNode(" Cluster: " + toDisplayString(clusterFilterName.value) + " · " + toDisplayString(clusterFilterCount.value) + " " + toDisplayString(clusterFilterCount.value === 1 ? "test" : "tests"), 1)
8438
8636
  ];
8439
8637
  }
8440
8638
  }),
@@ -8465,7 +8663,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8465
8663
  suites: unref(testRun)?.suites ?? [],
8466
8664
  "is-live": isLive.value,
8467
8665
  "live-steps": unref(liveSteps),
8468
- "failure-cluster-filter": unref(selectedClusterFilter),
8666
+ "failure-cluster-filter": unref(selectedClusterFilter)?.id ?? null,
8667
+ "cluster-names": unref(clusterNames),
8469
8668
  "project-key": unref(testRun)?.projectId,
8470
8669
  "project-name": unref(testRun)?.project?.name,
8471
8670
  class: "flex-1 min-h-0"
@@ -8482,7 +8681,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8482
8681
  size: "sm"
8483
8682
  }, {
8484
8683
  default: withCtx(() => [
8485
- createTextVNode(" Filtered by failure group ")
8684
+ createTextVNode(" Cluster: " + toDisplayString(clusterFilterName.value) + " · " + toDisplayString(clusterFilterCount.value) + " " + toDisplayString(clusterFilterCount.value === 1 ? "test" : "tests"), 1)
8486
8685
  ]),
8487
8686
  _: 1
8488
8687
  }),
@@ -8508,11 +8707,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8508
8707
  suites: unref(testRun)?.suites ?? [],
8509
8708
  "is-live": isLive.value,
8510
8709
  "live-steps": unref(liveSteps),
8511
- "failure-cluster-filter": unref(selectedClusterFilter),
8710
+ "failure-cluster-filter": unref(selectedClusterFilter)?.id ?? null,
8711
+ "cluster-names": unref(clusterNames),
8512
8712
  "project-key": unref(testRun)?.projectId,
8513
8713
  "project-name": unref(testRun)?.project?.name,
8514
8714
  class: "flex-1 min-h-0"
8515
- }, null, 8, ["search", "onUpdate:search", "active-statuses", "onUpdate:activeStatuses", "browser-filter", "onUpdate:browserFilter", "test-cases", "suites", "is-live", "live-steps", "failure-cluster-filter", "project-key", "project-name"])
8715
+ }, null, 8, ["search", "onUpdate:search", "active-statuses", "onUpdate:activeStatuses", "browser-filter", "onUpdate:browserFilter", "test-cases", "suites", "is-live", "live-steps", "failure-cluster-filter", "cluster-names", "project-key", "project-name"])
8516
8716
  ];
8517
8717
  }
8518
8718
  }),
@@ -8626,12 +8826,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8626
8826
  "all-reports": allReports.value,
8627
8827
  "show-custom-data": unref(showCustomData),
8628
8828
  finalizing: unref(isFinalizing),
8629
- "active-filter": statusFilterForSummary.value,
8829
+ "active-statuses": unref(testCaseActiveStatuses),
8630
8830
  "total-wasted-time": totalWastedTime.value,
8631
8831
  "onUpdate:showCustomData": ($event) => showCustomData.value = $event,
8632
- onFilterStatus: handleFilterStatus,
8832
+ onToggleStatus: handleFilterStatus,
8633
8833
  onLabelUpdated: unref(refresh)
8634
- }, null, 8, ["test-run", "display-progress", "all-reports", "show-custom-data", "finalizing", "active-filter", "total-wasted-time", "onUpdate:showCustomData", "onLabelUpdated"])) : createCommentVNode("", true)
8834
+ }, null, 8, ["test-run", "display-progress", "all-reports", "show-custom-data", "finalizing", "active-statuses", "total-wasted-time", "onUpdate:showCustomData", "onLabelUpdated"])) : createCommentVNode("", true)
8635
8835
  ]),
8636
8836
  "tab-test-cases": withCtx(() => [
8637
8837
  unref(selectedClusterFilter) != null ? (openBlock(), createBlock("div", {
@@ -8644,7 +8844,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8644
8844
  size: "sm"
8645
8845
  }, {
8646
8846
  default: withCtx(() => [
8647
- createTextVNode(" Filtered by failure group ")
8847
+ createTextVNode(" Cluster: " + toDisplayString(clusterFilterName.value) + " · " + toDisplayString(clusterFilterCount.value) + " " + toDisplayString(clusterFilterCount.value === 1 ? "test" : "tests"), 1)
8648
8848
  ]),
8649
8849
  _: 1
8650
8850
  }),
@@ -8670,11 +8870,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8670
8870
  suites: unref(testRun)?.suites ?? [],
8671
8871
  "is-live": isLive.value,
8672
8872
  "live-steps": unref(liveSteps),
8673
- "failure-cluster-filter": unref(selectedClusterFilter),
8873
+ "failure-cluster-filter": unref(selectedClusterFilter)?.id ?? null,
8874
+ "cluster-names": unref(clusterNames),
8674
8875
  "project-key": unref(testRun)?.projectId,
8675
8876
  "project-name": unref(testRun)?.project?.name,
8676
8877
  class: "flex-1 min-h-0"
8677
- }, null, 8, ["search", "onUpdate:search", "active-statuses", "onUpdate:activeStatuses", "browser-filter", "onUpdate:browserFilter", "test-cases", "suites", "is-live", "live-steps", "failure-cluster-filter", "project-key", "project-name"])
8878
+ }, null, 8, ["search", "onUpdate:search", "active-statuses", "onUpdate:activeStatuses", "browser-filter", "onUpdate:browserFilter", "test-cases", "suites", "is-live", "live-steps", "failure-cluster-filter", "cluster-names", "project-key", "project-name"])
8678
8879
  ]),
8679
8880
  "tab-insights": withCtx(() => [
8680
8881
  createVNode(_component_RunInsights, {
@@ -8733,4 +8934,4 @@ _sfc_main.setup = (props, ctx) => {
8733
8934
  };
8734
8935
 
8735
8936
  export { _sfc_main as default };
8736
- //# sourceMappingURL=_id_-DVPb1S93.mjs.map
8937
+ //# sourceMappingURL=_id_-DxHe32cW.mjs.map