Merge teacher composer height alignment

This commit is contained in:
鲨鱼辣椒 committed 2026-09-30 00:27:06 +08:00
commit 00cd3c114d
7 files changed
+158 -13

No files matched your search

+42 -3
View File
@@ -256,17 +256,55 @@ for (const width of [319, 508]) for (const kind of ['ordinary', 'ideas', 'struct
});
}
for (const width of [319, 508]) test(`teacher composer shows only microphone and send controls at ${width}px`, async ({ page }) => {
for (const width of [319, 508]) test(`teacher composer matches the operation composer and shows only microphone and send controls at ${width}px`, async ({ page }) => {
await page.setViewportSize({ width: 1180, height: 800 });
const savedModel = width === 508 ? 'test-second-model' : undefined;
await page.addInitScript((model) => {
localStorage.clear();
if (model) localStorage.setItem('makelore-teacher-model:fixture:coding-teacher:published', model);
}, savedModel);
await page.goto(`${url}?kind=rich-text&width=${width}`);
await page.route('https://example.com/teacher-preview.png', route => route.fulfill({
contentType: 'image/svg+xml',
body: '<svg xmlns="http://www.w3.org/2000/svg" width="900" height="250"><rect width="900" height="250" fill="#ebeedf"/></svg>',
}));
await page.goto(`${url}?kind=rich-text&width=${width}&compareComposers=1`);
const panel = page.getByTestId('teacher-chat-panel');
const input = page.getByRole('textbox', { name: '向智能体提问' });
const operationComposer = page.getByTestId('coding-message-composer');
const operationInput = operationComposer.getByRole('textbox');
const teacherSurface = panel.locator('.consultation-composer');
const operationSurface = operationComposer.locator('.chat-composer-surface');
const heights: number[] = [];
await expect(input).toBeEnabled();
for (const lines of [0, 1, 3, 6, 8]) {
const draft = Array.from({ length: lines }, (_, index) => `第 ${index + 1} 行想法`).join('\n');
await operationInput.fill(draft);
await input.fill(draft);
const [teacherInputBounds, operationInputBounds, teacherBounds, operationBounds] = await Promise.all([
input.boundingBox(), operationInput.boundingBox(), teacherSurface.boundingBox(), operationSurface.boundingBox(),
]);
expect(Math.abs(teacherInputBounds!.height - operationInputBounds!.height), `${lines} 行输入区域等高`).toBeLessThanOrEqual(1);
expect(Math.abs(teacherBounds!.height - operationBounds!.height), `${lines} 行输入框外框等高`).toBeLessThanOrEqual(1);
expect(Math.abs(teacherBounds!.y + teacherBounds!.height - operationBounds!.y - operationBounds!.height), `${lines} 行外框底边对齐`).toBeLessThanOrEqual(1);
expect(Math.abs(teacherInputBounds!.y + teacherInputBounds!.height - operationInputBounds!.y - operationInputBounds!.height), `${lines} 行文字区域底边对齐`).toBeLessThanOrEqual(1);
heights.push(teacherInputBounds!.height);
for (const element of [panel, operationComposer, teacherSurface, operationSurface, input, operationInput]) {
expect(await element.evaluate(el => el.scrollWidth <= el.clientWidth), `${lines} 行没有横向溢出`).toBe(true);
}
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true);
await page.screenshot({ path: test.info().outputPath(`teacher-operation-composers-${width}-${lines}-lines.png`) });
}
expect(heights[0]).toBe(heights[1]);
expect(heights[2]).toBeGreaterThan(heights[1]);
expect(heights[3]).toBeGreaterThan(heights[2]);
expect(heights[4]).toBe(heights[3]);
expect(await input.evaluate(el => el.scrollHeight > el.clientHeight)).toBe(true);
expect(await page.evaluate(() => (window as unknown as { __teacherReplyInputs: unknown[] }).__teacherReplyInputs)).toEqual([]);
await input.fill('保留麦克风和发送按钮');
await expect(panel.getByRole('button', { name: /老师模型/ })).toHaveCount(0);
await expect(panel.getByRole('button', { name: /添加图片|添加文件|添加附件/ })).toHaveCount(0);
await expect(panel.locator('input[type="file"]')).toHaveCount(0);
await expect(panel.getByRole('combobox')).toHaveCount(0);
await expect(panel.getByRole('button', { name: '语音输入' })).toBeVisible();
await expect(panel.getByRole('button', { name: '提问', exact: true })).toBeEnabled();
expect(await panel.evaluate(el => el.scrollWidth <= el.clientWidth)).toBe(true);
@@ -274,7 +312,8 @@ for (const width of [319, 508]) test(`teacher composer shows only microphone and
await expect(controls.getByRole('button')).toHaveCount(2);
await expect(controls).not.toContainText(/老师配置|模型默认|fixture|test-second-model/);
expect(await controls.evaluate(el => el.scrollWidth <= el.clientWidth)).toBe(true);
await panel.screenshot({ path: test.info().outputPath(`teacher-composer-${width}.png`) });
await operationInput.fill('保留麦克风和发送按钮');
await page.screenshot({ path: test.info().outputPath(`teacher-composer-${width}.png`) });
await panel.getByRole('button', { name: '提问', exact: true }).click();
expect(await page.evaluate(() => (window as unknown as { __teacherReplyInputs: Array<{text: string; modelId?: string}> }).__teacherReplyInputs.at(-1))).toMatchObject({ text: '保留麦克风和发送按钮' });
expect(await page.evaluate(() => (window as unknown as { __teacherReplyInputs: Array<{modelId?: string}> }).__teacherReplyInputs.at(-1)?.modelId)).toBe(savedModel);