@shipfox/client-workflows 12.0.2 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/.storybook/main.ts +16 -1
  2. package/.storybook/preview.tsx +3 -3
  3. package/.storybook/workspace-source.ts +31 -0
  4. package/.turbo/turbo-build.log +1 -1
  5. package/CHANGELOG.md +79 -0
  6. package/dist/components/job-graph/job-duration-format.d.ts +2 -2
  7. package/dist/components/job-graph/job-duration-format.d.ts.map +1 -1
  8. package/dist/components/job-graph/job-duration-format.js +4 -2
  9. package/dist/components/job-graph/job-duration-format.js.map +1 -1
  10. package/dist/components/job-graph/job-duration-label.js +1 -1
  11. package/dist/components/job-graph/job-duration-label.js.map +1 -1
  12. package/dist/components/job-graph/job-graph-content.d.ts +2 -1
  13. package/dist/components/job-graph/job-graph-content.d.ts.map +1 -1
  14. package/dist/components/job-graph/job-graph-content.js +3 -3
  15. package/dist/components/job-graph/job-graph-content.js.map +1 -1
  16. package/dist/components/job-graph/job-graph-view.d.ts +2 -1
  17. package/dist/components/job-graph/job-graph-view.d.ts.map +1 -1
  18. package/dist/components/job-graph/job-graph-view.js +2 -2
  19. package/dist/components/job-graph/job-graph-view.js.map +1 -1
  20. package/dist/components/job-graph/job-node.d.ts +1 -1
  21. package/dist/components/job-graph/job-node.d.ts.map +1 -1
  22. package/dist/components/job-graph/job-node.js +10 -9
  23. package/dist/components/job-graph/job-node.js.map +1 -1
  24. package/dist/components/job-graph/types.d.ts +2 -1
  25. package/dist/components/job-graph/types.d.ts.map +1 -1
  26. package/dist/components/job-graph/types.js.map +1 -1
  27. package/dist/components/step-list/step-list.d.ts +2 -2
  28. package/dist/components/step-list/step-list.d.ts.map +1 -1
  29. package/dist/components/step-list/step-list.js.map +1 -1
  30. package/dist/components/workflow-run-duration-label.js +1 -1
  31. package/dist/components/workflow-run-duration-label.js.map +1 -1
  32. package/dist/components/workflow-run-list/job-status-strip.d.ts +21 -0
  33. package/dist/components/workflow-run-list/job-status-strip.d.ts.map +1 -0
  34. package/dist/components/workflow-run-list/job-status-strip.js +185 -0
  35. package/dist/components/workflow-run-list/job-status-strip.js.map +1 -0
  36. package/dist/components/workflow-run-list/run-display.d.ts +27 -3
  37. package/dist/components/workflow-run-list/run-display.d.ts.map +1 -1
  38. package/dist/components/workflow-run-list/run-display.js +78 -7
  39. package/dist/components/workflow-run-list/run-display.js.map +1 -1
  40. package/dist/components/workflow-run-list/types.d.ts +23 -24
  41. package/dist/components/workflow-run-list/types.d.ts.map +1 -1
  42. package/dist/components/workflow-run-list/types.js.map +1 -1
  43. package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts +22 -0
  44. package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts.map +1 -0
  45. package/dist/components/workflow-run-list/workflow-run-filter-menu.js +68 -0
  46. package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -0
  47. package/dist/components/workflow-run-list/workflow-run-filters.d.ts +18 -0
  48. package/dist/components/workflow-run-list/workflow-run-filters.d.ts.map +1 -0
  49. package/dist/components/workflow-run-list/workflow-run-filters.js +236 -0
  50. package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -0
  51. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +8 -4
  52. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -1
  53. package/dist/components/workflow-run-list/workflow-run-list-content.js +40 -12
  54. package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -1
  55. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +29 -2
  56. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -1
  57. package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -44
  58. package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
  59. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +1 -1
  60. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
  61. package/dist/components/workflow-run-list/workflow-run-list-view.js +60 -43
  62. package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
  63. package/dist/components/workflow-run-list/workflow-run-list.d.ts +1 -1
  64. package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -1
  65. package/dist/components/workflow-run-list/workflow-run-list.js +20 -8
  66. package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -1
  67. package/dist/components/workflow-run-list/workflow-run-row.d.ts +19 -9
  68. package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
  69. package/dist/components/workflow-run-list/workflow-run-row.js +179 -112
  70. package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
  71. package/dist/components/workflow-run-number-label.d.ts +15 -0
  72. package/dist/components/workflow-run-number-label.d.ts.map +1 -0
  73. package/dist/components/workflow-run-number-label.js +41 -0
  74. package/dist/components/workflow-run-number-label.js.map +1 -0
  75. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +3 -3
  76. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -1
  77. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +10 -9
  78. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
  79. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +4 -9
  80. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
  81. package/dist/components/workflow-run-summary/workflow-run-summary.js +107 -74
  82. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
  83. package/dist/components/workflow-run-tabs/index.d.ts +6 -0
  84. package/dist/components/workflow-run-tabs/index.d.ts.map +1 -0
  85. package/dist/components/workflow-run-tabs/index.js +7 -0
  86. package/dist/components/workflow-run-tabs/index.js.map +1 -0
  87. package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts +11 -0
  88. package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -0
  89. package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +71 -0
  90. package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -0
  91. package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts +2 -0
  92. package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts.map +1 -0
  93. package/dist/components/workflow-run-tabs/run-annotations-empty.js +11 -0
  94. package/dist/components/workflow-run-tabs/run-annotations-empty.js.map +1 -0
  95. package/dist/components/workflow-run-tabs/run-jobs-list.d.ts +18 -0
  96. package/dist/components/workflow-run-tabs/run-jobs-list.d.ts.map +1 -0
  97. package/dist/components/workflow-run-tabs/run-jobs-list.js +107 -0
  98. package/dist/components/workflow-run-tabs/run-jobs-list.js.map +1 -0
  99. package/dist/components/workflow-run-tabs/run-tab-count.d.ts +6 -0
  100. package/dist/components/workflow-run-tabs/run-tab-count.d.ts.map +1 -0
  101. package/dist/components/workflow-run-tabs/run-tab-count.js +27 -0
  102. package/dist/components/workflow-run-tabs/run-tab-count.js.map +1 -0
  103. package/dist/components/workflow-run-tabs/run-tab-strip.d.ts +8 -0
  104. package/dist/components/workflow-run-tabs/run-tab-strip.d.ts.map +1 -0
  105. package/dist/components/workflow-run-tabs/run-tab-strip.js +82 -0
  106. package/dist/components/workflow-run-tabs/run-tab-strip.js.map +1 -0
  107. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +2 -2
  108. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -1
  109. package/dist/components/workflow-run-view/agent-config-failure-callout.js +4 -4
  110. package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -1
  111. package/dist/components/workflow-run-view/job-card.d.ts +2 -2
  112. package/dist/components/workflow-run-view/job-card.d.ts.map +1 -1
  113. package/dist/components/workflow-run-view/job-card.js +51 -32
  114. package/dist/components/workflow-run-view/job-card.js.map +1 -1
  115. package/dist/components/workflow-run-view/job-execution-switcher.d.ts +1 -1
  116. package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -1
  117. package/dist/components/workflow-run-view/job-execution-switcher.js +20 -8
  118. package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -1
  119. package/dist/components/workflow-run-view/workflow-run-selection.d.ts.map +1 -1
  120. package/dist/components/workflow-run-view/workflow-run-selection.js +40 -1
  121. package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -1
  122. package/dist/components/workflow-run-view/workflow-run-states.d.ts +1 -0
  123. package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -1
  124. package/dist/components/workflow-run-view/workflow-run-states.js +10 -1
  125. package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
  126. package/dist/components/workflow-run-view/workflow-run-view.d.ts +10 -5
  127. package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
  128. package/dist/components/workflow-run-view/workflow-run-view.js +136 -85
  129. package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
  130. package/dist/components/workflow-source-panel/index.d.ts +1 -0
  131. package/dist/components/workflow-source-panel/index.d.ts.map +1 -1
  132. package/dist/components/workflow-source-panel/index.js +1 -0
  133. package/dist/components/workflow-source-panel/index.js.map +1 -1
  134. package/dist/components/workflow-source-panel/workflow-source-content.d.ts +12 -0
  135. package/dist/components/workflow-source-panel/workflow-source-content.d.ts.map +1 -0
  136. package/dist/components/workflow-source-panel/workflow-source-content.js +53 -0
  137. package/dist/components/workflow-source-panel/workflow-source-content.js.map +1 -0
  138. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts +1 -1
  139. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts.map +1 -1
  140. package/dist/components/workflow-source-panel/workflow-source-panel.js +7 -54
  141. package/dist/components/workflow-source-panel/workflow-source-panel.js.map +1 -1
  142. package/dist/components/workflow-status/status-visuals.d.ts +4 -4
  143. package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
  144. package/dist/components/workflow-status/status-visuals.js +7 -0
  145. package/dist/components/workflow-status/status-visuals.js.map +1 -1
  146. package/dist/components/workflow-status/workflow-status-icon.d.ts +3 -4
  147. package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
  148. package/dist/components/workflow-status/workflow-status-icon.js +6 -4
  149. package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
  150. package/dist/core/entities/job-execution.d.ts +10 -0
  151. package/dist/core/entities/job-execution.d.ts.map +1 -1
  152. package/dist/core/entities/job-execution.js +11 -0
  153. package/dist/core/entities/job-execution.js.map +1 -1
  154. package/dist/core/entities/job.d.ts +4 -2
  155. package/dist/core/entities/job.d.ts.map +1 -1
  156. package/dist/core/entities/job.js +8 -1
  157. package/dist/core/entities/job.js.map +1 -1
  158. package/dist/core/entities/step.d.ts +1 -1
  159. package/dist/core/entities/step.d.ts.map +1 -1
  160. package/dist/core/entities/step.js +2 -0
  161. package/dist/core/entities/step.js.map +1 -1
  162. package/dist/core/entities/workflow-run.d.ts +52 -4
  163. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  164. package/dist/core/entities/workflow-run.js +22 -3
  165. package/dist/core/entities/workflow-run.js.map +1 -1
  166. package/dist/core/workflow-run-tabs.d.ts +9 -0
  167. package/dist/core/workflow-run-tabs.d.ts.map +1 -0
  168. package/dist/core/workflow-run-tabs.js +3 -0
  169. package/dist/core/workflow-run-tabs.js.map +1 -0
  170. package/dist/core/workflow-run.d.ts +6 -6
  171. package/dist/core/workflow-run.d.ts.map +1 -1
  172. package/dist/core/workflow-run.js +3 -3
  173. package/dist/core/workflow-run.js.map +1 -1
  174. package/dist/feature.d.ts +7 -7
  175. package/dist/feature.js +5 -5
  176. package/dist/feature.js.map +1 -1
  177. package/dist/hooks/api/workflow-run-mapper.d.ts +4 -3
  178. package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
  179. package/dist/hooks/api/workflow-run-mapper.js +31 -3
  180. package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
  181. package/dist/hooks/api/workflow-runs.d.ts +4 -4
  182. package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
  183. package/dist/hooks/api/workflow-runs.js +12 -4
  184. package/dist/hooks/api/workflow-runs.js.map +1 -1
  185. package/dist/index.d.ts +4 -3
  186. package/dist/index.d.ts.map +1 -1
  187. package/dist/index.js +3 -2
  188. package/dist/index.js.map +1 -1
  189. package/dist/pages/project-workflows-page.js +46 -1
  190. package/dist/pages/project-workflows-page.js.map +1 -1
  191. package/dist/pages/workflow-run-detail-page.d.ts +11 -0
  192. package/dist/pages/workflow-run-detail-page.d.ts.map +1 -0
  193. package/dist/pages/workflow-run-detail-page.js +52 -0
  194. package/dist/pages/workflow-run-detail-page.js.map +1 -0
  195. package/dist/pages/workflow-run-list-page.d.ts +10 -0
  196. package/dist/pages/workflow-run-list-page.d.ts.map +1 -0
  197. package/dist/pages/workflow-run-list-page.js +43 -0
  198. package/dist/pages/workflow-run-list-page.js.map +1 -0
  199. package/dist/routes/inputs.d.ts +94 -5
  200. package/dist/routes/inputs.d.ts.map +1 -1
  201. package/dist/routes/inputs.js +199 -13
  202. package/dist/routes/inputs.js.map +1 -1
  203. package/dist/routes/project-route.d.ts +6 -0
  204. package/dist/routes/project-route.d.ts.map +1 -0
  205. package/dist/routes/project-route.js +25 -0
  206. package/dist/routes/project-route.js.map +1 -0
  207. package/dist/routes/run-detail.d.ts.map +1 -1
  208. package/dist/routes/run-detail.js +12 -7
  209. package/dist/routes/run-detail.js.map +1 -1
  210. package/dist/routes/runs.d.ts.map +1 -1
  211. package/dist/routes/runs.js +11 -6
  212. package/dist/routes/runs.js.map +1 -1
  213. package/dist/routes/workflows.d.ts.map +1 -1
  214. package/dist/routes/workflows.js +6 -5
  215. package/dist/routes/workflows.js.map +1 -1
  216. package/dist/tsconfig.test.tsbuildinfo +1 -1
  217. package/package.json +9 -9
  218. package/src/components/job-graph/job-duration-format.ts +11 -2
  219. package/src/components/job-graph/job-duration-label.tsx +5 -1
  220. package/src/components/job-graph/job-graph-content.tsx +7 -4
  221. package/src/components/job-graph/job-graph-view.test.tsx +19 -8
  222. package/src/components/job-graph/job-graph-view.tsx +6 -3
  223. package/src/components/job-graph/job-graph.stories.tsx +24 -20
  224. package/src/components/job-graph/job-node.stories.tsx +11 -6
  225. package/src/components/job-graph/job-node.test.tsx +82 -12
  226. package/src/components/job-graph/job-node.tsx +22 -15
  227. package/src/components/job-graph/types.ts +5 -1
  228. package/src/components/step-list/step-list.stories.tsx +2 -3
  229. package/src/components/step-list/step-list.tsx +3 -2
  230. package/src/components/workflow-run-duration-label.tsx +1 -1
  231. package/src/components/workflow-run-list/job-status-strip.tsx +189 -0
  232. package/src/components/workflow-run-list/run-display.test.ts +169 -30
  233. package/src/components/workflow-run-list/run-display.ts +116 -9
  234. package/src/components/workflow-run-list/types.ts +21 -17
  235. package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +100 -0
  236. package/src/components/workflow-run-list/workflow-run-filters.tsx +243 -0
  237. package/src/components/workflow-run-list/workflow-run-list-content.tsx +44 -16
  238. package/src/components/workflow-run-list/workflow-run-list-states.tsx +128 -27
  239. package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +441 -104
  240. package/src/components/workflow-run-list/workflow-run-list-view.tsx +73 -43
  241. package/src/components/workflow-run-list/workflow-run-list.stories.tsx +140 -20
  242. package/src/components/workflow-run-list/workflow-run-list.tsx +20 -10
  243. package/src/components/workflow-run-list/workflow-run-row.tsx +173 -106
  244. package/src/components/workflow-run-number-label.test.tsx +45 -0
  245. package/src/components/workflow-run-number-label.tsx +47 -0
  246. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +7 -8
  247. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +15 -14
  248. package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +29 -38
  249. package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +30 -24
  250. package/src/components/workflow-run-summary/workflow-run-summary.tsx +102 -77
  251. package/src/components/workflow-run-tabs/index.ts +5 -0
  252. package/src/components/workflow-run-tabs/run-annotation-summary-line.test.tsx +69 -0
  253. package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +97 -0
  254. package/src/components/workflow-run-tabs/run-annotations-empty.tsx +11 -0
  255. package/src/components/workflow-run-tabs/run-jobs-list.tsx +151 -0
  256. package/src/components/workflow-run-tabs/run-tab-count.tsx +28 -0
  257. package/src/components/workflow-run-tabs/run-tab-strip.stories.tsx +52 -0
  258. package/src/components/workflow-run-tabs/run-tab-strip.test.tsx +117 -0
  259. package/src/components/workflow-run-tabs/run-tab-strip.tsx +97 -0
  260. package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +2 -3
  261. package/src/components/workflow-run-view/agent-config-failure-callout.tsx +4 -4
  262. package/src/components/workflow-run-view/job-card.stories.tsx +11 -10
  263. package/src/components/workflow-run-view/job-card.test.tsx +115 -0
  264. package/src/components/workflow-run-view/job-card.tsx +74 -35
  265. package/src/components/workflow-run-view/job-execution-switcher.tsx +31 -9
  266. package/src/components/workflow-run-view/workflow-run-selection.test.ts +48 -0
  267. package/src/components/workflow-run-view/workflow-run-selection.ts +48 -1
  268. package/src/components/workflow-run-view/workflow-run-states.tsx +12 -1
  269. package/src/components/workflow-run-view/workflow-run-view.test.tsx +152 -94
  270. package/src/components/workflow-run-view/workflow-run-view.tsx +219 -95
  271. package/src/components/workflow-source-panel/index.ts +1 -0
  272. package/src/components/workflow-source-panel/workflow-source-content.tsx +84 -0
  273. package/src/components/workflow-source-panel/workflow-source-panel.tsx +14 -81
  274. package/src/components/workflow-status/status-visuals.test.ts +9 -0
  275. package/src/components/workflow-status/status-visuals.ts +6 -4
  276. package/src/components/workflow-status/workflow-status-icon.stories.tsx +10 -2
  277. package/src/components/workflow-status/workflow-status-icon.test.tsx +18 -0
  278. package/src/components/workflow-status/workflow-status-icon.tsx +17 -24
  279. package/src/core/entities/job-execution.ts +22 -0
  280. package/src/core/entities/job-status.test.ts +104 -0
  281. package/src/core/entities/job.ts +18 -3
  282. package/src/core/entities/step.ts +4 -0
  283. package/src/core/entities/workflow-run.ts +76 -7
  284. package/src/core/workflow-run-tabs.ts +8 -0
  285. package/src/core/workflow-run.test.ts +24 -9
  286. package/src/core/workflow-run.ts +17 -2
  287. package/src/feature.ts +5 -5
  288. package/src/hooks/api/workflow-run-mapper.ts +30 -3
  289. package/src/hooks/api/workflow-runs.test.tsx +2 -0
  290. package/src/hooks/api/workflow-runs.ts +12 -7
  291. package/src/index.ts +7 -2
  292. package/src/page-harness-budget.test.ts +1 -1
  293. package/src/pages/project-workflows-page.test.tsx +59 -5
  294. package/src/pages/project-workflows-page.tsx +34 -1
  295. package/src/pages/workflow-run-detail-page.tsx +72 -0
  296. package/src/pages/workflow-run-list-page.tsx +65 -0
  297. package/src/pages/workflow-run-pages.test.tsx +823 -0
  298. package/src/routes/inputs.test.ts +240 -12
  299. package/src/routes/inputs.ts +215 -11
  300. package/src/routes/project-route.tsx +25 -0
  301. package/src/routes/run-detail.tsx +15 -8
  302. package/src/routes/runs.tsx +14 -7
  303. package/src/routes/workflows.tsx +5 -4
  304. package/src/storybook-config.test.ts +27 -0
  305. package/test/fixtures/workflow-run.ts +76 -7
  306. package/test/pages.tsx +18 -8
  307. package/test/render.tsx +8 -2
  308. package/tsconfig.build.tsbuildinfo +1 -1
  309. package/tsconfig.test.json +7 -1
  310. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +0 -10
  311. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +0 -1
  312. package/dist/components/workflow-run-list/workflow-run-list-header.js +0 -55
  313. package/dist/components/workflow-run-list/workflow-run-list-header.js.map +0 -1
  314. package/dist/pages/workflow-run-first-time-use.d.ts +0 -6
  315. package/dist/pages/workflow-run-first-time-use.d.ts.map +0 -1
  316. package/dist/pages/workflow-run-first-time-use.js +0 -17
  317. package/dist/pages/workflow-run-first-time-use.js.map +0 -1
  318. package/dist/pages/workflow-run-page.d.ts +0 -10
  319. package/dist/pages/workflow-run-page.d.ts.map +0 -1
  320. package/dist/pages/workflow-run-page.js +0 -90
  321. package/dist/pages/workflow-run-page.js.map +0 -1
  322. package/src/components/workflow-run-list/workflow-run-list-header.tsx +0 -53
  323. package/src/pages/workflow-run-first-time-use.tsx +0 -17
  324. package/src/pages/workflow-run-page.test.tsx +0 -519
  325. package/src/pages/workflow-run-page.tsx +0 -94
