@flanksource/clicky-ui 0.3.46 → 0.3.47

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 (379) hide show
  1. package/NOTICE.md +11 -0
  2. package/dist/ai.cjs +13 -8
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.js +7 -2
  5. package/dist/ai.js.map +1 -1
  6. package/dist/components/ErrorWrapper.cjs +2 -3
  7. package/dist/components/ErrorWrapper.cjs.map +1 -1
  8. package/dist/components/ErrorWrapper.d.ts.map +1 -1
  9. package/dist/components/ErrorWrapper.js +3 -4
  10. package/dist/components/ErrorWrapper.js.map +1 -1
  11. package/dist/data/Clicky.cjs +3 -0
  12. package/dist/data/Clicky.cjs.map +1 -1
  13. package/dist/data/Clicky.js +3 -0
  14. package/dist/data/Clicky.js.map +1 -1
  15. package/dist/data/FilterPill.cjs +15 -2
  16. package/dist/data/FilterPill.cjs.map +1 -1
  17. package/dist/data/FilterPill.d.ts +1 -1
  18. package/dist/data/FilterPill.d.ts.map +1 -1
  19. package/dist/data/FilterPill.js +15 -2
  20. package/dist/data/FilterPill.js.map +1 -1
  21. package/dist/data/LogViewer.cjs +27 -8
  22. package/dist/data/LogViewer.cjs.map +1 -1
  23. package/dist/data/LogViewer.d.ts +11 -3
  24. package/dist/data/LogViewer.d.ts.map +1 -1
  25. package/dist/data/LogViewer.js +27 -8
  26. package/dist/data/LogViewer.js.map +1 -1
  27. package/dist/data/Properties.cjs +2 -15
  28. package/dist/data/Properties.cjs.map +1 -1
  29. package/dist/data/Properties.d.ts +4 -0
  30. package/dist/data/Properties.d.ts.map +1 -1
  31. package/dist/data/Properties.js +2 -15
  32. package/dist/data/Properties.js.map +1 -1
  33. package/dist/data/PropertyValue.cjs +37 -0
  34. package/dist/data/PropertyValue.cjs.map +1 -0
  35. package/dist/data/PropertyValue.d.ts +6 -0
  36. package/dist/data/PropertyValue.d.ts.map +1 -0
  37. package/dist/data/PropertyValue.js +37 -0
  38. package/dist/data/PropertyValue.js.map +1 -0
  39. package/dist/data/Tree.cjs +4 -3
  40. package/dist/data/Tree.cjs.map +1 -1
  41. package/dist/data/Tree.d.ts +3 -1
  42. package/dist/data/Tree.d.ts.map +1 -1
  43. package/dist/data/Tree.js +4 -3
  44. package/dist/data/Tree.js.map +1 -1
  45. package/dist/data/ai/ChatFab.cjs +1 -1
  46. package/dist/data/ai/ChatFab.cjs.map +1 -1
  47. package/dist/data/ai/ChatFab.js +1 -1
  48. package/dist/data/ai/ChatFab.js.map +1 -1
  49. package/dist/data/ai/ChatWindow.cjs +106 -171
  50. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  51. package/dist/data/ai/ChatWindow.d.ts +6 -2
  52. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  53. package/dist/data/ai/ChatWindow.header.cjs +104 -0
  54. package/dist/data/ai/ChatWindow.header.cjs.map +1 -0
  55. package/dist/data/ai/ChatWindow.header.d.ts +29 -0
  56. package/dist/data/ai/ChatWindow.header.d.ts.map +1 -0
  57. package/dist/data/ai/ChatWindow.header.js +104 -0
  58. package/dist/data/ai/ChatWindow.header.js.map +1 -0
  59. package/dist/data/ai/ChatWindow.js +107 -172
  60. package/dist/data/ai/ChatWindow.js.map +1 -1
  61. package/dist/data/ai/ChatWindow.placement.cjs +95 -0
  62. package/dist/data/ai/ChatWindow.placement.cjs.map +1 -0
  63. package/dist/data/ai/ChatWindow.placement.d.ts +32 -0
  64. package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -0
  65. package/dist/data/ai/ChatWindow.placement.js +95 -0
  66. package/dist/data/ai/ChatWindow.placement.js.map +1 -0
  67. package/dist/data/ai/SessionChatComposer.cjs +3 -1
  68. package/dist/data/ai/SessionChatComposer.cjs.map +1 -1
  69. package/dist/data/ai/SessionChatComposer.d.ts +4 -1
  70. package/dist/data/ai/SessionChatComposer.d.ts.map +1 -1
  71. package/dist/data/ai/SessionChatComposer.js +3 -1
  72. package/dist/data/ai/SessionChatComposer.js.map +1 -1
  73. package/dist/data/ai/SessionInspector.cjs +68 -72
  74. package/dist/data/ai/SessionInspector.cjs.map +1 -1
  75. package/dist/data/ai/SessionInspector.composer-slot.cjs +8 -0
  76. package/dist/data/ai/SessionInspector.composer-slot.cjs.map +1 -0
  77. package/dist/data/ai/SessionInspector.composer-slot.d.ts +9 -0
  78. package/dist/data/ai/SessionInspector.composer-slot.d.ts.map +1 -0
  79. package/dist/data/ai/SessionInspector.composer-slot.js +8 -0
  80. package/dist/data/ai/SessionInspector.composer-slot.js.map +1 -0
  81. package/dist/data/ai/SessionInspector.d.ts +6 -1
  82. package/dist/data/ai/SessionInspector.d.ts.map +1 -1
  83. package/dist/data/ai/SessionInspector.js +69 -73
  84. package/dist/data/ai/SessionInspector.js.map +1 -1
  85. package/dist/data/ai/SessionInspector.legacy.cjs +41 -42
  86. package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -1
  87. package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -1
  88. package/dist/data/ai/SessionInspector.legacy.js +41 -42
  89. package/dist/data/ai/SessionInspector.legacy.js.map +1 -1
  90. package/dist/data/ai/SessionInspector.remote-view.cjs +14 -9
  91. package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -1
  92. package/dist/data/ai/SessionInspector.remote-view.d.ts +6 -2
  93. package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -1
  94. package/dist/data/ai/SessionInspector.remote-view.js +14 -9
  95. package/dist/data/ai/SessionInspector.remote-view.js.map +1 -1
  96. package/dist/data/ai/SessionInspector.remote.cjs +84 -16
  97. package/dist/data/ai/SessionInspector.remote.cjs.map +1 -1
  98. package/dist/data/ai/SessionInspector.remote.d.ts +42 -7
  99. package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -1
  100. package/dist/data/ai/SessionInspector.remote.js +86 -18
  101. package/dist/data/ai/SessionInspector.remote.js.map +1 -1
  102. package/dist/data/ai/SessionInspector.transcript.cjs +5 -0
  103. package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
  104. package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
  105. package/dist/data/ai/SessionInspector.transcript.js +5 -0
  106. package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
  107. package/dist/data/ai/SessionTail.cjs +63 -0
  108. package/dist/data/ai/SessionTail.cjs.map +1 -0
  109. package/dist/data/ai/SessionTail.d.ts +14 -0
  110. package/dist/data/ai/SessionTail.d.ts.map +1 -0
  111. package/dist/data/ai/SessionTail.js +63 -0
  112. package/dist/data/ai/SessionTail.js.map +1 -0
  113. package/dist/data/ai/SessionViewer.cjs +10 -3
  114. package/dist/data/ai/SessionViewer.cjs.map +1 -1
  115. package/dist/data/ai/SessionViewer.d.ts +7 -1
  116. package/dist/data/ai/SessionViewer.d.ts.map +1 -1
  117. package/dist/data/ai/SessionViewer.js +10 -3
  118. package/dist/data/ai/SessionViewer.js.map +1 -1
  119. package/dist/data/ai/SessionViewer.unified.d.ts +14 -0
  120. package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
  121. package/dist/data/ai/index.d.ts +4 -3
  122. package/dist/data/ai/index.d.ts.map +1 -1
  123. package/dist/data/ai/use-session-scroll.cjs +30 -6
  124. package/dist/data/ai/use-session-scroll.cjs.map +1 -1
  125. package/dist/data/ai/use-session-scroll.d.ts +7 -0
  126. package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
  127. package/dist/data/ai/use-session-scroll.js +30 -6
  128. package/dist/data/ai/use-session-scroll.js.map +1 -1
  129. package/dist/data/chat/Chat.cjs +1 -1
  130. package/dist/data/chat/Chat.cjs.map +1 -1
  131. package/dist/data/chat/Chat.js +1 -1
  132. package/dist/data/chat/Chat.js.map +1 -1
  133. package/dist/data/chat/ChatRuntimeToolbar.cjs +4 -4
  134. package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
  135. package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
  136. package/dist/data/chat/ChatRuntimeToolbar.js +4 -4
  137. package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
  138. package/dist/data/chat/PromptInput.cjs +4 -2
  139. package/dist/data/chat/PromptInput.cjs.map +1 -1
  140. package/dist/data/chat/PromptInput.d.ts +5 -1
  141. package/dist/data/chat/PromptInput.d.ts.map +1 -1
  142. package/dist/data/chat/PromptInput.js +4 -2
  143. package/dist/data/chat/PromptInput.js.map +1 -1
  144. package/dist/data/diagnostics/ErrorDetails.cjs +13 -2
  145. package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
  146. package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
  147. package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
  148. package/dist/data/diagnostics/ErrorDetails.js +14 -3
  149. package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
  150. package/dist/data/diagnostics/FrameSourceWindow.cjs +3 -2
  151. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  152. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  153. package/dist/data/diagnostics/FrameSourceWindow.js +3 -2
  154. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  155. package/dist/data/diagnostics/error-diagnostics.cjs +5 -0
  156. package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
  157. package/dist/data/diagnostics/error-diagnostics.d.ts +1 -0
  158. package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -1
  159. package/dist/data/diagnostics/error-diagnostics.js +6 -1
  160. package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
  161. package/dist/data/har/HarPanel.cjs +3 -1
  162. package/dist/data/har/HarPanel.cjs.map +1 -1
  163. package/dist/data/har/HarPanel.d.ts +4 -1
  164. package/dist/data/har/HarPanel.d.ts.map +1 -1
  165. package/dist/data/har/HarPanel.js +3 -1
  166. package/dist/data/har/HarPanel.js.map +1 -1
  167. package/dist/data/test-runner/Expectation.cjs +57 -0
  168. package/dist/data/test-runner/Expectation.cjs.map +1 -0
  169. package/dist/data/test-runner/Expectation.d.ts +19 -0
  170. package/dist/data/test-runner/Expectation.d.ts.map +1 -0
  171. package/dist/data/test-runner/Expectation.js +57 -0
  172. package/dist/data/test-runner/Expectation.js.map +1 -0
  173. package/dist/data/test-runner/MarkIcons.cjs +38 -0
  174. package/dist/data/test-runner/MarkIcons.cjs.map +1 -0
  175. package/dist/data/test-runner/MarkIcons.d.ts +15 -0
  176. package/dist/data/test-runner/MarkIcons.d.ts.map +1 -0
  177. package/dist/data/test-runner/MarkIcons.js +38 -0
  178. package/dist/data/test-runner/MarkIcons.js.map +1 -0
  179. package/dist/data/test-runner/TestDetailPanel.cjs +74 -42
  180. package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
  181. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
  182. package/dist/data/test-runner/TestDetailPanel.js +76 -44
  183. package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
  184. package/dist/data/test-runner/TestFailureDetail.cjs +23 -27
  185. package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
  186. package/dist/data/test-runner/TestFailureDetail.d.ts +2 -2
  187. package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
  188. package/dist/data/test-runner/TestFailureDetail.js +23 -27
  189. package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
  190. package/dist/data/test-runner/TestFilterBar.cjs +87 -93
  191. package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
  192. package/dist/data/test-runner/TestFilterBar.d.ts +3 -2
  193. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
  194. package/dist/data/test-runner/TestFilterBar.js +89 -95
  195. package/dist/data/test-runner/TestFilterBar.js.map +1 -1
  196. package/dist/data/test-runner/TestRunSummary.cjs +35 -21
  197. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  198. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  199. package/dist/data/test-runner/TestRunSummary.js +35 -21
  200. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  201. package/dist/data/test-runner/TestRunner.cjs +52 -30
  202. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  203. package/dist/data/test-runner/TestRunner.d.ts +3 -2
  204. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  205. package/dist/data/test-runner/TestRunner.js +52 -30
  206. package/dist/data/test-runner/TestRunner.js.map +1 -1
  207. package/dist/data/test-runner/TestTree.cjs +5 -2
  208. package/dist/data/test-runner/TestTree.cjs.map +1 -1
  209. package/dist/data/test-runner/TestTree.d.ts +5 -2
  210. package/dist/data/test-runner/TestTree.d.ts.map +1 -1
  211. package/dist/data/test-runner/TestTree.js +5 -2
  212. package/dist/data/test-runner/TestTree.js.map +1 -1
  213. package/dist/data/test-runner/TestTreeNode.cjs +27 -19
  214. package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
  215. package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
  216. package/dist/data/test-runner/TestTreeNode.js +28 -20
  217. package/dist/data/test-runner/TestTreeNode.js.map +1 -1
  218. package/dist/data/test-runner/adapter.cjs +11 -0
  219. package/dist/data/test-runner/adapter.cjs.map +1 -1
  220. package/dist/data/test-runner/adapter.d.ts +18 -7
  221. package/dist/data/test-runner/adapter.d.ts.map +1 -1
  222. package/dist/data/test-runner/adapter.js +11 -0
  223. package/dist/data/test-runner/adapter.js.map +1 -1
  224. package/dist/data/test-runner/copy.cjs +114 -0
  225. package/dist/data/test-runner/copy.cjs.map +1 -0
  226. package/dist/data/test-runner/copy.d.ts +47 -0
  227. package/dist/data/test-runner/copy.d.ts.map +1 -0
  228. package/dist/data/test-runner/copy.js +114 -0
  229. package/dist/data/test-runner/copy.js.map +1 -0
  230. package/dist/data/test-runner/index.d.ts +5 -2
  231. package/dist/data/test-runner/index.d.ts.map +1 -1
  232. package/dist/data/test-runner/marks.cjs +143 -0
  233. package/dist/data/test-runner/marks.cjs.map +1 -0
  234. package/dist/data/test-runner/marks.d.ts +30 -0
  235. package/dist/data/test-runner/marks.d.ts.map +1 -0
  236. package/dist/data/test-runner/marks.js +143 -0
  237. package/dist/data/test-runner/marks.js.map +1 -0
  238. package/dist/data/test-runner/status.cjs +27 -44
  239. package/dist/data/test-runner/status.cjs.map +1 -1
  240. package/dist/data/test-runner/status.d.ts +12 -3
  241. package/dist/data/test-runner/status.d.ts.map +1 -1
  242. package/dist/data/test-runner/status.js +27 -44
  243. package/dist/data/test-runner/status.js.map +1 -1
  244. package/dist/data/verification/adapterViews.cjs +16 -41
  245. package/dist/data/verification/adapterViews.cjs.map +1 -1
  246. package/dist/data/verification/adapterViews.d.ts.map +1 -1
  247. package/dist/data/verification/adapterViews.js +16 -41
  248. package/dist/data/verification/adapterViews.js.map +1 -1
  249. package/dist/data/verification/adapters.cjs +115 -3
  250. package/dist/data/verification/adapters.cjs.map +1 -1
  251. package/dist/data/verification/adapters.d.ts.map +1 -1
  252. package/dist/data/verification/adapters.js +115 -3
  253. package/dist/data/verification/adapters.js.map +1 -1
  254. package/dist/data/verification/verifyReportTests.cjs.map +1 -1
  255. package/dist/data/verification/verifyReportTests.js.map +1 -1
  256. package/dist/data/version-info.cjs +3 -3
  257. package/dist/data/version-info.js +3 -3
  258. package/dist/data.cjs +44 -3
  259. package/dist/data.cjs.map +1 -1
  260. package/dist/data.d.ts +2 -0
  261. package/dist/data.d.ts.map +1 -1
  262. package/dist/data.js +45 -4
  263. package/dist/data.js.map +1 -1
  264. package/dist/icons/components/UiLogoEslint.cjs +10 -0
  265. package/dist/icons/components/UiLogoEslint.cjs.map +1 -0
  266. package/dist/icons/components/UiLogoEslint.d.ts +9 -0
  267. package/dist/icons/components/UiLogoEslint.d.ts.map +1 -0
  268. package/dist/icons/components/UiLogoEslint.js +10 -0
  269. package/dist/icons/components/UiLogoEslint.js.map +1 -0
  270. package/dist/icons/components/UiLogoGo.cjs +10 -0
  271. package/dist/icons/components/UiLogoGo.cjs.map +1 -0
  272. package/dist/icons/components/UiLogoGo.d.ts +9 -0
  273. package/dist/icons/components/UiLogoGo.d.ts.map +1 -0
  274. package/dist/icons/components/UiLogoGo.js +10 -0
  275. package/dist/icons/components/UiLogoGo.js.map +1 -0
  276. package/dist/icons/components/UiLogoJest.cjs +10 -0
  277. package/dist/icons/components/UiLogoJest.cjs.map +1 -0
  278. package/dist/icons/components/UiLogoJest.d.ts +9 -0
  279. package/dist/icons/components/UiLogoJest.d.ts.map +1 -0
  280. package/dist/icons/components/UiLogoJest.js +10 -0
  281. package/dist/icons/components/UiLogoJest.js.map +1 -0
  282. package/dist/icons/components/UiLogoMarkdown.cjs +10 -0
  283. package/dist/icons/components/UiLogoMarkdown.cjs.map +1 -0
  284. package/dist/icons/components/UiLogoMarkdown.d.ts +9 -0
  285. package/dist/icons/components/UiLogoMarkdown.d.ts.map +1 -0
  286. package/dist/icons/components/UiLogoMarkdown.js +10 -0
  287. package/dist/icons/components/UiLogoMarkdown.js.map +1 -0
  288. package/dist/icons/components/UiLogoOxc.cjs +10 -0
  289. package/dist/icons/components/UiLogoOxc.cjs.map +1 -0
  290. package/dist/icons/components/UiLogoOxc.d.ts +9 -0
  291. package/dist/icons/components/UiLogoOxc.d.ts.map +1 -0
  292. package/dist/icons/components/UiLogoOxc.js +10 -0
  293. package/dist/icons/components/UiLogoOxc.js.map +1 -0
  294. package/dist/icons/components/UiLogoPlaywright.cjs +10 -0
  295. package/dist/icons/components/UiLogoPlaywright.cjs.map +1 -0
  296. package/dist/icons/components/UiLogoPlaywright.d.ts +9 -0
  297. package/dist/icons/components/UiLogoPlaywright.d.ts.map +1 -0
  298. package/dist/icons/components/UiLogoPlaywright.js +10 -0
  299. package/dist/icons/components/UiLogoPlaywright.js.map +1 -0
  300. package/dist/icons/components/UiLogoPython.cjs +10 -0
  301. package/dist/icons/components/UiLogoPython.cjs.map +1 -0
  302. package/dist/icons/components/UiLogoPython.d.ts +9 -0
  303. package/dist/icons/components/UiLogoPython.d.ts.map +1 -0
  304. package/dist/icons/components/UiLogoPython.js +10 -0
  305. package/dist/icons/components/UiLogoPython.js.map +1 -0
  306. package/dist/icons/components/UiLogoReact.cjs +10 -0
  307. package/dist/icons/components/UiLogoReact.cjs.map +1 -0
  308. package/dist/icons/components/UiLogoReact.d.ts +9 -0
  309. package/dist/icons/components/UiLogoReact.d.ts.map +1 -0
  310. package/dist/icons/components/UiLogoReact.js +10 -0
  311. package/dist/icons/components/UiLogoReact.js.map +1 -0
  312. package/dist/icons/components/UiLogoRuff.cjs +10 -0
  313. package/dist/icons/components/UiLogoRuff.cjs.map +1 -0
  314. package/dist/icons/components/UiLogoRuff.d.ts +9 -0
  315. package/dist/icons/components/UiLogoRuff.d.ts.map +1 -0
  316. package/dist/icons/components/UiLogoRuff.js +10 -0
  317. package/dist/icons/components/UiLogoRuff.js.map +1 -0
  318. package/dist/icons/components/UiLogoTypescript.cjs +10 -0
  319. package/dist/icons/components/UiLogoTypescript.cjs.map +1 -0
  320. package/dist/icons/components/UiLogoTypescript.d.ts +9 -0
  321. package/dist/icons/components/UiLogoTypescript.d.ts.map +1 -0
  322. package/dist/icons/components/UiLogoTypescript.js +10 -0
  323. package/dist/icons/components/UiLogoTypescript.js.map +1 -0
  324. package/dist/icons/components/UiLogoVitest.cjs +10 -0
  325. package/dist/icons/components/UiLogoVitest.cjs.map +1 -0
  326. package/dist/icons/components/UiLogoVitest.d.ts +9 -0
  327. package/dist/icons/components/UiLogoVitest.d.ts.map +1 -0
  328. package/dist/icons/components/UiLogoVitest.js +10 -0
  329. package/dist/icons/components/UiLogoVitest.js.map +1 -0
  330. package/dist/icons/index.d.ts +11 -0
  331. package/dist/icons/index.d.ts.map +1 -1
  332. package/dist/icons/registry.cjs +22 -0
  333. package/dist/icons/registry.cjs.map +1 -1
  334. package/dist/icons/registry.d.ts.map +1 -1
  335. package/dist/icons/registry.js +22 -0
  336. package/dist/icons/registry.js.map +1 -1
  337. package/dist/icons.cjs +22 -0
  338. package/dist/icons.cjs.map +1 -1
  339. package/dist/icons.js +22 -0
  340. package/dist/icons.js.map +1 -1
  341. package/dist/index.cjs +44 -3
  342. package/dist/index.cjs.map +1 -1
  343. package/dist/index.js +45 -4
  344. package/dist/index.js.map +1 -1
  345. package/dist/overlay/DropdownMenuSubmenu.cjs +4 -4
  346. package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
  347. package/dist/overlay/DropdownMenuSubmenu.js +4 -4
  348. package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
  349. package/dist/rpc/InlineError.cjs +12 -43
  350. package/dist/rpc/InlineError.cjs.map +1 -1
  351. package/dist/rpc/InlineError.d.ts.map +1 -1
  352. package/dist/rpc/InlineError.js +13 -44
  353. package/dist/rpc/InlineError.js.map +1 -1
  354. package/dist/rpc/OperationScheduleDialog.cjs +63 -10
  355. package/dist/rpc/OperationScheduleDialog.cjs.map +1 -1
  356. package/dist/rpc/OperationScheduleDialog.d.ts +4 -0
  357. package/dist/rpc/OperationScheduleDialog.d.ts.map +1 -1
  358. package/dist/rpc/OperationScheduleDialog.js +63 -10
  359. package/dist/rpc/OperationScheduleDialog.js.map +1 -1
  360. package/dist/rpc/OperationSchedules.cjs +12 -2
  361. package/dist/rpc/OperationSchedules.cjs.map +1 -1
  362. package/dist/rpc/OperationSchedules.d.ts.map +1 -1
  363. package/dist/rpc/OperationSchedules.js +12 -2
  364. package/dist/rpc/OperationSchedules.js.map +1 -1
  365. package/dist/rpc/operation-schedule-model.cjs +2 -0
  366. package/dist/rpc/operation-schedule-model.cjs.map +1 -1
  367. package/dist/rpc/operation-schedule-model.d.ts.map +1 -1
  368. package/dist/rpc/operation-schedule-model.js +2 -0
  369. package/dist/rpc/operation-schedule-model.js.map +1 -1
  370. package/dist/rpc/operation-schedule-types.d.ts +7 -1
  371. package/dist/rpc/operation-schedule-types.d.ts.map +1 -1
  372. package/dist/styles.css +1 -1
  373. package/package.json +1 -1
  374. package/dist/data/test-runner/frameworkIcon.cjs +0 -27
  375. package/dist/data/test-runner/frameworkIcon.cjs.map +0 -1
  376. package/dist/data/test-runner/frameworkIcon.d.ts +0 -3
  377. package/dist/data/test-runner/frameworkIcon.d.ts.map +0 -1
  378. package/dist/data/test-runner/frameworkIcon.js +0 -27
  379. package/dist/data/test-runner/frameworkIcon.js.map +0 -1
