from playwright.sync_api import sync_playwright import time import os def dismiss_vite_error(page): """关闭Vite错误覆盖层""" try: page.evaluate("document.querySelector('vite-error-overlay')?.remove()") time.sleep(0.3) except: pass def wait_for_page_load(page, timeout=10000): """等待页面加载""" try: page.wait_for_load_state('load', timeout=timeout) time.sleep(1) except: time.sleep(2) def test_frontend(): # 创建截图目录 os.makedirs('/tmp/frontend_test', exist_ok=True) with sync_playwright() as p: browser = p.chromium.launch(headless=True) context = browser.new_context(viewport={"width": 1400, "height": 900}) page = context.new_page() print("=" * 60) print("开始前端功能测试") print("=" * 60) # 1. 访问首页 print("\n[测试1] 访问首页") page.goto('http://localhost:5173', wait_until='load', timeout=15000) time.sleep(2) dismiss_vite_error(page) page.screenshot(path='/tmp/frontend_test/01_home.png', full_page=True) print(" ✓ 首页加载完成") # 2. 导航到二维码生成器 print("\n[测试2] 导航到二维码生成器") page.goto('http://localhost:5173/qrcode-generator', wait_until='load', timeout=15000) time.sleep(2) dismiss_vite_error(page) page.screenshot(path='/tmp/frontend_test/02_qr_page.png', full_page=True) print(" ✓ 二维码生成器页面访问完成") # 3. 检查输入框 print("\n[测试3] 检查输入框") textarea = page.locator('textarea').or_(page.locator('input[type="text"]')) if textarea.count() > 0: textarea.first.fill("https://example.com/browser-test") time.sleep(0.5) print(" ✓ 输入框可用,已填写测试内容") else: print(" ✗ 未找到输入框") page.screenshot(path='/tmp/frontend_test/03_input_filled.png', full_page=True) # 4. 查找生成按钮(文本为"生成二维码") print("\n[测试4] 检查生成按钮") generate_btn = page.locator('button:has-text("生成二维码")').or_(page.locator('button:has-text("生成")')) if generate_btn.count() > 0: dismiss_vite_error(page) generate_btn.first.click() time.sleep(2) page.screenshot(path='/tmp/frontend_test/04_after_generate.png', full_page=True) print(" ✓ 生成按钮可用,已点击") else: # 查找所有按钮 all_buttons = page.locator('button') print(f" 找到 {all_buttons.count()} 个按钮") for i in range(min(all_buttons.count(), 15)): btn_text = all_buttons.nth(i).inner_text() print(f" 按钮{i+1}: {btn_text.strip()}") print(" ✗ 未找到明确的生成按钮") # 5. 检查美化按钮并打开弹窗 print("\n[测试5] 检查美化按钮") dismiss_vite_error(page) beautify_btn = page.locator('button:has-text("二维码美化")').or_(page.locator('.qr-beautify-trigger-btn')) if beautify_btn.count() > 0: beautify_btn.first.click() time.sleep(1) page.screenshot(path='/tmp/frontend_test/05_beautify_modal.png', full_page=True) print(" ✓ 美化按钮可用,已打开弹窗") else: print(" ✗ 未找到美化按钮") # 6. 检查颜色预设 print("\n[测试6] 检查颜色预设") color_swatches = page.locator('.qr-color-swatch') if color_swatches.count() > 0: print(f" ✓ 找到 {color_swatches.count()} 个颜色预设") # 点击第二个颜色预设 color_swatches.nth(1).click() time.sleep(0.5) page.screenshot(path='/tmp/frontend_test/06_color_selected.png', full_page=True) print(" ✓ 颜色预设可点击") else: print(" 未找到颜色预设元素") # 7. 检查定位图案选项 print("\n[测试7] 检查定位图案选项") finder_select = page.locator('.qr-beautify-select, .ant-select') if finder_select.count() > 0: print(f" ✓ 找到 {finder_select.count()} 个选择器组件") else: print(" 未找到定位图案选择器") # 8. 检查关闭按钮位置 print("\n[测试8] 检查关闭按钮") close_btn = page.locator('.ant-modal-close') if close_btn.count() > 0: close_btn.first.click() time.sleep(0.5) print(" ✓ 关闭按钮可用,弹窗已关闭") else: print(" ✗ 未找到关闭按钮") # 9. 导航到计算器 print("\n[测试9] 导航到计算器") page.goto('http://localhost:5173/calculator', wait_until='load', timeout=15000) time.sleep(2) dismiss_vite_error(page) page.screenshot(path='/tmp/frontend_test/07_calculator.png', full_page=True) print(" ✓ 计算器页面访问完成") # 10. 检查计算器显示面板 print("\n[测试10] 检查计算器显示面板") display = page.locator('[class*="display"]').or_(page.locator('[class*="result"]')) if display.count() > 0: print(f" ✓ 找到 {display.count()} 个显示面板元素") else: print(" 未找到显示面板") # 11. 测试暗色模式 print("\n[测试11] 测试暗色模式") # 查找主题切换按钮 theme_toggle = page.locator('[class*="theme"]').or_(page.locator('[data-theme]')) if theme_toggle.count() > 0: theme_toggle.first.click() time.sleep(1) page.screenshot(path='/tmp/frontend_test/08_dark_mode.png', full_page=True) print(" ✓ 暗色模式切换成功") else: # 尝试在导航栏找 nav_theme = page.locator('nav button, header button') print(f" 导航栏按钮数量: {nav_theme.count()}") for i in range(nav_theme.count()): btn_text = nav_theme.nth(i).inner_text() print(f" 按钮{i+1}: {btn_text.strip()}") print(" 未找到明确的暗色模式切换按钮") # 12. 最终状态截图 print("\n[测试12] 最终状态截图") page.screenshot(path='/tmp/frontend_test/09_final.png', full_page=True) print(" ✓ 最终截图已保存") # 打印页面标题和URL print(f"\n页面标题: {page.title()}") print(f"当前URL: {page.url}") browser.close() print("\n" + "=" * 60) print("测试完成!所有截图已保存到 /tmp/frontend_test/ 目录") print("=" * 60) if __name__ == "__main__": test_frontend()