test(e2e): add Edit tool inline diff rendering tests

Add comprehensive e2e test coverage for the inline DiffView component
in ActivityStream. Tests verify:
- Inline diff rendering for Edit tool events
- Collapsed state by default in compact mode
- Expand on toggle click
- Diff summary with added/removed counts
- Non-rendering for non-Edit tools
- Graceful handling of missing diff data
- Multi-line diff rendering

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bead-Id: bd-kzr.1
This commit is contained in:
jedarden 2026-04-28 14:11:01 -04:00
parent 579062bc97
commit d68e300920

View file

@ -540,4 +540,184 @@ describe('E2E: ActivityStream Display and Scrolling', () => {
expect(screen.getAllByText(/bd-bbb/).length).toBeGreaterThan(0);
});
});
describe('Edit tool inline diff rendering', () => {
it('should render inline diff for Edit tool events', () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Editing file',
tool_args: {
file_path: '/src/example.ts',
old_string: 'const x = 1;',
new_string: 'const x = 2;',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
// DiffView should be rendered within the event item
const diffView = container.querySelector('.event-item .diff-view');
expect(diffView).toBeInTheDocument();
// File path should be shown
expect(diffView?.textContent).toContain('/src/example.ts');
});
it('should show collapsed diff by default in compact mode', () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Editing file',
tool_args: {
file_path: '/src/test.ts',
old_string: 'old line 1\nold line 2',
new_string: 'new line 1\nnew line 2',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
const diffView = container.querySelector('.diff-view');
expect(diffView).toHaveClass('compact');
// Diff content should not be visible when collapsed
const diffContent = container.querySelector('.diff-content');
expect(diffContent).not.toBeInTheDocument();
});
it('should expand diff on toggle click', async () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Editing file',
tool_args: {
file_path: '/src/test.ts',
old_string: 'old line',
new_string: 'new line',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
// Initially collapsed
expect(container.querySelector('.diff-content')).not.toBeInTheDocument();
// Click the toggle button
const toggleButton = container.querySelector('.diff-toggle');
expect(toggleButton).toBeInTheDocument();
await userEvent.click(toggleButton!);
// Diff content should now be visible
const diffContent = container.querySelector('.diff-content');
expect(diffContent).toBeInTheDocument();
// Should show diff lines
const diffLines = container.querySelectorAll('.diff-line');
expect(diffLines.length).toBeGreaterThan(0);
});
it('should display diff summary with added/removed counts', () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Editing file',
tool_args: {
file_path: '/src/test.ts',
old_string: 'line 1\nline 2\nline 3',
new_string: 'line 1\nline 2 modified\nline 3',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
const diffSummary = container.querySelector('.diff-summary');
expect(diffSummary).toBeInTheDocument();
expect(diffSummary?.textContent).toMatch(/\d+ removed/);
expect(diffSummary?.textContent).toMatch(/\d+ added/);
});
it('should not render diff for non-Edit tools', () => {
const events = [
createMockEvent({
tool: 'Read',
message: 'Reading file',
tool_args: {
file_path: '/src/test.ts',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
const diffView = container.querySelector('.event-item .diff-view');
expect(diffView).not.toBeInTheDocument();
});
it('should handle Edit events with missing diff data gracefully', () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Editing file',
tool_args: {
file_path: '/src/test.ts',
// old_string and new_string missing
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
// Should not render diff view when data is incomplete
const diffView = container.querySelector('.event-item .diff-view');
expect(diffView).not.toBeInTheDocument();
});
it('should render multi-line diffs correctly', async () => {
const events = [
createMockEvent({
tool: 'Edit',
message: 'Multi-line edit',
tool_args: {
file_path: '/src/component.tsx',
old_string: 'const a = 1;\nconst b = 2;\nconst c = 3;',
new_string: 'const a = 1;\nconst b = 20;\nconst c = 3;',
},
}),
];
const { container } = render(
<ActivityStream events={events} selectedWorker={null} />
);
// Expand the diff
const toggleButton = container.querySelector('.diff-toggle');
if (toggleButton) {
await userEvent.click(toggleButton);
}
// Check for diff line types
const removedLines = container.querySelectorAll('.diff-line-removed');
const addedLines = container.querySelectorAll('.diff-line-added');
expect(removedLines.length).toBeGreaterThan(0);
expect(addedLines.length).toBeGreaterThan(0);
});
});
});