From 72df285fed15b4ebd9de143089190d097de82e5b Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 12 Jun 2025 14:51:15 +0800 Subject: [PATCH] fix: get resultsPath --- internal/config/config.go | 13 +++-- internal/version/VERSION | 2 +- summary.go | 20 +------ uixt/ai/querier_test.go | 108 +++++++++++++++++++++++++++++++------- uixt/option/ai.go | 4 +- 5 files changed, 103 insertions(+), 44 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 89a42a11..928c9095 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -20,7 +20,6 @@ const ( type Config struct { RootDir string - ResultsDir string resultsPath string downloadsPath string screenShotsPath string @@ -48,11 +47,11 @@ func GetConfig() *Config { } startTimeStr := cfg.StartTime.Format("20060102150405") - cfg.ResultsDir = filepath.Join(ResultsDirName, startTimeStr) - cfg.resultsPath = filepath.Join(cfg.RootDir, cfg.ResultsDir) + resultsDir := filepath.Join(ResultsDirName, startTimeStr) + cfg.resultsPath = filepath.Join(cfg.RootDir, resultsDir) cfg.downloadsPath = filepath.Join(cfg.RootDir, filepath.Join(DownloadsDirName, startTimeStr)) cfg.screenShotsPath = filepath.Join(cfg.resultsPath, ScreenshotsDirName) - cfg.ActionLogFilePath = filepath.Join(cfg.ResultsDir, ActionLogDirName) + cfg.ActionLogFilePath = filepath.Join(resultsDir, ActionLogDirName) cfg.DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor" globalConfig = cfg @@ -71,7 +70,7 @@ func (c *Config) ResultsPath() string { if err := builtin.EnsureFolderExists(c.resultsPath); err != nil { log.Error().Err(err).Str("path", c.resultsPath).Msg("failed to create results directory") } else { - log.Info().Str("path", c.resultsPath).Msg("create folder") + log.Info().Str("path", c.resultsPath).Msg("created results folder") } } return c.resultsPath @@ -86,6 +85,8 @@ func (c *Config) DownloadsPath() string { if _, err := os.Stat(c.downloadsPath); os.IsNotExist(err) { if err := builtin.EnsureFolderExists(c.downloadsPath); err != nil { log.Error().Err(err).Str("path", c.downloadsPath).Msg("failed to create downloads directory") + } else { + log.Info().Str("path", c.downloadsPath).Msg("created downloads folder") } } return c.downloadsPath @@ -100,6 +101,8 @@ func (c *Config) ScreenShotsPath() string { if _, err := os.Stat(c.screenShotsPath); os.IsNotExist(err) { if err := builtin.EnsureFolderExists(c.screenShotsPath); err != nil { log.Error().Err(err).Str("path", c.screenShotsPath).Msg("failed to create screenshots directory") + } else { + log.Info().Str("path", c.screenShotsPath).Msg("created screenshots folder") } } return c.screenShotsPath diff --git a/internal/version/VERSION b/internal/version/VERSION index 0588426c..d40fdac9 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0-beta-2506111457 +v5.0.0-beta-2506121451 diff --git a/summary.go b/summary.go index 4227201e..9f7663bd 100644 --- a/summary.go +++ b/summary.go @@ -76,20 +76,8 @@ func (s *Summary) AddCaseSummary(caseSummary *TestCaseSummary) { } } -func (s *Summary) SetupDirPath() (path string, err error) { - dirPath := filepath.Join(s.rootDir, config.GetConfig().ResultsDir) - err = builtin.EnsureFolderExists(dirPath) - if err != nil { - return "", err - } - return dirPath, nil -} - func (s *Summary) GenHTMLReport() error { - reportsDir, err := s.SetupDirPath() - if err != nil { - return err - } + reportsDir := config.GetConfig().ResultsPath() // Find summary.json and hrp.log files summaryPath := filepath.Join(reportsDir, "summary.json") @@ -107,11 +95,7 @@ func (s *Summary) GenHTMLReport() error { } func (s *Summary) GenSummary() (path string, err error) { - reportsDir, err := s.SetupDirPath() - if err != nil { - return "", err - } - + reportsDir := config.GetConfig().ResultsPath() path = filepath.Join(reportsDir, "summary.json") err = builtin.Dump2JSON(s, path) if err != nil { diff --git a/uixt/ai/querier_test.go b/uixt/ai/querier_test.go index d67efc48..38ecdc00 100644 --- a/uixt/ai/querier_test.go +++ b/uixt/ai/querier_test.go @@ -2,6 +2,7 @@ package ai import ( "context" + "encoding/json" "fmt" "testing" @@ -16,12 +17,12 @@ import ( // GameInfo represents basic game information for testing type GameInfo struct { - Content string `json:"content"` // Description - Thought string `json:"thought"` // Reasoning - Rows int `json:"rows"` // Number of rows - Cols int `json:"cols"` // Number of columns - Icons []string `json:"icons"` // List of icon types - TotalIcons int `json:"totalIcons"` // Total number of icons + Content string `json:"content"` // Description + Thought string `json:"thought"` // Reasoning + Rows int `json:"rows"` // Number of rows + Cols int `json:"cols"` // Number of columns + Icons []string `json:"icons"` // List of icon types + TotalIcons int `json:"totalNumber"` // Total number of icons } // GameAnalysisResult represents comprehensive game analysis for testing @@ -72,15 +73,15 @@ type TypeCount struct { func setupTestQuerier(t *testing.T) *Querier { ctx := context.Background() - modelConfig, err := GetModelConfig(option.OPENAI_GPT_4O) + modelConfig, err := GetModelConfig(option.DOUBAO_SEED_1_6_250615) require.NoError(t, err) querier, err := NewQuerier(ctx, modelConfig) require.NoError(t, err) return querier } -func loadTestImage(t *testing.T) (string, types.Size) { - screenshot, size, err := builtin.LoadImage("testdata/llk_1.png") +func loadTestImage(t *testing.T, path string) (string, types.Size) { + screenshot, size, err := builtin.LoadImage(path) require.NoError(t, err) return screenshot, size } @@ -140,10 +141,86 @@ func TestParseQueryResult(t *testing.T) { } } +func TestModel(t *testing.T) { + // Test different models + models := []option.LLMServiceType{ + option.DOUBAO_SEED_1_6_250615, + option.DOUBAO_1_5_THINKING_VISION_PRO_250428, + option.DOUBAO_1_5_UI_TARS_250328, + option.OPENAI_GPT_4O, + } + + for _, path := range []string{"testdata/llk_1.png", "testdata/llk_4.png"} { + for _, modelType := range models { + t.Run(string(modelType), func(t *testing.T) { + modelConfig, err := GetModelConfig(modelType) + require.NoError(t, err) + querier, err := NewQuerier(context.Background(), modelConfig) + require.NoError(t, err) + + // Load test image + screenshot, size := loadTestImage(t, path) + + // Test query + opts := &QueryOptions{ + Query: "请分析这个连连看游戏界面,告诉我有多少行多少列,有哪些不同类型的图案,图案总数是多少", + Screenshot: screenshot, + Size: size, + OutputSchema: GameInfo{}, + } + + result1, err := querier.Query(context.Background(), opts) + assert.NoError(t, err) + + gameInfo, ok := result1.Data.(*GameInfo) + assert.True(t, ok) + jsonData1, _ := json.Marshal(gameInfo) + fmt.Printf("modelType: %v, gameInfo: %s\n", modelType, string(jsonData1)) + + opts2 := &QueryOptions{ + Query: `Analyze this game interface and provide structured information about: + 1. The type of game + 2. Grid dimensions (rows and columns) + 3. All game elements with their positions and types + 4. Statistics about element distribution`, + Screenshot: screenshot, + Size: size, + OutputSchema: GameAnalysisResult{}, + } + + result2, err := querier.Query(context.Background(), opts2) + assert.NoError(t, err) + + // Verify structured data + gameAnalysisResult, ok := result2.Data.(*GameAnalysisResult) + assert.True(t, ok) + jsonData2, _ := json.Marshal(gameAnalysisResult) + fmt.Printf("modelType: %v, gameAnalysisResult: %s\n", modelType, string(jsonData2)) + + opts3 := &QueryOptions{ + Query: "给出第一个苹果的坐标", + Screenshot: screenshot, + Size: size, + OutputSchema: BoundingBox{}, + } + + result3, err := querier.Query(context.Background(), opts3) + assert.NoError(t, err) + + boxInfo, ok := result3.Data.(*BoundingBox) + assert.True(t, ok) + jsonData3, _ := json.Marshal(boxInfo) + fmt.Printf("modelType: %v, thought: %v, boxInfo: %s\n", + modelType, result3.Thought, string(jsonData3)) + }) + } + } +} + // TestQueryFunctionality tests both basic and custom schema query functionality func TestQueryFunctionality(t *testing.T) { querier := setupTestQuerier(t) - screenshot, size := loadTestImage(t) + screenshot, size := loadTestImage(t, "testdata/llk_1.png") t.Run("BasicQuery", func(t *testing.T) { opts := &QueryOptions{ @@ -172,10 +249,6 @@ func TestQueryFunctionality(t *testing.T) { result, err := querier.Query(context.Background(), opts) assert.NoError(t, err) - assert.NotNil(t, result) - assert.NotEmpty(t, result.Content) - assert.NotEmpty(t, result.Thought) - assert.NotNil(t, result.Data) // Should contain structured data // Verify structured data gameInfo, ok := result.Data.(*GameInfo) @@ -204,11 +277,8 @@ func TestQueryFunctionality(t *testing.T) { result, err := querier.Query(context.Background(), opts) assert.NoError(t, err) - assert.NotNil(t, result) - assert.NotEmpty(t, result.Content) - assert.NotEmpty(t, result.Thought) - assert.NotNil(t, result.Data) + // Verify structured data gameAnalysisResult, ok := result.Data.(*GameAnalysisResult) assert.True(t, ok) assert.NotNil(t, gameAnalysisResult) @@ -226,7 +296,7 @@ func TestQueryFunctionality(t *testing.T) { // TestQueryWithDifferentPrompts tests various types of queries on the same screenshot func TestQueryWithDifferentPrompts(t *testing.T) { querier := setupTestQuerier(t) - screenshot, size := loadTestImage(t) + screenshot, size := loadTestImage(t, "testdata/llk_1.png") queries := []string{ "请描述这张图片中的内容", diff --git a/uixt/option/ai.go b/uixt/option/ai.go index ce8c8265..de5bb32f 100644 --- a/uixt/option/ai.go +++ b/uixt/option/ai.go @@ -31,6 +31,7 @@ func WithCVService(service CVServiceType) AIServiceOption { type LLMServiceType string +// UI-TARS do not support function calling and json response func IS_UI_TARS(modelType LLMServiceType) bool { return modelType == DOUBAO_1_5_UI_TARS_250328 || modelType == DOUBAO_1_5_UI_TARS_250428 @@ -38,8 +39,9 @@ func IS_UI_TARS(modelType LLMServiceType) bool { const ( DOUBAO_1_5_UI_TARS_250328 LLMServiceType = "doubao-1.5-ui-tars-250328" - DOUBAO_1_5_UI_TARS_250428 LLMServiceType = "doubao-1.5-ui-tars-250428" // not support function calling and json response + DOUBAO_1_5_UI_TARS_250428 LLMServiceType = "doubao-1.5-ui-tars-250428" DOUBAO_1_5_THINKING_VISION_PRO_250428 LLMServiceType = "doubao-1.5-thinking-vision-pro-250428" + DOUBAO_SEED_1_6_250615 LLMServiceType = "doubao-seed-1.6-250615" OPENAI_GPT_4O LLMServiceType = "openai/gpt-4o" DEEPSEEK_R1_250528 LLMServiceType = "deepseek-r1-250528" )