344 lines
14 KiB
JavaScript
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); |