story-kit: start 73_story_fade_out_completed_agents
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { AgentConfigInfo, AgentInfo } from "../api/agents";
|
||||
import { agentsApi } from "../api/agents";
|
||||
|
||||
@@ -156,3 +156,207 @@ describe("AgentPanel diff command", () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("AgentPanel fade-out", () => {
|
||||
beforeAll(() => {
|
||||
Element.prototype.scrollIntoView = vi.fn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockedAgents.getAgentConfig.mockResolvedValue(ROSTER);
|
||||
mockedAgents.listAgents.mockResolvedValue([]);
|
||||
});
|
||||
|
||||
it("applies fade animation to a completed agent", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_fade_test",
|
||||
agent_name: "coder-1",
|
||||
status: "completed",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
const entry = await waitFor(() => {
|
||||
const el = container.querySelector(
|
||||
'[data-testid="agent-entry-73_fade_test:coder-1"]',
|
||||
);
|
||||
expect(el).toBeInTheDocument();
|
||||
return el as HTMLElement;
|
||||
});
|
||||
|
||||
expect(entry.style.animationName).toBe("agentFadeOut");
|
||||
});
|
||||
|
||||
it("applies fade animation to a failed agent", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_fade_fail",
|
||||
agent_name: "coder-1",
|
||||
status: "failed",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
const entry = await waitFor(() => {
|
||||
const el = container.querySelector(
|
||||
'[data-testid="agent-entry-73_fade_fail:coder-1"]',
|
||||
);
|
||||
expect(el).toBeInTheDocument();
|
||||
return el as HTMLElement;
|
||||
});
|
||||
|
||||
expect(entry.style.animationName).toBe("agentFadeOut");
|
||||
});
|
||||
|
||||
it("does not apply fade animation to a running agent", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_running",
|
||||
agent_name: "coder-1",
|
||||
status: "running",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
const entry = await waitFor(() => {
|
||||
const el = container.querySelector(
|
||||
'[data-testid="agent-entry-73_running:coder-1"]',
|
||||
);
|
||||
expect(el).toBeInTheDocument();
|
||||
return el as HTMLElement;
|
||||
});
|
||||
|
||||
expect(entry.style.animationName).not.toBe("agentFadeOut");
|
||||
});
|
||||
|
||||
it("pauses the fade when the entry is expanded", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_pause_test",
|
||||
agent_name: "coder-1",
|
||||
status: "completed",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
const entry = await waitFor(() => {
|
||||
const el = container.querySelector(
|
||||
'[data-testid="agent-entry-73_pause_test:coder-1"]',
|
||||
);
|
||||
expect(el).toBeInTheDocument();
|
||||
return el as HTMLElement;
|
||||
});
|
||||
|
||||
// Initially running (not paused)
|
||||
expect(entry.style.animationPlayState).toBe("running");
|
||||
|
||||
// Expand the agent
|
||||
const expandButton = screen.getByRole("button", { name: "▶" });
|
||||
await userEvent.click(expandButton);
|
||||
|
||||
// Animation should be paused
|
||||
expect(entry.style.animationPlayState).toBe("paused");
|
||||
});
|
||||
|
||||
it("resumes the fade when the entry is collapsed", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_resume_test",
|
||||
agent_name: "coder-1",
|
||||
status: "completed",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
const entry = await waitFor(() => {
|
||||
const el = container.querySelector(
|
||||
'[data-testid="agent-entry-73_resume_test:coder-1"]',
|
||||
);
|
||||
expect(el).toBeInTheDocument();
|
||||
return el as HTMLElement;
|
||||
});
|
||||
|
||||
const expandButton = screen.getByRole("button", { name: "▶" });
|
||||
|
||||
// Expand
|
||||
await userEvent.click(expandButton);
|
||||
expect(entry.style.animationPlayState).toBe("paused");
|
||||
|
||||
// Collapse
|
||||
await userEvent.click(expandButton);
|
||||
expect(entry.style.animationPlayState).toBe("running");
|
||||
});
|
||||
|
||||
describe("removes the agent entry after 60s", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("removes the agent entry after the 60-second fade completes", async () => {
|
||||
const agentList: AgentInfo[] = [
|
||||
{
|
||||
story_id: "73_remove_test",
|
||||
agent_name: "coder-1",
|
||||
status: "completed",
|
||||
session_id: null,
|
||||
worktree_path: null,
|
||||
base_branch: null,
|
||||
},
|
||||
];
|
||||
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||
|
||||
const { container } = render(<AgentPanel />);
|
||||
|
||||
// Wait for the agent entry to appear
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
container.querySelector(
|
||||
'[data-testid="agent-entry-73_remove_test:coder-1"]',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Advance timers by 60 seconds
|
||||
vi.advanceTimersByTime(60_000);
|
||||
|
||||
// Entry should be removed
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
container.querySelector(
|
||||
'[data-testid="agent-entry-73_remove_test:coder-1"]',
|
||||
),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user