#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 金山文档上传测试 - 顺序执行版本 单线程顺序执行,最稳定 """ 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_for_user(): """等待用户按回车""" input("\n按Enter键继续...") def main(): """主函数 - 顺序执行所有测试""" print("=" * 70) print("[LOCK] 金山文档上传测试 - 顺序执行版本") print("=" * 70) print() print("此工具将按顺序执行以下测试:") print(" 1. 启动浏览器") print(" 2. 打开金山文档") print(" 3. 测试表格读取") print(" 4. 测试人员搜索") print(" 5. 测试图片上传(可选)") 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() # 变量初始化 playwright = None browser = None context = None page = None try: # ========== 测试1: 启动浏览器 ========== log("=" * 50) log("测试1: 启动浏览器") log("=" * 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') print() log("测试1完成 [OK]", 'SUCCESS') pause_for_user() # ========== 测试2: 打开文档 ========== log("=" * 50) log("测试2: 打开金山文档") log("=" * 50) log(f"正在导航到: {doc_url}", 'INFO') page.goto(doc_url, wait_until='domcontentloaded') log("[OK] 页面导航完成", 'SUCCESS') log("等待3秒让页面完全加载...", 'INFO') time.sleep(3) current_url = page.url log(f"当前URL: {current_url}", 'INFO') if "kdocs.cn" in current_url: log("[OK] 已成功进入金山文档", 'SUCCESS') else: log("⚠ 当前不在金山文档域名", 'WARNING') # 检查登录状态 try: login_visible = page.locator("text=登录").first.is_visible() if login_visible: log("⚠ 检测到登录页面,可能需要扫码登录", 'WARNING') else: log("[OK] 未检测到登录提示", 'SUCCESS') except: pass print() log("测试2完成 [OK]", 'SUCCESS') pause_for_user() # ========== 测试3: 表格读取 ========== log("=" * 50) log("测试3: 表格读取测试") log("=" * 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') print() log("测试3完成 [OK]", 'SUCCESS') pause_for_user() # ========== 测试4: 人员搜索 ========== log("=" * 50) log("测试4: 人员搜索测试") log("=" * 50) test_name = input("请输入要搜索的姓名 (默认: 张三): ").strip() if not test_name: test_name = "张三" log(f"搜索姓名: {test_name}", 'INFO') try: log("打开搜索框 (Ctrl+F)...", 'INFO') page.keyboard.press("Control+f") time.sleep(0.5) log(f"输入搜索内容: {test_name}", 'INFO') page.keyboard.type(test_name) time.sleep(0.3) log("执行搜索 (Enter)...", 'INFO') page.keyboard.press("Enter") time.sleep(1) log("关闭搜索框 (Escape)...", 'INFO') page.keyboard.press("Escape") time.sleep(0.3) log("[OK] 人员搜索测试完成", 'SUCCESS') log("请查看浏览器窗口,检查是否高亮显示了搜索结果", 'INFO') except Exception as e: log(f"✗ 搜索测试失败: {str(e)}", 'ERROR') print() log("测试4完成 [OK]", 'SUCCESS') pause_for_user() # ========== 测试5: 图片上传(可选) ========== log("=" * 50) log("测试5: 图片上传测试") log("=" * 50) print() upload_test = input("是否进行图片上传测试? (y/N): ").strip().lower() if upload_test == 'y': # 让用户选择图片 from tkinter import filedialog import tkinter as tk root = tk.Tk() root.withdraw() # 隐藏主窗口 image_path = filedialog.askopenfilename( title="选择测试图片", filetypes=[("图片文件", "*.jpg *.jpeg *.png *.gif")] ) root.destroy() if image_path: log(f"选中的图片: {image_path}", 'INFO') try: # 导航到D3单元格 log("导航到 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("点击插入按钮...", 'INFO') insert_btn = page.locator("text=插入").first insert_btn.click() time.sleep(0.5) # 点击图片选项 log("点击图片选项...", 'INFO') image_btn = page.locator("text=图片").first image_btn.click() time.sleep(0.5) # 选择本地图片 log("选择本地图片...", 'INFO') local_option = page.locator("text=本地").first local_option.click() # 上传文件 log("上传文件...", 'INFO') with page.expect_file_chooser() as fc_info: pass file_chooser = fc_info.value file_chooser.set_files(image_path) time.sleep(2) # 等待上传完成 log("[OK] 图片上传测试完成", 'SUCCESS') log("请检查浏览器窗口,确认图片已上传到D3单元格", 'INFO') except Exception as e: log(f"✗ 图片上传测试失败: {str(e)}", 'ERROR') else: log("未选择图片,跳过上传测试", 'WARNING') else: log("跳过图片上传测试", 'INFO') print() log("测试5完成 [OK]", 'SUCCESS') # ========== 测试完成 ========== log("=" * 70) log("所有测试完成!", 'SUCCESS') log("=" * 70) print() log("总结:", 'INFO') log("1. [OK] 浏览器启动 - 成功", 'SUCCESS') log("2. [OK] 文档打开 - 成功", 'SUCCESS') log("3. [OK] 表格读取 - 成功", 'SUCCESS') log("4. [OK] 人员搜索 - 成功", 'SUCCESS') if upload_test == 'y': log("5. [OK] 图片上传 - 已测试", 'SUCCESS') else: log("5. ⊝ 图片上传 - 已跳过", 'INFO') print() log("所有功能测试完成,浏览器窗口保持打开状态", 'INFO') log("您可以手动关闭浏览器窗口来结束测试", 'INFO') except KeyboardInterrupt: log("\n测试被用户中断", 'WARNING') except Exception as e: log(f"\n测试过程中出现错误: {str(e)}", 'ERROR') import traceback traceback.print_exc() finally: # 清理资源 print("\n" + "=" * 70) log("正在清理资源...", 'INFO') 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') if __name__ == "__main__": main()