Files
apress/src/pages/EnvSetup.test.tsx
T
Omar SobhandClaude Opus 4.8 a9a5176f7c feat(cockpit): Clawd mascot + live agent chat on Meet your agent
Rework the Meet-your-agent rail into a self-contained agent surface:

- Clawd, the Claude Code pixel crab, animates the LED matrix on a 26x16
  grid, coupled to the chat lifecycle (idle stare / claws pump while
  working / green flash on reply). Static antennas, permanent black eyes.
- A full free-form chat to the default agent (useAgentChat): free text
  goes to the blocking /webhook path so conversational replies actually
  render; the 3 canned prompts stay fire-and-forget + SSE (tool turns).
- Chat and the working log are separate panes; the 3 prompts became
  starter buttons; the ZeroClaw runtime + channels moved into an
  Advanced drawer. The whole agent rail is now theme-aware (light/dark).
- Strip the phase eyebrows from the sidebar + page headers; reduce the
  EnvSetup left column to editorial copy.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-23 16:35:17 -07:00

53 lines
1.8 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { EnvSetup } from './EnvSetup'
import { useSession } from '@/store/session'
// The chat, starters, runtime and channels all moved to the cockpit rail
// (CockpitRail's "agent" variant) — the page itself is now editorial copy + a
// proceed gate. Stub the mode call the rail would otherwise make elsewhere.
vi.mock('@/lib/api', async (orig) => ({
...(await orig<typeof import('@/lib/api')>()),
getMode: () => Promise.resolve({ localMode: false }),
}))
function renderPage() {
return render(
<MemoryRouter>
<EnvSetup />
</MemoryRouter>,
)
}
function connect(nodeUrl: string | null = 'http://192.168.1.7:8080') {
useSession.getState().setDevice({ connected: true, port: 'board · crimson-otter', uptimeS: 0, nodeUrl })
}
describe('EnvSetup — Meet your agent', () => {
beforeEach(() => {
useSession.getState().reset()
sessionStorage.clear()
})
it('renders the heading and the editorial intro', () => {
renderPage()
expect(screen.getByRole('heading', { name: /meet your agent/i })).toBeInTheDocument()
expect(screen.getByTestId('agent-intro')).toBeInTheDocument()
})
it('guides to connect the board first when not connected, and gates Proceed', () => {
renderPage()
expect(screen.getByText(/connect your board on the previous step/i)).toBeInTheDocument()
expect(screen.getByRole('button', { name: /proceed/i })).toBeDisabled()
})
it('enables Proceed once the board is connected', () => {
connect()
renderPage()
expect(screen.getByRole('button', { name: /proceed/i })).toBeEnabled()
// the connect nudge disappears once online
expect(screen.queryByText(/connect your board on the previous step/i)).toBeNull()
})
})