@@ -5,8 +5,9 @@ const Icon = require("../Icon.cjs");
5
5
  const ProgressBar = require("../ProgressBar.cjs");
6
6
  const utils = require("../../lib/utils.cjs");
7
7
  const status = require("./status.cjs");
8
+ const marks = require("./marks.cjs");
9
+ const MarkIcons = require("./MarkIcons.cjs");
8
10
  const UiClock = require("../../icons/components/UiClock.cjs");
9
- const UiCheck = require("../../icons/components/UiCheck.cjs");
10
11
  const UiLoader = require("../../icons/components/UiLoader.cjs");
11
12
  function pct(part, total) {
12
13
  return total > 0 ? Math.round(part / total * 100) : 0;
@@ -29,18 +30,37 @@ function TestRunSummary({
29
30
  { count: t.passed, color: "bg-green-500", label: "passed" },
30
31
  { count: t.skipped, color: "bg-yellow-400", label: "skipped" },
31
32
  { count: t.failed, color: "bg-red-500", label: "failed" },
33
+ { count: t.warned, color: "bg-amber-400", label: "warned" },
32
34
  { count: t.timedout, color: "bg-amber-500", label: "timed out" },
33
35
  { count: t.running, color: "bg-blue-400", label: "running" },
34
36
  { count: t.pending, color: "bg-muted-foreground/40", label: "queued" }
35
37
  ];
36
38
  const chips = [
37
- { n: t.passed, label: "passed", tone: "text-green-600 dark:text-green-400" },
38
- { n: t.failed, label: "failed", tone: "text-red-600 dark:text-red-400" },
39
- { n: t.timedout, label: "timed out", tone: "text-amber-600 dark:text-amber-400" },
40
- { n: t.skipped, label: "skipped", tone: "text-yellow-700 dark:text-yellow-500" },
41
- { n: t.running, label: "running", tone: "text-blue-600 dark:text-blue-400" },
42
- { n: t.pending, label: "queued", tone: "text-muted-foreground" }
39
+ { n: t.passed, label: "passed", outcome: "passed" },
40
+ { n: t.failed, label: "failed", outcome: "failed" },
41
+ { n: t.warned, label: "warned", outcome: "warned" },
42
+ { n: t.timedout, label: "timed out", outcome: "timedout" },
43
+ { n: t.skipped, label: "skipped", outcome: "skipped" },
44
+ { n: t.running, label: "running", outcome: "running" },
45
+ { n: t.pending, label: "queued", outcome: "pending" }
43
46
  ];
47
+ const chipRow = chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
48
+ "span",
49
+ {
50
+ className: utils.cn(
51
+ "inline-flex items-center gap-0.5 tabular-nums",
52
+ marks.TEST_OUTCOMES[c.outcome].className
53
+ ),
54
+ "aria-label": `${c.n} ${c.label}`,
55
+ title: `${c.n} ${c.label}`,
56
+ "data-summary-outcome": c.outcome,
57
+ children: [
58
+ /* @__PURE__ */ jsxRuntime.jsx(MarkIcons.OutcomeIcon, { outcome: c.outcome }),
59
+ c.n
60
+ ]
61
+ },
62
+ c.label
63
+ ));
44
64
  if (compact) {
45
65
  return /* @__PURE__ */ jsxRuntime.jsxs(
46
66
  "div",
@@ -52,14 +72,11 @@ function TestRunSummary({
52
72
  children: [
53
73
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
54
74
  t.total,
55
- " tests",
75
+ " ",
76
+ t.total === 1 ? "test" : "tests",
56
77
  (runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
57
78
  ] }),
58
- chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: c.tone, children: [
59
- c.n,
60
- " ",
61
- c.label
62
- ] }, c.label)),
79
+ chipRow,
63
80
  elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
