252 lines
8.7 KiB
Python
252 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Playwright自动化测试俄罗斯方块游戏
|
||
测试多个版本,找出真正能工作的版本
|
||
"""
|
||
|
||
import asyncio
|
||
from playwright.async_api import async_playwright
|
||
import os
|
||
import time
|
||
|
||
# 要测试的版本列表
|
||
VERSIONS_TO_TEST = [
|
||
# 1. 最终Canvas 2D版(应该工作)
|
||
("tetris_final_canvas2d.html", "最终Canvas 2D版"),
|
||
|
||
# 2. 简单修复版(用户确认能玩)
|
||
("tetris_simple_fixed.html", "简单修复版"),
|
||
|
||
# 3. 工作版(纯Canvas 2D)
|
||
("tetris_working.html", "工作版"),
|
||
|
||
# 4. 手机优化版
|
||
("tetris_mobile.html", "手机优化版"),
|
||
|
||
# 5. 默认版(小游戏中心当前版本)
|
||
("index.html", "默认版"),
|
||
|
||
# 6. PlayCanvas工作版(对比测试)
|
||
("tetris_playcanvas_working.html", "PlayCanvas工作版"),
|
||
|
||
# 7. PlayCanvas超级调试版
|
||
("tetris_playcanvas_super_debug.html", "PlayCanvas超级调试版"),
|
||
|
||
# 8. 简单下落测试版(已验证工作)
|
||
("tetris_simple_fall_test.html", "简单下落测试版"),
|
||
]
|
||
|
||
BASE_URL = "http://129.211.173.87:8895/games/tetris/"
|
||
|
||
async def test_version(page, version_file, version_name):
|
||
"""测试单个版本"""
|
||
print(f"\n{'='*60}")
|
||
print(f"测试: {version_name} ({version_file})")
|
||
print(f"URL: {BASE_URL}{version_file}")
|
||
print('='*60)
|
||
|
||
try:
|
||
# 导航到页面
|
||
await page.goto(f"{BASE_URL}{version_file}", timeout=10000)
|
||
print("✅ 页面加载成功")
|
||
|
||
# 等待页面完全加载
|
||
await page.wait_for_load_state('networkidle', timeout=5000)
|
||
|
||
# 捕获控制台日志
|
||
console_logs = []
|
||
|
||
def handle_console(msg):
|
||
console_logs.append(msg.text)
|
||
print(f" 控制台: {msg.text}")
|
||
|
||
page.on('console', handle_console)
|
||
|
||
# 检查Canvas是否存在
|
||
canvas_count = await page.locator('canvas').count()
|
||
print(f"✅ Canvas数量: {canvas_count}")
|
||
|
||
if canvas_count > 0:
|
||
# 获取Canvas尺寸
|
||
canvas = page.locator('canvas').first
|
||
canvas_size = await canvas.bounding_box()
|
||
if canvas_size:
|
||
print(f"✅ Canvas尺寸: {canvas_size['width']}x{canvas_size['height']}")
|
||
|
||
# 检查按钮
|
||
button_selectors = ['button', '#start-btn', '.control-btn', '#start-button']
|
||
for selector in button_selectors:
|
||
button_count = await page.locator(selector).count()
|
||
if button_count > 0:
|
||
print(f"✅ 找到按钮: {selector} ({button_count}个)")
|
||
break
|
||
|
||
# 尝试点击开始按钮
|
||
start_selectors = [
|
||
'#start-btn',
|
||
'button:has-text("开始")',
|
||
'button:has-text("Start")',
|
||
'button:has-text("▶️")',
|
||
'button:first-child'
|
||
]
|
||
|
||
clicked = False
|
||
for selector in start_selectors:
|
||
if await page.locator(selector).count() > 0:
|
||
try:
|
||
await page.locator(selector).click(timeout=3000)
|
||
print(f"✅ 点击开始按钮: {selector}")
|
||
clicked = True
|
||
break
|
||
except:
|
||
continue
|
||
|
||
if not clicked:
|
||
print("⚠️ 未找到开始按钮,尝试按空格键开始")
|
||
await page.keyboard.press(' ')
|
||
|
||
# 等待游戏开始
|
||
await asyncio.sleep(2)
|
||
|
||
# 检查是否有方块生成
|
||
game_started = False
|
||
for log in console_logs:
|
||
if any(keyword in log.lower() for keyword in ['生成', 'spawn', 'new piece', '方块']):
|
||
print(f"✅ 方块生成: {log}")
|
||
game_started = True
|
||
break
|
||
|
||
if not game_started:
|
||
print("⚠️ 未检测到方块生成日志")
|
||
|
||
# 等待方块下落
|
||
await asyncio.sleep(3)
|
||
|
||
# 检查是否有下落日志
|
||
piece_moved = False
|
||
for log in console_logs:
|
||
if any(keyword in log.lower() for keyword in ['移动', 'move', '下落', 'drop', '位置']):
|
||
print(f"✅ 方块移动: {log}")
|
||
piece_moved = True
|
||
break
|
||
|
||
# 截图保存
|
||
screenshot_path = f"/tmp/test_{version_name.replace(' ', '_')}.png"
|
||
await page.screenshot(path=screenshot_path, full_page=True)
|
||
print(f"✅ 截图保存: {screenshot_path}")
|
||
|
||
# 总结测试结果
|
||
print(f"\n📊 测试总结:")
|
||
print(f" 页面加载: ✅")
|
||
print(f" Canvas存在: ✅ ({canvas_count}个)")
|
||
print(f" 按钮点击: {'✅' if clicked else '⚠️'}")
|
||
print(f" 方块生成: {'✅' if game_started else '❌'}")
|
||
print(f" 方块下落: {'✅' if piece_moved else '❌'}")
|
||
|
||
# 检查是否有错误
|
||
errors = [log for log in console_logs if 'error' in log.lower() or '❌' in log or '失败' in log]
|
||
if errors:
|
||
print(f"⚠️ 发现错误 ({len(errors)}个):")
|
||
for err in errors[:3]: # 只显示前3个错误
|
||
print(f" - {err}")
|
||
|
||
return {
|
||
'version': version_name,
|
||
'file': version_file,
|
||
'canvas_found': canvas_count > 0,
|
||
'button_clicked': clicked,
|
||
'piece_spawned': game_started,
|
||
'piece_moved': piece_moved,
|
||
'errors': len(errors),
|
||
'screenshot': screenshot_path
|
||
}
|
||
|
||
except Exception as e:
|
||
print(f"❌ 测试失败: {str(e)}")
|
||
return {
|
||
'version': version_name,
|
||
'file': version_file,
|
||
'error': str(e),
|
||
'canvas_found': False,
|
||
'button_clicked': False,
|
||
'piece_spawned': False,
|
||
'piece_moved': False,
|
||
'errors': 1
|
||
}
|
||
|
||
async def main():
|
||
"""主测试函数"""
|
||
print("🎮 开始自动化测试俄罗斯方块游戏")
|
||
print(f"测试时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||
print(f"基础URL: {BASE_URL}")
|
||
print(f"测试版本数: {len(VERSIONS_TO_TEST)}")
|
||
|
||
results = []
|
||
|
||
async with async_playwright() as p:
|
||
# 使用Chromium浏览器
|
||
browser = await p.chromium.launch(headless=True)
|
||
context = await browser.new_context(
|
||
viewport={'width': 1280, 'height': 720},
|
||
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
||
)
|
||
|
||
page = await context.new_page()
|
||
|
||
# 测试每个版本
|
||
for version_file, version_name in VERSIONS_TO_TEST:
|
||
result = await test_version(page, version_file, version_name)
|
||
results.append(result)
|
||
|
||
# 清理页面状态
|
||
await page.goto('about:blank')
|
||
await asyncio.sleep(1)
|
||
|
||
await browser.close()
|
||
|
||
# 输出测试报告
|
||
print("\n" + "="*80)
|
||
print("🎯 俄罗斯方块游戏测试报告")
|
||
print("="*80)
|
||
|
||
working_versions = []
|
||
failing_versions = []
|
||
|
||
for result in results:
|
||
if result.get('piece_moved', False):
|
||
working_versions.append(result)
|
||
else:
|
||
failing_versions.append(result)
|
||
|
||
print(f"\n✅ 工作版本 ({len(working_versions)}个):")
|
||
for result in working_versions:
|
||
print(f" • {result['version']} ({result['file']})")
|
||
print(f" Canvas: {'✅' if result['canvas_found'] else '❌'}, "
|
||
f"按钮: {'✅' if result['button_clicked'] else '❌'}, "
|
||
f"生成: {'✅' if result['piece_spawned'] else '❌'}, "
|
||
f"下落: ✅, 错误: {result.get('errors', 0)}个")
|
||
|
||
print(f"\n❌ 失败版本 ({len(failing_versions)}个):")
|
||
for result in failing_versions:
|
||
error_msg = result.get('error', '未知错误')
|
||
print(f" • {result['version']} ({result['file']})")
|
||
print(f" 错误: {error_msg[:100]}...")
|
||
|
||
print(f"\n📈 成功率: {len(working_versions)}/{len(VERSIONS_TO_TEST)} ({len(working_versions)/len(VERSIONS_TO_TEST)*100:.1f}%)")
|
||
|
||
# 推荐最佳版本
|
||
if working_versions:
|
||
best_version = max(working_versions, key=lambda x: (
|
||
x.get('piece_spawned', False),
|
||
x.get('button_clicked', False),
|
||
-x.get('errors', 0)
|
||
))
|
||
print(f"\n🏆 推荐版本: {best_version['version']} ({best_version['file']})")
|
||
print(f" 访问: {BASE_URL}{best_version['file']}")
|
||
else:
|
||
print("\n⚠️ 警告: 没有找到能工作的版本!")
|
||
|
||
print("\n📁 截图保存在: /tmp/test_*.png")
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main()) |