package collect import ( "context" "fmt" "geo/internal/collect" "geo/internal/config" "log" "os" "strings" "testing" "github.com/go-rod/rod/lib/proto" ) var ( cfg, _ = config.LoadConfig() logger = log.New(os.Stdout, "", log.LstdFlags) manager = collect.NewCollectManager(context.Background(), cfg, logger) ) // TestCollectManager_Basic 测试收集管理器的基本功能 func TestCollectManager_Basic(t *testing.T) { // 测试列出平台 platforms := manager.ListPlatforms() t.Logf("支持的平台: %v", platforms) if len(platforms) != 4 { t.Errorf("期望4个平台,实际: %d", len(platforms)) } // 测试获取收集器 for _, platform := range platforms { params := &collect.CollectParams{ Headless: true, UserIndex: "test_user", PlatIndex: platform, RequestID: "test_req", Platform: platform, } collector, err := manager.GetCollector(platform, params) if err != nil { t.Errorf("获取%s收集器失败: %v", platform, err) continue } if collector == nil { t.Errorf("%s收集器为nil", platform) } t.Logf("成功创建%s收集器", platform) } } // TestWenxinCollector_WaitLogin 测试文心一言登录功能 func TestWenxinCollector_WaitLogin(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } params := &collect.CollectParams{ Headless: false, // 显示浏览器窗口以便扫码登录 UserIndex: "test_user", PlatIndex: "wenxin", RequestID: "test_wenxin_login_001", Platform: "wenxin", } t.Log("开始测试文心一言登录...") t.Log("请在打开的浏览器窗口中完成百度账号登录(扫码或输入账号密码)") success, msg := manager.WaitLogin("wenxin", params) if !success { t.Errorf("文心一言登录失败: %s", msg) return } t.Logf("文心一言登录成功: %s", msg) t.Log("Cookie已保存,后续测试可以使用已登录状态") } // TestWenxinCollector_SimpleAsk 简单测试文心一言提问 func TestWenxinCollector_SimpleAsk(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } params := &collect.CollectParams{ Headless: false, // 显示浏览器以便观察 UserIndex: "test_user", PlatIndex: "wenxin", RequestID: "test_wenxin_simple_001", Platform: "wenxin", } t.Log("=== 简单测试文心一言提问 ===") // 获取收集器 collector, err := manager.GetCollector("wenxin", params) if err != nil { t.Fatalf("获取收集器失败: %v", err) } wenxinCollector := collector.(*collect.WenxinCollector) // 初始化浏览器 if err := wenxinCollector.SetupDriver(); err != nil { t.Fatalf("启动浏览器失败: %v", err) } defer wenxinCollector.Close() // 加载Cookie if err := wenxinCollector.LoadCookies(); err != nil { t.Logf("未找到Cookie文件: %v", err) } // 导航到聊天页面 wenxinCollector.Page.MustNavigate(wenxinCollector.ChatURL) wenxinCollector.Sleep(5) // 检查登录状态 isLoggedIn := wenxinCollector.CheckLoginStatus() t.Logf("登录状态: %v", isLoggedIn) if !isLoggedIn { t.Fatal("未登录,请先调用WaitLogin登录") } // 手动输入问题 question := "你好" t.Logf("准备输入问题: %s", question) // 查找输入框 inputBox, err := wenxinCollector.WaitForElementVisible("[contenteditable='true']", 10) if err != nil { t.Fatalf("未找到输入框: %v", err) } t.Log("✓ 找到输入框") // 点击输入框 inputBox.Click(proto.InputMouseButtonLeft, 1) wenxinCollector.SleepMs(500) // 清空输入框 wenxinCollector.ClearInput(inputBox) wenxinCollector.SleepMs(300) // 使用键盘输入 t.Log("正在输入问题...") inputBox.Input(question) wenxinCollector.SleepMs(1000) t.Log("✓ 问题已输入") // 查找并点击发送按钮 sendBtn, err := wenxinCollector.Page.Element("button") if err != nil { t.Fatalf("未找到发送按钮: %v", err) } t.Log("✓ 找到发送按钮") t.Log("正在点击发送按钮...") sendBtn.Click(proto.InputMouseButtonLeft, 1) wenxinCollector.SleepMs(3000) t.Log("✓ 已点击发送按钮") t.Log("\n请观察浏览器窗口,查看是否成功发送问题并收到回答") t.Log("测试将在10秒后结束...") wenxinCollector.Sleep(10) t.Log("=== 测试完成 ===") } // TestWenxinCollector_AskQuestion 测试文心一言提问功能 // 注意:此测试需要有效的登录状态 func TestWenxinCollector_AskQuestion(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } // 设置收集参数 params := &collect.CollectParams{ Headless: false, // 显示浏览器以便调试 UserIndex: "test_user", PlatIndex: "wenxin", RequestID: "test_wenxin_001", Platform: "wenxin", } // 定义提问内容 question := "请用一句话介绍Go语言" t.Logf("向文心一言提问: %s", question) // 调用管理器提问并获取答案 answer, err := manager.AskQuestion("wenxin", params, question) if err != nil { t.Errorf("提问失败: %v", err) return } t.Logf("获取到答案:\n%s", answer) // 验证答案非空 if len(answer) == 0 { t.Error("答案为空") } } // TestMultiplePlatforms_Compare 测试多平台对比 func TestMultiplePlatforms_Compare(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } question := "什么是人工智能?" platforms := []string{"wenxin", "deepseek"} results := make(map[string]string) for _, platform := range platforms { params := &collect.CollectParams{ Headless: true, UserIndex: "test_user", PlatIndex: platform, RequestID: fmt.Sprintf("test_%s", platform), Platform: platform, } t.Logf("正在向%s提问...", platform) answer, err := manager.AskQuestion(platform, params, question) if err != nil { t.Logf("%s提问失败: %v", platform, err) results[platform] = fmt.Sprintf("错误: %v", err) continue } results[platform] = answer t.Logf("%s回答完成,长度: %d", platform, len(answer)) } // 输出对比结果 t.Log("\n===== 多平台回答对比 =====") for platform, answer := range results { t.Logf("\n[%s]:\n%s\n", platform, answer) } } // TestWenxinCollector_DebugPageStructure 调试页面结构 func TestWenxinCollector_DebugPageStructure(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } params := &collect.CollectParams{ Headless: false, UserIndex: "test_user", PlatIndex: "wenxin", RequestID: "test_wenxin_debug_001", Platform: "wenxin", } t.Log("=== 调试文心一言页面结构 ===") // 获取收集器 collector, err := manager.GetCollector("wenxin", params) if err != nil { t.Fatalf("获取收集器失败: %v", err) } wenxinCollector := collector.(*collect.WenxinCollector) if err := wenxinCollector.SetupDriver(); err != nil { t.Fatalf("启动浏览器失败: %v", err) } defer wenxinCollector.Close() // 加载Cookie if err := wenxinCollector.LoadCookies(); err != nil { t.Logf("未找到Cookie文件: %v", err) } // 导航到聊天页面 wenxinCollector.Page.MustNavigate(wenxinCollector.ChatURL) wenxinCollector.Sleep(5) // 检查登录状态 isLoggedIn := wenxinCollector.CheckLoginStatus() t.Logf("登录状态: %v", isLoggedIn) if !isLoggedIn { t.Fatal("未登录,请先调用WaitLogin登录") } // 查找所有可能的输入框 t.Log("\n=== 查找输入框 ===") inputSelectors := []string{ "textarea", "[contenteditable='true']", "input[type='text']", ".input-box", "#chat-input", "[placeholder]", } for _, selector := range inputSelectors { elements, err := wenxinCollector.Page.Elements(selector) if err == nil && len(elements) > 0 { t.Logf("✓ 找到 %d 个元素: %s", len(elements), selector) for i, elem := range elements { if i >= 3 { break // 只显示前3个 } text, _ := elem.Text() tagName, _ := elem.Property("tagName") class, _ := elem.Attribute("class") id, _ := elem.Attribute("id") placeholder, _ := elem.Attribute("placeholder") idStr := "" if id != nil { idStr = *id } classStr := "" if class != nil { classStr = *class } placeholderStr := "" if placeholder != nil { placeholderStr = *placeholder } t.Logf(" [%d] tag=%s, id=%s, class=%s, placeholder=%s, text=%s", i, tagName.Str(), idStr, classStr, placeholderStr, text[:min(50, len(text))]) } } else { t.Logf("✗ 未找到元素: %s", selector) } } // 查找所有按钮 t.Log("\n=== 查找发送按钮 ===") buttonSelectors := []string{ "button", "svg", "[aria-label]", } for _, selector := range buttonSelectors { elements, err := wenxinCollector.Page.Elements(selector) if err == nil && len(elements) > 0 { t.Logf("✓ 找到 %d 个元素: %s", len(elements), selector) for i, elem := range elements { if i >= 5 { break } text, _ := elem.Text() tagName, _ := elem.Property("tagName") class, _ := elem.Attribute("class") ariaLabel, _ := elem.Attribute("aria-label") ariaLabelText := "" if ariaLabel != nil { ariaLabelText = *ariaLabel } classStr := "" if class != nil { classStr = *class } trimmedText := strings.TrimSpace(text) if trimmedText != "" || ariaLabelText != "" { t.Logf(" [%d] tag=%s, class=%s, aria-label=%s, text=%s", i, tagName.Str(), classStr, ariaLabelText, trimmedText[:min(30, len(trimmedText))]) } } } } t.Log("\n=== 调试完成 ===") t.Log("请保持浏览器窗口打开,手动检查页面结构") // 等待用户观察 select {} } // TestWenxinCollector_DebugAnswer 调试答案区域 func TestWenxinCollector_DebugAnswer(t *testing.T) { if testing.Short() { t.Skip("跳过需要浏览器交互的测试") } params := &collect.CollectParams{ Headless: false, UserIndex: "test_user", PlatIndex: "wenxin", RequestID: "test_wenxin_debug_answer", Platform: "wenxin", } t.Log("=== 调试文心一言答案区域 ===") collector, err := manager.GetCollector("wenxin", params) if err != nil { t.Fatalf("获取收集器失败: %v", err) } wenxinCollector := collector.(*collect.WenxinCollector) if err := wenxinCollector.SetupDriver(); err != nil { t.Fatalf("启动浏览器失败: %v", err) } defer wenxinCollector.Close() if err := wenxinCollector.LoadCookies(); err != nil { t.Logf("未找到Cookie文件: %v", err) } wenxinCollector.Page.MustNavigate(wenxinCollector.ChatURL) wenxinCollector.Sleep(5) if !wenxinCollector.CheckLoginStatus() { t.Fatal("未登录") } // 手动输入问题并发送 t.Log("请在浏览器中手动输入问题并等待AI回答完成") t.Log("然后按回车键继续...") fmt.Scanln() // 查找所有可能的答案容器 t.Log("\n=== 查找答案容器 ===") // 方式1: 查找包含answer/response/message的元素 containers, _ := wenxinCollector.Page.Elements("[class*='answer'], [class*='response'], [class*='message']") t.Logf("找到 %d 个容器元素", len(containers)) for i, container := range containers { text, _ := container.Text() classAttr, _ := container.Attribute("class") tagName, _ := container.Property("tagName") classStr := "" if classAttr != nil { classStr = *classAttr } if len(strings.TrimSpace(text)) > 20 { t.Logf("[%d] tag=%s, class=%s, text长度=%d, 前100字符=%s", i, tagName.Str(), classStr, len(text), text[:min(100, len(text))]) } } // 方式2: 查找所有div,显示较长的文本 t.Log("\n=== 查找长文本div ===") allDivs, _ := wenxinCollector.Page.Elements("div") var longTextDivs []struct{ index int text string class string } for i, div := range allDivs { text, _ := div.Text() if len(strings.TrimSpace(text)) > 50 { classAttr, _ := div.Attribute("class") classStr := "" if classAttr != nil { classStr = *classAttr } longTextDivs = append(longTextDivs, struct{ index int text string class string }{i, text, classStr}) } } t.Logf("找到 %d 个长文本div", len(longTextDivs)) for _, item := range longTextDivs { t.Logf("[%d] class=%s, 长度=%d, 前150字符=%s", item.index, item.class, len(item.text), item.text[:min(150, len(item.text))]) } t.Log("\n=== 调试完成,请保持浏览器打开以便观察 ===") select {} } // BenchmarkWenxinCollector 性能测试(仅供参考) func BenchmarkWenxinCollector(b *testing.B) { b.Skip("跳过性能测试") } // ExampleCollectManager 使用示例 func ExampleCollectManager() { // 列出支持的平台 platforms := manager.ListPlatforms() fmt.Printf("支持的平台: %v\n", platforms) // 设置参数 params := &collect.CollectParams{ Headless: true, UserIndex: "user_001", PlatIndex: "wenxin", RequestID: "req_001", Platform: "wenxin", } // 向文心一言提问 answer, err := manager.AskQuestion("wenxin", params, "什么是人工智能?") if err != nil { fmt.Printf("错误: %v\n", err) return } fmt.Printf("答案: %s\n", answer) } // ExampleWenxinCollector_WaitLogin 文心一言登录示例 func ExampleWenxinCollector_WaitLogin() { params := &collect.CollectParams{ Headless: false, // 登录时需要显示浏览器 UserIndex: "user_001", PlatIndex: "wenxin", RequestID: "example_login_001", Platform: "wenxin", } fmt.Println("正在打开文心一言登录页面...") success, msg := manager.WaitLogin("wenxin", params) if success { fmt.Printf("登录成功: %s\n", msg) fmt.Println("Cookie已保存,下次可以自动登录") } else { fmt.Printf("登录失败: %s\n", msg) } }