Merge pull request #6 from RooVetGit/feature/addTerminateTaskButton

This commit is contained in:
John Stearns
2024-11-05 17:11:54 -08:00
committed by GitHub
4 changed files with 175 additions and 3 deletions

View File

@@ -2,7 +2,7 @@
"name": "roo-cline",
"displayName": "Roo Cline",
"description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.",
"version": "1.0.3",
"version": "1.0.4",
"icon": "assets/icons/icon.png",
"galleryBanner": {
"color": "#617A91",

View File

@@ -146,8 +146,8 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
setClineAsk("resume_task")
setEnableButtons(true)
setPrimaryButtonText("Resume Task")
setSecondaryButtonText(undefined)
setDidClickCancel(false) // special case where we reset the cancel button state
setSecondaryButtonText("Terminate")
setDidClickCancel(false) // special case where we reset the cancel button state
break
case "resume_completed_task":
setTextAreaDisabled(false)
@@ -316,6 +316,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
switch (clineAsk) {
case "api_req_failed":
case "mistake_limit_reached":
case "resume_task":
startNewTask()
break
case "command":

View File

@@ -0,0 +1,171 @@
import { render, screen, act } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { ExtensionStateContextType } from '../../../context/ExtensionStateContext'
import ChatView from '../ChatView'
import { vscode } from '../../../utils/vscode'
import * as ExtensionStateContext from '../../../context/ExtensionStateContext'
// Mock vscode
jest.mock('../../../utils/vscode', () => ({
vscode: {
postMessage: jest.fn()
}
}))
// Mock all components that use problematic dependencies
jest.mock('../../common/CodeBlock', () => ({
__esModule: true,
default: () => <div data-testid="mock-code-block" />
}))
jest.mock('../../common/MarkdownBlock', () => ({
__esModule: true,
default: () => <div data-testid="mock-markdown-block" />
}))
jest.mock('../BrowserSessionRow', () => ({
__esModule: true,
default: () => <div data-testid="mock-browser-session-row" />
}))
// Update ChatRow mock to capture props
let chatRowProps = null
jest.mock('../ChatRow', () => ({
__esModule: true,
default: (props: any) => {
chatRowProps = props
return <div data-testid="mock-chat-row" />
}
}))
// Mock Virtuoso component
jest.mock('react-virtuoso', () => ({
Virtuoso: ({ children }: any) => (
<div data-testid="mock-virtuoso">{children}</div>
)
}))
// Mock VS Code components
jest.mock('@vscode/webview-ui-toolkit/react', () => ({
VSCodeButton: ({ children, onClick }: any) => (
<button onClick={onClick}>{children}</button>
),
VSCodeProgressRing: () => <div data-testid="progress-ring" />
}))
describe('ChatView', () => {
const mockShowHistoryView = jest.fn()
const mockHideAnnouncement = jest.fn()
let mockState: ExtensionStateContextType
beforeEach(() => {
jest.clearAllMocks()
mockState = {
clineMessages: [],
apiConfiguration: {
apiProvider: 'anthropic',
apiModelId: 'claude-3-sonnet'
},
version: '1.0.0',
customInstructions: '',
alwaysAllowReadOnly: true,
alwaysAllowWrite: true,
alwaysAllowExecute: true,
openRouterModels: {},
didHydrateState: true,
showWelcome: false,
theme: 'dark',
filePaths: [],
taskHistory: [],
shouldShowAnnouncement: false,
uriScheme: 'vscode',
setAlwaysAllowReadOnly: jest.fn(),
setAlwaysAllowWrite: jest.fn(),
setCustomInstructions: jest.fn(),
setAlwaysAllowExecute: jest.fn(),
setApiConfiguration: jest.fn(),
setShowAnnouncement: jest.fn()
}
// Mock the useExtensionState hook
jest.spyOn(ExtensionStateContext, 'useExtensionState').mockReturnValue(mockState)
})
const renderChatView = () => {
return render(
<ChatView
isHidden={false}
showAnnouncement={false}
hideAnnouncement={mockHideAnnouncement}
showHistoryView={mockShowHistoryView}
/>
)
}
describe('Streaming State', () => {
it('should show cancel button while streaming and trigger cancel on click', async () => {
mockState.clineMessages = [
{
type: 'say',
say: 'task',
ts: Date.now(),
},
{
type: 'say',
say: 'text',
partial: true,
ts: Date.now(),
}
]
renderChatView()
const cancelButton = screen.getByText('Cancel')
await userEvent.click(cancelButton)
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'cancelTask'
})
})
it('should show terminate button when task is paused and trigger terminate on click', async () => {
mockState.clineMessages = [
{
type: 'ask',
ask: 'resume_task',
ts: Date.now(),
}
]
renderChatView()
const terminateButton = screen.getByText('Terminate')
await userEvent.click(terminateButton)
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'clearTask'
})
})
it('should show retry button when API error occurs and trigger retry on click', async () => {
mockState.clineMessages = [
{
type: 'ask',
ask: 'api_req_failed',
ts: Date.now(),
}
]
renderChatView()
const retryButton = screen.getByText('Retry')
await userEvent.click(retryButton)
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'askResponse',
askResponse: 'yesButtonClicked'
})
})
})
})