Files
PlantAI-rag-new/tests/e2e/docgen-regression.spec.js
jerryandClaude Fable 5 5888e1d5c1 test(docgen): 测试治理资产——131 条验收用例 + 三轮留痕 + E2E/回归套件
- 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>
2026-09-03 21:13:47 +08:00

77 lines
4.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}
});