From b30461e90a67c2beb15632c2c4a25b91892984ee Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Tue, 31 Oct 2023 14:43:55 +0800 Subject: [PATCH 01/15] feat: set ocrCluster to default_1600 for live --- examples/uitest/android_follow_live_test.json | 192 ++++++++++++++++++ hrp/pkg/uixt/service_vedem.go | 4 + 2 files changed, 196 insertions(+) create mode 100644 examples/uitest/android_follow_live_test.json diff --git a/examples/uitest/android_follow_live_test.json b/examples/uitest/android_follow_live_test.json new file mode 100644 index 00000000..e1c57a25 --- /dev/null +++ b/examples/uitest/android_follow_live_test.json @@ -0,0 +1,192 @@ +{ + "config": { + "name": "直播_抖音_关注天窗_android", + "variables": { + "device": "${ENV(SerialNumber)}", + "ups": "${ENV(LIVEUPLIST)}" + }, + "android": [ + { + "serial": "$device", + "log_on": true, + "close_popup": true + } + ] + }, + "teststeps": [ + { + "name": "启动抖音", + "android": { + "actions": [ + { + "method": "app_terminate", + "params": "com.ss.android.ugc.aweme" + }, + { + "method": "app_launch", + "params": "com.ss.android.ugc.aweme" + }, + { + "method": "home" + }, + { + "method": "swipe_to_tap_app", + "params": "抖音", + "max_retry_times": 5, + "offset": [ + 0, + -50 + ] + }, + { + "method": "sleep", + "params": 20 + } + ] + } + }, + { + "name": "处理青少年弹窗", + "android": { + "actions": [ + { + "method": "tap_ocr", + "params": "我知道了", + "ignore_NotFoundError": true + } + ] + }, + "validate": [ + { + "check": "ui_ocr", + "assert": "exists", + "expect": "推荐", + "msg": "进入抖音失败" + } + ] + }, + { + "name": "点击关注", + "android": { + "actions": [ + { + "method": "tap_ocr", + "params": "关注", + "index": -1 + }, + { + "method": "sleep", + "params": 10 + } + ] + } + }, + { + "name": "点击直播标签,进入直播间", + "android": { + "actions": [ + { + "method": "swipe_to_tap_texts", + "params": "${split_by_comma($ups)}", + "identifier": "click_live", + "wait_time": 1, + "direction": [ + 0.6, + 0.2, + 0.4, + 0.2 + ], + "offset": [ + 0, + -50 + ] + } + ] + } + }, + { + "name": "等待1分钟", + "android": { + "actions": [ + { + "method": "sleep", + "params": 30 + } + ] + } + }, + { + "name": "上滑进入下一个直播间", + "android": { + "actions": [ + { + "method": "swipe", + "params": [ + 0.9, + 0.9, + 0.9, + 0.1 + ], + "identifier": "slide_in_live" + }, + { + "method": "sleep", + "params": 30 + } + ] + } + }, + { + "name": "再上滑进入下一个直播间", + "android": { + "actions": [ + { + "method": "swipe", + "params": [ + 0.9, + 0.9, + 0.9, + 0.1 + ], + "identifier": "slide_in_live" + }, + { + "method": "sleep", + "params": 30 + } + ] + } + }, + { + "name": "返回主界面,并打开本地时间戳", + "android": { + "actions": [ + { + "method": "home" + }, + { + "method": "swipe_to_tap_app", + "params": "local", + "max_retry_times": 5, + "offset": [ + 0, + -50 + ] + }, + { + "method": "sleep", + "params": 10 + } + ] + }, + "validate": [ + { + "check": "ui_ocr", + "assert": "exists", + "expect": "16", + "msg": "打开本地时间戳失败" + } + ] + } + ] +} \ No newline at end of file diff --git a/hrp/pkg/uixt/service_vedem.go b/hrp/pkg/uixt/service_vedem.go index e2c4330b..3d7c6e68 100644 --- a/hrp/pkg/uixt/service_vedem.go +++ b/hrp/pkg/uixt/service_vedem.go @@ -217,6 +217,10 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer, options ...ActionOp for _, uiType := range actionOptions.ScreenShotWithUITypes { bodyWriter.WriteField("uiTypes", uiType) } + + // 临时支持直播使用高精度集群 + bodyWriter.WriteField("ocrCluster", "default_1600") + if actionOptions.ScreenShotWithOCRCluster != "" { bodyWriter.WriteField("ocrCluster", actionOptions.ScreenShotWithOCRCluster) } From dc9310d638f9d8cd16b7351624271f148b47213f Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Tue, 31 Oct 2023 20:46:43 +0800 Subject: [PATCH 02/15] feat: compress screenshot --- hrp/internal/version/VERSION | 2 +- hrp/pkg/uixt/ext.go | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index e764e622..38b378c2 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.6.2310111458 \ No newline at end of file +v4.3.7.2310312044 \ No newline at end of file diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index 54009453..46b571c2 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -239,7 +239,9 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin return "", errors.Wrap(err, "decode screenshot image failed") } - screenshotPath := filepath.Join(fmt.Sprintf("%s.%s", fileName, format)) + // The default format uses jpeg for compression + screenshotPath := filepath.Join(fmt.Sprintf("%s.%s", fileName, "jpeg")) + // screenshotPath := filepath.Join(fmt.Sprintf("%s.%s", fileName, "jpeg")) file, err := os.Create(screenshotPath) if err != nil { return "", errors.Wrap(err, "create screenshot image file failed") @@ -249,11 +251,15 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin }() switch format { - case "png": + // Convert to jpeg uniformly and compress with a compression rate of 95 + case "jpeg", "png": + jpegOptions := &jpeg.Options{Quality: 95} + err = jpeg.Encode(file, img, jpegOptions) + case "png_import": err = png.Encode(file, img) - case "jpeg": - err = jpeg.Encode(file, img, nil) - case "gif": + // case "jpeg": + // err = jpeg.Encode(file, img, nil) + case "gif_import": err = gif.Encode(file, img, nil) default: return "", fmt.Errorf("unsupported image format: %s", format) From fb01e80153b6c05ab8fecf5fe067f5acc343552f Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Wed, 15 Nov 2023 11:20:27 +0800 Subject: [PATCH 03/15] feat: set ocr timeout to 10s --- hrp/pkg/uixt/service_vedem.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hrp/pkg/uixt/service_vedem.go b/hrp/pkg/uixt/service_vedem.go index 3d7c6e68..00e8efee 100644 --- a/hrp/pkg/uixt/service_vedem.go +++ b/hrp/pkg/uixt/service_vedem.go @@ -227,6 +227,8 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer, options ...ActionOp if actionOptions.Timeout > 0 { bodyWriter.WriteField("timeout", fmt.Sprintf("%v", actionOptions.Timeout)) + } else { + bodyWriter.WriteField("timeout", fmt.Sprintf("%v", 10)) } formWriter, err := bodyWriter.CreateFormFile("image", "screenshot.png") From c690b86f2e12ea2c1a43b2a4f19c9883405b86f9 Mon Sep 17 00:00:00 2001 From: buyuxiang Date: Thu, 23 Nov 2023 16:08:16 +0800 Subject: [PATCH 04/15] update hrp version --- hrp/internal/version/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 38b378c2..7f16698d 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.7.2310312044 \ No newline at end of file +v4.3.7.2311231600 \ No newline at end of file From b41aa6fde66b2dca51dcf8f432c733ee51eab795 Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Wed, 29 Nov 2023 21:08:06 +0800 Subject: [PATCH 05/15] fix: use log file when not found log content --- examples/uitest/android_follow_live_test.json | 130 +------- examples/uitest/demo_android_feed_swipe.json | 309 ++++++++++++------ hrp/internal/env/env.go | 17 +- hrp/pkg/uixt/android_adb_driver.go | 40 ++- hrp/runner.go | 7 + 5 files changed, 263 insertions(+), 240 deletions(-) diff --git a/examples/uitest/android_follow_live_test.json b/examples/uitest/android_follow_live_test.json index e1c57a25..3c50234c 100644 --- a/examples/uitest/android_follow_live_test.json +++ b/examples/uitest/android_follow_live_test.json @@ -25,22 +25,6 @@ { "method": "app_launch", "params": "com.ss.android.ugc.aweme" - }, - { - "method": "home" - }, - { - "method": "swipe_to_tap_app", - "params": "抖音", - "max_retry_times": 5, - "offset": [ - 0, - -50 - ] - }, - { - "method": "sleep", - "params": 20 } ] } @@ -72,121 +56,11 @@ { "method": "tap_ocr", "params": "关注", - "index": -1 - }, - { - "method": "sleep", - "params": 10 + "index": -1, + "identifier": "click_live_new" } ] } - }, - { - "name": "点击直播标签,进入直播间", - "android": { - "actions": [ - { - "method": "swipe_to_tap_texts", - "params": "${split_by_comma($ups)}", - "identifier": "click_live", - "wait_time": 1, - "direction": [ - 0.6, - 0.2, - 0.4, - 0.2 - ], - "offset": [ - 0, - -50 - ] - } - ] - } - }, - { - "name": "等待1分钟", - "android": { - "actions": [ - { - "method": "sleep", - "params": 30 - } - ] - } - }, - { - "name": "上滑进入下一个直播间", - "android": { - "actions": [ - { - "method": "swipe", - "params": [ - 0.9, - 0.9, - 0.9, - 0.1 - ], - "identifier": "slide_in_live" - }, - { - "method": "sleep", - "params": 30 - } - ] - } - }, - { - "name": "再上滑进入下一个直播间", - "android": { - "actions": [ - { - "method": "swipe", - "params": [ - 0.9, - 0.9, - 0.9, - 0.1 - ], - "identifier": "slide_in_live" - }, - { - "method": "sleep", - "params": 30 - } - ] - } - }, - { - "name": "返回主界面,并打开本地时间戳", - "android": { - "actions": [ - { - "method": "home" - }, - { - "method": "swipe_to_tap_app", - "params": "local", - "max_retry_times": 5, - "offset": [ - 0, - -50 - ] - }, - { - "method": "sleep", - "params": 10 - } - ] - }, - "validate": [ - { - "check": "ui_ocr", - "assert": "exists", - "expect": "16", - "msg": "打开本地时间戳失败" - } - ] } ] } \ No newline at end of file diff --git a/examples/uitest/demo_android_feed_swipe.json b/examples/uitest/demo_android_feed_swipe.json index c50ba576..7f8fe3bc 100644 --- a/examples/uitest/demo_android_feed_swipe.json +++ b/examples/uitest/demo_android_feed_swipe.json @@ -1,27 +1,223 @@ { "config": { - "name": "点播_抖音_滑动场景_随机间隔_android", + "name": "直播_抖极_feed卡片_android", "variables": { "device": "${ENV(SerialNumber)}" }, "android": [ { - "serial": "$device" + "serial": "$device", + "log_on": true, + "close_popup": true } ] }, "teststeps": [ { - "name": "启动抖音", + "name": "清理android无关进程", "android": { "actions": [ { "method": "app_terminate", "params": "com.ss.android.ugc.aweme" }, + { + "method": "app_terminate", + "params": "com.ss.android.ugc.aweme.lite" + }, + { + "method": "app_terminate", + "params": "com.smile.gifmaker" + }, + { + "method": "app_terminate", + "params": "com.kuaishou.nebula" + }, + { + "method": "app_terminate", + "params": "com.tencent.mm" + }, + { + "method": "app_terminate", + "params": "com.duowan.kiwi" + }, + { + "method": "app_terminate", + "params": "air.tv.douyu.android" + }, + { + "method": "app_terminate", + "params": "com.xingin.xhs" + }, + { + "method": "app_terminate", + "params": "com.taobao.taobao" + }, + { + "method": "app_terminate", + "params": "tv.danmaku.bili" + }, + { + "method": "app_terminate", + "params": "com.cmcc.cmvideo" + }, + { + "method": "app_terminate", + "params": "com.xunmeng.pinduoduo" + }, + { + "method": "app_terminate", + "params": "com.cctv.yangshipin.app.androidp" + } + ] + } + }, + { + "name": "启动抖音极速版", + "android": { + "actions": [ + { + "method": "app_terminate", + "params": "com.ss.android.ugc.aweme.lite" + }, { "method": "app_launch", - "params": "com.ss.android.ugc.aweme" + "params": "com.ss.android.ugc.aweme.lite" + }, + { + "method": "sleep", + "params": 10 + }, + { + "method": "close_popups", + "options": { + "max_retry_times": 2 + } + } + ] + }, + "validate": [ + { + "check": "ui_foreground_app", + "assert": "equal", + "expect": "com.ss.android.ugc.aweme.lite", + "msg": "app [com.ss.android.ugc.aweme.lite] should be in foreground" + } + ] + }, + { + "name": "处理通讯录弹窗", + "android": { + "actions": [ + { + "method": "tap_ocr", + "params": "拒绝", + "ignore_NotFoundError": true + } + ] + } + }, + { + "name": "处理青少年弹窗", + "android": { + "actions": [ + { + "method": "sleep", + "params": 5 + }, + { + "method": "tap_ocr", + "params": "我知道了", + "ignore_NotFoundError": true + } + ] + } + }, + { + "name": "点击直播标签,进入直播间", + "android": { + "actions": [ + { + "method": "swipe_to_tap_texts", + "params": [ + "看直播开宝箱", + "最高领", + "点击进入直播间" + ], + "identifier": "click_live_new", + "max_retry_times": 40, + "wait_time": 2, + "direction": [ + 0.5, + 0.8, + 0.5, + 0.2 + ], + "scope": [ + 0.1, + 0.5, + 0.9, + 0.9 + ], + "offset": [ + 0, + -100 + ] + } + ] + } + }, + { + "name": "等待30s", + "android": { + "actions": [ + { + "method": "sleep", + "params": 30 + } + ] + } + }, + { + "name": "下滑进入下一个直播间", + "android": { + "actions": [ + { + "method": "swipe", + "params": [ + 0.5, + 0.7, + 0.5, + 0.1 + ], + "identifier": "slide_in_live_new" + }, + { + "method": "sleep", + "params": 30 + } + ] + } + }, + { + "name": "返回主界面,并打开本地时间戳", + "android": { + "actions": [ + { + "method": "app_terminate", + "params": "com.ss.android.ugc.aweme.lite" + }, + { + "method": "home" + }, + { + "method": "swipe_to_tap_app", + "params": "local", + "max_retry_times": 5, + "offset": [ + 0, + -50 + ] }, { "method": "sleep", @@ -31,107 +227,10 @@ }, "validate": [ { - "check": "ui_foreground_app", - "assert": "equal", - "expect": "com.ss.android.ugc.aweme", - "msg": "app [com.ss.android.ugc.aweme] should be in foreground" - } - ] - }, - { - "name": "处理青少年弹窗", - "android": { - "actions": [ - { - "method": "tap_ocr", - "params": "我知道了", - "options": { - "ignore_NotFoundError": true - } - } - ] - } - }, - { - "name": "滑动 Feed 3 次,随机间隔 0-5s", - "android": { - "actions": [ - { - "method": "swipe", - "params": "up", - "options": {} - }, - { - "method": "sleep_random", - "params": [ - 0, - 5 - ] - } - ] - }, - "loops": 3 - }, - { - "name": "滑动 Feed 1 次,随机间隔 5-10s", - "android": { - "actions": [ - { - "method": "swipe", - "params": "up", - "options": {} - }, - { - "method": "sleep_random", - "params": [ - 5, - 10 - ] - } - ] - }, - "loops": 1 - }, - { - "name": "滑动 Feed 10 次,70% 随机间隔 0-5s,30% 随机间隔 5-10s", - "android": { - "actions": [ - { - "method": "swipe", - "params": "up", - "options": {} - }, - { - "method": "sleep_random", - "params": [ - 0, - 5, - 0.7, - 5, - 10, - 0.3 - ] - } - ] - }, - "loops": 10 - }, - { - "name": "exit", - "android": { - "actions": [ - { - "method": "app_terminate", - "params": "com.ss.android.ugc.aweme" - } - ] - }, - "validate": [ - { - "check": "ui_foreground_app", - "assert": "not_equal", - "expect": "com.ss.android.ugc.aweme", - "msg": "app [com.ss.android.ugc.aweme] should not be in foreground" + "check": "ui_ocr", + "assert": "exists", + "expect": "17", + "msg": "打开本地时间戳失败" } ] } diff --git a/hrp/internal/env/env.go b/hrp/internal/env/env.go index 8bb808bf..5168990d 100644 --- a/hrp/internal/env/env.go +++ b/hrp/internal/env/env.go @@ -22,15 +22,18 @@ var ( const ( ResultsDirName = "results" ScreenshotsDirName = "screenshots" + ActionLogDireName = "action_log" ) var ( - RootDir string - ResultsDir string - ResultsPath string - ScreenShotsPath string - StartTime = time.Now() - StartTimeStr = StartTime.Format("20060102150405") + RootDir string + ResultsDir string + ResultsPath string + ScreenShotsPath string + StartTime = time.Now() + StartTimeStr = StartTime.Format("20060102150405") + ActionLogFilePath string + DeviceActionLogFilePath string ) func init() { @@ -43,4 +46,6 @@ func init() { ResultsDir = filepath.Join(ResultsDirName, StartTimeStr) ResultsPath = filepath.Join(RootDir, ResultsDir) ScreenShotsPath = filepath.Join(ResultsPath, ScreenshotsDirName) + ActionLogFilePath = filepath.Join(ResultsDir, ActionLogDireName) + DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor" } diff --git a/hrp/pkg/uixt/android_adb_driver.go b/hrp/pkg/uixt/android_adb_driver.go index 64b4d94e..2fc80a57 100644 --- a/hrp/pkg/uixt/android_adb_driver.go +++ b/hrp/pkg/uixt/android_adb_driver.go @@ -3,6 +3,9 @@ package uixt import ( "bytes" "fmt" + "io/fs" + "io/ioutil" + "path/filepath" "strconv" "strings" "time" @@ -10,7 +13,9 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" + "github.com/httprunner/funplugin/myexec" "github.com/httprunner/httprunner/v4/hrp/internal/code" + "github.com/httprunner/httprunner/v4/hrp/internal/env" "github.com/httprunner/httprunner/v4/hrp/pkg/gadb" ) @@ -448,7 +453,40 @@ func (ad *adbDriver) StopCaptureLog() (result interface{}, err error) { } content := ad.logcat.logBuffer.String() log.Info().Str("logcat content", content).Msg("display logcat content") - return ConvertPoints(content), nil + pointRes := ConvertPoints(content) + // 没有解析到打点日志,走兜底逻辑 + if len(pointRes) == 0 { + logFilePathPrefix := fmt.Sprintf("%v/data", env.ActionLogFilePath) + files := []string{} + myexec.RunCommand("adb", "pull", env.DeviceActionLogFilePath, env.ActionLogFilePath) + err = filepath.Walk(env.ActionLogFilePath, func(path string, info fs.FileInfo, err error) error { + // 只是需要日志文件 + if ok := strings.Contains(path, logFilePathPrefix); ok { + files = append(files, path) + } + return nil + }) + + // 先保持原有状态码不变,这里不return error + if err != nil { + log.Error().Err(err).Msg("read log file fail") + return pointRes, nil + } + + if len(files) != 1 { + log.Error().Err(err).Msg("log file count error") + return pointRes, nil + } + + data, err := ioutil.ReadFile(files[0]) + if err != nil { + log.Info().Msg("read File error") + return pointRes, nil + } + + pointRes = ConvertPoints(string(data)) + } + return pointRes, nil } func (ad *adbDriver) GetForegroundApp() (app AppInfo, err error) { diff --git a/hrp/runner.go b/hrp/runner.go index b68a5208..986dc931 100644 --- a/hrp/runner.go +++ b/hrp/runner.go @@ -18,6 +18,7 @@ import ( "github.com/gorilla/websocket" "github.com/httprunner/funplugin" + "github.com/httprunner/funplugin/myexec" "github.com/jinzhu/copier" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -25,6 +26,7 @@ import ( "github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/code" + "github.com/httprunner/httprunner/v4/hrp/internal/env" "github.com/httprunner/httprunner/v4/hrp/internal/sdk" "github.com/httprunner/httprunner/v4/hrp/internal/version" "github.com/httprunner/httprunner/v4/hrp/pkg/uixt" @@ -523,6 +525,11 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) error { config := r.caseRunner.testCase.Config log.Info().Str("testcase", config.Name).Msg("run testcase start") + // 安卓系统删除打点日志文件 + if r.caseRunner.testCase.Config.Android != nil { + myexec.RunCommand("adb", "-s", r.caseRunner.testCase.Config.Android[0].SerialNumber, "shell", "rm", "-r", env.DeviceActionLogFilePath) + } + // update config variables with given variables r.InitWithParameters(givenVars) From 7da433285b6852e5a0ea1d818e711b776a1be229 Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Thu, 30 Nov 2023 11:12:18 +0800 Subject: [PATCH 06/15] chore: add log for action log file --- hrp/internal/version/VERSION | 2 +- hrp/pkg/uixt/android_adb_driver.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 7f16698d..c776583b 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.7.2311231600 \ No newline at end of file +v4.3.7.2311301111 \ No newline at end of file diff --git a/hrp/pkg/uixt/android_adb_driver.go b/hrp/pkg/uixt/android_adb_driver.go index 2fc80a57..c20ce648 100644 --- a/hrp/pkg/uixt/android_adb_driver.go +++ b/hrp/pkg/uixt/android_adb_driver.go @@ -456,6 +456,7 @@ func (ad *adbDriver) StopCaptureLog() (result interface{}, err error) { pointRes := ConvertPoints(content) // 没有解析到打点日志,走兜底逻辑 if len(pointRes) == 0 { + log.Info().Msg("action log is null, use action file >>>") logFilePathPrefix := fmt.Sprintf("%v/data", env.ActionLogFilePath) files := []string{} myexec.RunCommand("adb", "pull", env.DeviceActionLogFilePath, env.ActionLogFilePath) From e5bf385aa933b83fc3fb8a03b5eeda2e6f617e1e Mon Sep 17 00:00:00 2001 From: "huangbin.beal" Date: Thu, 30 Nov 2023 12:05:23 +0800 Subject: [PATCH 07/15] fix: device serial in action log file --- hrp/pkg/uixt/android_adb_driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hrp/pkg/uixt/android_adb_driver.go b/hrp/pkg/uixt/android_adb_driver.go index c20ce648..790f4544 100644 --- a/hrp/pkg/uixt/android_adb_driver.go +++ b/hrp/pkg/uixt/android_adb_driver.go @@ -459,7 +459,7 @@ func (ad *adbDriver) StopCaptureLog() (result interface{}, err error) { log.Info().Msg("action log is null, use action file >>>") logFilePathPrefix := fmt.Sprintf("%v/data", env.ActionLogFilePath) files := []string{} - myexec.RunCommand("adb", "pull", env.DeviceActionLogFilePath, env.ActionLogFilePath) + myexec.RunCommand("adb", "-s", ad.adbClient.Serial(), "pull", env.DeviceActionLogFilePath, env.ActionLogFilePath) err = filepath.Walk(env.ActionLogFilePath, func(path string, info fs.FileInfo, err error) error { // 只是需要日志文件 if ok := strings.Contains(path, logFilePathPrefix); ok { From 3a77578c5ddaf7725b8b416983156eb984bede6f Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 27 Feb 2024 15:58:07 +0800 Subject: [PATCH 08/15] fix: return error when testcase count less than 1 --- hrp/internal/version/VERSION | 2 +- hrp/loader.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index c776583b..bbdcf681 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.7.2311301111 \ No newline at end of file +v4.3.7 \ No newline at end of file diff --git a/hrp/loader.go b/hrp/loader.go index ff737c6d..4af517eb 100644 --- a/hrp/loader.go +++ b/hrp/loader.go @@ -53,6 +53,7 @@ func LoadTestCases(iTestCases ...ITestCase) ([]*TestCase, error) { testCasePath := TestCasePath(path) tc, err := testCasePath.ToTestCase() if err != nil { + log.Error().Err(err).Msg("fail to parse test:") return nil } testCases = append(testCases, tc) @@ -63,6 +64,10 @@ func LoadTestCases(iTestCases ...ITestCase) ([]*TestCase, error) { } } + if len(testCases) < 1 { + return nil, errors.New("test case count less than 1 or parse error") + } + log.Info().Int("count", len(testCases)).Msg("load testcases successfully") return testCases, nil } From b6138f12d95f5dc01f98a1892da6c0ec5c6132ef Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 27 Feb 2024 16:00:48 +0800 Subject: [PATCH 09/15] chore: change note --- hrp/pkg/uixt/service_vedem.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hrp/pkg/uixt/service_vedem.go b/hrp/pkg/uixt/service_vedem.go index 00e8efee..e8e1f51e 100644 --- a/hrp/pkg/uixt/service_vedem.go +++ b/hrp/pkg/uixt/service_vedem.go @@ -218,7 +218,7 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer, options ...ActionOp bodyWriter.WriteField("uiTypes", uiType) } - // 临时支持直播使用高精度集群 + // 使用高精度集群 bodyWriter.WriteField("ocrCluster", "default_1600") if actionOptions.ScreenShotWithOCRCluster != "" { From 167d58cf7a28abb53f82fa3d747ff6c0e36e48fe Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 27 Feb 2024 16:21:35 +0800 Subject: [PATCH 10/15] chore: remove useless note --- hrp/pkg/uixt/ext.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index c7258be6..aa917fee 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -259,8 +259,6 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin err = jpeg.Encode(file, img, jpegOptions) case "png_import": err = png.Encode(file, img) - // case "jpeg": - // err = jpeg.Encode(file, img, nil) case "gif_import": err = gif.Encode(file, img, nil) default: From ec6181d65a483b43ae87233f8926f56e9b62a9b2 Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 27 Feb 2024 16:25:05 +0800 Subject: [PATCH 11/15] chore: remove useless note --- hrp/pkg/uixt/ext.go | 1 - 1 file changed, 1 deletion(-) diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index aa917fee..f234cdae 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -243,7 +243,6 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin // The default format uses jpeg for compression screenshotPath := filepath.Join(fmt.Sprintf("%s.%s", fileName, "jpeg")) - // screenshotPath := filepath.Join(fmt.Sprintf("%s.%s", fileName, "jpeg")) file, err := os.Create(screenshotPath) if err != nil { return "", errors.Wrap(err, "create screenshot image file failed") From cc4944b1333cb80637b66837842b6b4fa5db1cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=B3=93=E9=93=AE?= Date: Mon, 18 Mar 2024 14:49:03 +0800 Subject: [PATCH 12/15] fix: adb device parse attributes error --- hrp/pkg/gadb/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hrp/pkg/gadb/client.go b/hrp/pkg/gadb/client.go index 1c867dd1..eb6b9d8c 100644 --- a/hrp/pkg/gadb/client.go +++ b/hrp/pkg/gadb/client.go @@ -108,7 +108,7 @@ func (c Client) DeviceList() (devices []*Device, err error) { } fields := strings.Fields(line) - if len(fields) < 5 || len(fields[0]) == 0 { + if len(fields) < 4 || len(fields[0]) == 0 { log.Error().Str("line", line).Msg("get unexpected line") continue } @@ -117,6 +117,9 @@ func (c Client) DeviceList() (devices []*Device, err error) { mapAttrs := map[string]string{} for _, field := range sliceAttrs { split := strings.Split(field, ":") + if len(split) == 1 { + continue + } key, val := split[0], split[1] mapAttrs[key] = val } From bea0a6a2730dfc3f085dccbb1373a52df5dcb3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=B3=93=E9=93=AE?= Date: Mon, 18 Mar 2024 15:07:47 +0800 Subject: [PATCH 13/15] fix: adb device parse attributes error --- hrp/cmd/adb/devices.go | 6 +++++- hrp/pkg/gadb/device.go | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/hrp/cmd/adb/devices.go b/hrp/cmd/adb/devices.go index 6640a45e..7aef4d18 100644 --- a/hrp/cmd/adb/devices.go +++ b/hrp/cmd/adb/devices.go @@ -41,7 +41,11 @@ var listAndroidDevicesCmd = &cobra.Command{ if isDetail { fmt.Println(format(d.DeviceInfo())) } else { - fmt.Println(d.Serial(), d.Usb()) + if usb, err := d.Usb(); err != nil { + fmt.Println(d.Serial()) + } else { + fmt.Println(d.Serial(), usb) + } } } return nil diff --git a/hrp/pkg/gadb/device.go b/hrp/pkg/gadb/device.go index 8b9705b6..c9f61602 100644 --- a/hrp/pkg/gadb/device.go +++ b/hrp/pkg/gadb/device.go @@ -107,20 +107,37 @@ func (d *Device) features() (features Features, err error) { return features, nil } -func (d *Device) Product() string { - return d.attrs["product"] +func (d Device) HasAttribute(key string) bool { + _, ok := d.attrs[key] + return ok } -func (d *Device) Model() string { - return d.attrs["model"] +func (d Device) Product() (string, error) { + if d.HasAttribute("product") { + return d.attrs["product"], nil + } + return "", errors.New("does not have attribute: product") } -func (d *Device) Usb() string { - return d.attrs["usb"] +func (d Device) Model() (string, error) { + if d.HasAttribute("model") { + return d.attrs["model"], nil + } + return "", errors.New("does not have attribute: model") } -func (d *Device) transportId() string { - return d.attrs["transport_id"] +func (d *Device) Usb() (string, error) { + if d.HasAttribute("usb") { + return d.attrs["usb"], nil + } + return "", errors.New("does not have attribute: usb") +} + +func (d Device) transportId() (string, error) { + if d.HasAttribute("transport_id") { + return d.attrs["transport_id"], nil + } + return "", errors.New("does not have attribute: transport_id") } func (d *Device) DeviceInfo() map[string]string { @@ -132,8 +149,13 @@ func (d *Device) Serial() string { return d.serial } -func (d *Device) IsUsb() bool { - return d.Usb() != "" +func (d *Device) IsUsb() (bool, error) { + usb, err := d.Usb() + if err != nil { + return false, err + } + + return usb != "", nil } func (d *Device) State() (DeviceState, error) { From 4979d4e1e296d0c854553c05ff98d20d9807ee95 Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 19 Mar 2024 11:53:28 +0800 Subject: [PATCH 14/15] fix: ocr cluster --- hrp/pkg/uixt/ext.go | 8 ++------ hrp/pkg/uixt/service_vedem.go | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index f234cdae..b9ad0041 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -4,9 +4,9 @@ import ( "bytes" "fmt" "image" - "image/gif" + _ "image/gif" "image/jpeg" - "image/png" + _ "image/png" "math/rand" "mime" "mime/multipart" @@ -256,10 +256,6 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin case "jpeg", "png": jpegOptions := &jpeg.Options{Quality: 95} err = jpeg.Encode(file, img, jpegOptions) - case "png_import": - err = png.Encode(file, img) - case "gif_import": - err = gif.Encode(file, img, nil) default: return "", fmt.Errorf("unsupported image format: %s", format) } diff --git a/hrp/pkg/uixt/service_vedem.go b/hrp/pkg/uixt/service_vedem.go index e8e1f51e..86d66dd1 100644 --- a/hrp/pkg/uixt/service_vedem.go +++ b/hrp/pkg/uixt/service_vedem.go @@ -219,7 +219,7 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer, options ...ActionOp } // 使用高精度集群 - bodyWriter.WriteField("ocrCluster", "default_1600") + bodyWriter.WriteField("ocrCluster", "highPrecision") if actionOptions.ScreenShotWithOCRCluster != "" { bodyWriter.WriteField("ocrCluster", actionOptions.ScreenShotWithOCRCluster) From e9d039b58ba17d426fa796fef999843a6f74714b Mon Sep 17 00:00:00 2001 From: "huangbin.beal@163.com" Date: Tue, 19 Mar 2024 16:33:03 +0800 Subject: [PATCH 15/15] chore: add change log --- docs/CHANGELOG.md | 10 ++++++++++ hrp/internal/version/VERSION | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ed37df31..901e1744 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History +## v4.3.8 (2023-09-19) +- feat: OCR calls use the high-precision cluster interface, and the default timeout is changed from 3s to 10s +- feat: use jpeg to compress screenshots +- feat: increase live broadcast end-to-end collection capabilities +- fix: add file reading and writing methods as a log management logic +- fix: throws an error when the number of use cases is 0 +- fix: fixed the problem that the new version of adb format fails to parse + +**go version** + ## v4.3.7 (2023-09-19) **go version** diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index f59ab889..fdd709db 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.7 +v4.3.8