open-design/e2e/tests/assistant-message.test.tsx
Zakaria a46764fb1b
Some checks failed
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
first-commit
2026-05-04 14:58:14 -04:00

113 lines
3.5 KiB
TypeScript

import { cleanup, fireEvent, render, screen, within } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { AssistantMessage } from '../../apps/web/src/components/AssistantMessage';
import type { AgentEvent, ChatMessage } from '../../apps/web/src/types';
function messageWithEvents(events: AgentEvent[]): ChatMessage {
return {
id: 'assistant-1',
role: 'assistant',
content: '',
events,
startedAt: 1_000,
endedAt: 3_000,
};
}
describe('AssistantMessage unfinished todo state', () => {
afterEach(() => cleanup());
it('keeps Done for a completed latest TodoWrite fixture', () => {
render(
<AssistantMessage
message={messageWithEvents([
{
kind: 'tool_use',
id: 'todo-1',
name: 'TodoWrite',
input: { todos: [{ content: 'Ship layout', status: 'completed' }] },
},
])}
streaming={false}
projectId="project-1"
isLast
/>,
);
expect(screen.getByText('Done')).toBeTruthy();
expect(screen.queryByText('Stopped with unfinished work')).toBeNull();
expect(screen.queryByRole('button', { name: 'Continue remaining tasks' })).toBeNull();
});
it('shows unfinished state and passes unfinished todos to the continue callback', () => {
const onContinue = vi.fn();
render(
<AssistantMessage
message={messageWithEvents([
{
kind: 'tool_use',
id: 'todo-1',
name: 'TodoWrite',
input: {
todos: [
{ content: 'Draft layout', status: 'completed' },
{
content: 'Build components',
status: 'in_progress',
activeForm: 'Building components',
},
{ content: 'Run QA', status: 'pending' },
],
},
},
])}
streaming={false}
projectId="project-1"
isLast
onContinueRemainingTasks={onContinue}
/>,
);
expect(screen.getByText('Stopped with unfinished work')).toBeTruthy();
expect(screen.getByText('2 task(s) remain')).toBeTruthy();
const remainingList = screen.getByText('2 task(s) remain').closest('.unfinished-todos');
expect(remainingList).not.toBeNull();
expect(within(remainingList as HTMLElement).getByText('Building components')).toBeTruthy();
expect(within(remainingList as HTMLElement).getByText('Run QA')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: 'Continue remaining tasks' }));
expect(onContinue).toHaveBeenCalledWith([
{
content: 'Build components',
status: 'in_progress',
activeForm: 'Building components',
},
{ content: 'Run QA', status: 'pending', activeForm: undefined },
]);
});
it('hides the continue button on older assistant turns', () => {
render(
<AssistantMessage
message={messageWithEvents([
{
kind: 'tool_use',
id: 'todo-1',
name: 'TodoWrite',
input: { todos: [{ content: 'Run QA', status: 'pending' }] },
},
])}
streaming={false}
projectId="project-1"
isLast={false}
onContinueRemainingTasks={vi.fn()}
/>,
);
expect(screen.getByText('Stopped with unfinished work')).toBeTruthy();
expect(screen.getByText('1 task(s) remain')).toBeTruthy();
expect(screen.queryByRole('button', { name: 'Continue remaining tasks' })).toBeNull();
});
});