diff --git a/frontend/src/components/AgentPanel.test.tsx b/frontend/src/components/AgentPanel.test.tsx
index 211cfda..ef4aafa 100644
--- a/frontend/src/components/AgentPanel.test.tsx
+++ b/frontend/src/components/AgentPanel.test.tsx
@@ -139,3 +139,74 @@ describe("RosterBadge availability state", () => {
expect(badge.style.color).toBe("rgb(88, 166, 255)");
});
});
+
+describe("RosterBadge availability state", () => {
+ beforeAll(() => {
+ Element.prototype.scrollIntoView = vi.fn();
+ });
+
+ beforeEach(() => {
+ mockedAgents.getAgentConfig.mockResolvedValue(ROSTER);
+ mockedAgents.listAgents.mockResolvedValue([]);
+ });
+
+ it("shows a green dot for an idle agent", async () => {
+ render();
+
+ const dot = await screen.findByTestId("roster-dot-coder-1");
+ // JSDOM normalizes #3fb950 to rgb(63, 185, 80)
+ expect(dot.style.background).toBe("rgb(63, 185, 80)");
+ expect(dot.style.animation).toBe("");
+ });
+
+ it("shows green badge styling for an idle agent", async () => {
+ render();
+
+ const badge = await screen.findByTestId("roster-badge-coder-1");
+ // JSDOM normalizes #3fb95015 to rgba(63, 185, 80, 0.082) and #3fb950 to rgb(63, 185, 80)
+ expect(badge.style.background).toBe("rgba(63, 185, 80, 0.082)");
+ expect(badge.style.color).toBe("rgb(63, 185, 80)");
+ });
+
+ it("shows a blue pulsing dot for an active agent", async () => {
+ const agentList: AgentInfo[] = [
+ {
+ story_id: "81_active",
+ agent_name: "coder-1",
+ status: "running",
+ session_id: null,
+ worktree_path: null,
+ base_branch: null,
+ },
+ ];
+ mockedAgents.listAgents.mockResolvedValue(agentList);
+
+ render();
+
+ const dot = await screen.findByTestId("roster-dot-coder-1");
+ // JSDOM normalizes #58a6ff to rgb(88, 166, 255)
+ expect(dot.style.background).toBe("rgb(88, 166, 255)");
+ expect(dot.style.animation).toBe("pulse 1.5s infinite");
+ });
+
+ it("shows blue badge styling for an active agent", async () => {
+ const agentList: AgentInfo[] = [
+ {
+ story_id: "81_active",
+ agent_name: "coder-1",
+ status: "running",
+ session_id: null,
+ worktree_path: null,
+ base_branch: null,
+ },
+ ];
+ mockedAgents.listAgents.mockResolvedValue(agentList);
+
+ render();
+
+ const badge = await screen.findByTestId("roster-badge-coder-1");
+ // JSDOM normalizes #58a6ff18 to rgba(88, 166, 255, 0.094) and #58a6ff to rgb(88, 166, 255)
+ expect(badge.style.background).toBe("rgba(88, 166, 255, 0.094)");
+ expect(badge.style.color).toBe("rgb(88, 166, 255)");
+ });
+});