256 lines
9.4 KiB
Python
256 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
简单俄罗斯方块测试脚本
|
|
使用Playwright无头浏览器
|
|
"""
|
|
|
|
import asyncio
|
|
from playwright.async_api import async_playwright
|
|
import time
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
# 测试配置
|
|
BASE_URL = "http://129.211.173.87:8895/games/tetris/"
|
|
OUTPUT_DIR = Path("/tmp/tetris_simple_test")
|
|
OUTPUT_DIR.mkdir(exist_ok=True)
|
|
|
|
# 测试版本
|
|
TEST_VERSIONS = [
|
|
{"file": "tetris_playcanvas_working.html", "name": "PlayCanvas工作版"},
|
|
{"file": "tetris_final_canvas2d.html", "name": "最终Canvas 2D版"},
|
|
{"file": "tetris_simple_fall_test.html", "name": "简单下落测试版"},
|
|
{"file": "index.html", "name": "默认版"},
|
|
]
|
|
|
|
async def test_game(page, version):
|
|
"""测试游戏基本功能"""
|
|
print(f"\n🎮 测试: {version['name']}")
|
|
print("-" * 50)
|
|
|
|
url = BASE_URL + version["file"]
|
|
print(f"📡 URL: {url}")
|
|
|
|
# 导航到页面
|
|
await page.goto(url, wait_until="networkidle", timeout=10000)
|
|
print("✅ 页面加载成功")
|
|
|
|
# 等待页面初始化
|
|
await page.wait_for_timeout(2000)
|
|
|
|
# 检查Canvas
|
|
canvas_count = await page.locator("canvas").count()
|
|
print(f"🎨 Canvas数量: {canvas_count}")
|
|
|
|
if canvas_count > 0:
|
|
canvas = page.locator("canvas").first()
|
|
box = await canvas.bounding_box()
|
|
if box:
|
|
print(f"📐 Canvas尺寸: {int(box['width'])}x{int(box['height'])}")
|
|
|
|
# 监听控制台日志
|
|
console_logs = []
|
|
page.on("console", lambda msg: console_logs.append({
|
|
"time": datetime.now().strftime("%H:%M:%S"),
|
|
"type": msg.type,
|
|
"text": msg.text[:100] # 只取前100字符
|
|
}))
|
|
|
|
# 尝试点击开始按钮
|
|
print("🔘 尝试点击开始按钮...")
|
|
|
|
# 多种方式尝试点击开始
|
|
click_success = False
|
|
click_methods = [
|
|
("#start-btn", "通过ID选择器"),
|
|
("button:has-text('开始')", "通过文本选择器"),
|
|
("button:has-text('Start')", "通过英文文本"),
|
|
("button:first-child", "第一个按钮"),
|
|
]
|
|
|
|
for selector, method in click_methods:
|
|
try:
|
|
if await page.locator(selector).count() > 0:
|
|
await page.locator(selector).first.click(timeout=2000)
|
|
print(f"✅ {method}点击成功")
|
|
click_success = True
|
|
break
|
|
except Exception as e:
|
|
print(f"⚠️ {method}点击失败: {e}")
|
|
|
|
# 如果按钮点击失败,尝试按空格键
|
|
if not click_success:
|
|
print("⚠️ 按钮点击失败,尝试按空格键...")
|
|
await page.keyboard.press(" ")
|
|
|
|
# 等待游戏运行
|
|
print("⏳ 等待游戏运行5秒...")
|
|
await page.wait_for_timeout(5000)
|
|
|
|
# 分析日志
|
|
spawn_count = sum(1 for log in console_logs if any(keyword in log["text"].lower()
|
|
for keyword in ["生成", "spawn", "new piece", "方块"]))
|
|
move_count = sum(1 for log in console_logs if any(keyword in log["text"].lower()
|
|
for keyword in ["移动", "move", "下落", "drop", "位置"]))
|
|
error_count = sum(1 for log in console_logs if log["type"] == "error")
|
|
|
|
print(f"📊 日志分析:")
|
|
print(f" 总日志: {len(console_logs)}条")
|
|
print(f" 方块生成: {spawn_count}次")
|
|
print(f" 方块移动: {move_count}次")
|
|
print(f" 错误日志: {error_count}条")
|
|
|
|
# 显示关键日志
|
|
if spawn_count > 0:
|
|
spawn_logs = [log for log in console_logs if any(keyword in log["text"].lower()
|
|
for keyword in ["生成", "spawn", "new piece", "方块"])]
|
|
print(f" 最后生成: {spawn_logs[-1]['text'][:60]}...")
|
|
|
|
if move_count > 0:
|
|
move_logs = [log for log in console_logs if any(keyword in log["text"].lower()
|
|
for keyword in ["移动", "move", "下落", "drop", "位置"])]
|
|
recent_moves = move_logs[-3:] if len(move_logs) >= 3 else move_logs
|
|
print(f" 最近移动:")
|
|
for i, move in enumerate(recent_moves):
|
|
print(f" {i+1}. {move['text'][:50]}...")
|
|
|
|
# 截图
|
|
screenshot_path = OUTPUT_DIR / f"{version['name'].replace(' ', '_')}.png"
|
|
await page.screenshot(path=str(screenshot_path), full_page=True)
|
|
print(f"📸 截图保存: {screenshot_path}")
|
|
|
|
# 判断游戏状态
|
|
if spawn_count > 0 and move_count > 0:
|
|
status = "🎉 完美工作"
|
|
score = 100
|
|
elif spawn_count > 0 and move_count == 0:
|
|
status = "⚠️ 方块生成但不下落"
|
|
score = 60
|
|
elif spawn_count == 0:
|
|
status = "❌ 方块未生成"
|
|
score = 30
|
|
else:
|
|
status = "❓ 未知状态"
|
|
score = 50
|
|
|
|
print(f"📈 状态: {status}")
|
|
print(f"🏆 评分: {score}/100")
|
|
|
|
return {
|
|
"version": version,
|
|
"spawn_count": spawn_count,
|
|
"move_count": move_count,
|
|
"error_count": error_count,
|
|
"total_logs": len(console_logs),
|
|
"status": status,
|
|
"score": score,
|
|
"screenshot": str(screenshot_path),
|
|
"url": url
|
|
}
|
|
|
|
async def main():
|
|
"""主函数"""
|
|
print("🚀 俄罗斯方块简单测试开始")
|
|
print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print(f"测试版本: {len(TEST_VERSIONS)}个")
|
|
|
|
results = []
|
|
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
|
|
try:
|
|
for i, version in enumerate(TEST_VERSIONS):
|
|
print(f"\n{'#'*60}")
|
|
print(f"测试进度: {i+1}/{len(TEST_VERSIONS)}")
|
|
|
|
context = await browser.new_context(
|
|
viewport={"width": 1280, "height": 720}
|
|
)
|
|
page = await context.new_page()
|
|
|
|
try:
|
|
result = await test_game(page, version)
|
|
results.append(result)
|
|
finally:
|
|
await page.close()
|
|
await context.close()
|
|
|
|
# 版本间间隔
|
|
await asyncio.sleep(1)
|
|
|
|
finally:
|
|
await browser.close()
|
|
|
|
# 生成报告
|
|
generate_report(results)
|
|
|
|
print(f"\n✅ 所有测试完成!")
|
|
print(f"📁 结果保存在: {OUTPUT_DIR}")
|
|
|
|
def generate_report(results):
|
|
"""生成测试报告"""
|
|
report_file = OUTPUT_DIR / "test_report.md"
|
|
|
|
with open(report_file, "w", encoding="utf-8") as f:
|
|
f.write("# 🎮 俄罗斯方块游戏测试报告\n\n")
|
|
f.write(f"**测试时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
|
|
|
f.write("## 📊 测试结果\n\n")
|
|
f.write("| 版本 | 评分 | 状态 | 方块生成 | 方块移动 | 错误数 |\n")
|
|
f.write("|------|------|------|----------|----------|--------|\n")
|
|
|
|
for result in sorted(results, key=lambda x: x["score"], reverse=True):
|
|
f.write(f"| {result['version']['name']} | ")
|
|
f.write(f"{result['score']}/100 | {result['status']} | ")
|
|
f.write(f"{result['spawn_count']} | {result['move_count']} | ")
|
|
f.write(f"{result['error_count']} |\n")
|
|
|
|
f.write("\n## 🏆 推荐版本\n\n")
|
|
|
|
# 找出最佳版本
|
|
best_result = max(results, key=lambda x: x["score"])
|
|
f.write(f"### 最佳版本: **{best_result['version']['name']}**\n")
|
|
f.write(f"- **评分**: {best_result['score']}/100\n")
|
|
f.write(f"- **状态**: {best_result['status']}\n")
|
|
f.write(f"- **访问地址**: {best_result['url']}\n")
|
|
f.write(f"- **截图**: {best_result['screenshot']}\n")
|
|
|
|
f.write("\n### 所有版本详情\n\n")
|
|
for result in results:
|
|
f.write(f"#### {result['version']['name']}\n")
|
|
f.write(f"- 文件: `{result['version']['file']}`\n")
|
|
f.write(f"- 评分: {result['score']}/100\n")
|
|
f.write(f"- 状态: {result['status']}\n")
|
|
f.write(f"- 方块生成: {result['spawn_count']}次\n")
|
|
f.write(f"- 方块移动: {result['move_count']}次\n")
|
|
f.write(f"- 错误数: {result['error_count']}个\n")
|
|
f.write(f"- 访问: {result['url']}\n")
|
|
f.write("\n")
|
|
|
|
f.write("## 🔧 问题分析\n\n")
|
|
|
|
# 分析问题
|
|
problem_versions = [r for r in results if r["score"] < 80]
|
|
if problem_versions:
|
|
f.write("### 需要修复的版本:\n")
|
|
for result in problem_versions:
|
|
f.write(f"- **{result['version']['name']}**: {result['status']}\n")
|
|
if result["spawn_count"] > 0 and result["move_count"] == 0:
|
|
f.write(" - 问题: 方块生成但不下落\n")
|
|
f.write(" - 可能原因: 游戏循环未启动或时间计算错误\n")
|
|
elif result["spawn_count"] == 0:
|
|
f.write(" - 问题: 方块未生成\n")
|
|
f.write(" - 可能原因: 游戏初始化失败\n")
|
|
f.write("\n")
|
|
|
|
f.write("## 🚀 建议\n\n")
|
|
f.write("1. **立即使用**: 评分最高的版本\n")
|
|
f.write("2. **问题修复**: 检查游戏循环逻辑\n")
|
|
f.write("3. **兼容性**: 确保在不同浏览器上都能工作\n")
|
|
f.write("4. **移动端**: 测试触摸控制\n")
|
|
|
|
print(f"📄 报告生成: {report_file}")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |