- 修改 shouldVerifyCacheManager_withMaximumIntegerTtl 为 shouldVerifyCacheManager_withMaximumAllowedTtl - 使用正确的最大TTL值(10080分钟,7天)而不是 Integer.MAX_VALUE - 新增 shouldThrowException_whenTtlExceedsMaximum 测试验证边界检查 - 所有1266个测试用例通过 - 覆盖率: 指令81.89%, 行88.48%, 分支51.55% docs: 添加项目状态报告 - 生成 PROJECT_STATUS_REPORT.md 详细记录项目当前状态 - 包含质量指标、已完成功能、待办事项和技术债务
182 lines
5.4 KiB
JavaScript
182 lines
5.4 KiB
JavaScript
/**
|
||
* E2E测试环境验证脚本
|
||
* 在运行完整测试前验证配置
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
console.log('🔍 验证E2E测试环境...\n');
|
||
|
||
// 检查目录结构
|
||
const requiredDirs = [
|
||
'e2e',
|
||
'e2e/fixtures',
|
||
'e2e/tests',
|
||
'e2e/utils',
|
||
];
|
||
|
||
console.log('📂 检查目录结构:');
|
||
let allDirsExist = true;
|
||
for (const dir of requiredDirs) {
|
||
const dirPath = path.join(__dirname, '..', dir);
|
||
if (fs.existsSync(dirPath)) {
|
||
console.log(` ✅ ${dir}`);
|
||
} else {
|
||
console.log(` ❌ ${dir} (缺失)`);
|
||
allDirsExist = false;
|
||
}
|
||
}
|
||
|
||
if (!allDirsExist) {
|
||
console.log('\n❌ 目录结构不完整');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 检查关键文件
|
||
const requiredFiles = [
|
||
'playwright.config.ts',
|
||
'e2e/global-setup.ts',
|
||
'e2e/global-teardown.ts',
|
||
'e2e/fixtures/test-data.ts',
|
||
'e2e/tests/user-journey.spec.ts',
|
||
'e2e/utils/auth-helper.ts',
|
||
'e2e/utils/wait-helper.ts',
|
||
];
|
||
|
||
console.log('\n📄 检查关键文件:');
|
||
let allFilesExist = true;
|
||
for (const file of requiredFiles) {
|
||
const filePath = path.join(__dirname, '..', file);
|
||
if (fs.existsSync(filePath)) {
|
||
const stats = fs.statSync(filePath);
|
||
console.log(` ✅ ${file} (${(stats.size / 1024).toFixed(1)} KB)`);
|
||
} else {
|
||
console.log(` ❌ ${file} (缺失)`);
|
||
allFilesExist = false;
|
||
}
|
||
}
|
||
|
||
if (!allFilesExist) {
|
||
console.log('\n❌ 关键文件缺失');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 检查package.json中的脚本
|
||
console.log('\n📦 检查npm脚本:');
|
||
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
||
|
||
const requiredScripts = [
|
||
'test:e2e',
|
||
'test:e2e:ui',
|
||
'test:e2e:debug',
|
||
'test:e2e:report',
|
||
];
|
||
|
||
for (const script of requiredScripts) {
|
||
if (packageJson.scripts && packageJson.scripts[script]) {
|
||
console.log(` ✅ ${script}`);
|
||
} else {
|
||
console.log(` ⚠️ ${script} (可选)`);
|
||
}
|
||
}
|
||
|
||
// 检查Playwright配置
|
||
console.log('\n⚙️ 检查Playwright配置:');
|
||
const playwrightConfigPath = path.join(__dirname, '..', 'playwright.config.ts');
|
||
if (fs.existsSync(playwrightConfigPath)) {
|
||
const configContent = fs.readFileSync(playwrightConfigPath, 'utf-8');
|
||
|
||
const checks = [
|
||
{ name: '测试目录', pattern: /testDir/ },
|
||
{ name: '多浏览器支持', pattern: /chromium.*firefox.*webkit/s },
|
||
{ name: '移动端设备', pattern: /Pixel 5.*iPhone 12/s },
|
||
{ name: '截图配置', pattern: /screenshot/ },
|
||
{ name: '录屏配置', pattern: /video/ },
|
||
{ name: 'Web服务器配置', pattern: /webServer/ },
|
||
];
|
||
|
||
for (const check of checks) {
|
||
if (check.pattern.test(configContent)) {
|
||
console.log(` ✅ ${check.name}`);
|
||
} else {
|
||
console.log(` ⚠️ ${check.name}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查后端E2E配置
|
||
console.log('\n🔧 检查后端E2E配置:');
|
||
const backendE2EConfigPath = path.join(__dirname, '..', '..', 'src', 'main', 'resources', 'application-e2e.properties');
|
||
if (fs.existsSync(backendE2EConfigPath)) {
|
||
console.log(' ✅ application-e2e.properties');
|
||
|
||
const configContent = fs.readFileSync(backendE2EConfigPath, 'utf-8');
|
||
const checks = [
|
||
{ name: 'H2数据库配置', pattern: /spring\.datasource\.url.*h2/i },
|
||
{ name: 'Flyway禁用', pattern: /spring\.flyway\.enabled=false/i },
|
||
];
|
||
|
||
for (const check of checks) {
|
||
if (check.pattern.test(configContent)) {
|
||
console.log(` ✅ ${check.name}`);
|
||
} else {
|
||
console.log(` ⚠️ ${check.name}`);
|
||
}
|
||
}
|
||
} else {
|
||
console.log(' ❌ application-e2e.properties (缺失)');
|
||
}
|
||
|
||
// 检查启动脚本
|
||
console.log('\n🚀 检查启动脚本:');
|
||
const scriptPath = path.join(__dirname, 'run-e2e-tests.sh');
|
||
if (fs.existsSync(scriptPath)) {
|
||
const stats = fs.statSync(scriptPath);
|
||
const isExecutable = (stats.mode & parseInt('111', 8)) !== 0;
|
||
|
||
if (isExecutable) {
|
||
console.log(' ✅ run-e2e-tests.sh (可执行)');
|
||
} else {
|
||
console.log(' ⚠️ run-e2e-tests.sh (需要执行权限)');
|
||
console.log(' 运行: chmod +x scripts/run-e2e-tests.sh');
|
||
}
|
||
} else {
|
||
console.log(' ❌ run-e2e-tests.sh (缺失)');
|
||
}
|
||
|
||
// 统计测试用例
|
||
console.log('\n🧪 统计测试用例:');
|
||
const testFilePath = path.join(__dirname, '..', 'e2e', 'tests', 'user-journey.spec.ts');
|
||
if (fs.existsSync(testFilePath)) {
|
||
const testContent = fs.readFileSync(testFilePath, 'utf-8');
|
||
|
||
// 统计test.describe和test('')
|
||
const describeMatches = testContent.match(/test\.describe\(/g);
|
||
const testMatches = testContent.match(/test\(['`]/g);
|
||
|
||
console.log(` 测试套件: ${describeMatches ? describeMatches.length : 0} 个`);
|
||
console.log(` 测试用例: ${testMatches ? testMatches.length : 0} 个`);
|
||
|
||
// 提取测试描述
|
||
const testDescriptions = testContent.match(/test\(['`]([^'`]+)['`]/g);
|
||
if (testDescriptions) {
|
||
console.log('\n 测试场景:');
|
||
testDescriptions.forEach((desc, i) => {
|
||
const cleanDesc = desc.replace(/test\(['`]/, '').replace(/['`]$/, '');
|
||
console.log(` ${i + 1}. ${cleanDesc}`);
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log('\n✅ 验证完成!');
|
||
console.log('');
|
||
console.log('📖 使用指南:');
|
||
console.log(' 快速运行: cd frontend && ./scripts/run-e2e-tests.sh');
|
||
console.log(' 分步运行:');
|
||
console.log(' 1. mvn spring-boot:run -Dspring-boot.run.profiles=e2e');
|
||
console.log(' 2. cd frontend && npm run dev -- --port 5173');
|
||
console.log(' 3. cd frontend && npm run test:e2e');
|
||
console.log('');
|