Files
zsglpt/test_no_ui.py
zsglpt Optimizer 7e9a772104 🎉 项目优化与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环境
2026-01-16 17:39:55 +08:00

330 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()