feat: add terminal broadcast, context menu, and shell close
Complete multi-pane broadcast, standard terminal right-click actions, batch host selection with progress, and native ssh_close_shell so closing a pane tears down the remote shell. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
494ef6b9d0
commit
9ce71795b8
38 files changed
+1437
-186
No files matched your search
@@ -33,7 +33,7 @@ describe('BatchCommandDialog', () => {
|
||||
render(<BatchCommandDialog isOpen sessions={sessions} onClose={vi.fn()} />)
|
||||
|
||||
await user.type(screen.getByLabelText('远程命令'), 'date')
|
||||
await user.click(screen.getByRole('button', { name: '执行命令' }))
|
||||
await user.click(screen.getByRole('button', { name: '执行到 2 台' }))
|
||||
|
||||
await waitFor(() => expect(mockDesktopApi.sshExec).toHaveBeenCalledTimes(2))
|
||||
expect(mockDesktopApi.sshExec).toHaveBeenCalledWith('connection-10.0.0.1', 'date')
|
||||
@@ -43,4 +43,41 @@ describe('BatchCommandDialog', () => {
|
||||
expect(screen.getByText('connection-10.0.0.1: date')).toBeVisible()
|
||||
expect(screen.getByText('connection-10.0.0.2: date')).toBeVisible()
|
||||
})
|
||||
|
||||
it('starts with the sidebar selection and lets the user adjust targets in the dialog', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<BatchCommandDialog
|
||||
isOpen
|
||||
sessions={sessions}
|
||||
initialSelectedIds={['host-a']}
|
||||
onClose={vi.fn()}
|
||||
/>
|
||||
)
|
||||
|
||||
expect(screen.getByRole('checkbox', { name: /Host A/ })).toHaveAttribute('aria-checked', 'true')
|
||||
expect(screen.getByRole('checkbox', { name: /Host B/ })).toHaveAttribute('aria-checked', 'false')
|
||||
await user.click(screen.getByRole('checkbox', { name: /Host B/ }))
|
||||
expect(screen.getByRole('button', { name: '执行到 2 台' })).toBeVisible()
|
||||
|
||||
await user.type(screen.getByLabelText('筛选主机'), '10.0.0.1')
|
||||
expect(screen.getByRole('checkbox', { name: /Host A/ })).toBeVisible()
|
||||
expect(screen.queryByRole('checkbox', { name: /Host B/ })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('clears the command when reopened so sensitive input is not retained', async () => {
|
||||
const user = userEvent.setup()
|
||||
const { rerender } = render(
|
||||
<BatchCommandDialog isOpen sessions={sessions} onClose={vi.fn()} />
|
||||
)
|
||||
|
||||
const command = screen.getByLabelText('远程命令')
|
||||
await user.type(command, 'cat /etc/shadow')
|
||||
expect(command).toHaveValue('cat /etc/shadow')
|
||||
|
||||
rerender(<BatchCommandDialog isOpen={false} sessions={sessions} onClose={vi.fn()} />)
|
||||
rerender(<BatchCommandDialog isOpen sessions={sessions} onClose={vi.fn()} />)
|
||||
|
||||
expect(screen.getByLabelText('远程命令')).toHaveValue('')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user