#!/usr/bin/env python3 """ 快速俄罗斯方块测试 使用同步Playwright API """ from playwright.sync_api import sync_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_quick_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": "默认版"}, ] def test_game(page, version): """测试游戏基本功能""" print(f"\n🎮 测试: {version['name']}") print("-" * 50) url = BASE_URL + version["file"] print(f"📡 URL: {url}") # 导航到页面 page.goto(url, wait_until="networkidle", timeout=10000) print("✅ 页面加载成功") # 等待页面初始化 time.sleep(2) # 检查Canvas canvas_elements = page.query_selector_all("canvas") canvas_count = len(canvas_elements) print(f"🎨 Canvas数量: {canvas_count}") if canvas_count > 0: canvas = canvas_elements[0] box = canvas.bounding_box() if box: print(f"📐 Canvas尺寸: {int(box['width'])}x{int(box['height'])}") # 收集控制台日志 console_logs = [] def on_console(msg): console_logs.append({ "time": datetime.now().strftime("%H:%M:%S"), "type": msg.type, "text": msg.text[:100] # 只取前100字符 }) page.on("console", on_console) # 尝试点击开始按钮 print("🔘 尝试点击开始按钮...") # 多种方式尝试点击开始 click_success = False # 方法1: 通过ID start_btn = page.query_selector("#start-btn") if start_btn: try: start_btn.click(timeout=2000) print("✅ 通过#start-btn点击成功") click_success = True except Exception as e: print(f"⚠️ #start-btn点击失败: {e}") # 方法2: 通过文本 if not click_success: start_btns = page.query_selector_all("button:has-text('开始')") if start_btns: try: start_btns[0].click(timeout=2000) print("✅ 通过'开始'文本点击成功") click_success = True except Exception as e: print(f"⚠️ '开始'文本点击失败: {e}") # 方法3: 按空格键 if not click_success: print("⚠️ 按钮点击失败,尝试按空格键...") page.keyboard.press(" ") # 等待游戏运行 print("⏳ 等待游戏运行5秒...") time.sleep(5) # 分析日志 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" 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 } def main(): """主函数""" print("🚀 俄罗斯方块快速测试开始") print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"测试版本: {len(TEST_VERSIONS)}个") results = [] with sync_playwright() as p: browser = 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 = browser.new_context( viewport={"width": 1280, "height": 720} ) page = context.new_page() try: result = test_game(page, version) results.append(result) finally: page.close() context.close() # 版本间间隔 time.sleep(1) finally: browser.close() # 生成报告 generate_report(results) print(f"\n✅ 所有测试完成!") print(f"📁 结果保存在: {OUTPUT_DIR}") def generate_report(results): """生成测试报告""" report_file = OUTPUT_DIR / "quick_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") # 找出最佳版本 if results: 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") # 总结技术问题 f.write("### 发现的问题:\n") for result in results: if result["score"] < 80: f.write(f"\n#### {result['version']['name']}:\n") if result["spawn_count"] > 0 and result["move_count"] == 0: f.write("- 问题: 方块生成但不下落\n") f.write("- 可能原因: 游戏循环未正确启动\n") f.write("- 解决方案: 检查游戏循环逻辑和时间计算\n") elif result["spawn_count"] == 0: f.write("- 问题: 方块未生成\n") f.write("- 可能原因: 游戏初始化失败\n") f.write("- 解决方案: 检查游戏初始化代码\n") f.write("\n## 🚀 下一步建议\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__": main()