64
81
  /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClock.UiClock, className: "text-xs" }),
65
82
  elapsed
@@ -71,7 +88,7 @@ function TestRunSummary({
71
88
  "%"
72
89
  ] })
73
90
  ] }),
74
- done ? /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiCheck.UiCheck, className: "text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiLoader.UiLoader, className: "animate-spin text-blue-500" })
91
+ !done && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiLoader.UiLoader, className: "animate-spin text-blue-500" })
75
92
  ]
76
93
  }
77
94
  );
@@ -80,19 +97,16 @@ function TestRunSummary({
80
97
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground", children: [
81
98
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
82
99
  t.total,
83
- " tests",
100
+ " ",
101
+ t.total === 1 ? "test" : "tests",
84
102
  (runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
85
103
  ] }),
86
- chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: c.tone, children: [
87
- c.n,
88
- " ",
89
- c.label
90
- ] }, c.label)),
104
+ chipRow,
91
105
  elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
92
106
  /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClock.UiClock, className: "text-xs" }),
93
107
  elapsed
94
108
  ] }),
95
- done ? /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiCheck.UiCheck, className: "text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiLoader.UiLoader, className: "animate-spin text-blue-500" })
109
+ !done && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiLoader.UiLoader, className: "animate-spin text-blue-500" })
96
110
  ] }),