@@ -15,7 +15,7 @@ import {
15
15
  workflowStepAttemptDto,
16
16
  workflowStepDto,
17
17
  } from '#test/fixtures/workflow-run.js';
18
- import {jsonResponse, PROJECT_TEST_WID, renderProjectPage} from '#test/pages.js';
18
+ import {jsonResponse, PROJECT_TEST_WSLUG, renderProjectPage} from '#test/pages.js';
19
19
  import {WorkflowRunView} from './workflow-run-view.js';
20
20
 
21
21
  const RUN_ID = '66666666-6666-4666-8666-666666666666';
@@ -26,12 +26,29 @@ const DEPLOY_JOB_ID = '88888888-8888-4888-8888-888888888888';
26
26
  const CHECKOUT_STEP_ID = '99999999-9999-4999-8999-999999999999';
27
27
  const CHECKOUT_ATTEMPT_ID = 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa';
28
28
  const RERUN_BUTTON_NAME = /^Re-run/;
29
+ const BUILD_JOB_BUTTON_NAME = 'build, Succeeded';
30
+ const DEPLOY_JOB_BUTTON_NAME = 'deploy, Running';
29
31
  const ATTEMPT_2_PATTERN = /Attempt 2/;
30
32
  const COPY_RUN_BUTTON_NAME = /Copy run/;
