@flanksource/clicky-ui 0.3.49 → 0.3.50
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.
- package/dist/connections/ConnectionsPage.cjs +219 -0
- package/dist/connections/ConnectionsPage.cjs.map +1 -0
- package/dist/connections/ConnectionsPage.d.ts +23 -0
- package/dist/connections/ConnectionsPage.d.ts.map +1 -0
- package/dist/connections/ConnectionsPage.js +219 -0
- package/dist/connections/ConnectionsPage.js.map +1 -0
- package/dist/connections/connectionActionStatus.cjs +43 -0
- package/dist/connections/connectionActionStatus.cjs.map +1 -0
- package/dist/connections/connectionActionStatus.d.ts +5 -0
- package/dist/connections/connectionActionStatus.d.ts.map +1 -0
- package/dist/connections/connectionActionStatus.js +43 -0
- package/dist/connections/connectionActionStatus.js.map +1 -0
- package/dist/connections/connectionActionTypes.cjs +24 -0
- package/dist/connections/connectionActionTypes.cjs.map +1 -0
- package/dist/connections/connectionActionTypes.d.ts +36 -0
- package/dist/connections/connectionActionTypes.d.ts.map +1 -0
- package/dist/connections/connectionActionTypes.js +24 -0
- package/dist/connections/connectionActionTypes.js.map +1 -0
- package/dist/connections/connectionActions.cjs +11 -0
- package/dist/connections/connectionActions.cjs.map +1 -0
- package/dist/connections/connectionActions.d.ts +15 -0
- package/dist/connections/connectionActions.d.ts.map +1 -0
- package/dist/connections/connectionActions.js +11 -0
- package/dist/connections/connectionActions.js.map +1 -0
- package/dist/connections/connectionDashboard.cjs +185 -0
- package/dist/connections/connectionDashboard.cjs.map +1 -0
- package/dist/connections/connectionDashboard.d.ts +25 -0
- package/dist/connections/connectionDashboard.d.ts.map +1 -0
- package/dist/connections/connectionDashboard.js +185 -0
- package/dist/connections/connectionDashboard.js.map +1 -0
- package/dist/connections/connectionDashboardModel.cjs +43 -0
- package/dist/connections/connectionDashboardModel.cjs.map +1 -0
- package/dist/connections/connectionDashboardModel.d.ts +75 -0
- package/dist/connections/connectionDashboardModel.d.ts.map +1 -0
- package/dist/connections/connectionDashboardModel.js +43 -0
- package/dist/connections/connectionDashboardModel.js.map +1 -0
- package/dist/connections/connectionDashboardRenderer.cjs +21 -0
- package/dist/connections/connectionDashboardRenderer.cjs.map +1 -0
- package/dist/connections/connectionDashboardRenderer.d.ts +15 -0
- package/dist/connections/connectionDashboardRenderer.d.ts.map +1 -0
- package/dist/connections/connectionDashboardRenderer.js +21 -0
- package/dist/connections/connectionDashboardRenderer.js.map +1 -0
- package/dist/connections/connectionDashboardRow.cjs +169 -0
- package/dist/connections/connectionDashboardRow.cjs.map +1 -0
- package/dist/connections/connectionDashboardRow.d.ts +12 -0
- package/dist/connections/connectionDashboardRow.d.ts.map +1 -0
- package/dist/connections/connectionDashboardRow.js +169 -0
- package/dist/connections/connectionDashboardRow.js.map +1 -0
- package/dist/connections/connectionErrorView.cjs +8 -0
- package/dist/connections/connectionErrorView.cjs.map +1 -0
- package/dist/connections/connectionErrorView.d.ts +4 -0
- package/dist/connections/connectionErrorView.d.ts.map +1 -0
- package/dist/connections/connectionErrorView.js +8 -0
- package/dist/connections/connectionErrorView.js.map +1 -0
- package/dist/connections/connectionHealth.cjs +82 -0
- package/dist/connections/connectionHealth.cjs.map +1 -0
- package/dist/connections/connectionHealth.d.ts +33 -0
- package/dist/connections/connectionHealth.d.ts.map +1 -0
- package/dist/connections/connectionHealth.js +82 -0
- package/dist/connections/connectionHealth.js.map +1 -0
- package/dist/connections/connectionLogging.cjs +29 -0
- package/dist/connections/connectionLogging.cjs.map +1 -0
- package/dist/connections/connectionLogging.d.ts +11 -0
- package/dist/connections/connectionLogging.d.ts.map +1 -0
- package/dist/connections/connectionLogging.js +29 -0
- package/dist/connections/connectionLogging.js.map +1 -0
- package/dist/connections/connectionLoggingField.cjs +37 -0
- package/dist/connections/connectionLoggingField.cjs.map +1 -0
- package/dist/connections/connectionLoggingField.d.ts +12 -0
- package/dist/connections/connectionLoggingField.d.ts.map +1 -0
- package/dist/connections/connectionLoggingField.js +37 -0
- package/dist/connections/connectionLoggingField.js.map +1 -0
- package/dist/connections/connectionLoggingModel.cjs +16 -0
- package/dist/connections/connectionLoggingModel.cjs.map +1 -0
- package/dist/connections/connectionLoggingModel.d.ts +6 -0
- package/dist/connections/connectionLoggingModel.d.ts.map +1 -0
- package/dist/connections/connectionLoggingModel.js +16 -0
- package/dist/connections/connectionLoggingModel.js.map +1 -0
- package/dist/connections/connectionResolveView.cjs +24 -0
- package/dist/connections/connectionResolveView.cjs.map +1 -0
- package/dist/connections/connectionResolveView.d.ts +5 -0
- package/dist/connections/connectionResolveView.d.ts.map +1 -0
- package/dist/connections/connectionResolveView.js +24 -0
- package/dist/connections/connectionResolveView.js.map +1 -0
- package/dist/connections/connectionTestButton.cjs +58 -0
- package/dist/connections/connectionTestButton.cjs.map +1 -0
- package/dist/connections/connectionTestButton.d.ts +6 -0
- package/dist/connections/connectionTestButton.d.ts.map +1 -0
- package/dist/connections/connectionTestButton.js +58 -0
- package/dist/connections/connectionTestButton.js.map +1 -0
- package/dist/connections/connectionTestView.cjs +12 -0
- package/dist/connections/connectionTestView.cjs.map +1 -0
- package/dist/connections/connectionTestView.d.ts +5 -0
- package/dist/connections/connectionTestView.d.ts.map +1 -0
- package/dist/connections/connectionTestView.js +12 -0
- package/dist/connections/connectionTestView.js.map +1 -0
- package/dist/connections/connectionsPageModel.cjs +33 -0
- package/dist/connections/connectionsPageModel.cjs.map +1 -0
- package/dist/connections/connectionsPageModel.d.ts +24 -0
- package/dist/connections/connectionsPageModel.d.ts.map +1 -0
- package/dist/connections/connectionsPageModel.js +33 -0
- package/dist/connections/connectionsPageModel.js.map +1 -0
- package/dist/connections/iconProvider.cjs +20 -0
- package/dist/connections/iconProvider.cjs.map +1 -0
- package/dist/connections/iconProvider.d.ts +7 -0
- package/dist/connections/iconProvider.d.ts.map +1 -0
- package/dist/connections/iconProvider.js +20 -0
- package/dist/connections/iconProvider.js.map +1 -0
- package/dist/connections.cjs +45 -0
- package/dist/connections.cjs.map +1 -0
- package/dist/connections.d.ts +34 -0
- package/dist/connections.d.ts.map +1 -0
- package/dist/connections.js +45 -0
- package/dist/connections.js.map +1 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +52 -295
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +47 -290
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
- package/dist/data/diagnostics/MetricTile.cjs +44 -0
- package/dist/data/diagnostics/MetricTile.cjs.map +1 -0
- package/dist/data/diagnostics/MetricTile.d.ts +13 -0
- package/dist/data/diagnostics/MetricTile.d.ts.map +1 -0
- package/dist/data/diagnostics/MetricTile.js +44 -0
- package/dist/data/diagnostics/MetricTile.js.map +1 -0
- package/dist/data/diagnostics/StackDumpView.cjs +227 -0
- package/dist/data/diagnostics/StackDumpView.cjs.map +1 -0
- package/dist/data/diagnostics/StackDumpView.d.ts +53 -0
- package/dist/data/diagnostics/StackDumpView.d.ts.map +1 -0
- package/dist/data/diagnostics/StackDumpView.js +227 -0
- package/dist/data/diagnostics/StackDumpView.js.map +1 -0
- package/dist/data/diagnostics/fixtures.d.ts +1 -0
- package/dist/data/diagnostics/fixtures.d.ts.map +1 -1
- package/dist/data/diagnostics/metric-tone.cjs +18 -0
- package/dist/data/diagnostics/metric-tone.cjs.map +1 -0
- package/dist/data/diagnostics/metric-tone.d.ts +6 -0
- package/dist/data/diagnostics/metric-tone.d.ts.map +1 -0
- package/dist/data/diagnostics/metric-tone.js +18 -0
- package/dist/data/diagnostics/metric-tone.js.map +1 -0
- package/dist/data/diagnostics/stacktrace.cjs +44 -0
- package/dist/data/diagnostics/stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/stacktrace.d.ts +7 -0
- package/dist/data/diagnostics/stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/stacktrace.js +44 -0
- package/dist/data/diagnostics/stacktrace.js.map +1 -1
- package/dist/data/diagnostics/types.d.ts +2 -8
- package/dist/data/diagnostics/types.d.ts.map +1 -1
- package/dist/data/lint/LintDetail.cjs +339 -0
- package/dist/data/lint/LintDetail.cjs.map +1 -0
- package/dist/data/lint/LintDetail.d.ts +17 -0
- package/dist/data/lint/LintDetail.d.ts.map +1 -0
- package/dist/data/lint/LintDetail.js +339 -0
- package/dist/data/lint/LintDetail.js.map +1 -0
- package/dist/data/lint/LintFilterBar.cjs +103 -0
- package/dist/data/lint/LintFilterBar.cjs.map +1 -0
- package/dist/data/lint/LintFilterBar.d.ts +16 -0
- package/dist/data/lint/LintFilterBar.d.ts.map +1 -0
- package/dist/data/lint/LintFilterBar.js +103 -0
- package/dist/data/lint/LintFilterBar.js.map +1 -0
- package/dist/data/lint/LintResults.cjs +144 -0
- package/dist/data/lint/LintResults.cjs.map +1 -0
- package/dist/data/lint/LintResults.d.ts +39 -0
- package/dist/data/lint/LintResults.d.ts.map +1 -0
- package/dist/data/lint/LintResults.fixtures.d.ts +10 -0
- package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -0
- package/dist/data/lint/LintResults.js +144 -0
- package/dist/data/lint/LintResults.js.map +1 -0
- package/dist/data/lint/LintTreeNode.cjs +66 -0
- package/dist/data/lint/LintTreeNode.cjs.map +1 -0
- package/dist/data/lint/LintTreeNode.d.ts +7 -0
- package/dist/data/lint/LintTreeNode.d.ts.map +1 -0
- package/dist/data/lint/LintTreeNode.js +66 -0
- package/dist/data/lint/LintTreeNode.js.map +1 -0
- package/dist/data/lint/actions.cjs +195 -0
- package/dist/data/lint/actions.cjs.map +1 -0
- package/dist/data/lint/actions.d.ts +29 -0
- package/dist/data/lint/actions.d.ts.map +1 -0
- package/dist/data/lint/actions.js +195 -0
- package/dist/data/lint/actions.js.map +1 -0
- package/dist/data/lint/grouping-options.cjs +14 -0
- package/dist/data/lint/grouping-options.cjs.map +1 -0
- package/dist/data/lint/grouping-options.d.ts +9 -0
- package/dist/data/lint/grouping-options.d.ts.map +1 -0
- package/dist/data/lint/grouping-options.js +14 -0
- package/dist/data/lint/grouping-options.js.map +1 -0
- package/dist/data/lint/grouping.cjs +450 -0
- package/dist/data/lint/grouping.cjs.map +1 -0
- package/dist/data/lint/grouping.d.ts +10 -0
- package/dist/data/lint/grouping.d.ts.map +1 -0
- package/dist/data/lint/grouping.js +450 -0
- package/dist/data/lint/grouping.js.map +1 -0
- package/dist/data/lint/index.d.ts +10 -0
- package/dist/data/lint/index.d.ts.map +1 -0
- package/dist/data/lint/paths.cjs +35 -0
- package/dist/data/lint/paths.cjs.map +1 -0
- package/dist/data/lint/paths.d.ts +13 -0
- package/dist/data/lint/paths.d.ts.map +1 -0
- package/dist/data/lint/paths.js +35 -0
- package/dist/data/lint/paths.js.map +1 -0
- package/dist/data/lint/stats.cjs +76 -0
- package/dist/data/lint/stats.cjs.map +1 -0
- package/dist/data/lint/stats.d.ts +19 -0
- package/dist/data/lint/stats.d.ts.map +1 -0
- package/dist/data/lint/stats.js +76 -0
- package/dist/data/lint/stats.js.map +1 -0
- package/dist/data/lint/types.cjs +16 -0
- package/dist/data/lint/types.cjs.map +1 -0
- package/dist/data/lint/types.d.ts +93 -0
- package/dist/data/lint/types.d.ts.map +1 -0
- package/dist/data/lint/types.js +16 -0
- package/dist/data/lint/types.js.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.cjs +113 -0
- package/dist/data/test-runner/TestAttemptDetail.cjs.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.d.ts +19 -0
- package/dist/data/test-runner/TestAttemptDetail.d.ts.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.js +113 -0
- package/dist/data/test-runner/TestAttemptDetail.js.map +1 -0
- package/dist/data/test-runner/TestAttempts.cjs +36 -0
- package/dist/data/test-runner/TestAttempts.cjs.map +1 -0
- package/dist/data/test-runner/TestAttempts.d.ts +5 -0
- package/dist/data/test-runner/TestAttempts.d.ts.map +1 -0
- package/dist/data/test-runner/TestAttempts.js +36 -0
- package/dist/data/test-runner/TestAttempts.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +13 -3
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +14 -4
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.cjs +9 -29
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.d.ts +6 -6
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.js +9 -29
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +33 -0
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +34 -1
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +3 -0
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +8 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +3 -0
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +3 -1
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +3 -1
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +9 -1
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +5 -0
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +9 -1
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/attempts.cjs +62 -0
- package/dist/data/test-runner/attempts.cjs.map +1 -0
- package/dist/data/test-runner/attempts.d.ts +13 -0
- package/dist/data/test-runner/attempts.d.ts.map +1 -0
- package/dist/data/test-runner/attempts.js +62 -0
- package/dist/data/test-runner/attempts.js.map +1 -0
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +6 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +5 -1
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +2 -0
- package/dist/data/test-runner/marks.cjs.map +1 -1
- package/dist/data/test-runner/marks.d.ts.map +1 -1
- package/dist/data/test-runner/marks.js +2 -0
- package/dist/data/test-runner/marks.js.map +1 -1
- package/dist/data/test-runner/process-metrics.cjs +15 -0
- package/dist/data/test-runner/process-metrics.cjs.map +1 -0
- package/dist/data/test-runner/process-metrics.d.ts +22 -0
- package/dist/data/test-runner/process-metrics.d.ts.map +1 -0
- package/dist/data/test-runner/process-metrics.js +15 -0
- package/dist/data/test-runner/process-metrics.js.map +1 -0
- package/dist/data/test-runner/status.cjs +11 -3
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.d.ts +3 -1
- package/dist/data/test-runner/status.d.ts.map +1 -1
- package/dist/data/test-runner/status.js +11 -3
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/test-runner/types.d.ts +14 -0
- package/dist/data/test-runner/types.d.ts.map +1 -1
- package/dist/data/traces/GoProfileView.cjs +176 -0
- package/dist/data/traces/GoProfileView.cjs.map +1 -0
- package/dist/data/traces/GoProfileView.d.ts +30 -0
- package/dist/data/traces/GoProfileView.d.ts.map +1 -0
- package/dist/data/traces/GoProfileView.js +176 -0
- package/dist/data/traces/GoProfileView.js.map +1 -0
- package/dist/data/traces/ProcessFacetTable.cjs +79 -0
- package/dist/data/traces/ProcessFacetTable.cjs.map +1 -0
- package/dist/data/traces/ProcessFacetTable.d.ts +21 -0
- package/dist/data/traces/ProcessFacetTable.d.ts.map +1 -0
- package/dist/data/traces/ProcessFacetTable.js +79 -0
- package/dist/data/traces/ProcessFacetTable.js.map +1 -0
- package/dist/data/traces/ProcessRecordViews.cjs +41 -0
- package/dist/data/traces/ProcessRecordViews.cjs.map +1 -0
- package/dist/data/traces/ProcessRecordViews.d.ts +16 -0
- package/dist/data/traces/ProcessRecordViews.d.ts.map +1 -0
- package/dist/data/traces/ProcessRecordViews.js +41 -0
- package/dist/data/traces/ProcessRecordViews.js.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.cjs +316 -0
- package/dist/data/traces/ProcessTraceDetail.cjs.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.d.ts +39 -0
- package/dist/data/traces/ProcessTraceDetail.d.ts.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.js +316 -0
- package/dist/data/traces/ProcessTraceDetail.js.map +1 -0
- package/dist/data/traces/ProcessTraceTree.cjs +76 -34
- package/dist/data/traces/ProcessTraceTree.cjs.map +1 -1
- package/dist/data/traces/ProcessTraceTree.d.ts +21 -4
- package/dist/data/traces/ProcessTraceTree.d.ts.map +1 -1
- package/dist/data/traces/ProcessTraceTree.js +72 -30
- package/dist/data/traces/ProcessTraceTree.js.map +1 -1
- package/dist/data/traces/Sparkline.cjs +27 -5
- package/dist/data/traces/Sparkline.cjs.map +1 -1
- package/dist/data/traces/Sparkline.d.ts +17 -1
- package/dist/data/traces/Sparkline.d.ts.map +1 -1
- package/dist/data/traces/Sparkline.js +28 -6
- package/dist/data/traces/Sparkline.js.map +1 -1
- package/dist/data/traces/TraceView.cjs +9 -0
- package/dist/data/traces/TraceView.cjs.map +1 -1
- package/dist/data/traces/TraceView.d.ts +4 -2
- package/dist/data/traces/TraceView.d.ts.map +1 -1
- package/dist/data/traces/TraceView.js +9 -0
- package/dist/data/traces/TraceView.js.map +1 -1
- package/dist/data/traces/TraceWindowList.cjs +117 -0
- package/dist/data/traces/TraceWindowList.cjs.map +1 -0
- package/dist/data/traces/TraceWindowList.d.ts +48 -0
- package/dist/data/traces/TraceWindowList.d.ts.map +1 -0
- package/dist/data/traces/TraceWindowList.js +117 -0
- package/dist/data/traces/TraceWindowList.js.map +1 -0
- package/dist/data/traces/fixtures.d.ts +25 -1
- package/dist/data/traces/fixtures.d.ts.map +1 -1
- package/dist/data/traces/index.d.ts +10 -3
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/traces/process-facets.cjs +48 -0
- package/dist/data/traces/process-facets.cjs.map +1 -0
- package/dist/data/traces/process-facets.d.ts +38 -0
- package/dist/data/traces/process-facets.d.ts.map +1 -0
- package/dist/data/traces/process-facets.js +48 -0
- package/dist/data/traces/process-facets.js.map +1 -0
- package/dist/data/traces/process-tree.cjs +36 -4
- package/dist/data/traces/process-tree.cjs.map +1 -1
- package/dist/data/traces/process-tree.d.ts +20 -1
- package/dist/data/traces/process-tree.d.ts.map +1 -1
- package/dist/data/traces/process-tree.js +36 -4
- package/dist/data/traces/process-tree.js.map +1 -1
- package/dist/data/traces/profile-aggregate.cjs +78 -0
- package/dist/data/traces/profile-aggregate.cjs.map +1 -0
- package/dist/data/traces/profile-aggregate.d.ts +41 -0
- package/dist/data/traces/profile-aggregate.d.ts.map +1 -0
- package/dist/data/traces/profile-aggregate.js +78 -0
- package/dist/data/traces/profile-aggregate.js.map +1 -0
- package/dist/data/traces/stack-checkpoints.cjs +22 -0
- package/dist/data/traces/stack-checkpoints.cjs.map +1 -0
- package/dist/data/traces/stack-checkpoints.d.ts +18 -0
- package/dist/data/traces/stack-checkpoints.d.ts.map +1 -0
- package/dist/data/traces/stack-checkpoints.js +22 -0
- package/dist/data/traces/stack-checkpoints.js.map +1 -0
- package/dist/data/traces/types.d.ts +120 -5
- package/dist/data/traces/types.d.ts.map +1 -1
- package/dist/data/verification/adapters.cjs +1 -0
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +1 -0
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +85 -7
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +4 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +81 -3
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +87 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -3
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { FailureDetail, Test
|
|
2
|
-
/**
|
|
1
|
+
import { FailureDetail, Test } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Renders a structured failure: its summary, the expectation, and the stack.
|
|
4
|
+
* A stack that is a Go goroutine dump (a panic) is shown as searchable
|
|
5
|
+
* goroutine cards; any other stack stays a log.
|
|
6
|
+
*/
|
|
3
7
|
export declare function TestFailureDetail({ failure }: {
|
|
4
8
|
failure: FailureDetail;
|
|
5
9
|
}): import("react").JSX.Element;
|
|
@@ -7,8 +11,4 @@ export declare function TestFailureDetail({ failure }: {
|
|
|
7
11
|
export declare function TestOutput({ node }: {
|
|
8
12
|
node: Test;
|
|
9
13
|
}): import("react").JSX.Element | null;
|
|
10
|
-
/** Prior attempts list for flaky/reran tests. */
|
|
11
|
-
export declare function TestAttempts({ attempts }: {
|
|
12
|
-
attempts: TestAttempt[];
|
|
13
|
-
}): import("react").JSX.Element | null;
|
|
14
14
|
//# sourceMappingURL=TestFailureDetail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestFailureDetail.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestFailureDetail.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TestFailureDetail.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestFailureDetail.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAanD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,aAAa,CAAA;CAAE,+BAuBxE;AAKD,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,sCAuBlD"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
2
3
|
import { LogViewer } from "../LogViewer.js";
|
|
3
|
-
import {
|
|
4
|
+
import { parseStackDump } from "../diagnostics/stacktrace.js";
|
|
5
|
+
import { StackDumpView } from "../diagnostics/StackDumpView.js";
|
|
4
6
|
import { Expectation } from "./Expectation.js";
|
|
5
|
-
|
|
7
|
+
function FailureStack({ stack }) {
|
|
8
|
+
const parsed = useMemo(() => parseStackDump(stack), [stack]);
|
|
9
|
+
if (parsed.format !== "go") return /* @__PURE__ */ jsx(LogViewer, { logs: stack, collapsedLines: 6 });
|
|
10
|
+
return /* @__PURE__ */ jsx("div", { className: "flex max-h-[32rem] min-h-0 flex-col", "data-failure-stack": "go", children: /* @__PURE__ */ jsx(StackDumpView, { text: stack, singleItem: parsed.goroutines.length === 1 }) });
|
|
11
|
+
}
|
|
6
12
|
function TestFailureDetail({ failure }) {
|
|
7
13
|
const hasExpectation = !!(failure.matcher || failure.expected || failure.actual || failure.location);
|
|
8
14
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
@@ -16,7 +22,7 @@ function TestFailureDetail({ failure }) {
|
|
|
16
22
|
location: failure.location
|
|
17
23
|
}
|
|
18
24
|
),
|
|
19
|
-
failure.stack && /* @__PURE__ */ jsx(
|
|
25
|
+
failure.stack && /* @__PURE__ */ jsx(FailureStack, { stack: failure.stack })
|
|
20
26
|
] });
|
|
21
27
|
}
|
|
22
28
|
const OUTPUT_MAX_HEIGHT = "25cqh";
|
|
@@ -41,33 +47,7 @@ function TestOutput({ node }) {
|
|
|
41
47
|
] })
|
|
42
48
|
] });
|
|
43
49
|
}
|
|
44
|
-
function attemptTone(a) {
|
|
45
|
-
if (a.failed || a.timed_out) return "text-red-600 dark:text-red-400";
|
|
46
|
-
if (a.passed) return "text-green-600 dark:text-green-400";
|
|
47
|
-
return "text-muted-foreground";
|
|
48
|
-
}
|
|
49
|
-
function TestAttempts({ attempts }) {
|
|
50
|
-
if (attempts.length === 0) return null;
|
|
51
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
52
|
-
/* @__PURE__ */ jsxs("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: [
|
|
53
|
-
"Attempts (",
|
|
54
|
-
attempts.length,
|
|
55
|
-
")"
|
|
56
|
-
] }),
|
|
57
|
-
/* @__PURE__ */ jsx("ul", { className: "divide-y divide-border rounded-md border border-border text-xs", children: attempts.map((a) => /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2 px-2 py-1", children: [
|
|
58
|
-
/* @__PURE__ */ jsxs("span", { className: cn("font-medium", attemptTone(a)), children: [
|
|
59
|
-
"#",
|
|
60
|
-
a.sequence,
|
|
61
|
-
" ",
|
|
62
|
-
a.run_kind ?? ""
|
|
63
|
-
] }),
|
|
64
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-muted-foreground", children: a.message }),
|
|
65
|
-
a.duration ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: formatTestDuration(a.duration) }) : null
|
|
66
|
-
] }, a.sequence)) })
|
|
67
|
-
] });
|
|
68
|
-
}
|
|
69
50
|
export {
|
|
70
|
-
TestAttempts,
|
|
71
51
|
TestFailureDetail,
|
|
72
52
|
TestOutput
|
|
73
53
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestFailureDetail.js","sources":["../../../src/data/test-runner/TestFailureDetail.tsx"],"sourcesContent":["import { LogViewer } from \"../LogViewer\";\nimport {
|
|
1
|
+
{"version":3,"file":"TestFailureDetail.js","sources":["../../../src/data/test-runner/TestFailureDetail.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { LogViewer } from \"../LogViewer\";\nimport { parseStackDump } from \"../diagnostics/stacktrace\";\nimport { StackDumpView } from \"../diagnostics/StackDumpView\";\nimport { Expectation } from \"./Expectation\";\nimport type { FailureDetail, Test } from \"./types\";\n\n/** A failure stack: a Go panic dump as goroutine cards, anything else as a log. */\nfunction FailureStack({ stack }: { stack: string }) {\n const parsed = useMemo(() => parseStackDump(stack), [stack]);\n if (parsed.format !== \"go\") return <LogViewer logs={stack} collapsedLines={6} />;\n return (\n <div className=\"flex max-h-[32rem] min-h-0 flex-col\" data-failure-stack=\"go\">\n <StackDumpView text={stack} singleItem={parsed.goroutines.length === 1} />\n </div>\n );\n}\n\n/**\n * Renders a structured failure: its summary, the expectation, and the stack.\n * A stack that is a Go goroutine dump (a panic) is shown as searchable\n * goroutine cards; any other stack stays a log.\n */\nexport function TestFailureDetail({ failure }: { failure: FailureDetail }) {\n const hasExpectation = !!(\n failure.matcher ||\n failure.expected ||\n failure.actual ||\n failure.location\n );\n return (\n <div className=\"space-y-2\">\n {failure.summary && (\n <p className=\"text-sm font-medium text-red-700 dark:text-red-300\">{failure.summary}</p>\n )}\n {hasExpectation && (\n <Expectation\n check={failure.matcher}\n expected={failure.expected || undefined}\n actual={failure.actual || undefined}\n location={failure.location}\n />\n )}\n {failure.stack && <FailureStack stack={failure.stack} />}\n </div>\n );\n}\n\n// A quarter of the detail pane, which TestDetailPanel makes a size container.\nconst OUTPUT_MAX_HEIGHT = \"25cqh\";\n\n/** stdout / stderr as terminal blocks, each scrolling within a quarter of the detail pane. */\nexport function TestOutput({ node }: { node: Test }) {\n if (!node.stdout && !node.stderr) return null;\n return (\n <div className=\"space-y-3\">\n {node.stdout && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">stdout</div>\n <LogViewer logs={node.stdout} variant=\"terminal\" maxHeight={OUTPUT_MAX_HEIGHT} />\n </div>\n )}\n {node.stderr && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">stderr</div>\n <LogViewer\n logs={node.stderr}\n variant=\"terminal\"\n maxHeight={OUTPUT_MAX_HEIGHT}\n borderClass=\"border-red-500/70\"\n />\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AAQA,SAAS,aAAa,EAAE,SAA4B;AAClD,QAAM,SAAS,QAAQ,MAAM,eAAe,KAAK,GAAG,CAAC,KAAK,CAAC;AAC3D,MAAI,OAAO,WAAW,KAAM,4BAAQ,WAAA,EAAU,MAAM,OAAO,gBAAgB,EAAA,CAAG;AAC9E,SACE,oBAAC,OAAA,EAAI,WAAU,uCAAsC,sBAAmB,MACtE,UAAA,oBAAC,eAAA,EAAc,MAAM,OAAO,YAAY,OAAO,WAAW,WAAW,GAAG,GAC1E;AAEJ;AAOO,SAAS,kBAAkB,EAAE,WAAuC;AACzE,QAAM,iBAAiB,CAAC,EACtB,QAAQ,WACR,QAAQ,YACR,QAAQ,UACR,QAAQ;AAEV,SACE,qBAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA,QAAQ,WACP,oBAAC,KAAA,EAAE,WAAU,sDAAsD,kBAAQ,SAAQ;AAAA,IAEpF,kBACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ,YAAY;AAAA,QAC9B,QAAQ,QAAQ,UAAU;AAAA,QAC1B,UAAU,QAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAGrB,QAAQ,SAAS,oBAAC,cAAA,EAAa,OAAO,QAAQ,MAAA,CAAO;AAAA,EAAA,GACxD;AAEJ;AAGA,MAAM,oBAAoB;AAGnB,SAAS,WAAW,EAAE,QAAwB;AACnD,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,OAAQ,QAAO;AACzC,SACE,qBAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA,KAAK,UACJ,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,6DAA4D,UAAA,UAAM;AAAA,MACjF,oBAAC,aAAU,MAAM,KAAK,QAAQ,SAAQ,YAAW,WAAW,kBAAA,CAAmB;AAAA,IAAA,GACjF;AAAA,IAED,KAAK,UACJ,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,6DAA4D,UAAA,UAAM;AAAA,MACjF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM,KAAK;AAAA,UACX,SAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACd,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;"}
|
|
@@ -31,6 +31,7 @@ function TestRunSummary({
|
|
|
31
31
|
{ count: t.skipped, color: "bg-yellow-400", label: "skipped" },
|
|
32
32
|
{ count: t.failed, color: "bg-red-500", label: "failed" },
|
|
33
33
|
{ count: t.warned, color: "bg-amber-400", label: "warned" },
|
|
34
|
+
{ count: t.aborted, color: "bg-red-300", label: "aborted" },
|
|
34
35
|
{ count: t.timedout, color: "bg-amber-500", label: "timed out" },
|
|
35
36
|
{ count: t.running, color: "bg-blue-400", label: "running" },
|
|
36
37
|
{ count: t.pending, color: "bg-muted-foreground/40", label: "queued" }
|
|
@@ -39,6 +40,7 @@ function TestRunSummary({
|
|
|
39
40
|
{ n: t.passed, label: "passed", outcome: "passed" },
|
|
40
41
|
{ n: t.failed, label: "failed", outcome: "failed" },
|
|
41
42
|
{ n: t.warned, label: "warned", outcome: "warned" },
|
|
43
|
+
{ n: t.aborted, label: "aborted", outcome: "aborted" },
|
|
42
44
|
{ n: t.timedout, label: "timed out", outcome: "timedout" },
|
|
43
45
|
{ n: t.skipped, label: "skipped", outcome: "skipped" },
|
|
44
46
|
{ n: t.running, label: "running", outcome: "running" },
|
|
@@ -61,6 +63,35 @@ function TestRunSummary({
|
|
|
61
63
|
},
|
|
62
64
|
c.label
|
|
63
65
|
));
|
|
66
|
+
const runChips = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
67
|
+
(runMeta == null ? void 0 : runMeta.timed_out) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68
|
+
"span",
|
|
69
|
+
{
|
|
70
|
+
className: utils.cn("inline-flex items-center gap-0.5", marks.TEST_OUTCOMES.timedout.className),
|
|
71
|
+
title: "The run hit its timeout",
|
|
72
|
+
"data-summary-run": "timed-out",
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx(MarkIcons.OutcomeIcon, { outcome: "timedout" }),
|
|
75
|
+
"Timed out"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
(runMeta == null ? void 0 : runMeta.exit_code) !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
80
|
+
"span",
|
|
81
|
+
{
|
|
82
|
+
className: utils.cn(
|
|
83
|
+
"inline-flex items-center tabular-nums",
|
|
84
|
+
runMeta.exit_code === 0 ? "text-muted-foreground" : marks.TEST_OUTCOMES.failed.className
|
|
85
|
+
),
|
|
86
|
+
title: `Exit code ${runMeta.exit_code}`,
|
|
87
|
+
"data-summary-run": "exit-code",
|
|
88
|
+
children: [
|
|
89
|
+
"exit ",
|
|
90
|
+
runMeta.exit_code
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
] });
|
|
64
95
|
if (compact) {
|
|
65
96
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
66
97
|
"div",
|
|
@@ -77,6 +108,7 @@ function TestRunSummary({
|
|
|
77
108
|
(runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
|
|
78
109
|
] }),
|
|
79
110
|
chipRow,
|
|
111
|
+
runChips,
|
|
80
112
|
elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
81
113
|
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClock.UiClock, className: "text-xs" }),
|
|
82
114
|
elapsed
|
|
@@ -102,6 +134,7 @@ function TestRunSummary({
|
|
|
102
134
|
(runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
|
|
103
135
|
] }),
|
|
104
136
|
chipRow,
|
|
137
|
+
runChips,
|
|
105
138
|
elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
106
139
|
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClock.UiClock, className: "text-xs" }),
|
|
107
140
|
elapsed
|
|
@@ -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 { 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
|
+
{"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.aborted, color: \"bg-red-300\", label: \"aborted\" },\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.aborted, label: \"aborted\", outcome: \"aborted\" },\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 const runChips = (\n <>\n {runMeta?.timed_out && (\n <span\n className={cn(\"inline-flex items-center gap-0.5\", TEST_OUTCOMES.timedout.className)}\n title=\"The run hit its timeout\"\n data-summary-run=\"timed-out\"\n >\n <OutcomeIcon outcome=\"timedout\" />\n Timed out\n </span>\n )}\n {runMeta?.exit_code !== undefined && (\n <span\n className={cn(\n \"inline-flex items-center tabular-nums\",\n runMeta.exit_code === 0 ? \"text-muted-foreground\" : TEST_OUTCOMES.failed.className,\n )}\n title={`Exit code ${runMeta.exit_code}`}\n data-summary-run=\"exit-code\"\n >\n exit {runMeta.exit_code}\n </span>\n )}\n </>\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 {runChips}\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 {runChips}\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","Fragment","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;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,+
|
|
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,+BAuIrB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Icon } from "../Icon.js";
|
|
3
3
|
import { ProgressBar } from "../ProgressBar.js";
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
@@ -29,6 +29,7 @@ function TestRunSummary({
|
|
|
29
29
|
{ count: t.skipped, color: "bg-yellow-400", label: "skipped" },
|
|
30
30
|
{ count: t.failed, color: "bg-red-500", label: "failed" },
|
|
31
31
|
{ count: t.warned, color: "bg-amber-400", label: "warned" },
|
|
32
|
+
{ count: t.aborted, color: "bg-red-300", label: "aborted" },
|
|
32
33
|
{ count: t.timedout, color: "bg-amber-500", label: "timed out" },
|
|
33
34
|
{ count: t.running, color: "bg-blue-400", label: "running" },
|
|
34
35
|
{ count: t.pending, color: "bg-muted-foreground/40", label: "queued" }
|
|
@@ -37,6 +38,7 @@ function TestRunSummary({
|
|
|
37
38
|
{ n: t.passed, label: "passed", outcome: "passed" },
|
|
38
39
|
{ n: t.failed, label: "failed", outcome: "failed" },
|
|
39
40
|
{ n: t.warned, label: "warned", outcome: "warned" },
|
|
41
|
+
{ n: t.aborted, label: "aborted", outcome: "aborted" },
|
|
40
42
|
{ n: t.timedout, label: "timed out", outcome: "timedout" },
|
|
41
43
|
{ n: t.skipped, label: "skipped", outcome: "skipped" },
|
|
42
44
|
{ n: t.running, label: "running", outcome: "running" },
|
|
@@ -59,6 +61,35 @@ function TestRunSummary({
|
|
|
59
61
|
},
|
|
60
62
|
c.label
|
|
61
63
|
));
|
|
64
|
+
const runChips = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65
|
+
(runMeta == null ? void 0 : runMeta.timed_out) && /* @__PURE__ */ jsxs(
|
|
66
|
+
"span",
|
|
67
|
+
{
|
|
68
|
+
className: cn("inline-flex items-center gap-0.5", TEST_OUTCOMES.timedout.className),
|
|
69
|
+
title: "The run hit its timeout",
|
|
70
|
+
"data-summary-run": "timed-out",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(OutcomeIcon, { outcome: "timedout" }),
|
|
73
|
+
"Timed out"
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
(runMeta == null ? void 0 : runMeta.exit_code) !== void 0 && /* @__PURE__ */ jsxs(
|
|
78
|
+
"span",
|
|
79
|
+
{
|
|
80
|
+
className: cn(
|
|
81
|
+
"inline-flex items-center tabular-nums",
|
|
82
|
+
runMeta.exit_code === 0 ? "text-muted-foreground" : TEST_OUTCOMES.failed.className
|
|
83
|
+
),
|
|
84
|
+
title: `Exit code ${runMeta.exit_code}`,
|
|
85
|
+
"data-summary-run": "exit-code",
|
|
86
|
+
children: [
|
|
87
|
+
"exit ",
|
|
88
|
+
runMeta.exit_code
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
] });
|
|
62
93
|
if (compact) {
|
|
63
94
|
return /* @__PURE__ */ jsxs(
|
|
64
95
|
"div",
|
|
@@ -75,6 +106,7 @@ function TestRunSummary({
|
|
|
75
106
|
(runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
|
|
76
107
|
] }),
|
|
77
108
|
chipRow,
|
|
109
|
+
runChips,
|
|
78
110
|
elapsed && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
79
111
|
/* @__PURE__ */ jsx(Icon, { icon: UiClock, className: "text-xs" }),
|
|
80
112
|
elapsed
|
|
@@ -100,6 +132,7 @@ function TestRunSummary({
|
|
|
100
132
|
(runMeta == null ? void 0 : runMeta.kind) === "rerun" ? ` · rerun #${runMeta.sequence}` : ""
|
|
101
133
|
] }),
|
|
102
134
|
chipRow,
|
|
135
|
+
runChips,
|
|
103
136
|
elapsed && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
104
137
|
/* @__PURE__ */ jsx(Icon, { icon: UiClock, className: "text-xs" }),
|
|
105
138
|
elapsed
|
|
@@ -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 { 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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"}
|
|
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.aborted, color: \"bg-red-300\", label: \"aborted\" },\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.aborted, label: \"aborted\", outcome: \"aborted\" },\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 const runChips = (\n <>\n {runMeta?.timed_out && (\n <span\n className={cn(\"inline-flex items-center gap-0.5\", TEST_OUTCOMES.timedout.className)}\n title=\"The run hit its timeout\"\n data-summary-run=\"timed-out\"\n >\n <OutcomeIcon outcome=\"timedout\" />\n Timed out\n </span>\n )}\n {runMeta?.exit_code !== undefined && (\n <span\n className={cn(\n \"inline-flex items-center tabular-nums\",\n runMeta.exit_code === 0 ? \"text-muted-foreground\" : TEST_OUTCOMES.failed.className,\n )}\n title={`Exit code ${runMeta.exit_code}`}\n data-summary-run=\"exit-code\"\n >\n exit {runMeta.exit_code}\n </span>\n )}\n </>\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 {runChips}\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 {runChips}\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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"}
|
|
@@ -41,6 +41,7 @@ function TestRunner({
|
|
|
41
41
|
onExpandAllChange,
|
|
42
42
|
onRerun,
|
|
43
43
|
onStop,
|
|
44
|
+
fetchProcessMetrics,
|
|
44
45
|
adapters,
|
|
45
46
|
title,
|
|
46
47
|
showSummary = true,
|
|
@@ -72,6 +73,7 @@ function TestRunner({
|
|
|
72
73
|
onExpandAllChange,
|
|
73
74
|
onRerun,
|
|
74
75
|
onStop,
|
|
76
|
+
fetchProcessMetrics,
|
|
75
77
|
adapters: registry
|
|
76
78
|
}),
|
|
77
79
|
[
|
|
@@ -93,6 +95,7 @@ function TestRunner({
|
|
|
93
95
|
onExpandAllChange,
|
|
94
96
|
onRerun,
|
|
95
97
|
onStop,
|
|
98
|
+
fetchProcessMetrics,
|
|
96
99
|
registry
|
|
97
100
|
]
|
|
98
101
|
);
|
|
@@ -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 { 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 activeAttempt?: number;\n onAttemptChange?: (attempt: number) => 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 activeAttempt,\n onAttemptChange,\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 activeAttempt,\n onAttemptChange,\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 activeAttempt,\n onAttemptChange,\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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"}
|
|
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\";\nimport type { FetchProcessMetrics } from \"./process-metrics\";\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 activeAttempt?: number;\n onAttemptChange?: (attempt: number) => 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 /**\n * Reads a live attempt's process (CPU, RSS, open files) by pid. The detail\n * pane polls it every two seconds while the attempt runs, and stops when the\n * attempt finishes or the fetch rejects with `ProcessNotFoundError`.\n */\n fetchProcessMetrics?: FetchProcessMetrics;\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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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"}
|
|
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { RunMeta, SnapshotStatus, Test } from './types.js';
|
|
3
3
|
import { TestFilters } from './filterState.js';
|
|
4
4
|
import { TestNodeAdapter, TestNodeAdapterRegistry } from './adapter.js';
|
|
5
|
+
import { FetchProcessMetrics } from './process-metrics.js';
|
|
5
6
|
export type TestRunnerProps = {
|
|
6
7
|
tests: Test[];
|
|
7
8
|
/**
|
|
@@ -37,6 +38,12 @@ export type TestRunnerProps = {
|
|
|
37
38
|
onExpandAllChange: (next: boolean | null) => void;
|
|
38
39
|
onRerun?: (node: Test) => void;
|
|
39
40
|
onStop?: (node: Test) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Reads a live attempt's process (CPU, RSS, open files) by pid. The detail
|
|
43
|
+
* pane polls it every two seconds while the attempt runs, and stops when the
|
|
44
|
+
* attempt finishes or the fetch rejects with `ProcessNotFoundError`.
|
|
45
|
+
*/
|
|
46
|
+
fetchProcessMetrics?: FetchProcessMetrics;
|
|
40
47
|
/** Domain node adapters, or a pre-built registry. Defaults to default-only. */
|
|
41
48
|
adapters?: TestNodeAdapter[] | TestNodeAdapterRegistry;
|
|
42
49
|
/**
|
|
@@ -73,5 +80,5 @@ export type TestRunnerProps = {
|
|
|
73
80
|
* are exposed to sub-components through a single `TestRunnerContext`. Domain
|
|
74
81
|
* rendering is pluggable via node adapters; no fetch/SSE/routing lives here.
|
|
75
82
|
*/
|
|
76
|
-
export declare function TestRunner({ tests, allTests, selected, filters, expandAll, done, runMeta, status, statusText, now, busy, activeTab, onTabChange, activeAttempt, onAttemptChange, onSelect, onFiltersChange, onExpandAllChange, onRerun, onStop, adapters, title, showSummary, headerSlot, hideHeader, defaultSplit, startTime, endTime, className, }: TestRunnerProps): import("react").JSX.Element;
|
|
83
|
+
export declare function TestRunner({ tests, allTests, selected, filters, expandAll, done, runMeta, status, statusText, now, busy, activeTab, onTabChange, activeAttempt, onAttemptChange, onSelect, onFiltersChange, onExpandAllChange, onRerun, onStop, fetchProcessMetrics, adapters, title, showSummary, headerSlot, hideHeader, defaultSplit, startTime, endTime, className, }: TestRunnerProps): import("react").JSX.Element;
|
|
77
84
|
//# sourceMappingURL=TestRunner.d.ts.map
|
|
@@ -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;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;
|
|
1
|
+
{"version":3,"file":"TestRunner.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestRunner.tsx"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,7 @@ function TestRunner({
|
|
|
39
39
|
onExpandAllChange,
|
|
40
40
|
onRerun,
|
|
41
41
|
onStop,
|
|
42
|
+
fetchProcessMetrics,
|
|
42
43
|
adapters,
|
|
43
44
|
title,
|
|
44
45
|
showSummary = true,
|
|
@@ -70,6 +71,7 @@ function TestRunner({
|
|
|
70
71
|
onExpandAllChange,
|
|
71
72
|
onRerun,
|
|
72
73
|
onStop,
|
|
74
|
+
fetchProcessMetrics,
|
|
73
75
|
adapters: registry
|
|
74
76
|
}),
|
|
75
77
|
[
|
|
@@ -91,6 +93,7 @@ function TestRunner({
|
|
|
91
93
|
onExpandAllChange,
|
|
92
94
|
onRerun,
|
|
93
95
|
onStop,
|
|
96
|
+
fetchProcessMetrics,
|
|
94
97
|
registry
|
|
95
98
|
]
|
|
96
99
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestRunner.js","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 activeAttempt?: number;\n onAttemptChange?: (attempt: number) => 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 activeAttempt,\n onAttemptChange,\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 activeAttempt,\n onAttemptChange,\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 activeAttempt,\n onAttemptChange,\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":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TestRunner.js","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\";\nimport type { FetchProcessMetrics } from \"./process-metrics\";\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 activeAttempt?: number;\n onAttemptChange?: (attempt: number) => 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 /**\n * Reads a live attempt's process (CPU, RSS, open files) by pid. The detail\n * pane polls it every two seconds while the attempt runs, and stops when the\n * attempt finishes or the fetch rejects with `ProcessNotFoundError`.\n */\n fetchProcessMetrics?: FetchProcessMetrics;\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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 activeAttempt,\n onAttemptChange,\n onSelect,\n onFiltersChange,\n onExpandAllChange,\n onRerun,\n onStop,\n fetchProcessMetrics,\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":[],"mappings":";;;;;;;;;;;;;;;AA8FA,SAAS,WACP,UACyB;AACzB,MAAI,oBAAoB,wBAAyB,QAAO;AACxD,SAAO,yBAAyB,YAAY,EAAE;AAChD;AAEA,MAAM,kBAAkB;AAQjB,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,aAAa;AAAA,EACb,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,WAAW,QAAQ,MAAM,WAAW,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAE/D,QAAM,MAAyB;AAAA,IAC7B,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,QAAQ,CAAA;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IAAA;AAAA,IAEZ;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAGF,QAAM,eAAe,YAAY;AACjC,QAAM,aAAa,QAAQ,MAAM,kBAAkB,YAAY,GAAG,CAAC,YAAY,CAAC;AAChF,QAAM,eAAe,QAAQ,MAAM,sBAAsB,YAAY,GAAG,CAAC,YAAY,CAAC;AAEtF,QAAM,YACJ,CAAC,cAAc,aAAa,SAAS,IACnC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR;AAAA,IAAA;AAAA,EAAA,IAEA;AAGN,QAAM,EAAE,KAAK,OAAO,MAAA,IAAU,sBAAsB,eAAe;AAEnE,SACE,oBAAC,oBAAA,EAAmB,OAAO,KACzB,UAAA,qBAAC,OAAA,EAAI,KAAU,WAAW,GAAG,8CAA8C,SAAS,GACjF,UAAA;AAAA,IAAA,CAAC,cACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,sBAAmB;AAAA,QAEnB,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,mCACZ,UAAA;AAAA,YAAA,UAAU,SACT,qBAAC,MAAA,EAAG,WAAU,iEACZ,UAAA;AAAA,cAAA,oBAAC,MAAA,EAAK,MAAM,UAAU,WAAU,gBAAe;AAAA,cAAE;AAAA,YAAA,EAAA,CAEnD,IAEA;AAAA,YAED,cACC,oBAAC,QAAA,EAAK,WAAU,0CAA0C,UAAA,WAAA,CAAW;AAAA,UAAA,GAEzE;AAAA,UACC,eACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,SAAO;AAAA,cACP,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAGb,cACC,oBAAC,OAAA,EAAI,WAAW,GAAG,oCAAoC,CAAC,eAAe,SAAS,GAC7E,UAAA,WAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKL,QACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAU;AAAA,QACV,MAAM,oBAAC,UAAA,EAAS,SAAS,UAAA,CAAW;AAAA,QACpC,2BAAQ,iBAAA,CAAA,CAAgB;AAAA,MAAA;AAAA,IAAA,IAExB,WACF,qBAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,SAAS,IAAI;AAAA,UAC5B,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,oBAAC,MAAA,EAAK,MAAM,YAAA,CAAa;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,0BAG5B,OAAA,EAAI,WAAU,kCACb,UAAA,oBAAC,mBAAgB,EAAA,CACnB;AAAA,IAAA,EAAA,CACF,wBAEC,OAAA,EAAI,WAAU,kCACb,UAAA,oBAAC,UAAA,EAAS,SAAS,UAAA,CAAW,EAAA,CAChC;AAAA,EAAA,EAAA,CAEJ,EAAA,CACF;AAEJ;"}
|
|
@@ -16,12 +16,13 @@ const NAME_TONE = {
|
|
|
16
16
|
failed: "text-red-600 dark:text-red-400",
|
|
17
17
|
timedout: "text-amber-600 dark:text-amber-400",
|
|
18
18
|
warned: "text-amber-600 dark:text-amber-400",
|
|
19
|
+
aborted: "text-red-500 dark:text-red-300",
|
|
19
20
|
running: "text-blue-600 dark:text-blue-400",
|
|
20
21
|
skipped: "text-yellow-700 dark:text-yellow-500",
|
|
21
22
|
pending: "text-muted-foreground",
|
|
22
23
|
passed: "text-foreground"
|
|
23
24
|
};
|
|
24
|
-
const MESSAGE_STATUSES = /* @__PURE__ */ new Set(["failed", "timedout", "warned", "skipped"]);
|
|
25
|
+
const MESSAGE_STATUSES = /* @__PURE__ */ new Set(["failed", "timedout", "warned", "aborted", "skipped"]);
|
|
25
26
|
function CountBadges({ node }) {
|
|
26
27
|
const s = status.sum(node);
|
|
27
28
|
if (s.total === 0) return null;
|
|
@@ -30,6 +31,7 @@ function CountBadges({ node }) {
|
|
|
30
31
|
s.failed > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "danger", variant: "solid", size: "xxs", count: s.failed }),
|
|
31
32
|
s.warned > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "outline", size: "xxs", count: s.warned }),
|
|
32
33
|
s.timedout > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "solid", size: "xxs", count: s.timedout }),
|
|
34
|
+
s.aborted > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "danger", variant: "soft", size: "xxs", count: s.aborted }),
|
|
33
35
|
s.skipped > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "soft", size: "xxs", count: s.skipped }),
|
|
34
36
|
s.running > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "info", variant: "solid", size: "xxs", count: s.running }),
|
|
35
37
|
s.pending > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "neutral", variant: "soft", size: "xxs", count: s.pending })
|