97
111
  t.total > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-72 items-center gap-2", children: [
98
112
  /* @__PURE__ */ jsxRuntime.jsx(ProgressBar.ProgressBar, { className: "flex-1", segments, total: t.total, height: "h-2" }),
@@ -1 +1 @@
1
- {"version":3,"file":"TestRunSummary.cjs","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { ProgressBar, type ProgressSegment } from \"../ProgressBar\";\nimport { cn } from \"../../lib/utils\";\nimport { UiCheck, UiClock, UiLoader } from \"../../icons\";\nimport type { RunMeta, Test } from \"./types\";\nimport { aggregateStatusCounts } from \"./status\";\n\nexport type TestRunSummaryProps = {\n tests: Test[];\n /** Run start, epoch ms (host-provided). */\n startTime?: number | null | undefined;\n /** Run end, epoch ms; falls back to `now` while running. */\n endTime?: number | null | undefined;\n done: boolean;\n /** Injected clock (epoch ms) so the component stays pure. */\n now?: number | undefined;\n runMeta?: RunMeta | undefined;\n /**\n * Single-line layout for embedding in a host header (e.g. a dialog header):\n * counts + a short inline progress bar on one row, instead of the default\n * two-line right-aligned column.\n */\n compact?: boolean | undefined;\n className?: string | undefined;\n};\n\nfunction pct(part: number, total: number): number {\n return total > 0 ? Math.round((part / total) * 100) : 0;\n}\n\n/**\n * Header summary: per-status counts, elapsed time, a stacked progress bar, and\n * pass/fail/pending gauge cards. Pure — elapsed time comes from injected `now`.\n */\nexport function TestRunSummary({\n tests,\n startTime,\n endTime,\n done,\n now,\n runMeta,\n compact = false,\n className,\n}: TestRunSummaryProps) {\n const t = aggregateStatusCounts(tests);\n const clock = now ?? 0;\n const end = done && endTime ? endTime : clock;\n const elapsed = startTime && end >= startTime ? `${((end - startTime) / 1000).toFixed(1)}s` : \"\";\n\n const segments: ProgressSegment[] = [\n { count: t.passed, color: \"bg-green-500\", label: \"passed\" },\n { count: t.skipped, color: \"bg-yellow-400\", label: \"skipped\" },\n { count: t.failed, color: \"bg-red-500\", label: \"failed\" },\n { count: t.timedout, color: \"bg-amber-500\", label: \"timed out\" },\n { count: t.running, color: \"bg-blue-400\", label: \"running\" },\n { count: t.pending, color: \"bg-muted-foreground/40\", label: \"queued\" },\n ];\n\n // Each status appears once, as a coloured count chip — no separate gauge-card\n // row repeating the same numbers as percentages.\n const chips: { n: number; label: string; tone: string }[] = [\n { n: t.passed, label: \"passed\", tone: \"text-green-600 dark:text-green-400\" },\n { n: t.failed, label: \"failed\", tone: \"text-red-600 dark:text-red-400\" },\n { n: t.timedout, label: \"timed out\", tone: \"text-amber-600 dark:text-amber-400\" },\n { n: t.skipped, label: \"skipped\", tone: \"text-yellow-700 dark:text-yellow-500\" },\n { n: t.running, label: \"running\", tone: \"text-blue-600 dark:text-blue-400\" },\n { n: t.pending, label: \"queued\", tone: \"text-muted-foreground\" },\n ];\n\n if (compact) {\n return (\n <div\n className={cn(\n \"flex flex-wrap items-center gap-x-3 gap-y-0.5 text-sm text-muted-foreground\",\n className,\n )}\n >\n <span className=\"font-medium text-foreground\">\n {t.total} tests\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span key={c.label} className={c.tone}>\n {c.n} {c.label}\n </span>\n ))}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {t.total > 0 && (\n <span className=\"inline-flex items-center gap-1.5\">\n <ProgressBar className=\"w-24\" segments={segments} total={t.total} height=\"h-1.5\" />\n <span className=\"text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </span>\n )}\n {done ? (\n <Icon icon={UiCheck} className=\"text-green-600 dark:text-green-400\" />\n ) : (\n <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />\n )}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-w-[18rem] flex-col items-end gap-1.5\", className)}>\n <div className=\"flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {t.total} tests\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span key={c.label} className={c.tone}>\n {c.n} {c.label}\n </span>\n ))}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {done ? (\n <Icon icon={UiCheck} className=\"text-green-600 dark:text-green-400\" />\n ) : (\n <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />\n )}\n </div>\n\n {t.total > 0 && (\n <div className=\"flex w-72 items-center gap-2\">\n <ProgressBar className=\"flex-1\" segments={segments} total={t.total} height=\"h-2\" />\n <span className=\"shrink-0 text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":["aggregateStatusCounts","jsxs","cn","jsx","Icon","UiClock","ProgressBar","UiCheck","UiLoader"],"mappings":"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"}
1
+ {"version":3,"file":"TestRunSummary.cjs","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { ProgressBar, type ProgressSegment } from \"../ProgressBar\";\nimport { cn } from \"../../lib/utils\";\nimport { UiClock, UiLoader } from \"../../icons\";\nimport type { RunMeta, Test } from \"./types\";\nimport { aggregateStatusCounts, type TestOutcome } from \"./status\";\nimport { TEST_OUTCOMES } from \"./marks\";\nimport { OutcomeIcon } from \"./MarkIcons\";\n\nexport type TestRunSummaryProps = {\n tests: Test[];\n /** Run start, epoch ms (host-provided). */\n startTime?: number | null | undefined;\n /** Run end, epoch ms; falls back to `now` while running. */\n endTime?: number | null | undefined;\n done: boolean;\n /** Injected clock (epoch ms) so the component stays pure. */\n now?: number | undefined;\n runMeta?: RunMeta | undefined;\n /**\n * Single-line layout for embedding in a host header (e.g. a dialog header):\n * counts + a short inline progress bar on one row, instead of the default\n * two-line right-aligned column.\n */\n compact?: boolean | undefined;\n className?: string | undefined;\n};\n\nfunction pct(part: number, total: number): number {\n return total > 0 ? Math.round((part / total) * 100) : 0;\n}\n\n/**\n * Header summary: per-status counts, elapsed time, a stacked progress bar, and\n * pass/fail/pending gauge cards. Pure — elapsed time comes from injected `now`.\n */\nexport function TestRunSummary({\n tests,\n startTime,\n endTime,\n done,\n now,\n runMeta,\n compact = false,\n className,\n}: TestRunSummaryProps) {\n const t = aggregateStatusCounts(tests);\n const clock = now ?? 0;\n const end = done && endTime ? endTime : clock;\n const elapsed = startTime && end >= startTime ? `${((end - startTime) / 1000).toFixed(1)}s` : \"\";\n\n const segments: ProgressSegment[] = [\n { count: t.passed, color: \"bg-green-500\", label: \"passed\" },\n { count: t.skipped, color: \"bg-yellow-400\", label: \"skipped\" },\n { count: t.failed, color: \"bg-red-500\", label: \"failed\" },\n { count: t.warned, color: \"bg-amber-400\", label: \"warned\" },\n { count: t.timedout, color: \"bg-amber-500\", label: \"timed out\" },\n { count: t.running, color: \"bg-blue-400\", label: \"running\" },\n { count: t.pending, color: \"bg-muted-foreground/40\", label: \"queued\" },\n ];\n\n // Each status appears once, as its outcome mark and a count — the same\n // glyphs the tree uses, so the header reads in the tree's vocabulary.\n const chips: { n: number; label: string; outcome: TestOutcome }[] = [\n { n: t.passed, label: \"passed\", outcome: \"passed\" },\n { n: t.failed, label: \"failed\", outcome: \"failed\" },\n { n: t.warned, label: \"warned\", outcome: \"warned\" },\n { n: t.timedout, label: \"timed out\", outcome: \"timedout\" },\n { n: t.skipped, label: \"skipped\", outcome: \"skipped\" },\n { n: t.running, label: \"running\", outcome: \"running\" },\n { n: t.pending, label: \"queued\", outcome: \"pending\" },\n ];\n const chipRow = chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span\n key={c.label}\n className={cn(\n \"inline-flex items-center gap-0.5 tabular-nums\",\n TEST_OUTCOMES[c.outcome].className,\n )}\n aria-label={`${c.n} ${c.label}`}\n title={`${c.n} ${c.label}`}\n data-summary-outcome={c.outcome}\n >\n <OutcomeIcon outcome={c.outcome} />\n {c.n}\n </span>\n ));\n\n if (compact) {\n return (\n <div\n className={cn(\n \"flex flex-wrap items-center gap-x-3 gap-y-0.5 text-sm text-muted-foreground\",\n className,\n )}\n >\n <span className=\"font-medium text-foreground\">\n {t.total} {t.total === 1 ? \"test\" : \"tests\"}\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chipRow}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {t.total > 0 && (\n <span className=\"inline-flex items-center gap-1.5\">\n <ProgressBar className=\"w-24\" segments={segments} total={t.total} height=\"h-1.5\" />\n <span className=\"text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </span>\n )}\n {!done && <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-w-[18rem] flex-col items-end gap-1.5\", className)}>\n <div className=\"flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {t.total} {t.total === 1 ? \"test\" : \"tests\"}\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chipRow}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {!done && <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />}\n </div>\n\n {t.total > 0 && (\n <div className=\"flex w-72 items-center gap-2\">\n <ProgressBar className=\"flex-1\" segments={segments} total={t.total} height=\"h-2\" />\n <span className=\"shrink-0 text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":["aggregateStatusCounts","jsxs","cn","TEST_OUTCOMES","jsx","OutcomeIcon","Icon","UiClock","ProgressBar","UiLoader"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TestRunSummary.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAMF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,SAAS,EACT,OAAO,EACP,IAAI,EACJ,GAAG,EACH,OAAO,EACP,OAAe,EACf,SAAS,GACV,EAAE,mBAAmB,+BAyGrB"}
1
+ {"version":3,"file":"TestRunSummary.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAK7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAMF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,SAAS,EACT,OAAO,EACP,IAAI,EACJ,GAAG,EACH,OAAO,EACP,OAAe,EACf,SAAS,GACV,EAAE,mBAAmB,+BAwGrB"}
@@ -3,8 +3,9 @@ import { Icon } from "../Icon.js";
3
3
  import { ProgressBar } from "../ProgressBar.js";
4
4
  import { cn } from "../../lib/utils.js";
5
5
  import { aggregateStatusCounts } from "./status.js";
6
+ import { TEST_OUTCOMES } from "./marks.js";
7
+ import { OutcomeIcon } from "./MarkIcons.js";
6
8
  import { UiClock } from "../../icons/components/UiClock.js";
7
- import { UiCheck } from "../../icons/components/UiCheck.js";
8
9
  import { UiLoader } from "../../icons/components/UiLoader.js";
9
10
  function pct(part, total) {
10
11
  return total > 0 ? Math.round(part / total * 100) : 0;
@@ -27,18 +28,37 @@ function TestRunSummary({
27
28
  { count: t.passed, color: "bg-green-500", label: "passed" },
28
29
  { count: t.skipped, color: "bg-yellow-400", label: "skipped" },
29
30
  { count: t.failed, color: "bg-red-500", label: "failed" },
31
+ { count: t.warned, color: "bg-amber-400", label: "warned" },
30
32
  { count: t.timedout, color: "bg-amber-500", label: "timed out" },
31
33
  { count: t.running, color: "bg-blue-400", label: "running" },
32
34
  { count: t.pending, color: "bg-muted-foreground/40", label: "queued" }
33
35
  ];
34
36
  const chips = [
35
- { n: t.passed, label: "passed", tone: "text-green-600 dark:text-green-400" },
36
- { n: t.failed, label: "failed", tone: "text-red-600 dark:text-red-400" },
37
- { n: t.timedout, label: "timed out", tone: "text-amber-600 dark:text-amber-400" },
38
- { n: t.skipped, label: "skipped", tone: "text-yellow-700 dark:text-yellow-500" },
39
- { n: t.running, label: "running", tone: "text-blue-600 dark:text-blue-400" },
40
- { n: t.pending, label: "queued", tone: "text-muted-foreground" }
37
+ { n: t.passed, label: "passed", outcome: "passed" },
38
+ { n: t.failed, label: "failed", outcome: "failed" },
39
+ { n: t.warned, label: "warned", outcome: "warned" },
40
+ { n: t.timedout, label: "timed out", outcome: "timedout" },
41
+ { n: t.skipped, label: "skipped", outcome: "skipped" },
42
+ { n: t.running, label: "running", outcome: "running" },
43
+ { n: t.pending, label: "queued", outcome: "pending" }
41
44
  ];
45
+ const chipRow = chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxs(
46
+ "span",
47
+ {
48
+ className: cn(
49
+ "inline-flex items-center gap-0.5 tabular-nums",
50
+ TEST_OUTCOMES[c.outcome].className
51
+ ),
52
+ "aria-label": `${c.n} ${c.label}`,
53
+ title: `${c.n} ${c.label}`,
54
+ "data-summary-outcome": c.outcome,
55
+ children: [
56
+ /* @__PURE__ */ jsx(OutcomeIcon, { outcome: c.outcome }),
57
+ c.n
58
+ ]
59
+ },
60
+ c.label
61
+ ));
42
62
  if (compact) {
43
63
  return /* @__PURE__ */ jsxs(
44
64
  "div",
@@ -50,14 +70,11 @@ function TestRunSummary({
50
70
  children: [
51
71
  /* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
52
72
  t.total,
53
- " tests",
73
+ " ",
74
+ t.total === 1 ? "test" : "tests",
54
75
  (runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
55
76
  ] }),
56
- chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxs("span", { className: c.tone, children: [
57
- c.n,
58
- " ",
59
- c.label
60
- ] }, c.label)),
77
+ chipRow,
61
78
  elapsed && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
62
79
  /* @__PURE__ */ jsx(Icon, { icon: UiClock, className: "text-xs" }),
63
80
  elapsed
@@ -69,7 +86,7 @@ function TestRunSummary({
69
86
  "%"
70
87
  ] })
71
88
  ] }),
72
- done ? /* @__PURE__ */ jsx(Icon, { icon: UiCheck, className: "text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx(Icon, { icon: UiLoader, className: "animate-spin text-blue-500" })
89
+ !done && /* @__PURE__ */ jsx(Icon, { icon: UiLoader, className: "animate-spin text-blue-500" })
73
90
  ]
74
91
  }
75
92
  );
@@ -78,19 +95,16 @@ function TestRunSummary({
78
95
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground", children: [
79
96
  /* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
80
97
  t.total,
81
- " tests",
98
+ " ",
99
+ t.total === 1 ? "test" : "tests",
82
100
  (runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
83
101
  ] }),
84
- chips.filter((c) => c.n > 0).map((c) => /* @__PURE__ */ jsxs("span", { className: c.tone, children: [
85
- c.n,
86
- " ",
87
- c.label
88
- ] }, c.label)),
102
+ chipRow,
89
103
  elapsed && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
90
104
  /* @__PURE__ */ jsx(Icon, { icon: UiClock, className: "text-xs" }),
91
105
  elapsed
92
106
  ] }),
93
- done ? /* @__PURE__ */ jsx(Icon, { icon: UiCheck, className: "text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx(Icon, { icon: UiLoader, className: "animate-spin text-blue-500" })
107
+ !done && /* @__PURE__ */ jsx(Icon, { icon: UiLoader, className: "animate-spin text-blue-500" })
94
108
  ] }),
