Place teacher prompt buttons above the composer

This commit is contained in:
鲨鱼辣椒
2026-09-29 20:06:31 +08:00
parent bb96941461
commit efd1894269
6 changed files with 96 additions and 24 deletions

View File

@@ -56,6 +56,15 @@ for (const width of [319, 508]) {
await expect(shortcuts.first()).toHaveText('看看进展');
await expect(shortcuts.nth(1)).toHaveText('解释代码');
await expect(shortcuts.nth(1)).toBeEnabled();
const row = panel.getByRole('group', { name: '快捷提问' });
const composer = panel.locator('.consultation-composer');
await expect(composer.locator('.consultation-hint')).toHaveCount(0);
await expect(shortcuts.first()).toHaveCSS('font-size', await panel.getByTestId('teacher-reply').first().evaluate(el => getComputedStyle(el).fontSize));
await expect(shortcuts.first()).toHaveCSS('font-weight', '400');
await expect(shortcuts.first()).toHaveCSS('box-shadow', 'none');
expect((await row.boundingBox())!.y + (await row.boundingBox())!.height).toBeLessThan((await composer.boundingBox())!.y);
await shortcuts.first().focus();
await expect(shortcuts.first()).toHaveCSS('outline-style', 'solid');
const form = (await panel.locator('form').boundingBox())!;
expect(form.y + form.height).toBeLessThanOrEqual(800);
expect(await panel.evaluate(el => el.scrollWidth <= el.clientWidth)).toBe(true);
@@ -120,12 +129,12 @@ for (const width of [319, 508]) {
await expect(hint).toBeEnabled();
await expect(hint).toHaveText('帮我整体看🧠');
expect(await hint.evaluate(el => el.scrollWidth <= el.clientWidth && el.scrollHeight <= el.clientHeight)).toBe(true);
await expect(hint).toHaveCSS('background-color', 'rgb(255, 242, 201)');
await expect(hint).toHaveCSS('background-color', 'rgb(250, 245, 232)');
const initialSend = (await send.boundingBox())!;
const hintBounds = (await hint.boundingBox())!;
expect(hintBounds.x).toBeLessThan(initialSend.x);
expect(hintBounds.height).toBeGreaterThanOrEqual(44);
expect(hintBounds.x + hintBounds.width).toBeLessThanOrEqual(initialSend.x);
expect(hintBounds.height).toBeGreaterThanOrEqual(36);
expect(hintBounds.y + hintBounds.height).toBeLessThan((await page.locator('.consultation-composer').boundingBox())!.y);
await page.getByTestId('teacher-chat-panel').screenshot({ path: test.info().outputPath(`composer-hint-${width}.png`) });
expect(await sent()).toEqual([]);
await input.fill('我想先自己说说');

View File

@@ -108,22 +108,22 @@ describe('teacher side chat', () => {
api.sendConversation.mockRejectedValue(new Error('结果暂未确认'));
render(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={agent} />);
await waitFor(() => expect(screen.getByRole('button', { name: '看看进展' })).toBeEnabled());
expect([...screen.getByTestId('consultation-composer-actions').querySelectorAll('.consultation-hint')].map(el => el.textContent)).toEqual(shortcuts.map(item => item.label));
expect(screen.queryByRole('button', { name: '继续看看👀' })).not.toBeInTheDocument();
expect([...screen.getByTestId('consultation-shortcuts').querySelectorAll('.consultation-hint')].map(el => el.textContent)).toEqual(shortcuts.map(item => item.label));
expect(screen.queryByRole('button', { name: '帮我整体看🧠' })).not.toBeInTheDocument();
expect(screen.queryByText(shortcuts[0].prompt)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '看看进展' }));
await screen.findByText('结果暂未确认');
const original = api.sendConversation.mock.calls[0][2];
const original = api.sendConversation.mock.calls[0][1];
expect(original).toMatchObject({ text: shortcuts[0].prompt, projectId: 'p', sourceConversationId: 'c', references: [] });
expect(original.intent).toBeUndefined();
fireEvent.click(screen.getByRole('button', { name: '看看进展' }));
await waitFor(() => expect(api.sendConversation).toHaveBeenCalledTimes(2));
await waitFor(() => expect(screen.getByRole('button', { name: '解释代码' })).toBeEnabled());
expect(api.sendConversation.mock.calls[1][2]).toEqual(original);
expect(api.sendConversation.mock.calls[1][1]).toEqual(original);
fireEvent.click(screen.getByRole('button', { name: '解释代码' }));
await waitFor(() => expect(api.sendConversation).toHaveBeenCalledTimes(3));
expect(api.sendConversation.mock.calls[2][2].text).toBe(shortcuts[1].prompt);
expect(api.sendConversation.mock.calls[2][2].requestId).not.toBe(original.requestId);
expect(api.sendConversation.mock.calls[2][1].text).toBe(shortcuts[1].prompt);
expect(api.sendConversation.mock.calls[2][1].requestId).not.toBe(original.requestId);
});
it('updates published shortcuts without replacing chat history or a composed draft, and supports clearing the list', async () => {
@@ -146,7 +146,7 @@ describe('teacher side chat', () => {
expect(screen.queryByRole('button', { name: '旧入口' })).not.toBeInTheDocument();
const cleared = { ...updated, version: 3, definition: { ...updated.definition, shortcuts: [] } };
view.rerender(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={cleared} catalogState={state(cleared)} />);
expect(screen.getByTestId('consultation-composer-actions').querySelectorAll('.consultation-hint')).toHaveLength(0);
expect(screen.queryByTestId('consultation-shortcuts')).not.toBeInTheDocument();
expect(screen.getByText('之前的回答')).toBeVisible();
expect(api.sendConversation).not.toHaveBeenCalled();
});
@@ -550,7 +550,8 @@ describe('teacher side chat', () => {
const input = screen.getByLabelText('向智能体提问');
const help = () => screen.getByText((_text, element) => element?.textContent === '帮我整体看🧠', { selector: 'form .consultation-hint' });
await waitFor(() => expect(help()).toBeEnabled());
expect(screen.getByTestId('consultation-composer-actions')).toContainElement(help());
expect(screen.getByTestId('consultation-shortcuts')).toContainElement(help());
expect(screen.getByTestId('consultation-composer-actions')).not.toContainElement(help());
expect(help()).toHaveAccessibleName('帮我整体看🧠');
expect(api.send).not.toHaveBeenCalled();
fireEvent.change(input, { target: { value: '我先自己想想' } });