Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

344 lines
14 KiB
JavaScript

const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
// 测试配置
const BASE_URL = 'http://129.211.173.87:8895/games/tetris/';
const TEST_VERSIONS = [
{ file: 'tetris_final_canvas2d.html', name: '最终Canvas 2D版', expected: '工作' },
{ file: 'tetris_simple_fall_test.html', name: '简单下落测试版', expected: '工作' },
{ file: 'tetris_playcanvas_working.html', name: 'PlayCanvas工作版', expected: '可能工作' },
{ file: 'index.html', name: '默认版', expected: '可能失败' },
];
async function testGameVersion(browser, version) {
console.log(`\n🎮 测试: ${version.name} (${version.file})`);
console.log('='.repeat(60));
const page = await browser.newPage();
const logs = [];
const errors = [];
try {
// 页面事件监听
page.on('console', msg => {
logs.push(`[${msg.type()}] ${msg.text()}`);
if (msg.type() === 'error') {
errors.push(msg.text());
}
});
page.on('pageerror', error => {
errors.push(`页面错误: ${error.message}`);
});
// 导航到页面
const url = BASE_URL + version.file;
console.log(`📡 访问: ${url}`);
await page.goto(url, { waitUntil: 'networkidle', timeout: 10000 });
console.log('✅ 页面加载成功');
// 等待页面完全加载
await page.waitForTimeout(2000);
// 检查Canvas
const canvasCount = await page.locator('canvas').count();
console.log(`🎨 Canvas数量: ${canvasCount}`);
if (canvasCount === 0) {
console.log('❌ 未找到Canvas元素');
return { ...version, status: '失败', reason: '未找到Canvas' };
}
// 获取Canvas信息
const canvas = page.locator('canvas').first();
const canvasBox = await canvas.boundingBox();
console.log(`📐 Canvas尺寸: ${canvasBox?.width || '未知'}x${canvasBox?.height || '未知'}`);
// 检查按钮
const buttonSelectors = ['#start-btn', 'button:has-text("开始")', 'button:has-text("Start")', 'button'];
let startButton = null;
for (const selector of buttonSelectors) {
if (await page.locator(selector).count() > 0) {
startButton = page.locator(selector).first();
console.log(`🔘 找到按钮: ${selector}`);
break;
}
}
if (!startButton) {
console.log('⚠️ 未找到开始按钮,尝试按空格键');
await page.keyboard.press(' ');
} else {
// 点击开始按钮
await startButton.click();
console.log('✅ 点击开始按钮');
}
// 等待游戏开始
await page.waitForTimeout(3000);
// 分析日志
const spawnLogs = logs.filter(log =>
log.includes('生成') ||
log.includes('spawn') ||
log.includes('方块') ||
log.includes('piece')
);
const moveLogs = logs.filter(log =>
log.includes('移动') ||
log.includes('move') ||
log.includes('下落') ||
log.includes('drop') ||
log.includes('位置')
);
console.log(`📊 方块生成日志: ${spawnLogs.length}条`);
console.log(`📊 方块移动日志: ${moveLogs.length}条`);
// 显示关键日志
if (spawnLogs.length > 0) {
console.log(`📝 生成日志: ${spawnLogs[0]}`);
}
if (moveLogs.length > 0) {
console.log(`📝 移动日志: ${moveLogs.slice(0, 3).join(' | ')}`);
}
// 检查错误
if (errors.length > 0) {
console.log(`⚠️ 发现错误: ${errors.length}个`);
errors.slice(0, 3).forEach(err => console.log(` - ${err}`));
}
// 截图
const screenshotDir = '/tmp/tetris_tests';
if (!fs.existsSync(screenshotDir)) {
fs.mkdirSync(screenshotDir, { recursive: true });
}
const screenshotPath = path.join(screenshotDir, `${version.name.replace(/\s+/g, '_')}.png`);
await page.screenshot({ path: screenshotPath, fullPage: true });
console.log(`📸 截图保存: ${screenshotPath}`);
// 判断测试结果
let status = '未知';
let reason = '';
if (errors.length > 5) {
status = '失败';
reason = `发现${errors.length}个错误`;
} else if (spawnLogs.length === 0) {
status = '失败';
reason = '方块未生成';
} else if (moveLogs.length === 0) {
status = '部分工作';
reason = '方块生成但未移动';
} else {
status = '成功';
reason = `方块生成并移动${moveLogs.length}次`;
}
console.log(`📈 测试结果: ${status} - ${reason}`);
return {
...version,
status,
reason,
canvasCount,
canvasSize: canvasBox ? `${canvasBox.width}x${canvasBox.height}` : '未知',
spawnLogs: spawnLogs.length,
moveLogs: moveLogs.length,
errors: errors.length,
screenshot: screenshotPath,
logs: logs.slice(-10) // 最后10条日志
};
} catch (error) {
console.log(`❌ 测试异常: ${error.message}`);
return {
...version,
status: '异常',
reason: error.message,
errors: 1
};
} finally {
await page.close();
}
}
async function main() {
console.log('🚀 开始全面测试俄罗斯方块游戏');
console.log(`测试时间: ${new Date().toLocaleString()}`);
console.log(`基础URL: ${BASE_URL}`);
console.log('='.repeat(80));
const browser = await chromium.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const results = [];
try {
// 测试每个版本
for (const version of TEST_VERSIONS) {
const result = await testGameVersion(browser, version);
results.push(result);
// 版本间间隔
await new Promise(resolve => setTimeout(resolve, 1000));
}
// 生成测试报告
console.log('\n' + '='.repeat(80));
console.log('📋 俄罗斯方块游戏测试报告');
console.log('='.repeat(80));
const successful = results.filter(r => r.status === '成功');
const failed = results.filter(r => r.status !== '成功');
console.log(`\n✅ 成功版本 (${successful.length}/${results.length}):`);
successful.forEach(result => {
console.log(` 🏆 ${result.name}`);
console.log(` 文件: ${result.file}`);
console.log(` Canvas: ${result.canvasSize}`);
console.log(` 生成: ${result.spawnLogs}次, 移动: ${result.moveLogs}次`);
console.log(` 错误: ${result.errors}个`);
console.log(` 截图: ${result.screenshot}`);
console.log('');
});
if (failed.length > 0) {
console.log(`\n❌ 失败版本 (${failed.length}/${results.length}):`);
failed.forEach(result => {
console.log(` ⚠️ ${result.name}`);
console.log(` 状态: ${result.status}`);
console.log(` 原因: ${result.reason}`);
console.log(` 错误: ${result.errors}个`);
console.log('');
});
}
// 推荐最佳版本
if (successful.length > 0) {
const bestVersion = successful.reduce((best, current) => {
// 优先选择移动次数多的版本
if (current.moveLogs > (best.moveLogs || 0)) {
return current;
}
return best;
});
console.log('\n' + '='.repeat(80));
console.log('🎯 推荐使用版本');
console.log('='.repeat(80));
console.log(`🏆 ${bestVersion.name}`);
console.log(`📁 文件: ${bestVersion.file}`);
console.log(`🌐 访问: ${BASE_URL}${bestVersion.file}`);
console.log(`📊 测试结果: ${bestVersion.spawnLogs}次生成, ${bestVersion.moveLogs}次移动`);
console.log(`📸 截图: ${bestVersion.screenshot}`);
// 生成HTML报告
generateHtmlReport(results, bestVersion);
} else {
console.log('\n⚠️ 警告: 没有找到完全成功的版本!');
}
} finally {
await browser.close();
}
}
function generateHtmlReport(results, bestVersion) {
const reportDir = '/tmp/tetris_tests';
const reportPath = path.join(reportDir, 'test_report.html');
const html = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>俄罗斯方块游戏测试报告</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #333; border-bottom: 2px solid #4CAF50; padding-bottom: 10px; }
h2 { color: #555; margin-top: 30px; }
.summary { background: #e8f5e9; padding: 15px; border-radius: 5px; margin: 20px 0; }
.result-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin: 20px 0; }
.card { border: 1px solid #ddd; border-radius: 5px; padding: 15px; }
.card.success { border-left: 5px solid #4CAF50; }
.card.failed { border-left: 5px solid #f44336; }
.card.partial { border-left: 5px solid #ff9800; }
.status { font-weight: bold; padding: 3px 8px; border-radius: 3px; display: inline-block; }
.status-success { background: #4CAF50; color: white; }
.status-failed { background: #f44336; color: white; }
.status-partial { background: #ff9800; color: white; }
.screenshot { max-width: 100%; height: auto; border: 1px solid #ddd; margin-top: 10px; }
.recommendation { background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; border-radius: 5px; margin: 20px 0; }
.log { background: #f8f9fa; padding: 10px; border-radius: 3px; font-family: monospace; font-size: 12px; max-height: 200px; overflow-y: auto; }
</style>
</head>
<body>
<div class="container">
<h1>🎮 俄罗斯方块游戏测试报告</h1>
<p>测试时间: ${new Date().toLocaleString()}</p>
<div class="summary">
<h2>📊 测试摘要</h2>
<p>测试版本数: ${results.length}</p>
<p>成功版本: ${results.filter(r => r.status === '成功').length}</p>
<p>失败版本: ${results.filter(r => r.status !== '成功').length}</p>
</div>
<div class="recommendation">
<h2>🏆 推荐版本</h2>
<h3>${bestVersion.name}</h3>
<p><strong>文件:</strong> ${bestVersion.file}</p>
<p><strong>访问地址:</strong> <a href="${BASE_URL}${bestVersion.file}" target="_blank">${BASE_URL}${bestVersion.file}</a></p>
<p><strong>测试结果:</strong> ${bestVersion.spawnLogs}次方块生成, ${bestVersion.moveLogs}次方块移动</p>
<p><strong>Canvas尺寸:</strong> ${bestVersion.canvasSize}</p>
${bestVersion.screenshot ? `<img src="file://${bestVersion.screenshot}" alt="${bestVersion.name}截图" class="screenshot">` : ''}
</div>
<h2>📋 详细测试结果</h2>
<div class="result-grid">
${results.map(result => `
<div class="card ${result.status === '成功' ? 'success' : result.status === '部分工作' ? 'partial' : 'failed'}">
<h3>${result.name}</h3>
<p><strong>状态:</strong> <span class="status status-${result.status === '成功' ? 'success' : result.status === '部分工作' ? 'partial' : 'failed'}">${result.status}</span></p>
<p><strong>文件:</strong> ${result.file}</p>
<p><strong>Canvas:</strong> ${result.canvasSize || '未找到'}</p>
<p><strong>方块生成:</strong> ${result.spawnLogs || 0}次</p>
<p><strong>方块移动:</strong> ${result.moveLogs || 0}次</p>
<p><strong>错误:</strong> ${result.errors || 0}个</p>
<p><strong>原因:</strong> ${result.reason || '无'}</p>
${result.screenshot ? `<img src="file://${result.screenshot}" alt="${result.name}截图" class="screenshot">` : ''}
${result.logs ? `<div class="log">${result.logs.slice(-5).join('<br>')}</div>` : ''}
</div>
`).join('')}
</div>
<h2>🔧 测试环境</h2>
<ul>
<li>测试工具: Playwright 1.58.0</li>
<li>浏览器: Chromium</li>
<li>测试模式: Headless</li>
<li>基础URL: ${BASE_URL}</li>
<li>截图保存: /tmp/tetris_tests/</li>
</ul>
</div>
</body>
</html>`;
fs.writeFileSync(reportPath, html);
console.log(`📄 HTML报告生成: ${reportPath}`);
}
// 运行测试
main().catch(console.error);