Some checks failed
AI Web Tester CI / test (push) Has been cancelled
主要改进: - 新增统一测试器 (universal_tester.py) 支持多种测试模式 - 优化测试报告生成器,支持汇总报告和操作截图 - 增强探索器 DFS 算法和状态指纹识别 - 新增智能测试配置 (smart_test.yaml) - 改进 AI 模型集成 (GLM/Gemini 支持) - 添加开发调试工具和文档
206 lines
7.7 KiB
Python
206 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
增强的零配置测试 - 支持无AI模式
|
||
"""
|
||
|
||
import sys
|
||
sys.path.insert(0, ".")
|
||
|
||
from src import WebTester
|
||
import time
|
||
|
||
def smart_test(url: str, model: str = "glm", headless: bool = False, auto_login: bool = True):
|
||
"""
|
||
智能测试,即使AI失败也能继续
|
||
"""
|
||
|
||
print("=" * 60)
|
||
print("🤖 增强智能测试")
|
||
print("=" * 60)
|
||
print(f"🌐 目标URL: {url}")
|
||
print(f"🤖 AI模型: {model}")
|
||
print(f"🖥️ 无头模式: {'是' if headless else '否'}")
|
||
print(f"🔐 自动登录: {'是' if auto_login else '否'}")
|
||
print("-" * 60)
|
||
|
||
tester = WebTester(model=model, headless=headless)
|
||
|
||
try:
|
||
# 启动并导航
|
||
tester.start()
|
||
tester.goto(url)
|
||
time.sleep(2) # 等待页面加载
|
||
|
||
# 步骤1: 处理登录
|
||
current_url = tester.browser.page.url
|
||
print(f"\n📍 当前URL: {current_url}")
|
||
|
||
# 检查是否需要登录
|
||
need_login = ("login" in current_url.lower() or
|
||
tester.browser.page.locator("input[type='password']").count() > 0)
|
||
|
||
if need_login and auto_login:
|
||
print("\n🔐 检测到登录页面,尝试登录...")
|
||
|
||
# 方法1: 尝试AI登录(如果API可用)
|
||
login_success = False
|
||
try:
|
||
result = tester.test("输入用户名admin和密码password,点击登录按钮")
|
||
time.sleep(3)
|
||
new_url = tester.browser.page.url
|
||
if new_url != current_url and "login" not in new_url.lower():
|
||
print(" ✅ AI登录成功")
|
||
login_success = True
|
||
except Exception as e:
|
||
print(f" ⚠️ AI登录失败: {str(e)[:50]}...")
|
||
|
||
# 方法2: 如果AI失败,使用DOM直接登录
|
||
if not login_success:
|
||
print(" 🔄 尝试直接登录...")
|
||
try:
|
||
# 查找用户名和密码输入框
|
||
page = tester.browser.page
|
||
|
||
# 尝试多种可能的用户名输入框
|
||
username_selectors = [
|
||
"input[placeholder*='用户名']",
|
||
"input[placeholder*='账号']",
|
||
"input[name='username']",
|
||
"input[name='account']",
|
||
"input[type='text']"
|
||
]
|
||
|
||
username_input = None
|
||
for selector in username_selectors:
|
||
if page.locator(selector).count() > 0:
|
||
username_input = page.locator(selector).first
|
||
break
|
||
|
||
# 尝试多种可能的密码输入框
|
||
password_selectors = [
|
||
"input[type='password']",
|
||
"input[placeholder*='密码']",
|
||
"input[name='password']"
|
||
]
|
||
|
||
password_input = None
|
||
for selector in password_selectors:
|
||
if page.locator(selector).count() > 0:
|
||
password_input = page.locator(selector).first
|
||
break
|
||
|
||
# 填写并提交
|
||
if username_input and password_input:
|
||
username_input.fill("admin")
|
||
password_input.fill("password")
|
||
|
||
# 查找登录按钮
|
||
login_selectors = [
|
||
"button:has-text('登录')",
|
||
"button:has-text('登陆')",
|
||
"button:has-text('确定')",
|
||
"input[type='submit']",
|
||
".login-btn"
|
||
]
|
||
|
||
for selector in login_selectors:
|
||
if page.locator(selector).count() > 0:
|
||
page.locator(selector).first.click()
|
||
break
|
||
|
||
time.sleep(3)
|
||
new_url = tester.browser.page.url
|
||
if new_url != current_url:
|
||
print(" ✅ 直接登录成功")
|
||
login_success = True
|
||
except Exception as e:
|
||
print(f" ❌ 直接登录失败: {e}")
|
||
|
||
if not login_success:
|
||
print(" ⚠️ 无法自动登录,将测试登录页面功能")
|
||
|
||
# 步骤2: 开始探索
|
||
print("\n🔍 开始智能探索...")
|
||
|
||
# 根据是否登录成功调整探索策略
|
||
if login_success:
|
||
explore_config = {
|
||
"max_depth": 5,
|
||
"max_clicks": 100,
|
||
"focus_patterns": ["管理", "查询", "新增", "详情"],
|
||
"dangerous_patterns": ["删除", "退出", "注销"]
|
||
}
|
||
else:
|
||
explore_config = {
|
||
"max_depth": 2,
|
||
"max_clicks": 20,
|
||
"focus_patterns": ["登录", "用户", "密码"],
|
||
"dangerous_patterns": []
|
||
}
|
||
|
||
# 尝试AI探索,如果失败则使用DOM探索
|
||
try:
|
||
explore_result = tester.explore(explore_config)
|
||
print(" ✅ AI探索完成")
|
||
except Exception as e:
|
||
print(f" ⚠️ AI探索失败: {str(e)[:50]}...")
|
||
print(" 🔄 使用基础探索...")
|
||
|
||
# 基础探索:点击所有可见的按钮和链接
|
||
page = tester.browser.page
|
||
clickable_elements = page.locator("button, a, [role='button'], input[type='button']")
|
||
|
||
clicked_count = 0
|
||
for i in range(min(clickable_elements.count(), 10)):
|
||
try:
|
||
element = clickable_elements.nth(i)
|
||
if element.is_visible():
|
||
text = element.inner_text()[:20]
|
||
print(f" 点击: {text or '无文本'}")
|
||
element.click()
|
||
time.sleep(1)
|
||
page.go_back()
|
||
time.sleep(1)
|
||
clicked_count += 1
|
||
except:
|
||
continue
|
||
|
||
print(f" 📊 基础探索完成,点击了 {clicked_count} 个元素")
|
||
|
||
# 步骤3: 生成测试报告
|
||
print("\n📊 测试总结:")
|
||
print(f" ✅ 测试完成")
|
||
print(f" 📄 已访问页面: {tester.browser.page.url}")
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"\n❌ 测试失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
finally:
|
||
tester.stop()
|
||
|
||
def main():
|
||
import argparse
|
||
|
||
parser = argparse.ArgumentParser(description="增强智能测试工具")
|
||
parser.add_argument("url", help="要测试的网站URL")
|
||
parser.add_argument("--model", default="glm",
|
||
choices=["claude", "openai", "glm", "mimo"],
|
||
help="AI模型")
|
||
parser.add_argument("--headless", action="store_true",
|
||
help="无头模式")
|
||
parser.add_argument("--no-login", action="store_true",
|
||
help="跳过自动登录")
|
||
|
||
args = parser.parse_args()
|
||
|
||
# 运行测试
|
||
success = smart_test(args.url, args.model, args.headless, not args.no_login)
|
||
sys.exit(0 if success else 1)
|
||
|
||
if __name__ == "__main__":
|
||
main()
|