Add comprehensive test suite for progress tracking system

Test fixture updates:
- Add toolUseId fields (toolu_read1, toolu_edit1) to tool_use blocks
- Add parentToolUseID-linked progress events for read and edit tools
- Add orphaned SessionStart progress event (no parent)
- Update tool_result references to match new toolUseId values
- Add bash_progress and mcp_progress subtypes for subtype derivation

session-parser tests (7 new):
- toolUseId extraction from tool_use blocks with and without id field
- parentToolUseId and progressSubtype extraction from hook_progress
- Subtype derivation for bash_progress, mcp_progress, agent_progress
- Fallback to "hook" for unknown data types
- Undefined parentToolUseId when field is absent

progress-grouper tests (7 new):
- Partition parented progress into toolProgress map
- Remove parented progress from filtered messages array
- Keep orphaned progress (no parentToolUseId) in main stream
- Keep progress with invalid parentToolUseId (no matching tool_call)
- Empty input handling
- Sort each group by rawIndex
- Multiple tool_call parents tracked independently

agent-progress-parser tests (full suite):
- Parse user text events with prompt/agentId metadata extraction
- Parse tool_use blocks into AgentToolCall events
- Parse tool_result blocks with content extraction
- Parse text content as text_response with line counting
- Handle multiple content blocks in single turn
- Post-pass tool_result→tool_call linking (sourceTool, language)
- Empty input and malformed JSON → raw_content fallback
- stripLineNumbers for cat-n prefixed output
- summarizeToolCall for Read, Grep, Glob, Bash, Task, WarpGrep, etc.

ProgressBadge component tests:
- Collapsed state shows pill counts, hides content
- Expanded state shows all event content via markdown
- Subtype counting accuracy
- Agent-only events route to AgentProgressView

AgentProgressView component tests:
- Prompt banner rendering with truncation
- Agent ID and turn count display
- Summary rows with timestamps and tool names
- Click-to-expand drill-down content

html-exporter tests (8 new):
- Collapsible rendering for thinking, tool_call, tool_result
- Toggle button and JavaScript inclusion
- Non-collapsible messages lack collapse attributes
- Diff content detection and highlighting
- Progress badge rendering with toolProgress data

filters tests (2 new):
- hook_progress included/excluded by category toggle

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 23:05:01 -05:00
parent d4de363227
commit 3fe8d7d3b5
8 changed files with 1376 additions and 6 deletions

View File

@@ -216,4 +216,107 @@ describe("session-parser", () => {
expect(msgs[0].category).toBe("user_message");
expect(msgs[1].category).toBe("assistant_text");
});
it("extracts toolUseId from tool_use blocks with id field", () => {
const line = JSON.stringify({
type: "assistant",
message: {
role: "assistant",
content: [
{ type: "tool_use", id: "toolu_abc123", name: "Read", input: { file_path: "/src/index.ts" } },
],
},
uuid: "a-tu-1",
});
const msgs = parseSessionContent(line);
expect(msgs).toHaveLength(1);
expect(msgs[0].category).toBe("tool_call");
expect(msgs[0].toolUseId).toBe("toolu_abc123");
});
it("toolUseId is undefined when tool_use block has no id field", () => {
const line = JSON.stringify({
type: "assistant",
message: {
role: "assistant",
content: [
{ type: "tool_use", name: "Read", input: { file_path: "/src/index.ts" } },
],
},
uuid: "a-tu-2",
});
const msgs = parseSessionContent(line);
expect(msgs).toHaveLength(1);
expect(msgs[0].toolUseId).toBeUndefined();
});
it("extracts parentToolUseId and progressSubtype from hook_progress", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "hook_progress", hookEvent: "PreToolUse", hookName: "check" },
parentToolUseID: "toolu_abc123",
uuid: "p-linked",
timestamp: "2025-10-15T10:00:00Z",
});
const msgs = parseSessionContent(line);
expect(msgs).toHaveLength(1);
expect(msgs[0].category).toBe("hook_progress");
expect(msgs[0].parentToolUseId).toBe("toolu_abc123");
expect(msgs[0].progressSubtype).toBe("hook");
});
it("derives progressSubtype 'bash' from bash_progress data type", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "bash_progress", status: "running" },
parentToolUseID: "toolu_bash1",
uuid: "p-bash",
});
const msgs = parseSessionContent(line);
expect(msgs[0].progressSubtype).toBe("bash");
expect(msgs[0].parentToolUseId).toBe("toolu_bash1");
});
it("derives progressSubtype 'mcp' from mcp_progress data type", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "mcp_progress", serverName: "morph-mcp" },
parentToolUseID: "toolu_mcp1",
uuid: "p-mcp",
});
const msgs = parseSessionContent(line);
expect(msgs[0].progressSubtype).toBe("mcp");
});
it("derives progressSubtype 'agent' from agent_progress data type", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "agent_progress", status: "started" },
parentToolUseID: "toolu_agent1",
uuid: "p-agent",
});
const msgs = parseSessionContent(line);
expect(msgs[0].progressSubtype).toBe("agent");
});
it("parentToolUseId is undefined when progress has no parentToolUseID", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "hook_progress", hookEvent: "SessionStart" },
uuid: "p-orphan",
});
const msgs = parseSessionContent(line);
expect(msgs[0].parentToolUseId).toBeUndefined();
expect(msgs[0].progressSubtype).toBe("hook");
});
it("progressSubtype defaults to 'hook' for unknown data types", () => {
const line = JSON.stringify({
type: "progress",
data: { type: "unknown_thing", status: "ok" },
uuid: "p-unknown",
});
const msgs = parseSessionContent(line);
expect(msgs[0].progressSubtype).toBe("hook");
});
});