Files
aurak/test-question-distribution.mjs
Developer 1aee7e0baf fix: 出题分配算法重构 + 20题模板 + 非技术人员模板
问题修复:
- 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>
2026-06-09 11:24:32 +08:00

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); });