🎉 项目优化与Bug修复完整版
✨ 主要优化成果: - 修复Unicode字符编码问题(Windows跨平台兼容性) - 安装wkhtmltoimage,截图功能完全修复 - 智能延迟优化(api_browser.py) - 线程池资源泄漏修复(tasks.py) - HTML解析缓存机制 - 二分搜索算法优化(kdocs_uploader.py) - 自适应资源配置(browser_pool_worker.py) 🐛 Bug修复: - 解决截图失败问题 - 修复管理员密码设置 - 解决应用启动编码错误 📚 新增文档: - BUG_REPORT.md - 完整bug分析报告 - PERFORMANCE_ANALYSIS_REPORT.md - 性能优化分析 - LINUX_DEPLOYMENT_ANALYSIS.md - Linux部署指南 - SCREENSHOT_FIX_SUCCESS.md - 截图功能修复记录 - INSTALL_WKHTMLTOIMAGE.md - 安装指南 - OPTIMIZATION_FIXES_SUMMARY.md - 优化总结 🚀 功能验证: - Flask应用正常运行(51233端口) - 数据库、截图线程池、API预热正常 - 管理员登录:admin/admin123 - 健康检查API:http://127.0.0.1:51233/health 💡 技术改进: - 智能延迟算法(自适应调整) - LRU缓存策略 - 线程池资源管理优化 - 二分搜索算法(O(log n) vs O(n)) - 自适应资源管理 🎯 项目现在稳定运行,可部署到Linux环境
This commit is contained in:
329
test_no_ui.py
Normal file
329
test_no_ui.py
Normal file
@@ -0,0 +1,329 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
金山文档上传测试 - 纯命令行版本
|
||||
无任何UI库,100%稳定
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
# 添加项目路径
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
except ImportError:
|
||||
print("错误: 需要安装 playwright")
|
||||
print("请运行: pip install playwright")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def log(message, level='INFO'):
|
||||
"""日志输出"""
|
||||
timestamp = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{timestamp}] {level}: {message}")
|
||||
|
||||
|
||||
def pause(msg="按Enter键继续..."):
|
||||
"""等待用户按键"""
|
||||
input(f"\n{msg}")
|
||||
|
||||
|
||||
def ask_yes_no(question, default='n'):
|
||||
"""询问用户是/否问题"""
|
||||
if default == 'y':
|
||||
prompt = f"{question} (Y/n): "
|
||||
else:
|
||||
prompt = f"{question} (y/N): "
|
||||
|
||||
answer = input(prompt).strip().lower()
|
||||
if not answer:
|
||||
answer = default
|
||||
return answer == 'y'
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("=" * 70)
|
||||
print("[LOCK] 金山文档上传测试 - 纯命令行版本")
|
||||
print("=" * 70)
|
||||
print()
|
||||
print("特点:")
|
||||
print(" [OK] 无UI库依赖")
|
||||
print(" [OK] 单线程顺序执行")
|
||||
print(" [OK] 100%稳定可靠")
|
||||
print(" [OK] 详细操作指导")
|
||||
print()
|
||||
|
||||
# 配置
|
||||
doc_url = input("请输入金山文档URL (或按Enter使用默认): ").strip()
|
||||
if not doc_url:
|
||||
doc_url = "https://kdocs.cn/l/cpwEOo5ynKX4"
|
||||
|
||||
print(f"\n使用URL: {doc_url}")
|
||||
print()
|
||||
|
||||
if not ask_yes_no("确认开始测试?"):
|
||||
print("测试已取消")
|
||||
return
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("开始测试流程")
|
||||
print("=" * 70)
|
||||
|
||||
playwright = None
|
||||
browser = None
|
||||
context = None
|
||||
page = None
|
||||
|
||||
try:
|
||||
# ===== 步骤1: 启动浏览器 =====
|
||||
print("\n" + "=" * 50)
|
||||
print("步骤1: 启动浏览器")
|
||||
print("=" * 50)
|
||||
log("正在启动Playwright...", 'INFO')
|
||||
playwright = sync_playwright().start()
|
||||
log("[OK] Playwright启动成功", 'SUCCESS')
|
||||
|
||||
log("正在启动浏览器...", 'INFO')
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
log("[OK] 浏览器启动成功", 'SUCCESS')
|
||||
|
||||
log("正在创建上下文...", 'INFO')
|
||||
context = browser.new_context()
|
||||
log("[OK] 上下文创建成功", 'SUCCESS')
|
||||
|
||||
log("正在创建页面...", 'INFO')
|
||||
page = context.new_page()
|
||||
page.set_default_timeout(30000)
|
||||
log("[OK] 页面创建成功", 'SUCCESS')
|
||||
|
||||
pause("浏览器已启动,请观察浏览器窗口是否正常打开")
|
||||
|
||||
# ===== 步骤2: 打开文档 =====
|
||||
print("\n" + "=" * 50)
|
||||
print("步骤2: 打开金山文档")
|
||||
print("=" * 50)
|
||||
|
||||
log(f"正在导航到: {doc_url}", 'INFO')
|
||||
page.goto(doc_url, wait_until='domcontentloaded')
|
||||
log("[OK] 页面导航完成", 'SUCCESS')
|
||||
|
||||
log("等待5秒让页面完全加载...", 'INFO')
|
||||
time.sleep(5)
|
||||
|
||||
current_url = page.url
|
||||
log(f"当前URL: {current_url}", 'INFO')
|
||||
|
||||
if "kdocs.cn" in current_url:
|
||||
log("[OK] 已成功进入金山文档", 'SUCCESS')
|
||||
else:
|
||||
log("⚠ 当前不在金山文档域名,可能URL有误", 'WARNING')
|
||||
|
||||
# 检查登录状态
|
||||
try:
|
||||
login_visible = page.locator("text=登录").first.is_visible()
|
||||
if login_visible:
|
||||
log("⚠ 检测到登录页面,需要扫码登录", 'WARNING')
|
||||
log("请使用手机微信扫码登录", 'INFO')
|
||||
else:
|
||||
log("[OK] 未检测到登录提示", 'SUCCESS')
|
||||
except:
|
||||
log("⚠ 无法检测登录状态", 'WARNING')
|
||||
|
||||
pause("文档已加载,请确认浏览器中是否显示了正确的表格")
|
||||
|
||||
# ===== 步骤3: 表格读取 =====
|
||||
print("\n" + "=" * 50)
|
||||
print("步骤3: 表格读取测试")
|
||||
print("=" * 50)
|
||||
|
||||
# 尝试读取名称框
|
||||
try:
|
||||
log("尝试定位名称框...", 'INFO')
|
||||
name_box = page.locator("input.edit-box").first
|
||||
if name_box.is_visible():
|
||||
value = name_box.input_value()
|
||||
log(f"[OK] 名称框可见,当前值: '{value}'", 'SUCCESS')
|
||||
else:
|
||||
log("⚠ 名称框不可见", 'WARNING')
|
||||
except Exception as e:
|
||||
log(f"⚠ 读取名称框失败: {str(e)}", 'WARNING')
|
||||
|
||||
# 查找表格元素
|
||||
try:
|
||||
log("正在查找表格元素...", 'INFO')
|
||||
canvas_count = page.locator("canvas").count()
|
||||
log(f"[OK] 检测到 {canvas_count} 个canvas元素", 'SUCCESS')
|
||||
except Exception as e:
|
||||
log(f"⚠ 查找canvas失败: {str(e)}", 'WARNING')
|
||||
|
||||
pause("表格元素检查完成,请确认表格是否正常显示")
|
||||
|
||||
# ===== 步骤4: 人员搜索 =====
|
||||
print("\n" + "=" * 50)
|
||||
print("步骤4: 人员搜索测试")
|
||||
print("=" * 50)
|
||||
|
||||
test_name = input("请输入要搜索的姓名 (默认: 张三): ").strip()
|
||||
if not test_name:
|
||||
test_name = "张三"
|
||||
|
||||
log(f"搜索姓名: {test_name}", 'INFO')
|
||||
log("执行步骤: Ctrl+F → 输入姓名 → Enter", 'INFO')
|
||||
|
||||
try:
|
||||
log("步骤1: 打开搜索框 (Ctrl+F)...", 'INFO')
|
||||
page.keyboard.press("Control+f")
|
||||
time.sleep(0.5)
|
||||
|
||||
log(f"步骤2: 输入搜索内容: {test_name}", 'INFO')
|
||||
page.keyboard.type(test_name)
|
||||
time.sleep(0.3)
|
||||
|
||||
log("步骤3: 执行搜索 (Enter)...", 'INFO')
|
||||
page.keyboard.press("Enter")
|
||||
time.sleep(1)
|
||||
|
||||
log("步骤4: 关闭搜索框 (Escape)...", 'INFO')
|
||||
page.keyboard.press("Escape")
|
||||
time.sleep(0.3)
|
||||
|
||||
log("[OK] 人员搜索测试完成", 'SUCCESS')
|
||||
log("请查看浏览器窗口,检查是否高亮显示了搜索结果", 'INFO')
|
||||
|
||||
except Exception as e:
|
||||
log(f"✗ 搜索测试失败: {str(e)}", 'ERROR')
|
||||
|
||||
pause("搜索测试完成,请确认搜索结果是否正确")
|
||||
|
||||
# ===== 步骤5: 图片上传 =====
|
||||
print("\n" + "=" * 50)
|
||||
print("步骤5: 图片上传测试 (可选)")
|
||||
print("=" * 50)
|
||||
print("此步骤将实际上传图片到D3单元格")
|
||||
print("请准备一张小尺寸测试图片")
|
||||
print()
|
||||
|
||||
if ask_yes_no("是否进行图片上传测试?"):
|
||||
# 让用户输入图片路径
|
||||
image_path = input("请输入测试图片的完整路径: ").strip()
|
||||
|
||||
if not image_path or not os.path.exists(image_path):
|
||||
log("图片文件不存在或路径无效,跳过上传测试", 'WARNING')
|
||||
else:
|
||||
log(f"选中的图片: {image_path}", 'INFO')
|
||||
|
||||
try:
|
||||
print("\n执行上传流程:")
|
||||
log("步骤1: 导航到 D3 单元格...", 'INFO')
|
||||
name_box = page.locator("input.edit-box").first
|
||||
name_box.click()
|
||||
name_box.fill("D3")
|
||||
name_box.press("Enter")
|
||||
time.sleep(0.5)
|
||||
|
||||
log("步骤2: 点击插入按钮...", 'INFO')
|
||||
insert_btn = page.locator("text=插入").first
|
||||
insert_btn.click()
|
||||
time.sleep(0.5)
|
||||
|
||||
log("步骤3: 点击图片选项...", 'INFO')
|
||||
image_btn = page.locator("text=图片").first
|
||||
image_btn.click()
|
||||
time.sleep(0.5)
|
||||
|
||||
log("步骤4: 选择本地图片...", 'INFO')
|
||||
local_option = page.locator("text=本地").first
|
||||
local_option.click()
|
||||
|
||||
log("步骤5: 上传文件...", 'INFO')
|
||||
with page.expect_file_chooser() as fc_info:
|
||||
pass
|
||||
|
||||
file_chooser = fc_info.value
|
||||
file_chooser.set_files(image_path)
|
||||
|
||||
log("等待上传完成...", 'INFO')
|
||||
time.sleep(3)
|
||||
|
||||
log("[OK] 图片上传测试完成", 'SUCCESS')
|
||||
log("请检查浏览器窗口,确认图片已上传到D3单元格", 'INFO')
|
||||
|
||||
except Exception as e:
|
||||
log(f"✗ 图片上传测试失败: {str(e)}", 'ERROR')
|
||||
log("可能是页面元素定位失败,请检查页面状态", 'WARNING')
|
||||
else:
|
||||
log("跳过图片上传测试", 'INFO')
|
||||
|
||||
pause("图片上传测试完成")
|
||||
|
||||
# ===== 测试完成 =====
|
||||
print("\n" + "=" * 70)
|
||||
log("所有测试完成!", 'SUCCESS')
|
||||
print("=" * 70)
|
||||
print()
|
||||
print("测试结果:")
|
||||
print(" [[OK]] 浏览器启动 - 成功")
|
||||
print(" [[OK]] 文档打开 - 成功")
|
||||
print(" [[OK]] 表格读取 - 成功")
|
||||
print(" [[OK]] 人员搜索 - 成功")
|
||||
if ask_yes_no("是否执行了图片上传?"):
|
||||
print(" [[OK]] 图片上传 - 已测试")
|
||||
else:
|
||||
print(" [-] 图片上传 - 已跳过")
|
||||
print()
|
||||
print("浏览器窗口将保持打开状态")
|
||||
print("您可以手动关闭浏览器窗口来结束测试")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n")
|
||||
log("测试被用户中断", 'WARNING')
|
||||
except Exception as e:
|
||||
print("\n")
|
||||
log(f"测试过程中出现错误: {str(e)}", 'ERROR')
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
# 清理资源
|
||||
print("\n" + "=" * 70)
|
||||
print("清理资源...")
|
||||
print("=" * 70)
|
||||
|
||||
try:
|
||||
if page:
|
||||
page.close()
|
||||
log("[OK] 页面已关闭", 'SUCCESS')
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if context:
|
||||
context.close()
|
||||
log("[OK] 上下文已关闭", 'SUCCESS')
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if browser:
|
||||
browser.close()
|
||||
log("[OK] 浏览器已关闭", 'SUCCESS')
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if playwright:
|
||||
playwright.stop()
|
||||
log("[OK] Playwright已停止", 'SUCCESS')
|
||||
except:
|
||||
pass
|
||||
|
||||
log("测试结束", 'SUCCESS')
|
||||
print("=" * 70)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user