95
109
  t.total > 0 && /* @__PURE__ */ jsxs("div", { className: "flex w-72 items-center gap-2", children: [
96
110
  /* @__PURE__ */ jsx(ProgressBar, { className: "flex-1", segments, total: t.total, height: "h-2" }),
@@ -1 +1 @@
1
- {"version":3,"file":"TestRunSummary.js","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { ProgressBar, type ProgressSegment } from \"../ProgressBar\";\nimport { cn } from \"../../lib/utils\";\nimport { UiCheck, UiClock, UiLoader } from \"../../icons\";\nimport type { RunMeta, Test } from \"./types\";\nimport { aggregateStatusCounts } from \"./status\";\n\nexport type TestRunSummaryProps = {\n tests: Test[];\n /** Run start, epoch ms (host-provided). */\n startTime?: number | null | undefined;\n /** Run end, epoch ms; falls back to `now` while running. */\n endTime?: number | null | undefined;\n done: boolean;\n /** Injected clock (epoch ms) so the component stays pure. */\n now?: number | undefined;\n runMeta?: RunMeta | undefined;\n /**\n * Single-line layout for embedding in a host header (e.g. a dialog header):\n * counts + a short inline progress bar on one row, instead of the default\n * two-line right-aligned column.\n */\n compact?: boolean | undefined;\n className?: string | undefined;\n};\n\nfunction pct(part: number, total: number): number {\n return total > 0 ? Math.round((part / total) * 100) : 0;\n}\n\n/**\n * Header summary: per-status counts, elapsed time, a stacked progress bar, and\n * pass/fail/pending gauge cards. Pure — elapsed time comes from injected `now`.\n */\nexport function TestRunSummary({\n tests,\n startTime,\n endTime,\n done,\n now,\n runMeta,\n compact = false,\n className,\n}: TestRunSummaryProps) {\n const t = aggregateStatusCounts(tests);\n const clock = now ?? 0;\n const end = done && endTime ? endTime : clock;\n const elapsed = startTime && end >= startTime ? `${((end - startTime) / 1000).toFixed(1)}s` : \"\";\n\n const segments: ProgressSegment[] = [\n { count: t.passed, color: \"bg-green-500\", label: \"passed\" },\n { count: t.skipped, color: \"bg-yellow-400\", label: \"skipped\" },\n { count: t.failed, color: \"bg-red-500\", label: \"failed\" },\n { count: t.timedout, color: \"bg-amber-500\", label: \"timed out\" },\n { count: t.running, color: \"bg-blue-400\", label: \"running\" },\n { count: t.pending, color: \"bg-muted-foreground/40\", label: \"queued\" },\n ];\n\n // Each status appears once, as a coloured count chip — no separate gauge-card\n // row repeating the same numbers as percentages.\n const chips: { n: number; label: string; tone: string }[] = [\n { n: t.passed, label: \"passed\", tone: \"text-green-600 dark:text-green-400\" },\n { n: t.failed, label: \"failed\", tone: \"text-red-600 dark:text-red-400\" },\n { n: t.timedout, label: \"timed out\", tone: \"text-amber-600 dark:text-amber-400\" },\n { n: t.skipped, label: \"skipped\", tone: \"text-yellow-700 dark:text-yellow-500\" },\n { n: t.running, label: \"running\", tone: \"text-blue-600 dark:text-blue-400\" },\n { n: t.pending, label: \"queued\", tone: \"text-muted-foreground\" },\n ];\n\n if (compact) {\n return (\n <div\n className={cn(\n \"flex flex-wrap items-center gap-x-3 gap-y-0.5 text-sm text-muted-foreground\",\n className,\n )}\n >\n <span className=\"font-medium text-foreground\">\n {t.total} tests\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span key={c.label} className={c.tone}>\n {c.n} {c.label}\n </span>\n ))}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {t.total > 0 && (\n <span className=\"inline-flex items-center gap-1.5\">\n <ProgressBar className=\"w-24\" segments={segments} total={t.total} height=\"h-1.5\" />\n <span className=\"text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </span>\n )}\n {done ? (\n <Icon icon={UiCheck} className=\"text-green-600 dark:text-green-400\" />\n ) : (\n <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />\n )}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-w-[18rem] flex-col items-end gap-1.5\", className)}>\n <div className=\"flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {t.total} tests\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span key={c.label} className={c.tone}>\n {c.n} {c.label}\n </span>\n ))}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {done ? (\n <Icon icon={UiCheck} className=\"text-green-600 dark:text-green-400\" />\n ) : (\n <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />\n )}\n </div>\n\n {t.total > 0 && (\n <div className=\"flex w-72 items-center gap-2\">\n <ProgressBar className=\"flex-1\" segments={segments} total={t.total} height=\"h-2\" />\n <span className=\"shrink-0 text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestRunSummary.js","sources":["../../../src/data/test-runner/TestRunSummary.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { ProgressBar, type ProgressSegment } from \"../ProgressBar\";\nimport { cn } from \"../../lib/utils\";\nimport { UiClock, UiLoader } from \"../../icons\";\nimport type { RunMeta, Test } from \"./types\";\nimport { aggregateStatusCounts, type TestOutcome } from \"./status\";\nimport { TEST_OUTCOMES } from \"./marks\";\nimport { OutcomeIcon } from \"./MarkIcons\";\n\nexport type TestRunSummaryProps = {\n tests: Test[];\n /** Run start, epoch ms (host-provided). */\n startTime?: number | null | undefined;\n /** Run end, epoch ms; falls back to `now` while running. */\n endTime?: number | null | undefined;\n done: boolean;\n /** Injected clock (epoch ms) so the component stays pure. */\n now?: number | undefined;\n runMeta?: RunMeta | undefined;\n /**\n * Single-line layout for embedding in a host header (e.g. a dialog header):\n * counts + a short inline progress bar on one row, instead of the default\n * two-line right-aligned column.\n */\n compact?: boolean | undefined;\n className?: string | undefined;\n};\n\nfunction pct(part: number, total: number): number {\n return total > 0 ? Math.round((part / total) * 100) : 0;\n}\n\n/**\n * Header summary: per-status counts, elapsed time, a stacked progress bar, and\n * pass/fail/pending gauge cards. Pure — elapsed time comes from injected `now`.\n */\nexport function TestRunSummary({\n tests,\n startTime,\n endTime,\n done,\n now,\n runMeta,\n compact = false,\n className,\n}: TestRunSummaryProps) {\n const t = aggregateStatusCounts(tests);\n const clock = now ?? 0;\n const end = done && endTime ? endTime : clock;\n const elapsed = startTime && end >= startTime ? `${((end - startTime) / 1000).toFixed(1)}s` : \"\";\n\n const segments: ProgressSegment[] = [\n { count: t.passed, color: \"bg-green-500\", label: \"passed\" },\n { count: t.skipped, color: \"bg-yellow-400\", label: \"skipped\" },\n { count: t.failed, color: \"bg-red-500\", label: \"failed\" },\n { count: t.warned, color: \"bg-amber-400\", label: \"warned\" },\n { count: t.timedout, color: \"bg-amber-500\", label: \"timed out\" },\n { count: t.running, color: \"bg-blue-400\", label: \"running\" },\n { count: t.pending, color: \"bg-muted-foreground/40\", label: \"queued\" },\n ];\n\n // Each status appears once, as its outcome mark and a count — the same\n // glyphs the tree uses, so the header reads in the tree's vocabulary.\n const chips: { n: number; label: string; outcome: TestOutcome }[] = [\n { n: t.passed, label: \"passed\", outcome: \"passed\" },\n { n: t.failed, label: \"failed\", outcome: \"failed\" },\n { n: t.warned, label: \"warned\", outcome: \"warned\" },\n { n: t.timedout, label: \"timed out\", outcome: \"timedout\" },\n { n: t.skipped, label: \"skipped\", outcome: \"skipped\" },\n { n: t.running, label: \"running\", outcome: \"running\" },\n { n: t.pending, label: \"queued\", outcome: \"pending\" },\n ];\n const chipRow = chips\n .filter((c) => c.n > 0)\n .map((c) => (\n <span\n key={c.label}\n className={cn(\n \"inline-flex items-center gap-0.5 tabular-nums\",\n TEST_OUTCOMES[c.outcome].className,\n )}\n aria-label={`${c.n} ${c.label}`}\n title={`${c.n} ${c.label}`}\n data-summary-outcome={c.outcome}\n >\n <OutcomeIcon outcome={c.outcome} />\n {c.n}\n </span>\n ));\n\n if (compact) {\n return (\n <div\n className={cn(\n \"flex flex-wrap items-center gap-x-3 gap-y-0.5 text-sm text-muted-foreground\",\n className,\n )}\n >\n <span className=\"font-medium text-foreground\">\n {t.total} {t.total === 1 ? \"test\" : \"tests\"}\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chipRow}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {t.total > 0 && (\n <span className=\"inline-flex items-center gap-1.5\">\n <ProgressBar className=\"w-24\" segments={segments} total={t.total} height=\"h-1.5\" />\n <span className=\"text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </span>\n )}\n {!done && <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-w-[18rem] flex-col items-end gap-1.5\", className)}>\n <div className=\"flex flex-wrap items-center justify-end gap-x-3 gap-y-0.5 text-sm text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {t.total} {t.total === 1 ? \"test\" : \"tests\"}\n {runMeta?.kind === \"rerun\" ? ` · rerun #${runMeta.sequence}` : \"\"}\n </span>\n {chipRow}\n {elapsed && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {elapsed}\n </span>\n )}\n {!done && <Icon icon={UiLoader} className=\"animate-spin text-blue-500\" />}\n </div>\n\n {t.total > 0 && (\n <div className=\"flex w-72 items-center gap-2\">\n <ProgressBar className=\"flex-1\" segments={segments} total={t.total} height=\"h-2\" />\n <span className=\"shrink-0 text-xs font-medium text-green-600 dark:text-green-400\">\n {pct(t.passed, t.total)}%\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ const react = require("react");
5
5
  const Icon = require("../Icon.cjs");
6
6
  const SplitPane = require("../../layout/SplitPane.cjs");
7
7
  const utils = require("../../lib/utils.cjs");
8
+ const useContainerWidth = require("../../hooks/use-container-width.cjs");
8
9
  const status = require("./status.cjs");
9
10
  const adapter = require("./adapter.cjs");
10
11
  const context = require("./context.cjs");
@@ -13,10 +14,12 @@ const TestDetailPanel = require("./TestDetailPanel.cjs");
13
14
  const TestRunSummary = require("./TestRunSummary.cjs");
14
15
  const TestFilterBar = require("./TestFilterBar.cjs");
15
16
  const UiBeaker = require("../../icons/components/UiBeaker.cjs");
17
+ const UiArrowLeft = require("../../icons/components/UiArrowLeft.cjs");
16
18
  function toRegistry(adapters) {
17
19
  if (adapters instanceof adapter.TestNodeAdapterRegistry) return adapters;
18
20
  return adapter.createTestRunnerRegistry(adapters ?? []);
19
21
  }
22
+ const SPLIT_MIN_WIDTH = 640;
20
23
  function TestRunner({
21
24
  tests,
22
25
  allTests,
@@ -90,19 +93,30 @@ function TestRunner({
90
93
  const summaryTests = allTests ?? tests;
91
94
  const frameworks = react.useMemo(() => status.collectFrameworks(summaryTests), [summaryTests]);
92
95
  const filterCounts = react.useMemo(() => status.aggregateStatusCounts(summaryTests), [summaryTests]);
93
- const hasContent = summaryTests.length > 0;
94
- return /* @__PURE__ */ jsxRuntime.jsx(context.TestRunnerProvider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex h-full min-h-0 flex-col bg-background", className), children: [
95
- !hideHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border bg-card px-density-4 py-density-3", children: [
96
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
97
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
98
- title === void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "inline-flex items-center gap-1.5 text-lg font-bold", children: [
99
- /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiBeaker.UiBeaker, className: "text-primary" }),
100
- "Test Results"
101
- ] }) : title,
102
- statusText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: statusText })
103
- ] }),
104
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
105
- headerSlot,
96
+ const filterBar = !hideHeader && summaryTests.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
97
+ TestFilterBar.TestFilterBar,
98
+ {
99
+ filters,
100
+ onChange: onFiltersChange,
101
+ counts: filterCounts,
102
+ frameworks
103
+ }
104
+ ) : null;
105
+ const { ref, wider: roomy } = useContainerWidth.useContainerWiderThan(SPLIT_MIN_WIDTH);
106
+ return /* @__PURE__ */ jsxRuntime.jsx(context.TestRunnerProvider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: utils.cn("flex h-full min-h-0 flex-col bg-background", className), children: [
107
+ !hideHeader && /* @__PURE__ */ jsxRuntime.jsxs(
108
+ "div",
109
+ {
110
+ className: "flex min-w-0 items-center gap-3 border-b border-border bg-card px-density-4 py-density-2",
111
+ "data-runner-header": "",
112
+ children: [
113
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
114
+ title === void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "inline-flex shrink-0 items-center gap-1.5 text-base font-bold", children: [
115
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiBeaker.UiBeaker, className: "text-primary" }),
116
+ "Test Results"
117
+ ] }) : title,
118
+ statusText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm text-muted-foreground", children: statusText })
119
+ ] }),
106
120
  showSummary && /* @__PURE__ */ jsxRuntime.jsx(
107
121
  TestRunSummary.TestRunSummary,
108
122
  {
@@ -111,22 +125,16 @@ function TestRunner({
111
125
  endTime,
112
126
  done,
113
127
  now,
114
- runMeta
128
+ runMeta,
129
+ compact: true,
130
+ className: "ml-auto flex-nowrap"
115
131
  }
116
- )
117
- ] })
118
- ] }),
119
- hasContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
120
- TestFilterBar.TestFilterBar,
121
- {
122
- filters,
123
- onChange: onFiltersChange,
124
- counts: filterCounts,
125
- frameworks
126
- }
127
- ) })
128
- ] }),
129
- /* @__PURE__ */ jsxRuntime.jsx(
132
+ ),
133
+ headerSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("flex shrink-0 items-center gap-1", !showSummary && "ml-auto"), children: headerSlot })
134
+ ]
135
+ }
136
+ ),
137
+ roomy ? /* @__PURE__ */ jsxRuntime.jsx(
130
138
  SplitPane.SplitPane,
131
139
  {
132
140
  className: "min-h-0 flex-1",
@@ -134,10 +142,24 @@ function TestRunner({
134
142
  minLeft: 25,
135
143
  minRight: 30,
136
144
  leftClass: "border-r-2 border-border bg-muted/30",
137
- left: /* @__PURE__ */ jsxRuntime.jsx(TestTree.TestTree, {}),
145
+ left: /* @__PURE__ */ jsxRuntime.jsx(TestTree.TestTree, { actions: filterBar }),
138
146
  right: /* @__PURE__ */ jsxRuntime.jsx(TestDetailPanel.TestDetailPanel, {})
139
147
  }
140
- )
148
+ ) : selected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
149
+ /* @__PURE__ */ jsxRuntime.jsxs(
150
+ "button",
151
+ {
152
+ type: "button",
153
+ onClick: () => onSelect(null),
154
+ className: "inline-flex items-center gap-1.5 border-b border-border px-density-3 py-density-2 text-left text-sm text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
155
+ children: [
156
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiArrowLeft.UiArrowLeft }),
157
+ "Back to results"
158
+ ]
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(TestDetailPanel.TestDetailPanel, {}) })
162
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(TestTree.TestTree, { actions: filterBar }) })
141
163
  ] }) });
