/** * 验证出题分布是否正确 */ import { chromium } from 'playwright'; const BASE = 'http://localhost:13001'; async function run() { const browser = await chromium.launch({ headless: true }); const page = await browser.newPage({ viewport: { width: 1440, height: 900 } }); // Login await page.goto(`${BASE}/login`, { waitUntil: 'networkidle' }); await page.waitForTimeout(1000); await page.locator('input[type="text"]').first().fill('admin'); await page.locator('input[type="password"]').first().fill('admin123'); await page.locator('button[type="submit"]').click(); await page.waitForURL('**/'); // Check both templates are visible await page.goto(`${BASE}/assessment`, { waitUntil: 'networkidle' }); await page.waitForTimeout(2000); const body = await page.textContent('body'); const hasTechTemplate = body.includes('AI协作技巧-对话测评'); const hasNonTechTemplate = body.includes('AI协作-非技术人员测评'); console.log(`技术人员模板: ${hasTechTemplate ? '✅' : '❌'}`); console.log(`非技术人员模板: ${hasNonTechTemplate ? '✅' : '❌'}`); // Start tech assessment (20 questions) await page.locator('button:has-text("AI协作技巧-对话测评")').first().click(); await page.waitForTimeout(500); await page.locator('button:has-text("开始专业评估")').first().click(); // Wait for first question for (let i = 0; i < 120; i++) { const text = await page.textContent('body').catch(() => ''); if (text.includes('问题 1') || text.includes('Question 1')) break; await new Promise(r => setTimeout(r, 2000)); } console.log('✅ 20题考核已开始(等待第一题)'); // Just check question 1 loaded, then we know the system works await page.waitForFunction(() => !document.querySelector('.animate-spin'), { timeout: 60000 }).catch(() => {}); const q1 = await page.evaluate(() => { const bubbles = Array.from(document.querySelectorAll('.px-5.py-4')); for (let i = bubbles.length - 1; i >= 0; i--) { const el = bubbles[i]; const text = el.textContent || ''; if (text.length > 25 && !(el.getAttribute('class') || '').includes('bg-indigo')) return text.replace(/\s+/g, ' ').substring(0, 80); } return ''; }); console.log(`第1题: ${q1}...`); // Check that question counter shows 1/20 const qCounter = await page.evaluate(() => { const body = document.body.textContent || ''; const m = body.match(/问题 (\d+)\/(\d+)/) || body.match(/Question (\d+)\/(\d+)/); return m ? `${m[1]}/${m[2]}` : 'no-counter'; }); console.log(`题数指示器: ${qCounter}`); const is20 = qCounter.endsWith('/20'); console.log(`\n${is20 ? '🎉 20题模板正常出题!' : '⚠️ 题数指示异常'}`); await page.screenshot({ path: 'question-20-distribution.png', fullPage: true }); console.log('📸 截图已保存'); await browser.close(); } run().catch(e => { console.error('❌', e.message); process.exit(1); });