31
33
  const EXECUTION_ONE_MENU_ITEM_PATTERN = /#1/;
34
+ const LISTENING_EXECUTION_SWITCHER_NAME =
35
+ 'Switch job execution, currently execution 2: Deployment status event';
36
+ const JOB_TEMPLATE_NAME = ['Implement $', '{{ event.issue.identifier }}'].join('');
32
37
 
33
38
  describe('WorkflowRunView', () => {
34
- test('renders the run summary, jobs graph, and selected job step attempts when a run loads', async () => {
39
+ test('keeps the real tab strip visible while the run is loading', async () => {
40
+ configureApiClient({fetchImpl: vi.fn(() => new Promise<Response>(() => undefined))});
41
+
42
+ renderView({tab: 'summary'});
43
+
44
+ expect(await screen.findByRole('tab', {name: 'Summary'})).toBeInTheDocument();
45
+ expect(screen.getByRole('tab', {name: 'Jobs'})).toBeInTheDocument();
46
+ expect(screen.getByRole('tab', {name: 'Annotations'})).toBeInTheDocument();
47
+ expect(screen.getByRole('tab', {name: 'Source'})).toBeInTheDocument();
48
+ expect(screen.getByRole('region', {name: 'Loading workflow run content'})).toBeInTheDocument();
49
+ });
50
+
51
+ test('renders the run summary, jobs list, and selected job step attempts when a run loads', async () => {
35
52
  configureApiClient({
36
53
  fetchImpl: vi.fn(() => Promise.resolve(jsonResponse(workflowRunViewDetailDto()))),
37
54
  });
@@ -47,14 +64,50 @@ describe('WorkflowRunView', () => {
47
64
  within(summary).queryByRole('button', {name: COPY_RUN_BUTTON_NAME}),
48
65
  ).not.toBeInTheDocument();
49
66
  expect(await screen.findByRole('region', {name: 'Workflow jobs'})).toBeInTheDocument();
50
- expect(screen.getByRole('button', {name: 'build, Succeeded'})).toBeInTheDocument();
51
- expect(screen.getByRole('button', {name: 'deploy, Running'})).toBeInTheDocument();
67
+ expect(screen.getByRole('button', {name: BUILD_JOB_BUTTON_NAME})).toBeInTheDocument();
68
+ expect(screen.getByRole('button', {name: DEPLOY_JOB_BUTTON_NAME})).toBeInTheDocument();
69
+ expect(screen.getByRole('button', {name: BUILD_JOB_BUTTON_NAME})).toHaveClass(
70
+ 'bg-background-components-hover',
71
+ 'hover:bg-background-components-pressed',
72
+ );
73
+ expect(screen.getByRole('tabpanel')).toHaveClass('max-w-[1120px]', 'px-24');
52
74
  expect(screen.getByRole('region', {name: 'build'})).toBeInTheDocument();
53
75
  expect(
54
76
  screen.getByRole('button', {name: 'checkout, Succeeded, attempt 1'}),
55
77
  ).toBeInTheDocument();
56
78
  });
57
79
 
80
+ test('uses the selected job execution name as the job card title', async () => {
81
+ configureApiClient({
82
+ fetchImpl: vi.fn(() =>
83
+ Promise.resolve(
84
+ jsonResponse(
85
+ workflowRunViewDetailDto({
86
+ jobs: [
87
+ workflowJobDto({
88
+ id: BUILD_JOB_ID,
89
+ run_attempt_id: RUN_ID,
90
+ name: JOB_TEMPLATE_NAME,
91
+ job_executions: [
92
+ workflowJobExecutionDto({
93
+ job_id: BUILD_JOB_ID,
94
+ name: 'Implement ENG-123',
95
+ }),
96
+ ],
97
+ }),
98
+ ],
99
+ }),
100
+ ),
101
+ ),
102
+ ),
103
+ });
104
+
105
+ renderView();
106
+
107
+ expect(await screen.findByRole('region', {name: 'Implement ENG-123'})).toBeInTheDocument();
108
+ expect(screen.queryByRole('region', {name: JOB_TEMPLATE_NAME})).not.toBeInTheDocument();
109
+ });
110
+
58
111
  test('renders active step attempt logs inline when the selected job is running', async () => {
59
112
  const stepId = '99999999-9999-4999-8999-000000000001';
60
113
  const fetchImpl = vi.fn((input: RequestInfo | URL) => {
@@ -125,6 +178,7 @@ describe('WorkflowRunView', () => {
125
178
  id: '77777777-7777-4777-8777-000000000001',
126
179
  job_id: BUILD_JOB_ID,
127
180
  sequence: 1,
181
+ name: 'Pull request event',
128
182
  status: 'succeeded',
129
183
  trigger_events: [
130
184
  {
@@ -132,6 +186,10 @@ describe('WorkflowRunView', () => {
132
186
  event: 'pull_request',
133
187
  delivery_id: 'delivery-1',
134
188
  received_at: '2026-05-07T01:00:00.000Z',
189
+ project: null,
190
+ repository: null,
191
+ ref: null,
192
+ commit: null,
135
193
  data: {number: 12},
136
194
  },
137
195
  ],
@@ -155,6 +213,7 @@ describe('WorkflowRunView', () => {
155
213
  id: '77777777-7777-4777-8777-000000000002',
156
214
  job_id: BUILD_JOB_ID,
157
215
  sequence: 2,
216
+ name: 'Deployment status event',
158
217
  status: 'failed',
159
218
  status_reason: 'step_failed',
160
219
  trigger_events: [
@@ -163,6 +222,10 @@ describe('WorkflowRunView', () => {
163
222
  event: 'deployment_status',
164
223
  delivery_id: 'delivery-2',
165
224
  received_at: '2026-05-07T01:01:00.000Z',
225
+ project: null,
226
+ repository: null,
227
+ ref: null,
228
+ commit: null,
166
229
  data: {state: 'success'},
167
230
  },
168
231
  {
@@ -170,6 +233,10 @@ describe('WorkflowRunView', () => {
170
233
  event: 'check_run',
171
234
  delivery_id: 'delivery-3',
172
235
  received_at: '2026-05-07T01:01:10.000Z',
236
+ project: null,
237
+ repository: null,
238
+ ref: null,
239
+ commit: null,
173
240
  data: {status: 'completed'},
174
241
  },
175
242
  ],
@@ -200,18 +267,20 @@ describe('WorkflowRunView', () => {
200
267
  });
201
268
 
202
269
  renderView();
270
+ expect(
271
+ await screen.findByRole('region', {name: 'Deployment status event'}),
272
+ ).toBeInTheDocument();
203
273
  expect(await screen.findByText('second-event')).toBeInTheDocument();
204
274
  expect(
205
275
  await screen.findByRole('button', {name: 'github · deployment_status (2 events)'}),
206
276
  ).toBeInTheDocument();
207
277
  expect(screen.getByText('deployment_status (2)')).toBeInTheDocument();
208
278
 
209
- await user.click(
210
- screen.getByRole('button', {name: 'Switch job execution, currently execution 2'}),
211
- );
279
+ await user.click(screen.getByRole('button', {name: LISTENING_EXECUTION_SWITCHER_NAME}));
212
280
  await user.click(screen.getByRole('menuitem', {name: EXECUTION_ONE_MENU_ITEM_PATTERN}));
213
281
 
214
282
  expect(await screen.findByText('first-event')).toBeInTheDocument();
283
+ expect(screen.getByRole('region', {name: 'Pull request event'})).toBeInTheDocument();
215
284
  expect(screen.queryByText('second-event')).not.toBeInTheDocument();
216
285
  expect(await screen.findByRole('button', {name: 'github · pull_request'})).toBeInTheDocument();
217
286
  expect(screen.getByText('pull_request')).toBeInTheDocument();
@@ -301,7 +370,7 @@ describe('WorkflowRunView', () => {
301
370
  ).toBeInTheDocument();
302
371
  expect(screen.getByRole('link', {name: 'Configure Agents'})).toHaveAttribute(
303
372
  'href',
304
- `/workspaces/${PROJECT_TEST_WID}/settings/agents`,
373
+ `/w/${PROJECT_TEST_WSLUG}/settings/agents`,
305
374
  );
306
375
  });
307
376
 
@@ -378,7 +447,7 @@ describe('WorkflowRunView', () => {
378
447
  expect(screen.getByText('Configure credentials for anthropic')).toBeInTheDocument();
379
448
  expect(screen.getByRole('link', {name: 'Configure Agents'})).toHaveAttribute(
380
449
  'href',
381
- `/workspaces/${PROJECT_TEST_WID}/settings/agents`,
450
+ `/w/${PROJECT_TEST_WSLUG}/settings/agents`,
382
451
  );
383
452
  });
384
453
 
@@ -413,7 +482,7 @@ describe('WorkflowRunView', () => {
413
482
  expect(screen.queryByText('No steps recorded')).not.toBeInTheDocument();
414
483
  });
415
484
 
416
- test('uses the selected execution status for zero-step execution states', async () => {
485
+ test('keeps a terminal job status over inconsistent zero-step execution activity', async () => {
417
486
  configureApiClient({
418
487
  fetchImpl: vi.fn(() =>
419
488
  Promise.resolve(
@@ -445,11 +514,9 @@ describe('WorkflowRunView', () => {
445
514
 
446
515
  renderView();
447
516
 
448
- expect(await screen.findByText('Waiting for the first step')).toBeInTheDocument();
449
- expect(
450
- screen.getByText('This job is running, but no steps have started yet.'),
451
- ).toBeInTheDocument();
452
- expect(screen.queryByText('No steps recorded')).not.toBeInTheDocument();
517
+ expect(await screen.findByText('No steps recorded')).toBeInTheDocument();
518
+ expect(screen.getByText('Execution #2 finished without recorded steps.')).toBeInTheDocument();
519
+ expect(screen.queryByText('Waiting for the first step')).not.toBeInTheDocument();
453
520
  });
454
521
 
455
522
  test('renders pending zero-step jobs as waiting to start', async () => {
@@ -480,7 +547,7 @@ describe('WorkflowRunView', () => {
480
547
  expect(screen.queryByText('No steps recorded')).not.toBeInTheDocument();
481
548
  });
482
549
 
483
- test('renders running zero-step jobs as waiting for the first step', async () => {
550
+ test('renders claimed idle jobs as runner preparation', async () => {
484
551
  configureApiClient({
485
552
  fetchImpl: vi.fn(() =>
486
553
  Promise.resolve(
@@ -509,10 +576,13 @@ describe('WorkflowRunView', () => {
509
576
 
510
577
  renderView();
511
578
 
512
- expect(await screen.findByText('Waiting for the first step')).toBeInTheDocument();
579
+ expect(await screen.findByText('Runner preparing job')).toBeInTheDocument();
513
580
  expect(
514
- screen.getByText('This job is running, but no steps have started yet.'),
581
+ screen.getByText('A runner is assigned. Steps will appear here when work begins.'),
515
582
  ).toBeInTheDocument();
583
+ expect(
584
+ screen.queryByText('This job is running, but no steps have started yet.'),
585
+ ).not.toBeInTheDocument();
516
586
  expect(screen.queryByText('No steps recorded')).not.toBeInTheDocument();
517
587
  });
518
588
 
@@ -634,8 +704,7 @@ describe('WorkflowRunView', () => {
634
704
  ).toBeInTheDocument();
635
705
  });
636
706
 
637
- test('opens and closes workflow source without resetting the selected job', async () => {
638
- const user = userEvent.setup();
707
+ test('renders the full workflow source in the Source tab', async () => {
639
708
  configureApiClient({
640
709
  fetchImpl: vi.fn(() =>
641
710
  Promise.resolve(
@@ -651,38 +720,20 @@ describe('WorkflowRunView', () => {
651
720
  ),
652
721
  });
653
722
 
654
- renderView();
655
-
656
- const deployNode = await screen.findByRole('button', {name: 'deploy, Running'});
657
- await user.click(deployNode);
658
- expect(deployNode).toHaveAttribute('aria-pressed', 'true');
723
+ renderView({tab: 'source'});
659
724
 
660
- const sourceButton = within(screen.getByRole('region', {name: 'deploy-web'})).getByRole(
661
- 'button',
662
- {name: 'View source'},
725
+ expect(await screen.findByRole('tab', {name: 'Source'})).toHaveAttribute(
726
+ 'aria-selected',
727
+ 'true',
663
728
  );
664
- const panelId = sourceButton.getAttribute('aria-controls');
665
- expect(panelId).toBeTruthy();
666
- expect(sourceButton).toHaveAttribute('aria-expanded', 'false');
667
-
668
- await user.click(sourceButton);
669
-
670
- const sourcePanel = screen.getByRole('dialog', {name: 'Workflow source'});
671
- expect(sourceButton).toHaveAttribute('aria-expanded', 'true');
672
- expect(sourcePanel).toHaveAttribute('id', panelId);
673
- expect(sourcePanel).toHaveTextContent('pnpm test');
674
-
675
- await user.click(screen.getByRole('button', {name: 'Close source'}));
676
-
677
- await waitFor(() => expect(sourceButton).toHaveFocus());
678
- expect(sourceButton).toHaveAttribute('aria-expanded', 'false');
679
- expect(deployNode).toHaveAttribute('aria-pressed', 'true');
680
- expect(screen.getByRole('region', {name: 'deploy'})).toBeInTheDocument();
729
+ expect(await screen.findByText('pnpm test')).toBeInTheDocument();
730
+ expect(screen.queryByRole('dialog', {name: 'Workflow source'})).not.toBeInTheDocument();
681
731
  });
682
732
 
683
733
  test('highlights selected step source lines when the source panel opens', async () => {
684
734
  const user = userEvent.setup();
685
735
  const stepId = '99999999-9999-4999-8999-000000000003';
736
+ const stepAttemptId = 'aaaaaaaa-aaaa-4aaa-8aaa-000000000003';
686
737
  configureApiClient({
687
738
  fetchImpl: vi.fn(() =>
688
739
  Promise.resolve(
@@ -698,13 +749,27 @@ describe('WorkflowRunView', () => {
698
749
  run_attempt_id: RUN_ID,
699
750
  name: 'deploy',
700
751
  status: 'running',
701
- steps: [
702
- workflowStepDto({
703
- id: stepId,
704
- key: 'deploy',
752
+ job_executions: [
753
+ workflowJobExecutionDto({
754
+ job_id: DEPLOY_JOB_ID,
705
755
  name: 'deploy',
706
- source_location: {start_line: 2, end_line: 3},
707
756
  status: 'running',
757
+ steps: [
758
+ workflowStepDto({
759
+ id: stepId,
760
+ key: 'deploy',
761
+ name: 'deploy',
762
+ source_location: {start_line: 2, end_line: 3},
763
+ status: 'running',
764
+ attempts: [
765
+ workflowStepAttemptDto({
766
+ id: stepAttemptId,
767
+ step_id: stepId,
768
+ status: 'running',
769
+ }),
770
+ ],
771
+ }),
772
+ ],
708
773
  }),
709
774
  ],
710
775
  }),
@@ -715,29 +780,29 @@ describe('WorkflowRunView', () => {
715
780
  ),
716
781
  });
717
782
 
718
- renderView({selection: {stepId}});
719
- const summary = await screen.findByRole('region', {name: 'deploy-web'});
720
- await user.click(within(summary).getByRole('button', {name: 'View source'}));
783
+ renderView({tab: 'jobs', selection: {stepId, stepAttemptId}});
784
+ const jobRegion = await screen.findByRole('region', {name: 'deploy'});
785
+ await user.click(within(jobRegion).getByRole('button', {name: 'View source'}));
721
786
 
722
- await screen.findByRole('dialog', {name: 'Workflow source'});
723
- const highlightedLines = document.body.querySelectorAll('.line.highlighted-line');
787
+ const sourceDialog = await screen.findByRole('dialog', {name: 'Workflow source'});
788
+ const highlightedLines = sourceDialog.querySelectorAll('.line.highlighted-line');
724
789
  expect(highlightedLines).toHaveLength(2);
725
790
  expect(highlightedLines[0]).toHaveTextContent('deploy:');
726
791
  expect(highlightedLines[1]).toHaveTextContent('steps:');
727
792
  });
728
793
 
729
- test('does not render a source control when the run has no source snapshot', async () => {
794
+ test('explains when the run has no source snapshot', async () => {
730
795
  configureApiClient({
731
796
  fetchImpl: vi.fn(() =>
732
797
  Promise.resolve(jsonResponse(workflowRunViewDetailDto({source_snapshot: null}))),
733
798
  ),
734
799
  });
735
800
 
736
- renderView();
801
+ renderView({tab: 'source'});
737
802
 
738
803
  await screen.findByRole('region', {name: 'deploy-web'});
739
804
 
740
- expect(screen.queryByRole('button', {name: 'View source'})).not.toBeInTheDocument();
805
+ expect(await screen.findByText('Source snapshot unavailable')).toBeInTheDocument();
741
806
  });
742
807
 
743
808
  test('opens the source panel highlighting a step from the job header Source button', async () => {
@@ -751,25 +816,17 @@ describe('WorkflowRunView', () => {
751
816
  const jobRegion = await screen.findByRole('region', {name: 'build'});
752
817
  await user.click(screen.getByRole('button', {name: 'checkout, Succeeded, attempt 1'}));
753
818
  const jobSourceButton = within(jobRegion).getByRole('button', {name: 'View source'});
754
- const summaryButton = within(screen.getByRole('region', {name: 'deploy-web'})).getByRole(
755
- 'button',
756
- {name: 'View source'},
757
- );
758
819
  expect(jobSourceButton).toHaveAttribute('aria-expanded', 'false');
759
- expect(jobSourceButton).toHaveAttribute(
760
- 'aria-controls',
761
- summaryButton.getAttribute('aria-controls'),
762
- );
820
+ expect(jobSourceButton).toHaveAttribute('aria-controls');
763
821
 
764
822
  await user.click(jobSourceButton);
765
823
 
766
- await screen.findByRole('dialog', {name: 'Workflow source'});
767
- const highlighted = document.body.querySelectorAll('.line.highlighted-line');
824
+ const sourceDialog = await screen.findByRole('dialog', {name: 'Workflow source'});
825
+ const highlighted = sourceDialog.querySelectorAll('.line.highlighted-line');
768
826
  expect(highlighted).toHaveLength(2);
769
827
  expect(highlighted[0]).toHaveTextContent('build:');
770
828
  expect(highlighted[1]).toHaveTextContent('steps:');
771
829
  expect(jobSourceButton).toHaveAttribute('aria-expanded', 'true');
772
- expect(summaryButton).toHaveAttribute('aria-expanded', 'false');
773
830
  });
774
831
 
775
832
  test('returns focus to the job Source button on close and preserves the selected job', async () => {
@@ -793,7 +850,7 @@ describe('WorkflowRunView', () => {
793
850
  expect(screen.getByRole('region', {name: 'build'})).toBeInTheDocument();
794
851
  });
795
852
 
796
- test('falls back to the summary Source button when refetch removes the focused step source', async () => {
853
+ test('closes the source panel when refetch removes the focused step source', async () => {
797
854
  const user = userEvent.setup();
798
855
  let detailRequests = 0;
799
856
  const fetchImpl = vi.fn((input: RequestInfo | URL) => {
@@ -842,10 +899,6 @@ describe('WorkflowRunView', () => {
842
899
  const jobRegion = await screen.findByRole('region', {name: 'build'});
843
900
  await user.click(screen.getByRole('button', {name: 'checkout, Succeeded, attempt 1'}));
844
901
  const jobSourceButton = within(jobRegion).getByRole('button', {name: 'View source'});
845
- const summaryButton = within(screen.getByRole('region', {name: 'deploy-web'})).getByRole(
846
- 'button',
847
- {name: 'View source'},
848
- );
849
902
  await user.click(jobSourceButton);
850
903
  await screen.findByRole('dialog', {name: 'Workflow source'});
851
904
 
@@ -855,10 +908,7 @@ describe('WorkflowRunView', () => {
855
908
  within(jobRegion).queryByRole('button', {name: 'View source'}),
856
909
  ).not.toBeInTheDocument(),
857
910
  );
858
- await user.click(screen.getByRole('button', {name: 'Close source'}));
859
-
860
- await waitFor(() => expect(summaryButton).toHaveFocus());
861
- expect(summaryButton).toHaveAttribute('aria-expanded', 'false');
911
+ expect(screen.queryByRole('dialog', {name: 'Workflow source'})).not.toBeInTheDocument();
862
912
  });
863
913
 
864
914
  test('re-runs all jobs from a succeeded run and navigates to the new run', async () => {
@@ -898,7 +948,7 @@ describe('WorkflowRunView', () => {
898
948
  expect(successSpy).toHaveBeenCalledWith('Re-run started');
899
949
  await waitFor(() =>
900
950
  expect(router.state.location.pathname).toBe(
901
- `/workspaces/${PROJECT_TEST_WID}/projects/${PROJECT_ID}/runs/${rerunId}`,
951
+ `/w/${PROJECT_TEST_WSLUG}/p/project/runs/${rerunId}`,
902
952
  ),
903
953
  );
904
954
  expect((router.state.location.search as Record<string, unknown>).runAttempt).toBeUndefined();
@@ -1008,11 +1058,12 @@ describe('WorkflowRunView', () => {
1008
1058
  configureApiClient({fetchImpl: fetchImpl as typeof fetch});
1009
1059
 
1010
1060
  const {router} = renderProjectPage(
1011
- `/workspaces/${PROJECT_TEST_WID}/projects/${PROJECT_ID}/runs/${RUN_ID}?job=${BUILD_JOB_ID}&step=${CHECKOUT_STEP_ID}&stepAttempt=${CHECKOUT_ATTEMPT_ID}`,
1061
+ `/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}?job=${BUILD_JOB_ID}&step=${CHECKOUT_STEP_ID}&stepAttempt=${CHECKOUT_ATTEMPT_ID}`,
1012
1062
  () => (
1013
1063
  <WorkflowRunView
1014
- workspaceId={PROJECT_TEST_WID}
1015
1064
  projectId={PROJECT_ID}
1065
+ workspaceSlug={PROJECT_TEST_WSLUG}
1066
+ projectSlug="project"
1016
1067
  workflowRunId={RUN_ID}
1017
1068
  />
1018
1069
  ),
@@ -1023,7 +1074,7 @@ describe('WorkflowRunView', () => {
1023
1074
 
1024
1075
  await waitFor(() =>
1025
1076
  expect(router.state.location.pathname).toBe(
1026
- `/workspaces/${PROJECT_TEST_WID}/projects/${PROJECT_ID}/runs/${RUN_ID}`,
1077
+ `/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}`,
1027
1078
  ),
1028
1079
  );
1029
1080
  expect(router.state.location.search).toEqual({runAttempt: 2});
@@ -1075,7 +1126,7 @@ describe('WorkflowRunView', () => {
1075
1126
  expect(
1076
1127
  await screen.findByRole('button', {name: 'build, Succeeded, reused'}),
1077
1128
  ).toBeInTheDocument();
1078
- expect(screen.getAllByText('reused')).toHaveLength(2);
1129
+ expect(screen.getAllByText('reused')).toHaveLength(1);
1079
1130
  await user.click(screen.getByRole('button', {name: 'checkout, Succeeded, attempt 1'}));
1080
1131
 
1081
1132
  expect(await screen.findByText('Not executed in this run.')).toBeInTheDocument();
@@ -1086,17 +1137,16 @@ describe('WorkflowRunView', () => {
1086
1137
  });
1087
1138
 
1088
1139
  function renderView(props: Partial<Parameters<typeof WorkflowRunView>[0]> = {}, search = '') {
1089
- return renderProjectPage(
1090
- `/workspaces/${PROJECT_TEST_WID}/projects/x/runs/${RUN_ID}${search}`,
1091
- () => (
1092
- <WorkflowRunView
1093
- workspaceId={PROJECT_TEST_WID}
1094
- projectId={PROJECT_ID}
1095
- workflowRunId={RUN_ID}
1096
- {...props}
1097
- />
1098
- ),
1099
- );
1140
+ return renderProjectPage(`/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}${search}`, () => (
1141
+ <WorkflowRunView
1142
+ projectId={PROJECT_ID}
1143
+ workspaceSlug={PROJECT_TEST_WSLUG}
1144
+ projectSlug="project"
1145
+ workflowRunId={RUN_ID}
1146
+ tab="jobs"
1147
+ {...props}
1148
+ />
1149
+ ));
1100
1150
  }
1101
1151
 
1102
1152
  function requestUrl(input: RequestInfo | URL): URL {
@@ -1207,6 +1257,14 @@ function workflowRunViewDetailDto(
1207
1257
  status: 'running',
1208
1258
  position: 1,
1209
1259
  dependencies: ['build'],
1260
+ job_executions: [
1261
+ workflowJobExecutionDto({
1262
+ job_id: DEPLOY_JOB_ID,
1263
+ name: 'deploy',
1264
+ status: 'running',
1265
+ steps: [workflowStepDto({status: 'running'})],
1266
+ }),
1267
+ ],
1210
1268
  }),
1211
1269
  ],
1212
1270
  ...overrides,