import { expect, test } from '@playwright/test' const account = process.env.E2E_ACCOUNT || 'e2e-1785008967@local.test' const password = process.env.E2E_PASSWORD || 'Lingxi-E2E-2026!' const conversationId = process.env.LIVE_CONVERSATION_ID test.describe('真实收件箱 AI 交互', () => { test.skip(!conversationId, '需要 LIVE_CONVERSATION_ID') test('AI 回复可以关闭、重新打开并采用到输入框', async ({ page }) => { await page.goto('/login') await page.locator('input[autocomplete="username"]').fill(account) await page.locator('input[autocomplete="current-password"]').fill(password) await page.locator('button[type="submit"]').click() await expect(page).toHaveURL(/\/dashboard$/) await page.goto(`/inbox?c=${encodeURIComponent(conversationId!)}`) await expect(page.getByText('Eternity', { exact: true }).first()).toBeVisible() await expect(page.getByText('@jsjzlkj', { exact: true }).first()).toBeVisible() const eternityAvatar = page.locator('img[alt="Eternity"]').first() await expect(eternityAvatar).toBeVisible() await expect.poll(() => eternityAvatar.evaluate((image: HTMLImageElement) => image.naturalWidth)).toBeGreaterThan(0) const insightBar = page.getByTestId('conversation-insight-bar') await expect(insightBar).toBeVisible() await expect(insightBar).toContainText('意向') await expect(insightBar).toContainText(/积极|偏积极|中性|消极|愤怒|不满/) const messageList = page.getByTestId('message-list') await expect(messageList).not.toContainText('2026-07-27T') await expect.poll(() => messageList.evaluate((element) => Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop), )).toBeLessThanOrEqual(4) const customerBubble = page.locator('[data-testid="message-bubble"][data-sender="customer"]') await expect(customerBubble.first()).toHaveClass(/animate-message-in-left/) const agentBubble = page.locator('[data-testid="message-bubble"][data-sender="agent"]') await expect(agentBubble.first()).toHaveClass(/animate-message-in-right/) await page.getByTitle('客户洞察').click() await expect(page.getByText('成交概率', { exact: true })).toBeVisible() await expect(page.getByText('分析可信度', { exact: true })).toBeVisible() await expect(page.getByText('判断依据', { exact: true })).toBeVisible() if ((page.viewportSize()?.width || 1280) < 768) { await page.getByRole('button', { name: '返回会话' }).click() } await expect(page.getByText('AI 智能回复', { exact: true })).toBeVisible() await page.getByTitle('关闭 AI 智能回复').click() await expect(page.getByRole('button', { name: 'AI 智能回复', exact: true })).toBeVisible() await expect(page.getByTitle('关闭 AI 智能回复')).toHaveCount(0) await page.getByRole('button', { name: 'AI 智能回复', exact: true }).click() await page.getByRole('button', { name: '生成回复建议', exact: true }).click() const adoptButtons = page.getByRole('button', { name: '采用', exact: true }) await expect(adoptButtons).toHaveCount(3, { timeout: 30_000 }) await adoptButtons.first().click() const composer = page.getByPlaceholder('输入回复内容,Enter 发送,Shift+Enter 换行') await expect(composer).not.toHaveValue('') const adoptedReply = await composer.inputValue() expect(adoptedReply).toMatch(/[A-Za-z]/) expect(adoptedReply).not.toMatch(/[\u3400-\u9fff]/u) await expect(page.getByRole('button', { name: 'AI 智能回复', exact: true })).toBeVisible() }) })