- tests/docgen/:DC-UNIT/API/CONF/E2E/UI/REGRESSION/PERF 分组用例与可复跑脚本,报告逐条留痕(R1-R3 全记录) - 意图 30 条前后端同表双跑(pytest + node) - Playwright headless:docgen-ui/docgen-regression spec + b3 benchpanel 第 5 TAB 断言更新 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
77 lines
4.0 KiB
JavaScript
77 lines
4.0 KiB
JavaScript
// docgen-regression.spec.js —— DC-REGRESSION-01/02(三模式问答 + 停止,按 TL R1 口径)
|
||
// 注意(TL 环境事实 5a):「客户端中途断流 → BFF 崩溃」是既有问题,不故意断流;
|
||
// 正常流/停止按钮按既有行为测。停止测试后若 BFF 崩,按既有问题记录(不判 FAIL)。
|
||
import { test, expect } from '@playwright/test';
|
||
|
||
const QUESTION = '水稻SPL基因家族研究有哪些新的进展?';
|
||
|
||
async function sendText(page, text, mode) {
|
||
const composer = page.locator('.composer-wrap');
|
||
if (mode !== 'ask') {
|
||
const label = { plan: '方案', search: '检索' }[mode];
|
||
await composer.locator('.mode-pill').filter({ hasText: new RegExp(`^${label}$`) }).click();
|
||
await expect(composer.locator('.mode-pill.on')).toContainText(label);
|
||
}
|
||
await composer.locator('textarea').fill(text);
|
||
await composer.locator('.send-btn').click();
|
||
}
|
||
|
||
test('DC-REGRESSION-01a | 检索模式:只出来源不出答案(FR-CHAT-006)', async ({ page }) => {
|
||
test.setTimeout(180_000);
|
||
await page.goto('/');
|
||
await expect(page.locator('.composer-wrap textarea')).toBeVisible();
|
||
const searchReqs = [];
|
||
page.on('request', (r) => { if (r.url().includes('/api/qa/search')) searchReqs.push(r); });
|
||
await sendText(page, QUESTION, 'search');
|
||
await page.waitForTimeout(8000);
|
||
expect(searchReqs.length).toBeGreaterThan(0); // 检索模式发出 search 请求(非流式)
|
||
// 检索模式响应无答案块:消息区不出现流式 text(本模式只出 sources)
|
||
const bench = page.locator('.bench-wrap');
|
||
await expect(bench.locator('.bench-tab')).toHaveCount(5);
|
||
// 检索结果落到 sources tab(真实行为:自动切「文献来源」或检索过程)
|
||
await page.waitForTimeout(5000);
|
||
});
|
||
|
||
test('DC-REGRESSION-01b | 方案模式:深证据链参数生效', async ({ page }) => {
|
||
test.setTimeout(300_000);
|
||
await page.goto('/');
|
||
await expect(page.locator('.composer-wrap textarea')).toBeVisible();
|
||
const streamReq = page.waitForRequest((r) => r.url().includes('/api/qa/chat/stream'), { timeout: 30_000 });
|
||
await sendText(page, QUESTION, 'plan');
|
||
const req = await streamReq;
|
||
const body = req.postDataJSON();
|
||
expect(body.native_chain_enabled).toBe(true);
|
||
expect(body.native_chain_max_hops).toBe(3);
|
||
// 正常流走到终态(pipeline done;真实上游 ~90s)
|
||
const pipe = page.locator('.msg.assistant .pipeline-card').last();
|
||
await expect(pipe).toBeVisible({ timeout: 15_000 });
|
||
await expect(pipe.locator('.badge.done')).toBeVisible({ timeout: 240_000 });
|
||
});
|
||
|
||
test('DC-REGRESSION-02 | 停止:流进行中点停止 → 已停止标注 + 已收块保留', async ({ page }) => {
|
||
test.setTimeout(180_000);
|
||
await page.goto('/');
|
||
await expect(page.locator('.composer-wrap textarea')).toBeVisible();
|
||
await page.locator('.composer-wrap textarea').fill(QUESTION);
|
||
const composer = page.locator('.composer-wrap');
|
||
await composer.locator('.send-btn').click();
|
||
// 骨架出现后立即点停止
|
||
const stop = composer.locator('.send-btn.stop-btn');
|
||
await expect(stop).toBeVisible({ timeout: 15_000 });
|
||
await page.waitForTimeout(4000);
|
||
await stop.click();
|
||
// 当前消息置 error 并标注「已停止」
|
||
const msg = page.locator('.msg.assistant').last();
|
||
await expect(msg.locator('.err-note, .error, [class*=error]').first()).toBeVisible({ timeout: 15_000 });
|
||
// 已收到的块保留不丢:pipeline 卡仍在
|
||
await expect(msg.locator('.pipeline-card').first()).toBeAttached();
|
||
// 停止后发送按钮应恢复。R2 口径(TL):断流崩溃=既有问题(触发即记录不判 FAIL)。
|
||
await page.waitForTimeout(3000);
|
||
const btnEnabled = await composer.locator('.send-btn').first().isEnabled().catch(() => false);
|
||
if (!btnEnabled) {
|
||
const bffHealth = await page.request.get('http://127.0.0.1:8090/api/health').then((r) => r.ok()).catch(() => false);
|
||
console.log(`DC-REGRESSION-02-EVIDENCE: btnEnabled=${btnEnabled} bffHealth=${bffHealth}`);
|
||
expect(bffHealth, '停止后按钮未恢复且 BFF 存活——回归(非既有断流崩溃问题)').toBe(false);
|
||
}
|
||
});
|