#!/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())