@flanksource/clicky-ui 0.3.46 → 0.3.48
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/NOTICE.md +11 -0
- package/README.md +49 -0
- package/dist/ai.cjs +13 -8
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +7 -2
- package/dist/ai.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +10 -4
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts +2 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +10 -4
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +2 -0
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +2 -1
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +2 -0
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +3 -0
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +3 -1
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +3 -0
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/components/ErrorWrapper.cjs +2 -3
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.d.ts.map +1 -1
- package/dist/components/ErrorWrapper.js +3 -4
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/data/Clicky.cjs +3 -0
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +3 -0
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/CodeLine.cjs +4 -2
- package/dist/data/CodeLine.cjs.map +1 -1
- package/dist/data/CodeLine.d.ts.map +1 -1
- package/dist/data/CodeLine.js +4 -2
- package/dist/data/CodeLine.js.map +1 -1
- package/dist/data/FilterPill.cjs +15 -2
- package/dist/data/FilterPill.cjs.map +1 -1
- package/dist/data/FilterPill.d.ts +1 -1
- package/dist/data/FilterPill.d.ts.map +1 -1
- package/dist/data/FilterPill.js +15 -2
- package/dist/data/FilterPill.js.map +1 -1
- package/dist/data/LogViewer.cjs +27 -8
- package/dist/data/LogViewer.cjs.map +1 -1
- package/dist/data/LogViewer.d.ts +11 -3
- package/dist/data/LogViewer.d.ts.map +1 -1
- package/dist/data/LogViewer.js +27 -8
- package/dist/data/LogViewer.js.map +1 -1
- package/dist/data/Properties.cjs +2 -15
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.d.ts +4 -0
- package/dist/data/Properties.d.ts.map +1 -1
- package/dist/data/Properties.js +2 -15
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/PropertyValue.cjs +37 -0
- package/dist/data/PropertyValue.cjs.map +1 -0
- package/dist/data/PropertyValue.d.ts +6 -0
- package/dist/data/PropertyValue.d.ts.map +1 -0
- package/dist/data/PropertyValue.js +37 -0
- package/dist/data/PropertyValue.js.map +1 -0
- package/dist/data/SymbolBadge.cjs +61 -0
- package/dist/data/SymbolBadge.cjs.map +1 -0
- package/dist/data/SymbolBadge.d.ts +21 -0
- package/dist/data/SymbolBadge.d.ts.map +1 -0
- package/dist/data/SymbolBadge.js +61 -0
- package/dist/data/SymbolBadge.js.map +1 -0
- package/dist/data/Tree.cjs +4 -3
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +3 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +4 -3
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +1 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.js +1 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +106 -171
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +6 -2
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.header.cjs +104 -0
- package/dist/data/ai/ChatWindow.header.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.header.d.ts +29 -0
- package/dist/data/ai/ChatWindow.header.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.header.js +104 -0
- package/dist/data/ai/ChatWindow.header.js.map +1 -0
- package/dist/data/ai/ChatWindow.js +107 -172
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.placement.cjs +95 -0
- package/dist/data/ai/ChatWindow.placement.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.placement.d.ts +32 -0
- package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.placement.js +95 -0
- package/dist/data/ai/ChatWindow.placement.js.map +1 -0
- package/dist/data/ai/SessionChatComposer.cjs +3 -1
- package/dist/data/ai/SessionChatComposer.cjs.map +1 -1
- package/dist/data/ai/SessionChatComposer.d.ts +4 -1
- package/dist/data/ai/SessionChatComposer.d.ts.map +1 -1
- package/dist/data/ai/SessionChatComposer.js +3 -1
- package/dist/data/ai/SessionChatComposer.js.map +1 -1
- package/dist/data/ai/SessionInspector.cjs +68 -72
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.composer-slot.cjs +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts +9 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.js +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.js.map +1 -0
- package/dist/data/ai/SessionInspector.d.ts +6 -1
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.js +69 -73
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.cjs +41 -42
- package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.js +41 -42
- package/dist/data/ai/SessionInspector.legacy.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.cjs +14 -9
- package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.d.ts +6 -2
- package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.js +14 -9
- package/dist/data/ai/SessionInspector.remote-view.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote.cjs +84 -16
- package/dist/data/ai/SessionInspector.remote.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote.d.ts +42 -7
- package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote.js +86 -18
- package/dist/data/ai/SessionInspector.remote.js.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.cjs +5 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.js +5 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
- package/dist/data/ai/SessionTail.cjs +63 -0
- package/dist/data/ai/SessionTail.cjs.map +1 -0
- package/dist/data/ai/SessionTail.d.ts +14 -0
- package/dist/data/ai/SessionTail.d.ts.map +1 -0
- package/dist/data/ai/SessionTail.js +63 -0
- package/dist/data/ai/SessionTail.js.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +10 -3
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +7 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.js +10 -3
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +14 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/index.d.ts +4 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.cjs +30 -6
- package/dist/data/ai/use-session-scroll.cjs.map +1 -1
- package/dist/data/ai/use-session-scroll.d.ts +7 -0
- package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.js +30 -6
- package/dist/data/ai/use-session-scroll.js.map +1 -1
- package/dist/data/chat/Chat.cjs +1 -1
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.js +1 -1
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/PromptInput.cjs +4 -2
- package/dist/data/chat/PromptInput.cjs.map +1 -1
- package/dist/data/chat/PromptInput.d.ts +5 -1
- package/dist/data/chat/PromptInput.d.ts.map +1 -1
- package/dist/data/chat/PromptInput.js +4 -2
- package/dist/data/chat/PromptInput.js.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.cjs +13 -2
- package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.js +14 -3
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.cjs +5 -0
- package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.d.ts +1 -0
- package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.js +6 -1
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
- package/dist/data/har/HarPanel.cjs +3 -1
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts +4 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +3 -1
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/test-runner/Expectation.cjs +57 -0
- package/dist/data/test-runner/Expectation.cjs.map +1 -0
- package/dist/data/test-runner/Expectation.d.ts +19 -0
- package/dist/data/test-runner/Expectation.d.ts.map +1 -0
- package/dist/data/test-runner/Expectation.js +57 -0
- package/dist/data/test-runner/Expectation.js.map +1 -0
- package/dist/data/test-runner/MarkIcons.cjs +38 -0
- package/dist/data/test-runner/MarkIcons.cjs.map +1 -0
- package/dist/data/test-runner/MarkIcons.d.ts +15 -0
- package/dist/data/test-runner/MarkIcons.d.ts.map +1 -0
- package/dist/data/test-runner/MarkIcons.js +38 -0
- package/dist/data/test-runner/MarkIcons.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +99 -53
- 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 +101 -55
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.cjs +23 -27
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.d.ts +2 -2
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.js +23 -27
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
- package/dist/data/test-runner/TestFilterBar.cjs +87 -93
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
- package/dist/data/test-runner/TestFilterBar.d.ts +3 -2
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
- package/dist/data/test-runner/TestFilterBar.js +89 -95
- package/dist/data/test-runner/TestFilterBar.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +35 -21
- 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 +35 -21
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +58 -30
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +6 -3
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +58 -30
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTree.cjs +5 -2
- package/dist/data/test-runner/TestTree.cjs.map +1 -1
- package/dist/data/test-runner/TestTree.d.ts +5 -2
- package/dist/data/test-runner/TestTree.d.ts.map +1 -1
- package/dist/data/test-runner/TestTree.js +5 -2
- package/dist/data/test-runner/TestTree.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +28 -19
- 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 +29 -20
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +15 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +27 -7
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +15 -0
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +2 -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/copy.cjs +114 -0
- package/dist/data/test-runner/copy.cjs.map +1 -0
- package/dist/data/test-runner/copy.d.ts +47 -0
- package/dist/data/test-runner/copy.d.ts.map +1 -0
- package/dist/data/test-runner/copy.js +114 -0
- package/dist/data/test-runner/copy.js.map +1 -0
- package/dist/data/test-runner/index.d.ts +6 -3
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +184 -0
- package/dist/data/test-runner/marks.cjs.map +1 -0
- package/dist/data/test-runner/marks.d.ts +40 -0
- package/dist/data/test-runner/marks.d.ts.map +1 -0
- package/dist/data/test-runner/marks.js +184 -0
- package/dist/data/test-runner/marks.js.map +1 -0
- package/dist/data/test-runner/status.cjs +27 -44
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.d.ts +12 -3
- package/dist/data/test-runner/status.d.ts.map +1 -1
- package/dist/data/test-runner/status.js +27 -44
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/traces/TerminalCastPlayer.d.ts +21 -0
- package/dist/data/traces/TerminalCastPlayer.d.ts.map +1 -0
- package/dist/data/traces/TraceHarView.d.ts +13 -0
- package/dist/data/traces/TraceHarView.d.ts.map +1 -0
- package/dist/data/traces/cast.d.ts +9 -0
- package/dist/data/traces/cast.d.ts.map +1 -0
- package/dist/data/traces/fixtures.d.ts +8 -0
- package/dist/data/traces/fixtures.d.ts.map +1 -0
- package/dist/data/traces/har-adapter.d.ts +13 -0
- package/dist/data/traces/har-adapter.d.ts.map +1 -0
- package/dist/data/traces/terminal-screen.d.ts +45 -0
- package/dist/data/traces/terminal-screen.d.ts.map +1 -0
- package/dist/data/traces/terminal-timeline.d.ts +26 -0
- package/dist/data/traces/terminal-timeline.d.ts.map +1 -0
- package/dist/data/traces/types.d.ts +141 -0
- package/dist/data/traces/types.d.ts.map +1 -0
- package/dist/data/verification/VerificationResults.cjs +4 -0
- package/dist/data/verification/VerificationResults.cjs.map +1 -1
- package/dist/data/verification/VerificationResults.d.ts +3 -1
- package/dist/data/verification/VerificationResults.d.ts.map +1 -1
- package/dist/data/verification/VerificationResults.js +4 -0
- package/dist/data/verification/VerificationResults.js.map +1 -1
- package/dist/data/verification/adapterViews.cjs +28 -44
- package/dist/data/verification/adapterViews.cjs.map +1 -1
- package/dist/data/verification/adapterViews.d.ts +4 -1
- package/dist/data/verification/adapterViews.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.js +28 -44
- package/dist/data/verification/adapterViews.js.map +1 -1
- package/dist/data/verification/adapters.cjs +163 -8
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts +7 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +163 -8
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/verification/index.d.ts +4 -2
- package/dist/data/verification/index.d.ts.map +1 -1
- package/dist/data/verification/stepKind.cjs +217 -0
- package/dist/data/verification/stepKind.cjs.map +1 -0
- package/dist/data/verification/stepKind.d.ts +87 -0
- package/dist/data/verification/stepKind.d.ts.map +1 -0
- package/dist/data/verification/stepKind.js +217 -0
- package/dist/data/verification/stepKind.js.map +1 -0
- package/dist/data/verification/stepKindViews.cjs +111 -0
- package/dist/data/verification/stepKindViews.cjs.map +1 -0
- package/dist/data/verification/stepKindViews.d.ts +18 -0
- package/dist/data/verification/stepKindViews.d.ts.map +1 -0
- package/dist/data/verification/stepKindViews.js +111 -0
- package/dist/data/verification/stepKindViews.js.map +1 -0
- package/dist/data/verification/verifyReportTests.cjs +1 -0
- package/dist/data/verification/verifyReportTests.cjs.map +1 -1
- package/dist/data/verification/verifyReportTests.d.ts +2 -1
- package/dist/data/verification/verifyReportTests.d.ts.map +1 -1
- package/dist/data/verification/verifyReportTests.js +1 -0
- package/dist/data/verification/verifyReportTests.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +58 -3
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +3 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +60 -5
- package/dist/data.js.map +1 -1
- package/dist/icons/components/UiLogoEslint.cjs +10 -0
- package/dist/icons/components/UiLogoEslint.cjs.map +1 -0
- package/dist/icons/components/UiLogoEslint.d.ts +9 -0
- package/dist/icons/components/UiLogoEslint.d.ts.map +1 -0
- package/dist/icons/components/UiLogoEslint.js +10 -0
- package/dist/icons/components/UiLogoEslint.js.map +1 -0
- package/dist/icons/components/UiLogoGo.cjs +10 -0
- package/dist/icons/components/UiLogoGo.cjs.map +1 -0
- package/dist/icons/components/UiLogoGo.d.ts +9 -0
- package/dist/icons/components/UiLogoGo.d.ts.map +1 -0
- package/dist/icons/components/UiLogoGo.js +10 -0
- package/dist/icons/components/UiLogoGo.js.map +1 -0
- package/dist/icons/components/UiLogoJest.cjs +10 -0
- package/dist/icons/components/UiLogoJest.cjs.map +1 -0
- package/dist/icons/components/UiLogoJest.d.ts +9 -0
- package/dist/icons/components/UiLogoJest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoJest.js +10 -0
- package/dist/icons/components/UiLogoJest.js.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.cjs +10 -0
- package/dist/icons/components/UiLogoMarkdown.cjs.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts +9 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.js +10 -0
- package/dist/icons/components/UiLogoMarkdown.js.map +1 -0
- package/dist/icons/components/UiLogoOxc.cjs +10 -0
- package/dist/icons/components/UiLogoOxc.cjs.map +1 -0
- package/dist/icons/components/UiLogoOxc.d.ts +9 -0
- package/dist/icons/components/UiLogoOxc.d.ts.map +1 -0
- package/dist/icons/components/UiLogoOxc.js +10 -0
- package/dist/icons/components/UiLogoOxc.js.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.cjs +10 -0
- package/dist/icons/components/UiLogoPlaywright.cjs.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts +9 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.js +10 -0
- package/dist/icons/components/UiLogoPlaywright.js.map +1 -0
- package/dist/icons/components/UiLogoPython.cjs +10 -0
- package/dist/icons/components/UiLogoPython.cjs.map +1 -0
- package/dist/icons/components/UiLogoPython.d.ts +9 -0
- package/dist/icons/components/UiLogoPython.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPython.js +10 -0
- package/dist/icons/components/UiLogoPython.js.map +1 -0
- package/dist/icons/components/UiLogoReact.cjs +10 -0
- package/dist/icons/components/UiLogoReact.cjs.map +1 -0
- package/dist/icons/components/UiLogoReact.d.ts +9 -0
- package/dist/icons/components/UiLogoReact.d.ts.map +1 -0
- package/dist/icons/components/UiLogoReact.js +10 -0
- package/dist/icons/components/UiLogoReact.js.map +1 -0
- package/dist/icons/components/UiLogoRuff.cjs +10 -0
- package/dist/icons/components/UiLogoRuff.cjs.map +1 -0
- package/dist/icons/components/UiLogoRuff.d.ts +9 -0
- package/dist/icons/components/UiLogoRuff.d.ts.map +1 -0
- package/dist/icons/components/UiLogoRuff.js +10 -0
- package/dist/icons/components/UiLogoRuff.js.map +1 -0
- package/dist/icons/components/UiLogoTypescript.cjs +10 -0
- package/dist/icons/components/UiLogoTypescript.cjs.map +1 -0
- package/dist/icons/components/UiLogoTypescript.d.ts +9 -0
- package/dist/icons/components/UiLogoTypescript.d.ts.map +1 -0
- package/dist/icons/components/UiLogoTypescript.js +10 -0
- package/dist/icons/components/UiLogoTypescript.js.map +1 -0
- package/dist/icons/components/UiLogoVitest.cjs +10 -0
- package/dist/icons/components/UiLogoVitest.cjs.map +1 -0
- package/dist/icons/components/UiLogoVitest.d.ts +9 -0
- package/dist/icons/components/UiLogoVitest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoVitest.js +10 -0
- package/dist/icons/components/UiLogoVitest.js.map +1 -0
- package/dist/icons/index.d.ts +11 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +22 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +22 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +22 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +22 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +60 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +62 -5
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +4 -4
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +4 -4
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +9 -0
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.d.ts +5 -1
- package/dist/rpc/FilterForm.d.ts.map +1 -1
- package/dist/rpc/FilterForm.js +9 -0
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/InlineError.cjs +12 -43
- package/dist/rpc/InlineError.cjs.map +1 -1
- package/dist/rpc/InlineError.d.ts.map +1 -1
- package/dist/rpc/InlineError.js +13 -44
- package/dist/rpc/InlineError.js.map +1 -1
- package/dist/rpc/OperationArgsForm.cjs +153 -0
- package/dist/rpc/OperationArgsForm.cjs.map +1 -0
- package/dist/rpc/OperationArgsForm.d.ts +16 -0
- package/dist/rpc/OperationArgsForm.d.ts.map +1 -0
- package/dist/rpc/OperationArgsForm.js +153 -0
- package/dist/rpc/OperationArgsForm.js.map +1 -0
- package/dist/rpc/OperationScheduleDialog.cjs +119 -22
- package/dist/rpc/OperationScheduleDialog.cjs.map +1 -1
- package/dist/rpc/OperationScheduleDialog.d.ts +7 -0
- package/dist/rpc/OperationScheduleDialog.d.ts.map +1 -1
- package/dist/rpc/OperationScheduleDialog.js +120 -23
- package/dist/rpc/OperationScheduleDialog.js.map +1 -1
- package/dist/rpc/OperationSchedules.cjs +17 -2
- package/dist/rpc/OperationSchedules.cjs.map +1 -1
- package/dist/rpc/OperationSchedules.d.ts.map +1 -1
- package/dist/rpc/OperationSchedules.js +17 -2
- package/dist/rpc/OperationSchedules.js.map +1 -1
- package/dist/rpc/operation-schedule-model.cjs +2 -7
- package/dist/rpc/operation-schedule-model.cjs.map +1 -1
- package/dist/rpc/operation-schedule-model.d.ts +0 -2
- package/dist/rpc/operation-schedule-model.d.ts.map +1 -1
- package/dist/rpc/operation-schedule-model.js +2 -7
- package/dist/rpc/operation-schedule-model.js.map +1 -1
- package/dist/rpc/operation-schedule-types.d.ts +12 -1
- package/dist/rpc/operation-schedule-types.d.ts.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/data/test-runner/frameworkIcon.cjs +0 -27
- package/dist/data/test-runner/frameworkIcon.cjs.map +0 -1
- package/dist/data/test-runner/frameworkIcon.d.ts +0 -3
- package/dist/data/test-runner/frameworkIcon.d.ts.map +0 -1
- package/dist/data/test-runner/frameworkIcon.js +0 -27
- package/dist/data/test-runner/frameworkIcon.js.map +0 -1
|
@@ -7,7 +7,9 @@ const IconButton = require("../../components/IconButton.cjs");
|
|
|
7
7
|
const utils = require("../../lib/utils.cjs");
|
|
8
8
|
const context = require("./context.cjs");
|
|
9
9
|
const status = require("./status.cjs");
|
|
10
|
-
const
|
|
10
|
+
const marks = require("./marks.cjs");
|
|
11
|
+
const MarkIcons = require("./MarkIcons.cjs");
|
|
12
|
+
const UiClass = require("../../icons/components/UiClass.cjs");
|
|
11
13
|
const UiStop = require("../../icons/components/UiStop.cjs");
|
|
12
14
|
const UiRefresh = require("../../icons/components/UiRefresh.cjs");
|
|
13
15
|
const NAME_TONE = {
|
|
@@ -26,6 +28,7 @@ function CountBadges({ node }) {
|
|
|
26
28
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
27
29
|
s.passed > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "success", variant: "solid", size: "xxs", count: s.passed }),
|
|
28
30
|
s.failed > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "danger", variant: "solid", size: "xxs", count: s.failed }),
|
|
31
|
+
s.warned > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "outline", size: "xxs", count: s.warned }),
|
|
29
32
|
s.timedout > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "solid", size: "xxs", count: s.timedout }),
|
|
30
33
|
s.skipped > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", variant: "soft", size: "xxs", count: s.skipped }),
|
|
31
34
|
s.running > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "info", variant: "solid", size: "xxs", count: s.running }),
|
|
@@ -37,7 +40,7 @@ function TestTreeNode({ node, selected }) {
|
|
|
37
40
|
const runner = context.useTestRunner();
|
|
38
41
|
const hasChildren = (((_a = node.children) == null ? void 0 : _a.length) ?? 0) > 0;
|
|
39
42
|
const status$1 = status.testStatus(node);
|
|
40
|
-
const
|
|
43
|
+
const outcome = status.outcomeFor(node);
|
|
41
44
|
const fwAdapter = runner.adapters.resolveFrameworkIcon(node, runner);
|
|
42
45
|
const fwNode = (_b = fwAdapter == null ? void 0 : fwAdapter.renderFrameworkIcon) == null ? void 0 : _b.call(fwAdapter, { node, runner });
|
|
43
46
|
const leadingAdapter = runner.adapters.resolveRowLeading(node, runner);
|
|
@@ -46,24 +49,30 @@ function TestTreeNode({ node, selected }) {
|
|
|
46
49
|
const canStop = !!runner.onStop && !!node.can_stop && !!node.task_id;
|
|
47
50
|
const message = status$1 && MESSAGE_STATUSES.has(status$1) ? (node.message ?? "").trim() : "";
|
|
48
51
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon:
|
|
50
|
-
fwNode != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center text-sm
|
|
52
|
+
outcome ? /* @__PURE__ */ jsxRuntime.jsx(MarkIcons.OutcomeIcon, { outcome }) : /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClass.UiClass, className: "shrink-0 text-muted-foreground" }),
|
|
53
|
+
fwNode != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center text-sm", children: fwNode }) : /* @__PURE__ */ jsxRuntime.jsx(MarkIcons.ToolIcon, { tool: marks.toolKeyFor(node), className: "text-sm" }),
|
|
51
54
|
(_c = leadingAdapter == null ? void 0 : leadingAdapter.renderRowLeading) == null ? void 0 : _c.call(leadingAdapter, { node, runner }),
|
|
52
|
-
/* @__PURE__ */ jsxRuntime.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
56
|
+
"span",
|
|
57
|
+
{
|
|
58
|
+
className: utils.cn(
|
|
59
|
+
"min-w-0 truncate",
|
|
60
|
+
selected ? "font-semibold" : "font-medium",
|
|
61
|
+
status$1 && NAME_TONE[status$1] || "text-foreground"
|
|
62
|
+
),
|
|
63
|
+
title: message || void 0,
|
|
64
|
+
children: status.humanizeName(node.name, node.framework)
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
message ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
68
|
+
"span",
|
|
69
|
+
{
|
|
70
|
+
className: "min-w-0 flex-1 shrink-[100] truncate text-xs text-muted-foreground",
|
|
71
|
+
title: message,
|
|
72
|
+
"data-row-message": "",
|
|
73
|
+
children: message
|
|
74
|
+
}
|
|
75
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
67
76
|
node.progress && node.progress.total > 0 && !node.passed && !node.failed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
|
|
68
77
|
node.progress.phase && /* @__PURE__ */ jsxRuntime.jsx("span", { children: node.progress.phase }),
|
|
69
78
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums", children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestTreeNode.cjs","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport { IconButton } from \"../../components/IconButton\";\nimport { UiRefresh, UiStop } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport {\n formatTestDuration,\n humanizeName,\n
|
|
1
|
+
{"version":3,"file":"TestTreeNode.cjs","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport { IconButton } from \"../../components/IconButton\";\nimport { UiClass, UiRefresh, UiStop } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport {\n formatTestDuration,\n humanizeName,\n outcomeFor,\n sum,\n testStatus,\n totalDuration,\n} from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\n\nconst NAME_TONE: Record<string, string> = {\n failed: \"text-red-600 dark:text-red-400\",\n timedout: \"text-amber-600 dark:text-amber-400\",\n warned: \"text-amber-600 dark:text-amber-400\",\n running: \"text-blue-600 dark:text-blue-400\",\n skipped: \"text-yellow-700 dark:text-yellow-500\",\n pending: \"text-muted-foreground\",\n passed: \"text-foreground\",\n};\n\nconst MESSAGE_STATUSES = new Set([\"failed\", \"timedout\", \"warned\", \"skipped\"]);\n\n/** Per-status roll-up count badges shown on a container row. */\nfunction CountBadges({ node }: { node: Test }) {\n const s = sum(node);\n if (s.total === 0) return null;\n return (\n <span className=\"flex shrink-0 items-center gap-1\">\n {s.passed > 0 && <Badge tone=\"success\" variant=\"solid\" size=\"xxs\" count={s.passed} />}\n {s.failed > 0 && <Badge tone=\"danger\" variant=\"solid\" size=\"xxs\" count={s.failed} />}\n {s.warned > 0 && <Badge tone=\"warning\" variant=\"outline\" size=\"xxs\" count={s.warned} />}\n {s.timedout > 0 && <Badge tone=\"warning\" variant=\"solid\" size=\"xxs\" count={s.timedout} />}\n {s.skipped > 0 && <Badge tone=\"warning\" variant=\"soft\" size=\"xxs\" count={s.skipped} />}\n {s.running > 0 && <Badge tone=\"info\" variant=\"solid\" size=\"xxs\" count={s.running} />}\n {s.pending > 0 && <Badge tone=\"neutral\" variant=\"soft\" size=\"xxs\" count={s.pending} />}\n </span>\n );\n}\n\n/**\n * Renders one test tree row: status icon, optional adapter decoration + framework\n * icon, status-colored name, duration, per-status count badges, and (when the\n * runner exposes the handlers) rerun/stop buttons. Designed as the `renderRow`\n * for the clicky `Tree`.\n */\nexport function TestTreeNode({ node, selected }: { node: Test; selected: boolean }) {\n const runner = useTestRunner();\n const hasChildren = (node.children?.length ?? 0) > 0;\n const status = testStatus(node);\n const outcome = outcomeFor(node);\n const fwAdapter = runner.adapters.resolveFrameworkIcon(node, runner);\n const fwNode = fwAdapter?.renderFrameworkIcon?.({ node, runner });\n const leadingAdapter = runner.adapters.resolveRowLeading(node, runner);\n const dur = node.duration || (hasChildren ? totalDuration(node) : 0);\n const canRerun = !!runner.onRerun && node.framework !== \"task\";\n const canStop = !!runner.onStop && !!node.can_stop && !!node.task_id;\n // A verdict line under the name for rows that need explaining; green,\n // running, and queued rows stay single-line.\n const message = status && MESSAGE_STATUSES.has(status) ? (node.message ?? \"\").trim() : \"\";\n\n return (\n <>\n {outcome ? (\n <OutcomeIcon outcome={outcome} />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-muted-foreground\" />\n )}\n\n {fwNode != null ? (\n <span className=\"flex shrink-0 items-center text-sm\">{fwNode}</span>\n ) : (\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n )}\n\n {leadingAdapter?.renderRowLeading?.({ node, runner })}\n\n <span\n className={cn(\n \"min-w-0 truncate\",\n selected ? \"font-semibold\" : \"font-medium\",\n (status && NAME_TONE[status]) || \"text-foreground\",\n )}\n title={message || undefined}\n >\n {humanizeName(node.name, node.framework)}\n </span>\n {/* The verdict trails the name on the same line and gives way first. */}\n {message ? (\n <span\n className=\"min-w-0 flex-1 shrink-[100] truncate text-xs text-muted-foreground\"\n title={message}\n data-row-message=\"\"\n >\n {message}\n </span>\n ) : (\n <span className=\"flex-1\" />\n )}\n\n {node.progress && node.progress.total > 0 && !node.passed && !node.failed && (\n <span className=\"flex shrink-0 items-center gap-1 text-xs text-blue-600 dark:text-blue-400\">\n {node.progress.phase && <span>{node.progress.phase}</span>}\n <span className=\"tabular-nums\">\n {node.progress.done}/{node.progress.total}\n </span>\n </span>\n )}\n\n {dur > 0 && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">{formatTestDuration(dur)}</span>\n )}\n\n {hasChildren && <CountBadges node={node} />}\n\n {canStop && (\n <IconButton\n icon={UiStop}\n label=\"Stop\"\n disabled={runner.busy.stop}\n onClick={(e) => {\n e.stopPropagation();\n runner.onStop!(node);\n }}\n />\n )}\n\n {canRerun && (\n <IconButton\n icon={UiRefresh}\n label=\"Rerun\"\n disabled={runner.busy.rerun}\n onClick={(e) => {\n e.stopPropagation();\n runner.onRerun!(node);\n }}\n />\n )}\n </>\n );\n}\n"],"names":["sum","jsxs","jsx","Badge","useTestRunner","status","testStatus","outcomeFor","totalDuration","Fragment","OutcomeIcon","Icon","UiClass","ToolIcon","toolKeyFor","cn","humanizeName","formatTestDuration","IconButton","UiStop","UiRefresh"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestTreeNode.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"TestTreeNode.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AA0CpC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,+BA8FjF"}
|
|
@@ -4,8 +4,10 @@ import { Badge } from "../Badge.js";
|
|
|
4
4
|
import { IconButton } from "../../components/IconButton.js";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
6
|
import { useTestRunner } from "./context.js";
|
|
7
|
-
import { testStatus,
|
|
8
|
-
import {
|
|
7
|
+
import { testStatus, outcomeFor, totalDuration, humanizeName, formatTestDuration, sum } from "./status.js";
|
|
8
|
+
import { toolKeyFor } from "./marks.js";
|
|
9
|
+
import { OutcomeIcon, ToolIcon } from "./MarkIcons.js";
|
|
10
|
+
import { UiClass } from "../../icons/components/UiClass.js";
|
|
9
11
|
import { UiStop } from "../../icons/components/UiStop.js";
|
|
10
12
|
import { UiRefresh } from "../../icons/components/UiRefresh.js";
|
|
11
13
|
const NAME_TONE = {
|
|
@@ -24,6 +26,7 @@ function CountBadges({ node }) {
|
|
|
24
26
|
return /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
25
27
|
s.passed > 0 && /* @__PURE__ */ jsx(Badge, { tone: "success", variant: "solid", size: "xxs", count: s.passed }),
|
|
26
28
|
s.failed > 0 && /* @__PURE__ */ jsx(Badge, { tone: "danger", variant: "solid", size: "xxs", count: s.failed }),
|
|
29
|
+
s.warned > 0 && /* @__PURE__ */ jsx(Badge, { tone: "warning", variant: "outline", size: "xxs", count: s.warned }),
|
|
27
30
|
s.timedout > 0 && /* @__PURE__ */ jsx(Badge, { tone: "warning", variant: "solid", size: "xxs", count: s.timedout }),
|
|
28
31
|
s.skipped > 0 && /* @__PURE__ */ jsx(Badge, { tone: "warning", variant: "soft", size: "xxs", count: s.skipped }),
|
|
29
32
|
s.running > 0 && /* @__PURE__ */ jsx(Badge, { tone: "info", variant: "solid", size: "xxs", count: s.running }),
|
|
@@ -35,7 +38,7 @@ function TestTreeNode({ node, selected }) {
|
|
|
35
38
|
const runner = useTestRunner();
|
|
36
39
|
const hasChildren = (((_a = node.children) == null ? void 0 : _a.length) ?? 0) > 0;
|
|
37
40
|
const status = testStatus(node);
|
|
38
|
-
const
|
|
41
|
+
const outcome = outcomeFor(node);
|
|
39
42
|
const fwAdapter = runner.adapters.resolveFrameworkIcon(node, runner);
|
|
40
43
|
const fwNode = (_b = fwAdapter == null ? void 0 : fwAdapter.renderFrameworkIcon) == null ? void 0 : _b.call(fwAdapter, { node, runner });
|
|
41
44
|
const leadingAdapter = runner.adapters.resolveRowLeading(node, runner);
|
|
@@ -44,24 +47,30 @@ function TestTreeNode({ node, selected }) {
|
|
|
44
47
|
const canStop = !!runner.onStop && !!node.can_stop && !!node.task_id;
|
|
45
48
|
const message = status && MESSAGE_STATUSES.has(status) ? (node.message ?? "").trim() : "";
|
|
46
49
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
47
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
48
|
-
fwNode != null ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center text-sm
|
|
50
|
+
outcome ? /* @__PURE__ */ jsx(OutcomeIcon, { outcome }) : /* @__PURE__ */ jsx(Icon, { icon: UiClass, className: "shrink-0 text-muted-foreground" }),
|
|
51
|
+
fwNode != null ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center text-sm", children: fwNode }) : /* @__PURE__ */ jsx(ToolIcon, { tool: toolKeyFor(node), className: "text-sm" }),
|
|
49
52
|
(_c = leadingAdapter == null ? void 0 : leadingAdapter.renderRowLeading) == null ? void 0 : _c.call(leadingAdapter, { node, runner }),
|
|
50
|
-
/* @__PURE__ */
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
className: cn(
|
|
57
|
+
"min-w-0 truncate",
|
|
58
|
+
selected ? "font-semibold" : "font-medium",
|
|
59
|
+
status && NAME_TONE[status] || "text-foreground"
|
|
60
|
+
),
|
|
61
|
+
title: message || void 0,
|
|
62
|
+
children: humanizeName(node.name, node.framework)
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
message ? /* @__PURE__ */ jsx(
|
|
66
|
+
"span",
|
|
67
|
+
{
|
|
68
|
+
className: "min-w-0 flex-1 shrink-[100] truncate text-xs text-muted-foreground",
|
|
69
|
+
title: message,
|
|
70
|
+
"data-row-message": "",
|
|
71
|
+
children: message
|
|
72
|
+
}
|
|
73
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
65
74
|
node.progress && node.progress.total > 0 && !node.passed && !node.failed && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
|
|
66
75
|
node.progress.phase && /* @__PURE__ */ jsx("span", { children: node.progress.phase }),
|
|
67
76
|
/* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestTreeNode.js","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport { IconButton } from \"../../components/IconButton\";\nimport { UiRefresh, UiStop } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport {\n formatTestDuration,\n humanizeName,\n
|
|
1
|
+
{"version":3,"file":"TestTreeNode.js","sources":["../../../src/data/test-runner/TestTreeNode.tsx"],"sourcesContent":["import { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport { IconButton } from \"../../components/IconButton\";\nimport { UiClass, UiRefresh, UiStop } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport {\n formatTestDuration,\n humanizeName,\n outcomeFor,\n sum,\n testStatus,\n totalDuration,\n} from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\n\nconst NAME_TONE: Record<string, string> = {\n failed: \"text-red-600 dark:text-red-400\",\n timedout: \"text-amber-600 dark:text-amber-400\",\n warned: \"text-amber-600 dark:text-amber-400\",\n running: \"text-blue-600 dark:text-blue-400\",\n skipped: \"text-yellow-700 dark:text-yellow-500\",\n pending: \"text-muted-foreground\",\n passed: \"text-foreground\",\n};\n\nconst MESSAGE_STATUSES = new Set([\"failed\", \"timedout\", \"warned\", \"skipped\"]);\n\n/** Per-status roll-up count badges shown on a container row. */\nfunction CountBadges({ node }: { node: Test }) {\n const s = sum(node);\n if (s.total === 0) return null;\n return (\n <span className=\"flex shrink-0 items-center gap-1\">\n {s.passed > 0 && <Badge tone=\"success\" variant=\"solid\" size=\"xxs\" count={s.passed} />}\n {s.failed > 0 && <Badge tone=\"danger\" variant=\"solid\" size=\"xxs\" count={s.failed} />}\n {s.warned > 0 && <Badge tone=\"warning\" variant=\"outline\" size=\"xxs\" count={s.warned} />}\n {s.timedout > 0 && <Badge tone=\"warning\" variant=\"solid\" size=\"xxs\" count={s.timedout} />}\n {s.skipped > 0 && <Badge tone=\"warning\" variant=\"soft\" size=\"xxs\" count={s.skipped} />}\n {s.running > 0 && <Badge tone=\"info\" variant=\"solid\" size=\"xxs\" count={s.running} />}\n {s.pending > 0 && <Badge tone=\"neutral\" variant=\"soft\" size=\"xxs\" count={s.pending} />}\n </span>\n );\n}\n\n/**\n * Renders one test tree row: status icon, optional adapter decoration + framework\n * icon, status-colored name, duration, per-status count badges, and (when the\n * runner exposes the handlers) rerun/stop buttons. Designed as the `renderRow`\n * for the clicky `Tree`.\n */\nexport function TestTreeNode({ node, selected }: { node: Test; selected: boolean }) {\n const runner = useTestRunner();\n const hasChildren = (node.children?.length ?? 0) > 0;\n const status = testStatus(node);\n const outcome = outcomeFor(node);\n const fwAdapter = runner.adapters.resolveFrameworkIcon(node, runner);\n const fwNode = fwAdapter?.renderFrameworkIcon?.({ node, runner });\n const leadingAdapter = runner.adapters.resolveRowLeading(node, runner);\n const dur = node.duration || (hasChildren ? totalDuration(node) : 0);\n const canRerun = !!runner.onRerun && node.framework !== \"task\";\n const canStop = !!runner.onStop && !!node.can_stop && !!node.task_id;\n // A verdict line under the name for rows that need explaining; green,\n // running, and queued rows stay single-line.\n const message = status && MESSAGE_STATUSES.has(status) ? (node.message ?? \"\").trim() : \"\";\n\n return (\n <>\n {outcome ? (\n <OutcomeIcon outcome={outcome} />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-muted-foreground\" />\n )}\n\n {fwNode != null ? (\n <span className=\"flex shrink-0 items-center text-sm\">{fwNode}</span>\n ) : (\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n )}\n\n {leadingAdapter?.renderRowLeading?.({ node, runner })}\n\n <span\n className={cn(\n \"min-w-0 truncate\",\n selected ? \"font-semibold\" : \"font-medium\",\n (status && NAME_TONE[status]) || \"text-foreground\",\n )}\n title={message || undefined}\n >\n {humanizeName(node.name, node.framework)}\n </span>\n {/* The verdict trails the name on the same line and gives way first. */}\n {message ? (\n <span\n className=\"min-w-0 flex-1 shrink-[100] truncate text-xs text-muted-foreground\"\n title={message}\n data-row-message=\"\"\n >\n {message}\n </span>\n ) : (\n <span className=\"flex-1\" />\n )}\n\n {node.progress && node.progress.total > 0 && !node.passed && !node.failed && (\n <span className=\"flex shrink-0 items-center gap-1 text-xs text-blue-600 dark:text-blue-400\">\n {node.progress.phase && <span>{node.progress.phase}</span>}\n <span className=\"tabular-nums\">\n {node.progress.done}/{node.progress.total}\n </span>\n </span>\n )}\n\n {dur > 0 && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">{formatTestDuration(dur)}</span>\n )}\n\n {hasChildren && <CountBadges node={node} />}\n\n {canStop && (\n <IconButton\n icon={UiStop}\n label=\"Stop\"\n disabled={runner.busy.stop}\n onClick={(e) => {\n e.stopPropagation();\n runner.onStop!(node);\n }}\n />\n )}\n\n {canRerun && (\n <IconButton\n icon={UiRefresh}\n label=\"Rerun\"\n disabled={runner.busy.rerun}\n onClick={(e) => {\n e.stopPropagation();\n runner.onRerun!(node);\n }}\n />\n )}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
+
const copy = require("./copy.cjs");
|
|
6
7
|
class TestNodeAdapterRegistry {
|
|
7
8
|
constructor(adapters = []) {
|
|
8
9
|
__publicField(this, "adapters");
|
|
@@ -27,6 +28,10 @@ class TestNodeAdapterRegistry {
|
|
|
27
28
|
resolveActions(node, runner) {
|
|
28
29
|
return this.firstWith(node, runner, (a) => !!a.nodeActions);
|
|
29
30
|
}
|
|
31
|
+
resolveAttempts(node, runner) {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
return ((_b = (_a = this.firstWith(node, runner, (a) => !!a.detailAttempts)) == null ? void 0 : _a.detailAttempts) == null ? void 0 : _b.call(_a, { node, runner })) ?? [];
|
|
34
|
+
}
|
|
30
35
|
/** Merge `detailTabs` from every matching adapter, de-duplicated by tab id. */
|
|
31
36
|
resolveTabs(node, runner) {
|
|
32
37
|
const ctx = { node, runner };
|
|
@@ -42,6 +47,16 @@ class TestNodeAdapterRegistry {
|
|
|
42
47
|
}
|
|
43
48
|
return tabs;
|
|
44
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Merge `copy` sections from every matching adapter, de-duplicated by fact
|
|
52
|
+
* label, section title and item label — the first contributor wins.
|
|
53
|
+
*/
|
|
54
|
+
resolveCopy(node, runner) {
|
|
55
|
+
const ctx = { node, runner };
|
|
56
|
+
return copy.mergeCopySections(
|
|
57
|
+
this.adapters.flatMap((a) => a.copy && a.match(node, runner) ? [a.copy(ctx)] : [])
|
|
58
|
+
);
|
|
59
|
+
}
|
|
45
60
|
/** True when the resolved detail adapter owns its own scroll region. */
|
|
46
61
|
ownsScroll(node, runner) {
|
|
47
62
|
const a = this.resolveDetail(node, runner);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.cjs","sources":["../../../src/data/test-runner/adapter.ts"],"sourcesContent":["// Node adapters let a host plug domain-specific rendering into the test runner\n// without forking it. An adapter claims nodes via `match` and contributes how\n// they render in each surface (tree row, detail body, detail tabs, header\n// actions). The registry resolves the first matching adapter per surface;\n// surfaces with no match fall back to the runner's built-in default rendering.\n//\n// This formalizes the wrapper-with-an-if-chain pattern hosts use today (e.g.\n// a ResultDetailPane fall-through over domain panels + tab providers + per-step\n// actions) into a registered, composable contract.\n\nimport type { ReactNode } from \"react\";\nimport type { Test } from \"./types\";\nimport type { TestRunnerContext } from \"./context\";\n\nexport type AdapterContext = {\n node: Test;\n runner: TestRunnerContext;\n};\n\nexport type DetailTab = {\n id: string;\n label: string;\n render: () => ReactNode;\n};\n\nexport type TestNodeAdapter = {\n /** Stable identifier, used as a React key and for debugging. */\n id: string;\n /** Claim the node. The first registered adapter to return true wins per surface. */\n match: (node: Test, runner: TestRunnerContext) => boolean;\n /**\n * Replace the framework icon for the node — return any node
|
|
1
|
+
{"version":3,"file":"adapter.cjs","sources":["../../../src/data/test-runner/adapter.ts"],"sourcesContent":["// Node adapters let a host plug domain-specific rendering into the test runner\n// without forking it. An adapter claims nodes via `match` and contributes how\n// they render in each surface (tree row, detail body, detail tabs, header\n// actions). The registry resolves the first matching adapter per surface;\n// surfaces with no match fall back to the runner's built-in default rendering.\n//\n// This formalizes the wrapper-with-an-if-chain pattern hosts use today (e.g.\n// a ResultDetailPane fall-through over domain panels + tab providers + per-step\n// actions) into a registered, composable contract.\n\nimport type { ReactNode } from \"react\";\nimport type { Test } from \"./types\";\nimport type { TestRunnerContext } from \"./context\";\nimport { mergeCopySections, type CopySections } from \"./copy\";\n\nexport type AdapterContext = {\n node: Test;\n runner: TestRunnerContext;\n};\n\nexport type DetailTab = {\n id: string;\n label: string;\n render: () => ReactNode;\n};\n\nexport type DetailAttempt = { id: number; status: string; durationMs?: number; node: Test };\n\nexport type TestNodeAdapter = {\n /** Stable identifier, used as a React key and for debugging. */\n id: string;\n /** Claim the node. The first registered adapter to return true wins per surface. */\n match: (node: Test, runner: TestRunnerContext) => boolean;\n /**\n * Replace the framework icon for the node — return any node, or null to fall\n * back to the built-in tool mark (`TEST_TOOLS`). For a tool the catalog\n * lacks, prefer adding it to `TEST_TOOLS` so every surface shows it.\n */\n renderFrameworkIcon?: (c: AdapterContext) => ReactNode;\n /** Extra decoration rendered between the framework icon and the node name. */\n renderRowLeading?: (c: AdapterContext) => ReactNode;\n /** Primary detail body for the node, replacing the default panel body. */\n renderDetail?: (c: AdapterContext) => ReactNode;\n /** Extra detail tabs, merged (in registration order) across all matching adapters. */\n detailTabs?: (c: AdapterContext) => DetailTab[];\n /** Stored attempt views for the header chooser; tree and run totals remain step-level. */\n detailAttempts?: (c: AdapterContext) => DetailAttempt[];\n /** Node-scoped action buttons rendered in the detail header. */\n nodeActions?: (c: AdapterContext) => ReactNode;\n /**\n * Domain facts, brief sections and menu items for the header's \"Copy details\"\n * button, merged (in registration order) across all matching adapters on top\n * of the generic sections every node gets.\n */\n copy?: (c: AdapterContext) => CopySections;\n /**\n * Whether `renderDetail` owns its own full-height scroll container. When\n * false (the default for custom bodies), the panel wraps it in a scroll\n * region. The built-in default body owns its scroll.\n */\n ownsScroll?: (c: AdapterContext) => boolean;\n};\n\n/**\n * Ordered set of node adapters. First match wins per surface; `detailTabs` and\n * `copy` are the exceptions — they merge across every matching adapter so\n * independent adapters can each contribute a tab or a copy section.\n */\nexport class TestNodeAdapterRegistry {\n readonly adapters: TestNodeAdapter[];\n\n constructor(adapters: TestNodeAdapter[] = []) {\n this.adapters = adapters;\n }\n\n private firstWith(\n node: Test,\n runner: TestRunnerContext,\n has: (a: TestNodeAdapter) => boolean,\n ): TestNodeAdapter | null {\n for (const a of this.adapters) {\n if (has(a) && a.match(node, runner)) return a;\n }\n return null;\n }\n\n /** Adapter whose `renderDetail` should drive the body, or null for the default. */\n resolveDetail(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderDetail);\n }\n\n resolveRowLeading(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderRowLeading);\n }\n\n resolveFrameworkIcon(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderFrameworkIcon);\n }\n\n resolveActions(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.nodeActions);\n }\n\n resolveAttempts(node: Test, runner: TestRunnerContext): DetailAttempt[] {\n return this.firstWith(node, runner, (a) => !!a.detailAttempts)?.detailAttempts?.({ node, runner }) ?? [];\n }\n\n /** Merge `detailTabs` from every matching adapter, de-duplicated by tab id. */\n resolveTabs(node: Test, runner: TestRunnerContext): DetailTab[] {\n const ctx: AdapterContext = { node, runner };\n const seen = new Set<string>();\n const tabs: DetailTab[] = [];\n for (const a of this.adapters) {\n if (!a.detailTabs || !a.match(node, runner)) continue;\n for (const tab of a.detailTabs(ctx)) {\n if (seen.has(tab.id)) continue;\n seen.add(tab.id);\n tabs.push(tab);\n }\n }\n return tabs;\n }\n\n /**\n * Merge `copy` sections from every matching adapter, de-duplicated by fact\n * label, section title and item label — the first contributor wins.\n */\n resolveCopy(node: Test, runner: TestRunnerContext): Required<CopySections> {\n const ctx: AdapterContext = { node, runner };\n return mergeCopySections(\n this.adapters.flatMap((a) => (a.copy && a.match(node, runner) ? [a.copy(ctx)] : [])),\n );\n }\n\n /** True when the resolved detail adapter owns its own scroll region. */\n ownsScroll(node: Test, runner: TestRunnerContext): boolean {\n const a = this.resolveDetail(node, runner);\n if (!a?.ownsScroll) return false;\n return a.ownsScroll({ node, runner });\n }\n}\n\nexport function createTestRunnerRegistry(\n adapters: TestNodeAdapter[] = [],\n): TestNodeAdapterRegistry {\n return new TestNodeAdapterRegistry(adapters);\n}\n"],"names":["mergeCopySections"],"mappings":";;;;;;AAoEO,MAAM,wBAAwB;AAAA,EAGnC,YAAY,WAA8B,IAAI;AAFrC;AAGP,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,UACN,MACA,QACA,KACwB;AACxB,eAAW,KAAK,KAAK,UAAU;AAC7B,UAAI,IAAI,CAAC,KAAK,EAAE,MAAM,MAAM,MAAM,EAAG,QAAO;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,cAAc,MAAY,QAAmD;AAC3E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY;AAAA,EAC7D;AAAA,EAEA,kBAAkB,MAAY,QAAmD;AAC/E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB;AAAA,EACjE;AAAA,EAEA,qBAAqB,MAAY,QAAmD;AAClF,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,mBAAmB;AAAA,EACpE;AAAA,EAEA,eAAe,MAAY,QAAmD;AAC5E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW;AAAA,EAC5D;AAAA,EAEA,gBAAgB,MAAY,QAA4C;;AACtE,aAAO,gBAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,cAAc,MAAtD,mBAAyD,mBAAzD,4BAA0E,EAAE,MAAM,OAAA,OAAa,CAAA;AAAA,EACxG;AAAA;AAAA,EAGA,YAAY,MAAY,QAAwC;AAC9D,UAAM,MAAsB,EAAE,MAAM,OAAA;AACpC,UAAM,2BAAW,IAAA;AACjB,UAAM,OAAoB,CAAA;AAC1B,eAAW,KAAK,KAAK,UAAU;AAC7B,UAAI,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,MAAM,MAAM,EAAG;AAC7C,iBAAW,OAAO,EAAE,WAAW,GAAG,GAAG;AACnC,YAAI,KAAK,IAAI,IAAI,EAAE,EAAG;AACtB,aAAK,IAAI,IAAI,EAAE;AACf,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,MAAY,QAAmD;AACzE,UAAM,MAAsB,EAAE,MAAM,OAAA;AACpC,WAAOA,KAAAA;AAAAA,MACL,KAAK,SAAS,QAAQ,CAAC,MAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,MAAM,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,CAAA,CAAG;AAAA,IAAA;AAAA,EAEvF;AAAA;AAAA,EAGA,WAAW,MAAY,QAAoC;AACzD,UAAM,IAAI,KAAK,cAAc,MAAM,MAAM;AACzC,QAAI,EAAC,uBAAG,YAAY,QAAO;AAC3B,WAAO,EAAE,WAAW,EAAE,MAAM,QAAQ;AAAA,EACtC;AACF;AAEO,SAAS,yBACd,WAA8B,IACL;AACzB,SAAO,IAAI,wBAAwB,QAAQ;AAC7C;;;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { Test } from './types.js';
|
|
3
3
|
import { TestRunnerContext } from './context.js';
|
|
4
|
+
import { CopySections } from './copy.js';
|
|
4
5
|
export type AdapterContext = {
|
|
5
6
|
node: Test;
|
|
6
7
|
runner: TestRunnerContext;
|
|
@@ -10,16 +11,21 @@ export type DetailTab = {
|
|
|
10
11
|
label: string;
|
|
11
12
|
render: () => ReactNode;
|
|
12
13
|
};
|
|
14
|
+
export type DetailAttempt = {
|
|
15
|
+
id: number;
|
|
16
|
+
status: string;
|
|
17
|
+
durationMs?: number;
|
|
18
|
+
node: Test;
|
|
19
|
+
};
|
|
13
20
|
export type TestNodeAdapter = {
|
|
14
21
|
/** Stable identifier, used as a React key and for debugging. */
|
|
15
22
|
id: string;
|
|
16
23
|
/** Claim the node. The first registered adapter to return true wins per surface. */
|
|
17
24
|
match: (node: Test, runner: TestRunnerContext) => boolean;
|
|
18
25
|
/**
|
|
19
|
-
* Replace the framework icon for the node — return any node
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* depending on a runtime icon provider.
|
|
26
|
+
* Replace the framework icon for the node — return any node, or null to fall
|
|
27
|
+
* back to the built-in tool mark (`TEST_TOOLS`). For a tool the catalog
|
|
28
|
+
* lacks, prefer adding it to `TEST_TOOLS` so every surface shows it.
|
|
23
29
|
*/
|
|
24
30
|
renderFrameworkIcon?: (c: AdapterContext) => ReactNode;
|
|
25
31
|
/** Extra decoration rendered between the framework icon and the node name. */
|
|
@@ -28,8 +34,16 @@ export type TestNodeAdapter = {
|
|
|
28
34
|
renderDetail?: (c: AdapterContext) => ReactNode;
|
|
29
35
|
/** Extra detail tabs, merged (in registration order) across all matching adapters. */
|
|
30
36
|
detailTabs?: (c: AdapterContext) => DetailTab[];
|
|
37
|
+
/** Stored attempt views for the header chooser; tree and run totals remain step-level. */
|
|
38
|
+
detailAttempts?: (c: AdapterContext) => DetailAttempt[];
|
|
31
39
|
/** Node-scoped action buttons rendered in the detail header. */
|
|
32
40
|
nodeActions?: (c: AdapterContext) => ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* Domain facts, brief sections and menu items for the header's "Copy details"
|
|
43
|
+
* button, merged (in registration order) across all matching adapters on top
|
|
44
|
+
* of the generic sections every node gets.
|
|
45
|
+
*/
|
|
46
|
+
copy?: (c: AdapterContext) => CopySections;
|
|
33
47
|
/**
|
|
34
48
|
* Whether `renderDetail` owns its own full-height scroll container. When
|
|
35
49
|
* false (the default for custom bodies), the panel wraps it in a scroll
|
|
@@ -38,9 +52,9 @@ export type TestNodeAdapter = {
|
|
|
38
52
|
ownsScroll?: (c: AdapterContext) => boolean;
|
|
39
53
|
};
|
|
40
54
|
/**
|
|
41
|
-
* Ordered set of node adapters. First match wins per surface; `detailTabs`
|
|
42
|
-
* the
|
|
43
|
-
* adapters can each contribute a tab.
|
|
55
|
+
* Ordered set of node adapters. First match wins per surface; `detailTabs` and
|
|
56
|
+
* `copy` are the exceptions — they merge across every matching adapter so
|
|
57
|
+
* independent adapters can each contribute a tab or a copy section.
|
|
44
58
|
*/
|
|
45
59
|
export declare class TestNodeAdapterRegistry {
|
|
46
60
|
readonly adapters: TestNodeAdapter[];
|
|
@@ -51,8 +65,14 @@ export declare class TestNodeAdapterRegistry {
|
|
|
51
65
|
resolveRowLeading(node: Test, runner: TestRunnerContext): TestNodeAdapter | null;
|
|
52
66
|
resolveFrameworkIcon(node: Test, runner: TestRunnerContext): TestNodeAdapter | null;
|
|
53
67
|
resolveActions(node: Test, runner: TestRunnerContext): TestNodeAdapter | null;
|
|
68
|
+
resolveAttempts(node: Test, runner: TestRunnerContext): DetailAttempt[];
|
|
54
69
|
/** Merge `detailTabs` from every matching adapter, de-duplicated by tab id. */
|
|
55
70
|
resolveTabs(node: Test, runner: TestRunnerContext): DetailTab[];
|
|
71
|
+
/**
|
|
72
|
+
* Merge `copy` sections from every matching adapter, de-duplicated by fact
|
|
73
|
+
* label, section title and item label — the first contributor wins.
|
|
74
|
+
*/
|
|
75
|
+
resolveCopy(node: Test, runner: TestRunnerContext): Required<CopySections>;
|
|
56
76
|
/** True when the resolved detail adapter owns its own scroll region. */
|
|
57
77
|
ownsScroll(node: Test, runner: TestRunnerContext): boolean;
|
|
58
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { mergeCopySections } from "./copy.js";
|
|
4
5
|
class TestNodeAdapterRegistry {
|
|
5
6
|
constructor(adapters = []) {
|
|
6
7
|
__publicField(this, "adapters");
|
|
@@ -25,6 +26,10 @@ class TestNodeAdapterRegistry {
|
|
|
25
26
|
resolveActions(node, runner) {
|
|
26
27
|
return this.firstWith(node, runner, (a) => !!a.nodeActions);
|
|
27
28
|
}
|
|
29
|
+
resolveAttempts(node, runner) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
return ((_b = (_a = this.firstWith(node, runner, (a) => !!a.detailAttempts)) == null ? void 0 : _a.detailAttempts) == null ? void 0 : _b.call(_a, { node, runner })) ?? [];
|
|
32
|
+
}
|
|
28
33
|
/** Merge `detailTabs` from every matching adapter, de-duplicated by tab id. */
|
|
29
34
|
resolveTabs(node, runner) {
|
|
30
35
|
const ctx = { node, runner };
|
|
@@ -40,6 +45,16 @@ class TestNodeAdapterRegistry {
|
|
|
40
45
|
}
|
|
41
46
|
return tabs;
|
|
42
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Merge `copy` sections from every matching adapter, de-duplicated by fact
|
|
50
|
+
* label, section title and item label — the first contributor wins.
|
|
51
|
+
*/
|
|
52
|
+
resolveCopy(node, runner) {
|
|
53
|
+
const ctx = { node, runner };
|
|
54
|
+
return mergeCopySections(
|
|
55
|
+
this.adapters.flatMap((a) => a.copy && a.match(node, runner) ? [a.copy(ctx)] : [])
|
|
56
|
+
);
|
|
57
|
+
}
|
|
43
58
|
/** True when the resolved detail adapter owns its own scroll region. */
|
|
44
59
|
ownsScroll(node, runner) {
|
|
45
60
|
const a = this.resolveDetail(node, runner);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sources":["../../../src/data/test-runner/adapter.ts"],"sourcesContent":["// Node adapters let a host plug domain-specific rendering into the test runner\n// without forking it. An adapter claims nodes via `match` and contributes how\n// they render in each surface (tree row, detail body, detail tabs, header\n// actions). The registry resolves the first matching adapter per surface;\n// surfaces with no match fall back to the runner's built-in default rendering.\n//\n// This formalizes the wrapper-with-an-if-chain pattern hosts use today (e.g.\n// a ResultDetailPane fall-through over domain panels + tab providers + per-step\n// actions) into a registered, composable contract.\n\nimport type { ReactNode } from \"react\";\nimport type { Test } from \"./types\";\nimport type { TestRunnerContext } from \"./context\";\n\nexport type AdapterContext = {\n node: Test;\n runner: TestRunnerContext;\n};\n\nexport type DetailTab = {\n id: string;\n label: string;\n render: () => ReactNode;\n};\n\nexport type TestNodeAdapter = {\n /** Stable identifier, used as a React key and for debugging. */\n id: string;\n /** Claim the node. The first registered adapter to return true wins per surface. */\n match: (node: Test, runner: TestRunnerContext) => boolean;\n /**\n * Replace the framework icon for the node — return any node
|
|
1
|
+
{"version":3,"file":"adapter.js","sources":["../../../src/data/test-runner/adapter.ts"],"sourcesContent":["// Node adapters let a host plug domain-specific rendering into the test runner\n// without forking it. An adapter claims nodes via `match` and contributes how\n// they render in each surface (tree row, detail body, detail tabs, header\n// actions). The registry resolves the first matching adapter per surface;\n// surfaces with no match fall back to the runner's built-in default rendering.\n//\n// This formalizes the wrapper-with-an-if-chain pattern hosts use today (e.g.\n// a ResultDetailPane fall-through over domain panels + tab providers + per-step\n// actions) into a registered, composable contract.\n\nimport type { ReactNode } from \"react\";\nimport type { Test } from \"./types\";\nimport type { TestRunnerContext } from \"./context\";\nimport { mergeCopySections, type CopySections } from \"./copy\";\n\nexport type AdapterContext = {\n node: Test;\n runner: TestRunnerContext;\n};\n\nexport type DetailTab = {\n id: string;\n label: string;\n render: () => ReactNode;\n};\n\nexport type DetailAttempt = { id: number; status: string; durationMs?: number; node: Test };\n\nexport type TestNodeAdapter = {\n /** Stable identifier, used as a React key and for debugging. */\n id: string;\n /** Claim the node. The first registered adapter to return true wins per surface. */\n match: (node: Test, runner: TestRunnerContext) => boolean;\n /**\n * Replace the framework icon for the node — return any node, or null to fall\n * back to the built-in tool mark (`TEST_TOOLS`). For a tool the catalog\n * lacks, prefer adding it to `TEST_TOOLS` so every surface shows it.\n */\n renderFrameworkIcon?: (c: AdapterContext) => ReactNode;\n /** Extra decoration rendered between the framework icon and the node name. */\n renderRowLeading?: (c: AdapterContext) => ReactNode;\n /** Primary detail body for the node, replacing the default panel body. */\n renderDetail?: (c: AdapterContext) => ReactNode;\n /** Extra detail tabs, merged (in registration order) across all matching adapters. */\n detailTabs?: (c: AdapterContext) => DetailTab[];\n /** Stored attempt views for the header chooser; tree and run totals remain step-level. */\n detailAttempts?: (c: AdapterContext) => DetailAttempt[];\n /** Node-scoped action buttons rendered in the detail header. */\n nodeActions?: (c: AdapterContext) => ReactNode;\n /**\n * Domain facts, brief sections and menu items for the header's \"Copy details\"\n * button, merged (in registration order) across all matching adapters on top\n * of the generic sections every node gets.\n */\n copy?: (c: AdapterContext) => CopySections;\n /**\n * Whether `renderDetail` owns its own full-height scroll container. When\n * false (the default for custom bodies), the panel wraps it in a scroll\n * region. The built-in default body owns its scroll.\n */\n ownsScroll?: (c: AdapterContext) => boolean;\n};\n\n/**\n * Ordered set of node adapters. First match wins per surface; `detailTabs` and\n * `copy` are the exceptions — they merge across every matching adapter so\n * independent adapters can each contribute a tab or a copy section.\n */\nexport class TestNodeAdapterRegistry {\n readonly adapters: TestNodeAdapter[];\n\n constructor(adapters: TestNodeAdapter[] = []) {\n this.adapters = adapters;\n }\n\n private firstWith(\n node: Test,\n runner: TestRunnerContext,\n has: (a: TestNodeAdapter) => boolean,\n ): TestNodeAdapter | null {\n for (const a of this.adapters) {\n if (has(a) && a.match(node, runner)) return a;\n }\n return null;\n }\n\n /** Adapter whose `renderDetail` should drive the body, or null for the default. */\n resolveDetail(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderDetail);\n }\n\n resolveRowLeading(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderRowLeading);\n }\n\n resolveFrameworkIcon(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.renderFrameworkIcon);\n }\n\n resolveActions(node: Test, runner: TestRunnerContext): TestNodeAdapter | null {\n return this.firstWith(node, runner, (a) => !!a.nodeActions);\n }\n\n resolveAttempts(node: Test, runner: TestRunnerContext): DetailAttempt[] {\n return this.firstWith(node, runner, (a) => !!a.detailAttempts)?.detailAttempts?.({ node, runner }) ?? [];\n }\n\n /** Merge `detailTabs` from every matching adapter, de-duplicated by tab id. */\n resolveTabs(node: Test, runner: TestRunnerContext): DetailTab[] {\n const ctx: AdapterContext = { node, runner };\n const seen = new Set<string>();\n const tabs: DetailTab[] = [];\n for (const a of this.adapters) {\n if (!a.detailTabs || !a.match(node, runner)) continue;\n for (const tab of a.detailTabs(ctx)) {\n if (seen.has(tab.id)) continue;\n seen.add(tab.id);\n tabs.push(tab);\n }\n }\n return tabs;\n }\n\n /**\n * Merge `copy` sections from every matching adapter, de-duplicated by fact\n * label, section title and item label — the first contributor wins.\n */\n resolveCopy(node: Test, runner: TestRunnerContext): Required<CopySections> {\n const ctx: AdapterContext = { node, runner };\n return mergeCopySections(\n this.adapters.flatMap((a) => (a.copy && a.match(node, runner) ? [a.copy(ctx)] : [])),\n );\n }\n\n /** True when the resolved detail adapter owns its own scroll region. */\n ownsScroll(node: Test, runner: TestRunnerContext): boolean {\n const a = this.resolveDetail(node, runner);\n if (!a?.ownsScroll) return false;\n return a.ownsScroll({ node, runner });\n }\n}\n\nexport function createTestRunnerRegistry(\n adapters: TestNodeAdapter[] = [],\n): TestNodeAdapterRegistry {\n return new TestNodeAdapterRegistry(adapters);\n}\n"],"names":[],"mappings":";;;;AAoEO,MAAM,wBAAwB;AAAA,EAGnC,YAAY,WAA8B,IAAI;AAFrC;AAGP,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,UACN,MACA,QACA,KACwB;AACxB,eAAW,KAAK,KAAK,UAAU;AAC7B,UAAI,IAAI,CAAC,KAAK,EAAE,MAAM,MAAM,MAAM,EAAG,QAAO;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,cAAc,MAAY,QAAmD;AAC3E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY;AAAA,EAC7D;AAAA,EAEA,kBAAkB,MAAY,QAAmD;AAC/E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB;AAAA,EACjE;AAAA,EAEA,qBAAqB,MAAY,QAAmD;AAClF,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,mBAAmB;AAAA,EACpE;AAAA,EAEA,eAAe,MAAY,QAAmD;AAC5E,WAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW;AAAA,EAC5D;AAAA,EAEA,gBAAgB,MAAY,QAA4C;;AACtE,aAAO,gBAAK,UAAU,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,cAAc,MAAtD,mBAAyD,mBAAzD,4BAA0E,EAAE,MAAM,OAAA,OAAa,CAAA;AAAA,EACxG;AAAA;AAAA,EAGA,YAAY,MAAY,QAAwC;AAC9D,UAAM,MAAsB,EAAE,MAAM,OAAA;AACpC,UAAM,2BAAW,IAAA;AACjB,UAAM,OAAoB,CAAA;AAC1B,eAAW,KAAK,KAAK,UAAU;AAC7B,UAAI,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,MAAM,MAAM,EAAG;AAC7C,iBAAW,OAAO,EAAE,WAAW,GAAG,GAAG;AACnC,YAAI,KAAK,IAAI,IAAI,EAAE,EAAG;AACtB,aAAK,IAAI,IAAI,EAAE;AACf,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,MAAY,QAAmD;AACzE,UAAM,MAAsB,EAAE,MAAM,OAAA;AACpC,WAAO;AAAA,MACL,KAAK,SAAS,QAAQ,CAAC,MAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,MAAM,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,CAAA,CAAG;AAAA,IAAA;AAAA,EAEvF;AAAA;AAAA,EAGA,WAAW,MAAY,QAAoC;AACzD,UAAM,IAAI,KAAK,cAAc,MAAM,MAAM;AACzC,QAAI,EAAC,uBAAG,YAAY,QAAO;AAC3B,WAAO,EAAE,WAAW,EAAE,MAAM,QAAQ;AAAA,EACtC;AACF;AAEO,SAAS,yBACd,WAA8B,IACL;AACzB,SAAO,IAAI,wBAAwB,QAAQ;AAC7C;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.cjs","sources":["../../../src/data/test-runner/context.ts"],"sourcesContent":["// A single context object carries all runner state + handlers, provided once\n// and read by every sub-component via useTestRunner() — instead of threading\n// onRerun/onStop/selected/runMeta/... through each component's props. Matches\n// clicky's existing Provider idiom (ClickyRuntimeProvider / TagActionsProvider).\n\nimport { createContext, useContext } from \"react\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport type { TestFilters } from \"./filterState\";\nimport type { TestNodeAdapterRegistry } from \"./adapter\";\n\nexport type TestRunnerContext = {\n /** The (already filtered, host-owned) test forest to render. */\n tests: Test[];\n /** Currently selected node, or null. */\n selected: Test | null;\n runMeta?: RunMeta | undefined;\n /** Run status flags (data only — no transport lives here). */\n status?: SnapshotStatus | undefined;\n /** Whether the run has finished. */\n done: boolean;\n /**\n * Injected wall-clock epoch ms for elapsed-time display. Kept as data so the\n * summary stays pure and testable; hosts pass `Date.now()`.\n */\n now?: number | undefined;\n /** Active status/framework filters. */\n filters: TestFilters;\n /** Tri-state expand-all: true (all open), false (all closed), null (default). */\n expandAll: boolean | null;\n /** In-flight action flags driving button disabled/spinner states. */\n busy: { rerun?: boolean; stop?: boolean };\n\n /**\n * Active detail-tab id. When provided, TestDetailPanel renders this tab\n * (controlled); when omitted it keeps its own internal tab state.\n */\n activeTab?: string | undefined;\n /** Called with the picked tab id when the detail tab is controlled. */\n onTabChange?: ((tabId: string) => void) | undefined;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n /** Optional — when absent, the rerun affordance is hidden. */\n onRerun?: ((node: Test) => void) | undefined;\n /** Optional — when absent, the stop affordance is hidden. */\n onStop?: ((node: Test) => void) | undefined;\n\n /** Node adapters driving domain-specific rendering. */\n adapters: TestNodeAdapterRegistry;\n};\n\nconst Context = createContext<TestRunnerContext | null>(null);\n\nexport const TestRunnerProvider = Context.Provider;\n\nexport function useTestRunner(): TestRunnerContext {\n const ctx = useContext(Context);\n if (!ctx) {\n throw new Error(\"useTestRunner must be used within a <TestRunner> / TestRunnerProvider\");\n }\n return ctx;\n}\n"],"names":["createContext","useContext"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"context.cjs","sources":["../../../src/data/test-runner/context.ts"],"sourcesContent":["// A single context object carries all runner state + handlers, provided once\n// and read by every sub-component via useTestRunner() — instead of threading\n// onRerun/onStop/selected/runMeta/... through each component's props. Matches\n// clicky's existing Provider idiom (ClickyRuntimeProvider / TagActionsProvider).\n\nimport { createContext, useContext } from \"react\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport type { TestFilters } from \"./filterState\";\nimport type { TestNodeAdapterRegistry } from \"./adapter\";\n\nexport type TestRunnerContext = {\n /** The (already filtered, host-owned) test forest to render. */\n tests: Test[];\n /** Currently selected node, or null. */\n selected: Test | null;\n runMeta?: RunMeta | undefined;\n /** Run status flags (data only — no transport lives here). */\n status?: SnapshotStatus | undefined;\n /** Whether the run has finished. */\n done: boolean;\n /**\n * Injected wall-clock epoch ms for elapsed-time display. Kept as data so the\n * summary stays pure and testable; hosts pass `Date.now()`.\n */\n now?: number | undefined;\n /** Active status/framework filters. */\n filters: TestFilters;\n /** Tri-state expand-all: true (all open), false (all closed), null (default). */\n expandAll: boolean | null;\n /** In-flight action flags driving button disabled/spinner states. */\n busy: { rerun?: boolean; stop?: boolean };\n\n /**\n * Active detail-tab id. When provided, TestDetailPanel renders this tab\n * (controlled); when omitted it keeps its own internal tab state.\n */\n activeTab?: string | undefined;\n /** Called with the picked tab id when the detail tab is controlled. */\n onTabChange?: ((tabId: string) => void) | undefined;\n activeAttempt?: number | undefined;\n onAttemptChange?: ((attempt: number) => void) | undefined;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n /** Optional — when absent, the rerun affordance is hidden. */\n onRerun?: ((node: Test) => void) | undefined;\n /** Optional — when absent, the stop affordance is hidden. */\n onStop?: ((node: Test) => void) | undefined;\n\n /** Node adapters driving domain-specific rendering. */\n adapters: TestNodeAdapterRegistry;\n};\n\nconst Context = createContext<TestRunnerContext | null>(null);\n\nexport const TestRunnerProvider = Context.Provider;\n\nexport function useTestRunner(): TestRunnerContext {\n const ctx = useContext(Context);\n if (!ctx) {\n throw new Error(\"useTestRunner must be used within a <TestRunner> / TestRunnerProvider\");\n }\n return ctx;\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAsDA,MAAM,UAAUA,MAAAA,cAAwC,IAAI;AAErD,MAAM,qBAAqB,QAAQ;AAEnC,SAAS,gBAAmC;AACjD,QAAM,MAAMC,MAAAA,WAAW,OAAO;AAC9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AACA,SAAO;AACT;;;"}
|
|
@@ -32,6 +32,8 @@ export type TestRunnerContext = {
|
|
|
32
32
|
activeTab?: string | undefined;
|
|
33
33
|
/** Called with the picked tab id when the detail tab is controlled. */
|
|
34
34
|
onTabChange?: ((tabId: string) => void) | undefined;
|
|
35
|
+
activeAttempt?: number | undefined;
|
|
36
|
+
onAttemptChange?: ((attempt: number) => void) | undefined;
|
|
35
37
|
onSelect: (node: Test | null) => void;
|
|
36
38
|
onFiltersChange: (next: TestFilters) => void;
|
|
37
39
|
onExpandAllChange: (next: boolean | null) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gEAAgE;IAChE,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,oCAAoC;IACpC,IAAI,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,uCAAuC;IACvC,OAAO,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,qEAAqE;IACrE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gEAAgE;IAChE,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,oCAAoC;IACpC,IAAI,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,uCAAuC;IACvC,OAAO,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,qEAAqE;IACrE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAE1D,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7C,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAE5C,uDAAuD;IACvD,QAAQ,EAAE,uBAAuB,CAAC;CACnC,CAAC;AAIF,eAAO,MAAM,kBAAkB,oDAAmB,CAAC;AAEnD,wBAAgB,aAAa,IAAI,iBAAiB,CAMjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sources":["../../../src/data/test-runner/context.ts"],"sourcesContent":["// A single context object carries all runner state + handlers, provided once\n// and read by every sub-component via useTestRunner() — instead of threading\n// onRerun/onStop/selected/runMeta/... through each component's props. Matches\n// clicky's existing Provider idiom (ClickyRuntimeProvider / TagActionsProvider).\n\nimport { createContext, useContext } from \"react\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport type { TestFilters } from \"./filterState\";\nimport type { TestNodeAdapterRegistry } from \"./adapter\";\n\nexport type TestRunnerContext = {\n /** The (already filtered, host-owned) test forest to render. */\n tests: Test[];\n /** Currently selected node, or null. */\n selected: Test | null;\n runMeta?: RunMeta | undefined;\n /** Run status flags (data only — no transport lives here). */\n status?: SnapshotStatus | undefined;\n /** Whether the run has finished. */\n done: boolean;\n /**\n * Injected wall-clock epoch ms for elapsed-time display. Kept as data so the\n * summary stays pure and testable; hosts pass `Date.now()`.\n */\n now?: number | undefined;\n /** Active status/framework filters. */\n filters: TestFilters;\n /** Tri-state expand-all: true (all open), false (all closed), null (default). */\n expandAll: boolean | null;\n /** In-flight action flags driving button disabled/spinner states. */\n busy: { rerun?: boolean; stop?: boolean };\n\n /**\n * Active detail-tab id. When provided, TestDetailPanel renders this tab\n * (controlled); when omitted it keeps its own internal tab state.\n */\n activeTab?: string | undefined;\n /** Called with the picked tab id when the detail tab is controlled. */\n onTabChange?: ((tabId: string) => void) | undefined;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n /** Optional — when absent, the rerun affordance is hidden. */\n onRerun?: ((node: Test) => void) | undefined;\n /** Optional — when absent, the stop affordance is hidden. */\n onStop?: ((node: Test) => void) | undefined;\n\n /** Node adapters driving domain-specific rendering. */\n adapters: TestNodeAdapterRegistry;\n};\n\nconst Context = createContext<TestRunnerContext | null>(null);\n\nexport const TestRunnerProvider = Context.Provider;\n\nexport function useTestRunner(): TestRunnerContext {\n const ctx = useContext(Context);\n if (!ctx) {\n throw new Error(\"useTestRunner must be used within a <TestRunner> / TestRunnerProvider\");\n }\n return ctx;\n}\n"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../../../src/data/test-runner/context.ts"],"sourcesContent":["// A single context object carries all runner state + handlers, provided once\n// and read by every sub-component via useTestRunner() — instead of threading\n// onRerun/onStop/selected/runMeta/... through each component's props. Matches\n// clicky's existing Provider idiom (ClickyRuntimeProvider / TagActionsProvider).\n\nimport { createContext, useContext } from \"react\";\nimport type { RunMeta, SnapshotStatus, Test } from \"./types\";\nimport type { TestFilters } from \"./filterState\";\nimport type { TestNodeAdapterRegistry } from \"./adapter\";\n\nexport type TestRunnerContext = {\n /** The (already filtered, host-owned) test forest to render. */\n tests: Test[];\n /** Currently selected node, or null. */\n selected: Test | null;\n runMeta?: RunMeta | undefined;\n /** Run status flags (data only — no transport lives here). */\n status?: SnapshotStatus | undefined;\n /** Whether the run has finished. */\n done: boolean;\n /**\n * Injected wall-clock epoch ms for elapsed-time display. Kept as data so the\n * summary stays pure and testable; hosts pass `Date.now()`.\n */\n now?: number | undefined;\n /** Active status/framework filters. */\n filters: TestFilters;\n /** Tri-state expand-all: true (all open), false (all closed), null (default). */\n expandAll: boolean | null;\n /** In-flight action flags driving button disabled/spinner states. */\n busy: { rerun?: boolean; stop?: boolean };\n\n /**\n * Active detail-tab id. When provided, TestDetailPanel renders this tab\n * (controlled); when omitted it keeps its own internal tab state.\n */\n activeTab?: string | undefined;\n /** Called with the picked tab id when the detail tab is controlled. */\n onTabChange?: ((tabId: string) => void) | undefined;\n activeAttempt?: number | undefined;\n onAttemptChange?: ((attempt: number) => void) | undefined;\n\n onSelect: (node: Test | null) => void;\n onFiltersChange: (next: TestFilters) => void;\n onExpandAllChange: (next: boolean | null) => void;\n /** Optional — when absent, the rerun affordance is hidden. */\n onRerun?: ((node: Test) => void) | undefined;\n /** Optional — when absent, the stop affordance is hidden. */\n onStop?: ((node: Test) => void) | undefined;\n\n /** Node adapters driving domain-specific rendering. */\n adapters: TestNodeAdapterRegistry;\n};\n\nconst Context = createContext<TestRunnerContext | null>(null);\n\nexport const TestRunnerProvider = Context.Provider;\n\nexport function useTestRunner(): TestRunnerContext {\n const ctx = useContext(Context);\n if (!ctx) {\n throw new Error(\"useTestRunner must be used within a <TestRunner> / TestRunnerProvider\");\n }\n return ctx;\n}\n"],"names":[],"mappings":";AAsDA,MAAM,UAAU,cAAwC,IAAI;AAErD,MAAM,qBAAqB,QAAQ;AAEnC,SAAS,gBAAmC;AACjD,QAAM,MAAM,WAAW,OAAO;AAC9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AACA,SAAO;AACT;"}
|