142
164
  }
143
165
  exports.TestRunner = TestRunner;
@@ -1 +1 @@
1
- {"version":3,"file":"TestRunner.cjs","sources":["../../../src/data/test-runner/TestRunner.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { cn } from \"../../lib/utils\";\nimport { UiBeaker } from \"../../icons\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport { aggregateStatusCounts, collectFrameworks } from \"./status\";\nimport { type TestFilters } from \"./filterState\";\nimport {\n createTestRunnerRegistry,\n type TestNodeAdapter,\n TestNodeAdapterRegistry,\n} from \"./adapter\";\nimport { TestRunnerProvider, type TestRunnerContext } from \"./context\";\nimport { TestTree } from \"./TestTree\";\nimport { TestDetailPanel } from \"./TestDetailPanel\";\nimport { TestRunSummary } from \"./TestRunSummary\";\nimport { TestFilterBar } from \"./TestFilterBar\";\n\nexport type TestRunnerProps = {\n tests: Test[];\n /**\n * The full, unfiltered forest driving the filter bar's pills/counts and the\n * header summary — falls back to `tests` when omitted (every existing\n * caller pre-filters `tests` itself). Pass this explicitly when `tests` is a\n * filtered subset of a larger report, so toggling a status filter (e.g.\n * excluding the only failed node) can't make its own pill — or the whole\n * filter bar, once every pill's count reads zero — disappear.\n */\n allTests?: Test[];\n selected: Test | null;\n filters: TestFilters;\n expandAll: boolean | null;\n done: boolean;\n runMeta?: RunMeta;\n status?: SnapshotStatus;\n /** Free-form status line shown next to the title (e.g. \"Running tests...\"). */\n statusText?: string;\n now?: number;\n busy?: { rerun?: boolean; stop?: boolean };\n\n /** Controlled active detail-tab id; omit to let the detail pane own tab state. */\n activeTab?: string;\n /** Called with the picked tab id when `activeTab` is controlled. */\n onTabChange?: (tabId: string) => void;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n onRerun?: (node: Test) => void;\n onStop?: (node: Test) => void;\n\n /** Domain node adapters, or a pre-built registry. Defaults to default-only. */\n adapters?: TestNodeAdapter[] | TestNodeAdapterRegistry;\n /**\n * Header title. Defaults (when omitted) to the \"Test Results\" beaker heading.\n * Pass `null` to render no title — e.g. a host that owns the title in its own\n * dialog/page header and embeds the runner below it.\n */\n title?: ReactNode;\n /**\n * Render the built-in run summary (counts + progress) in the header. Defaults\n * to true; pass false when the host shows the summary itself (e.g. in a dialog\n * header) to avoid duplicating it.\n */\n showSummary?: boolean;\n /** Extra header content (e.g. export/download controls owned by the host). */\n headerSlot?: ReactNode;\n /**\n * Suppresses the entire built-in header bar (title, summary, filter row).\n * Defaults to false; pass true when a host renders its own combined header\n * (e.g. a dialog header that already embeds `TestRunSummary` and filters) so\n * the runner doesn't render a second bordered bar underneath it.\n */\n hideHeader?: boolean;\n /** Initial left-pane width percentage. */\n defaultSplit?: number;\n startTime?: number | null;\n endTime?: number | null;\n className?: string;\n};\n\nfunction toRegistry(\n adapters: TestNodeAdapter[] | TestNodeAdapterRegistry | undefined,\n): TestNodeAdapterRegistry {\n if (adapters instanceof TestNodeAdapterRegistry) return adapters;\n return createTestRunnerRegistry(adapters ?? []);\n}\n\n/**\n * Top-level, pure-presentational test runner: a summary/filter header over a\n * resizable tree + detail split. All data and handlers flow in via props and\n * are exposed to sub-components through a single `TestRunnerContext`. Domain\n * rendering is pluggable via node adapters; no fetch/SSE/routing lives here.\n */\nexport function TestRunner({\n tests,\n allTests,\n selected,\n filters,\n expandAll,\n done,\n runMeta,\n status,\n statusText,\n now,\n busy,\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n adapters,\n title,\n showSummary = true,\n headerSlot,\n hideHeader = false,\n defaultSplit = 45,\n startTime,\n endTime,\n className,\n}: TestRunnerProps) {\n const registry = useMemo(() => toRegistry(adapters), [adapters]);\n\n const ctx: TestRunnerContext = useMemo(\n () => ({\n tests,\n selected,\n runMeta,\n status,\n done,\n now,\n filters,\n expandAll,\n busy: busy ?? {},\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n adapters: registry,\n }),\n [\n tests,\n selected,\n runMeta,\n status,\n done,\n now,\n filters,\n expandAll,\n busy,\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n registry,\n ],\n );\n\n const summaryTests = allTests ?? tests;\n const frameworks = useMemo(() => collectFrameworks(summaryTests), [summaryTests]);\n const filterCounts = useMemo(() => aggregateStatusCounts(summaryTests), [summaryTests]);\n const hasContent = summaryTests.length > 0;\n\n return (\n <TestRunnerProvider value={ctx}>\n <div className={cn(\"flex h-full min-h-0 flex-col bg-background\", className)}>\n {!hideHeader && (\n <div className=\"border-b border-border bg-card px-density-4 py-density-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n {title === undefined ? (\n <h1 className=\"inline-flex items-center gap-1.5 text-lg font-bold\">\n <Icon icon={UiBeaker} className=\"text-primary\" />\n Test Results\n </h1>\n ) : (\n title\n )}\n {statusText && <span className=\"text-sm text-muted-foreground\">{statusText}</span>}\n </div>\n <div className=\"flex items-center gap-3\">\n {headerSlot}\n {showSummary && (\n <TestRunSummary\n tests={summaryTests}\n startTime={startTime}\n endTime={endTime}\n done={done}\n now={now}\n runMeta={runMeta}\n />\n )}\n </div>\n </div>\n {hasContent && (\n <div className=\"mt-2\">\n <TestFilterBar\n filters={filters}\n onChange={onFiltersChange}\n counts={filterCounts}\n frameworks={frameworks}\n />\n </div>\n )}\n </div>\n )}\n\n <SplitPane\n className=\"min-h-0 flex-1\"\n defaultSplit={defaultSplit}\n minLeft={25}\n minRight={30}\n leftClass=\"border-r-2 border-border bg-muted/30\"\n left={<TestTree />}\n right={<TestDetailPanel />}\n />\n </div>\n </TestRunnerProvider>\n );\n}\n"],"names":["TestNodeAdapterRegistry","createTestRunnerRegistry","status","useMemo","collectFrameworks","aggregateStatusCounts","jsx","TestRunnerProvider","jsxs","cn","Icon","UiBeaker","TestRunSummary","TestFilterBar","SplitPane","TestTree","TestDetailPanel"],"mappings":"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"}
1
+ {"version":3,"file":"TestRunner.cjs","sources":["../../../src/data/test-runner/TestRunner.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { cn } from \"../../lib/utils\";\nimport { UiArrowLeft, UiBeaker } from \"../../icons\";\nimport { useContainerWiderThan } from \"../../hooks/use-container-width\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport { aggregateStatusCounts, collectFrameworks } from \"./status\";\nimport { type TestFilters } from \"./filterState\";\nimport {\n createTestRunnerRegistry,\n type TestNodeAdapter,\n TestNodeAdapterRegistry,\n} from \"./adapter\";\nimport { TestRunnerProvider, type TestRunnerContext } from \"./context\";\nimport { TestTree } from \"./TestTree\";\nimport { TestDetailPanel } from \"./TestDetailPanel\";\nimport { TestRunSummary } from \"./TestRunSummary\";\nimport { TestFilterBar } from \"./TestFilterBar\";\n\nexport type TestRunnerProps = {\n tests: Test[];\n /**\n * The full, unfiltered forest driving the filter bar's pills/counts and the\n * header summary — falls back to `tests` when omitted (every existing\n * caller pre-filters `tests` itself). Pass this explicitly when `tests` is a\n * filtered subset of a larger report, so toggling a status filter (e.g.\n * excluding the only failed node) can't make its own pill — or the whole\n * filter bar, once every pill's count reads zero — disappear.\n */\n allTests?: Test[];\n selected: Test | null;\n filters: TestFilters;\n expandAll: boolean | null;\n done: boolean;\n runMeta?: RunMeta;\n status?: SnapshotStatus;\n /** Free-form status line shown next to the title (e.g. \"Running tests...\"). */\n statusText?: string;\n now?: number;\n busy?: { rerun?: boolean; stop?: boolean };\n\n /** Controlled active detail-tab id; omit to let the detail pane own tab state. */\n activeTab?: string;\n /** Called with the picked tab id when `activeTab` is controlled. */\n onTabChange?: (tabId: string) => void;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n onRerun?: (node: Test) => void;\n onStop?: (node: Test) => void;\n\n /** Domain node adapters, or a pre-built registry. Defaults to default-only. */\n adapters?: TestNodeAdapter[] | TestNodeAdapterRegistry;\n /**\n * Header title. Defaults (when omitted) to the \"Test Results\" beaker heading.\n * Pass `null` to render no title — e.g. a host that owns the title in its own\n * dialog/page header and embeds the runner below it.\n */\n title?: ReactNode;\n /**\n * Render the built-in run summary (counts + progress) in the header. Defaults\n * to true; pass false when the host shows the summary itself (e.g. in a dialog\n * header) to avoid duplicating it.\n */\n showSummary?: boolean;\n /** Run actions at the right end of the one-line header (e.g. re-run, export, copy). */\n headerSlot?: ReactNode;\n /**\n * Suppresses the built-in header bar (title, summary) and the status/tool\n * facets in the tree toolbar.\n * Defaults to false; pass true when a host renders its own combined header\n * (e.g. a dialog header that already embeds `TestRunSummary` and filters) so\n * the runner doesn't render a second bordered bar underneath it.\n */\n hideHeader?: boolean;\n /** Initial left-pane width percentage. */\n defaultSplit?: number;\n startTime?: number | null;\n endTime?: number | null;\n className?: string;\n};\n\nfunction toRegistry(\n adapters: TestNodeAdapter[] | TestNodeAdapterRegistry | undefined,\n): TestNodeAdapterRegistry {\n if (adapters instanceof TestNodeAdapterRegistry) return adapters;\n return createTestRunnerRegistry(adapters ?? []);\n}\n\nconst SPLIT_MIN_WIDTH = 640;\n\n/**\n * Top-level, pure-presentational test runner: a summary/filter header over a\n * resizable tree + detail split. All data and handlers flow in via props and\n * are exposed to sub-components through a single `TestRunnerContext`. Domain\n * rendering is pluggable via node adapters; no fetch/SSE/routing lives here.\n */\nexport function TestRunner({\n tests,\n allTests,\n selected,\n filters,\n expandAll,\n done,\n runMeta,\n status,\n statusText,\n now,\n busy,\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n adapters,\n title,\n showSummary = true,\n headerSlot,\n hideHeader = false,\n defaultSplit = 45,\n startTime,\n endTime,\n className,\n}: TestRunnerProps) {\n const registry = useMemo(() => toRegistry(adapters), [adapters]);\n\n const ctx: TestRunnerContext = useMemo(\n () => ({\n tests,\n selected,\n runMeta,\n status,\n done,\n now,\n filters,\n expandAll,\n busy: busy ?? {},\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n adapters: registry,\n }),\n [\n tests,\n selected,\n runMeta,\n status,\n done,\n now,\n filters,\n expandAll,\n busy,\n activeTab,\n onTabChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n registry,\n ],\n );\n\n const summaryTests = allTests ?? tests;\n const frameworks = useMemo(() => collectFrameworks(summaryTests), [summaryTests]);\n const filterCounts = useMemo(() => aggregateStatusCounts(summaryTests), [summaryTests]);\n // A host that hides the header renders its own filters (see hideHeader).\n const filterBar =\n !hideHeader && summaryTests.length > 0 ? (\n <TestFilterBar\n filters={filters}\n onChange={onFiltersChange}\n counts={filterCounts}\n frameworks={frameworks}\n />\n ) : null;\n // Below this the split leaves both panes too narrow to read, so the runner\n // goes master/detail: the tree, then the selected test with a way back.\n const { ref, wider: roomy } = useContainerWiderThan(SPLIT_MIN_WIDTH);\n\n return (\n <TestRunnerProvider value={ctx}>\n <div ref={ref} className={cn(\"flex h-full min-h-0 flex-col bg-background\", className)}>\n {!hideHeader && (\n <div\n className=\"flex min-w-0 items-center gap-3 border-b border-border bg-card px-density-4 py-density-2\"\n data-runner-header=\"\"\n >\n <div className=\"flex min-w-0 items-center gap-3\">\n {title === undefined ? (\n <h1 className=\"inline-flex shrink-0 items-center gap-1.5 text-base font-bold\">\n <Icon icon={UiBeaker} className=\"text-primary\" />\n Test Results\n </h1>\n ) : (\n title\n )}\n {statusText && (\n <span className=\"truncate text-sm text-muted-foreground\">{statusText}</span>\n )}\n </div>\n {showSummary && (\n <TestRunSummary\n tests={summaryTests}\n startTime={startTime}\n endTime={endTime}\n done={done}\n now={now}\n runMeta={runMeta}\n compact\n className=\"ml-auto flex-nowrap\"\n />\n )}\n {headerSlot && (\n <div className={cn(\"flex shrink-0 items-center gap-1\", !showSummary && \"ml-auto\")}>\n {headerSlot}\n </div>\n )}\n </div>\n )}\n\n {roomy ? (\n <SplitPane\n className=\"min-h-0 flex-1\"\n defaultSplit={defaultSplit}\n minLeft={25}\n minRight={30}\n leftClass=\"border-r-2 border-border bg-muted/30\"\n left={<TestTree actions={filterBar} />}\n right={<TestDetailPanel />}\n />\n ) : selected ? (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <button\n type=\"button\"\n onClick={() => onSelect(null)}\n className=\"inline-flex items-center gap-1.5 border-b border-border px-density-3 py-density-2 text-left text-sm text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Icon icon={UiArrowLeft} />\n Back to results\n </button>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <TestDetailPanel />\n </div>\n </div>\n ) : (\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n <TestTree actions={filterBar} />\n </div>\n )}\n </div>\n </TestRunnerProvider>\n );\n}\n"],"names":["TestNodeAdapterRegistry","createTestRunnerRegistry","status","useMemo","collectFrameworks","aggregateStatusCounts","jsx","TestFilterBar","useContainerWiderThan","TestRunnerProvider","jsxs","cn","Icon","UiBeaker","TestRunSummary","SplitPane","TestTree","TestDetailPanel","UiArrowLeft"],"mappings":"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"}
@@ -49,10 +49,11 @@ export type TestRunnerProps = {
49
49
  * header) to avoid duplicating it.
