1aee7e0baf
问题修复: - Math.round 导致合计偏差(3题→4题,5题→6题等) - 补充轮次破坏维度权重比例 - 各维度无题型比例控制 修正方案: - floor + remainder 分配法,保证合计永远 = count - 按weight降序分配余数,权重高的优先 - 不足时仅补充轮,但仍保持维度优先 - 补充轮日志记录各维度实际分配数 新增功能: - 技术人员模板 20题 (PROMPT:30/LLM:30/IDE:20/DEV_PATTERN:20) - 非技术人员模板 10题 (PROMPT:50/LLM:30/WORK_CAPABILITY:20) → 面向非技术角色,不考核IDE和开发范式 - 模板支持任意维度组合,可灵活配置 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
74 lines
2.9 KiB
JavaScript
74 lines
2.9 KiB
JavaScript
/**
|
|
* 验证出题分布是否正确
|
|
*/
|
|
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); });
|