import test from 'node:test'; import assert from 'node:assert/strict'; import { existsSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; test('sidebar labels AI assistant before smart warning', () => { const sidebar = readFileSync(join(process.cwd(), 'components/layout/Sidebar.tsx'), 'utf8'); const askIndex = sidebar.indexOf("label: 'AI 助手'"); const warningIndex = sidebar.indexOf("label: '智能预警'"); assert.notEqual(askIndex, -1); assert.notEqual(warningIndex, -1); assert.ok(askIndex < warningIndex); assert.doesNotMatch(sidebar, /label: '问翻小宝'/); assert.doesNotMatch(sidebar, /label: '小宝预警'/); assert.match(sidebar, /path: '\/wenfan-xiaobao'/); }); test('wenfan xiaobao page provides records, chat, and voice input surfaces', () => { const pagePath = join(process.cwd(), 'app/wenfan-xiaobao/page.tsx'); assert.equal(existsSync(pagePath), true); const page = readFileSync(pagePath, 'utf8'); assert.match(page, /

AI 助手<\/h1>/); assert.doesNotMatch(page, /

问翻小宝<\/h1>/); assert.match(page, /历史记录/); assert.match(page, /对话/); assert.match(page, /textarea/); assert.match(page, /Mic/); assert.match(page, /searchHelpArticles/); assert.match(page, /HelpAnswer/); assert.match(page, /shouldShowGenericHelpSuggestions/); assert.match(page, /showGenericSuggestions/); assert.match(page, /showStarterQuestions/); assert.match(page, /showGenericSuggestions && message\.suggestions\.length > 0/); assert.match(page, /createWenfanConversationRecord/); assert.match(page, /updateWenfanConversationRecord/); assert.match(page, /deleteWenfanConversationRecord/); assert.match(page, /删除历史记录/); assert.doesNotMatch(page, /setHistory\(\(current\) => \[question/); assert.doesNotMatch(page, /

问翻小宝<\/p>/); assert.match(page, /入口路径/); assert.match(page, /必填字段/); assert.match(page, /状态流转/); assert.match(page, /注意事项/); assert.match(page, /previewImage/); assert.match(page, /aria-modal="true"/); assert.match(page, /点击放大/); assert.match(page, /lg:grid-cols-\[300px_minmax\(0,1fr\)\]/); assert.match(page, /rounded-\[28px\]/); assert.doesNotMatch(page, /: 'border-\[var\(--line\)\] bg-\[var\(--bg\)\]/); assert.match(page, /: 'bg-white hover:bg-\[var\(--bg-subtle\)\]'/); }); test('wenfan xiaobao page does not ship seeded conversation history', () => { const page = readFileSync(join(process.cwd(), 'app/wenfan-xiaobao/page.tsx'), 'utf8'); assert.match(page, /useState\(\[\]\)/); assert.doesNotMatch(page, /INITIAL_CONVERSATIONS/); assert.doesNotMatch(page, /history-product-create/); assert.doesNotMatch(page, /history-version-requirements/); assert.doesNotMatch(page, /history-dev-task-submit/); assert.doesNotMatch(page, /history-test-bug/); assert.doesNotMatch(page, /history-activity-log/); }); test('wenfan help screenshot script targets version detail tabs and failed test case bug entry', () => { const script = readFileSync(join(process.cwd(), 'scripts/capture-wenfan-help-screenshots.mjs'), 'utf8'); assert.match(script, /resolveScreenshotContext/); assert.match(script, /loadDataKey\('test-cases'\)/); assert.match(script, /loadDataKey\('version-plans'\)/); assert.match(script, /findFailedTestCase/); assert.match(script, /findAiReadyProductPlan/); assert.match(script, /openProductPlanAiEntry/); assert.match(script, /tabLabel: '关联需求'/); assert.match(script, /tabLabel: '产品方案'/); assert.match(script, /tabLabel: '开发任务'/); assert.match(script, /tabLabel: '测试用例'/); assert.match(script, /openFailedTestCaseBugEntry/); assert.match(script, /提 BUG/); assert.doesNotMatch(script, /\{ file: 'bug-workflow\.png', route: '\/versions' \}/); });