50
50
  */
51
51
  showSummary?: boolean;
52
- /** Extra header content (e.g. export/download controls owned by the host). */
52
+ /** Run actions at the right end of the one-line header (e.g. re-run, export, copy). */
53
53
  headerSlot?: ReactNode;
54
54
  /**
55
- * Suppresses the entire built-in header bar (title, summary, filter row).
55
+ * Suppresses the built-in header bar (title, summary) and the status/tool
56
+ * facets in the tree toolbar.
56
57
  * Defaults to false; pass true when a host renders its own combined header
57
58
  * (e.g. a dialog header that already embeds `TestRunSummary` and filters) so
58
59
  * the runner doesn't render a second bordered bar underneath it.
@@ -1 +1 @@
1
- {"version":3,"file":"TestRunner.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestRunner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKhD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAEL,KAAK,eAAe,EACpB,uBAAuB,EACxB,MAAM,WAAW,CAAC;AAOnB,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAClB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE3C,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAE9B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,eAAe,EAAE,GAAG,uBAAuB,CAAC;IACvD;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AASF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,IAAI,EACJ,OAAO,EACP,MAAM,EACN,UAAU,EACV,GAAG,EACH,IAAI,EACJ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,WAAkB,EAClB,UAAU,EACV,UAAkB,EAClB,YAAiB,EACjB,SAAS,EACT,OAAO,EACP,SAAS,GACV,EAAE,eAAe,+BAyGjB"}
1
+ {"version":3,"file":"TestRunner.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestRunner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMhD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAEL,KAAK,eAAe,EACpB,uBAAuB,EACxB,MAAM,WAAW,CAAC;AAOnB,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAClB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE3C,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAE9B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,eAAe,EAAE,GAAG,uBAAuB,CAAC;IACvD;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uFAAuF;IACvF,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,IAAI,EACJ,OAAO,EACP,MAAM,EACN,UAAU,EACV,GAAG,EACH,IAAI,EACJ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,WAAkB,EAClB,UAAU,EACV,UAAkB,EAClB,YAAiB,EACjB,SAAS,EACT,OAAO,EACP,SAAS,GACV,EAAE,eAAe,+BAsIjB"}