fix: show empty work preview without invoking the Agent

This commit is contained in:
鲨鱼辣椒 committed 2026-09-29 16:31:19 +08:00
1 parent 077184aaba
commit 0167d361ed
11 files changed
+391 -15

No files matched your search

+73
View File
@@ -115,6 +115,79 @@ describe('AgentBrowserPanel', () => {
vi.restoreAllMocks();
});
it('shows an empty work hint without starting or recovering a conversation', async () => {
const original = hostApiFetchMock.getMockImplementation()!;
hostApiFetchMock.mockImplementation(async (path: string, init?: RequestInit) => {
if (path === '/api/agent-browser/ensure-work') return { status: 'empty' };
return original(path, init);
});
const onOpenChange = vi.fn();
const onWorkConversation = vi.fn();
const onRecovery = vi.fn();
render(<AgentBrowserPanel projectId="project-a" conversationId="c1" embedded open
onOpenChange={onOpenChange} onWorkConversation={onWorkConversation} onRecovery={onRecovery} />);
expect(await screen.findByRole('status')).toHaveTextContent('还没有作品,快和老师聊聊吧');
expect(screen.queryByText('正在打开你的作品…')).not.toBeInTheDocument();
expect(screen.queryByText('准备好后,页面会自动出现在这里。')).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /再试一次|帮我检查并打开|重新打开作品|登录并继续/ })).not.toBeInTheDocument();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
await waitFor(() => expect(latestPresentation()).toMatchObject({ visible: false }));
expect(onWorkConversation).not.toHaveBeenCalled();
expect(onRecovery).not.toHaveBeenCalled();
expect(onOpenChange).not.toHaveBeenCalled();
fireEvent.click(screen.getByRole('button', { name: '回到操作对话' }));
expect(onOpenChange).toHaveBeenCalledWith(false);
expect(hostApiFetchMock.mock.calls.filter(([path]) => path === '/api/agent-browser/ensure-work')).toHaveLength(1);
});
it('replaces an earlier presentation failure with the empty hint and can later show a work', async () => {
const original = hostApiFetchMock.getMockImplementation()!;
let result: 'ready' | 'empty' = 'ready';
let unavailable = true;
hostApiFetchMock.mockImplementation(async (path: string, init?: RequestInit) => {
if (path === '/api/agent-browser/ensure-work' && result === 'empty') return { status: 'empty' };
if (path === '/api/agent-browser/present' && body(init).visible && unavailable) throw new Error('开发浏览器已关闭。');
return original(path, init);
});
render(<AgentBrowserPanel projectId="project-a" embedded open onOpenChange={vi.fn()} />);
await screen.findByRole('button', { name: '重新打开作品' });
result = 'empty';
act(() => window.dispatchEvent(new Event('focus')));
await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('还没有作品,快和老师聊聊吧'));
expect(screen.queryByRole('button', { name: '重新打开作品' })).not.toBeInTheDocument();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
result = 'ready';
unavailable = false;
act(() => window.dispatchEvent(new Event('focus')));
await waitFor(() => expect(latestPresentation()).toMatchObject({ visible: true }));
expect(screen.queryByText('还没有作品,快和老师聊聊吧')).not.toBeInTheDocument();
});
it('checks and displays a host-opened work while the empty work tab stays open', async () => {
const original = hostApiFetchMock.getMockImplementation()!;
let opened = false;
hostApiFetchMock.mockImplementation(async (path: string, init?: RequestInit) => {
if (path === '/api/agent-browser/ensure-work' && !opened) return { status: 'empty' };
if (path.startsWith('/api/agent-browser/state?') && !opened) {
return { success: true, browser: snapshot({ browserId: null, state: 'closed', url: '' }) };
}
return original(path, init);
});
const onWorkConversation = vi.fn();
render(<AgentBrowserPanel projectId="project-a" embedded open onOpenChange={vi.fn()} onWorkConversation={onWorkConversation} />);
await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('还没有作品,快和老师聊聊吧'));
opened = true;
act(() => hostEventListeners.get('agent-browser:show')?.(snapshot()));
await waitFor(() => expect(latestPresentation()).toMatchObject({ visible: true }));
expect(screen.queryByText('还没有作品,快和老师聊聊吧')).not.toBeInTheDocument();
expect(onWorkConversation).not.toHaveBeenCalled();
const checks = hostApiFetchMock.mock.calls.filter(([path]) => path === '/api/agent-browser/ensure-work');
expect(checks).toHaveLength(2);
expect(body(checks[1][1]).request_id).toBe(body(checks[0][1]).request_id);
});
it('offers login recovery instead of repeatedly trying to start the page', async () => {
const original = hostApiFetchMock.getMockImplementation()!;
hostApiFetchMock.mockImplementation(async (path: string, init?: RequestInit) => path === '/api/agent-browser/ensure-work'