From a98c497995c466711a6c95a9a53d823ee6b10a86 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 22 Jun 2023 12:48:29 +0800 Subject: [PATCH 01/10] feat: auto handle popups on each step finished --- hrp/pkg/uixt/action.go | 2 +- hrp/pkg/uixt/ext.go | 21 ++++++++------------- hrp/pkg/uixt/ocr_vedem.go | 28 +++++++++++++++++----------- hrp/pkg/uixt/opencv.go | 2 +- hrp/pkg/uixt/popups.go | 6 +++--- hrp/pkg/uixt/video_crawler.go | 16 +++++----------- hrp/step_mobile_ui.go | 12 ++++++++---- 7 files changed, 43 insertions(+), 44 deletions(-) diff --git a/hrp/pkg/uixt/action.go b/hrp/pkg/uixt/action.go index ee12b7a9..b47ba5a1 100644 --- a/hrp/pkg/uixt/action.go +++ b/hrp/pkg/uixt/action.go @@ -506,7 +506,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error { case ACTION_ScreenShot: // take screenshot log.Info().Msg("take screenshot for current screen") - _, _, err := dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_screenshot")) + _, _, err := dExt.takeScreenShot(builtin.GenNameWithTimestamp("%d_screenshot")) return err case ACTION_StartCamera: return dExt.Driver.StartCamera() diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index a5f50b40..0390cc28 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -124,9 +124,8 @@ func NewDriverExt(device Device, driver WebDriver) (dExt *DriverExt, err error) return dExt, nil } -// TakeScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder -// if fileName is empty, it will not save image file and only return raw image data -func (dExt *DriverExt) TakeScreenShot(fileName ...string) (raw *bytes.Buffer, path string, err error) { +// takeScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder +func (dExt *DriverExt) takeScreenShot(fileName string) (raw *bytes.Buffer, path string, err error) { // iOS 优先使用 MJPEG 流进行截图,性能最优 // 如果 MJPEG 流未开启,则使用 WebDriver 的截图接口 if dExt.frame != nil { @@ -145,17 +144,13 @@ func (dExt *DriverExt) TakeScreenShot(fileName ...string) (raw *bytes.Buffer, pa } // save screenshot to file - if len(fileName) > 0 && fileName[0] != "" { - path := filepath.Join(env.ScreenShotsPath, fileName[0]) - path, err := dExt.saveScreenShot(compressed, path) - if err != nil { - log.Error().Err(err).Msg("save screenshot file failed") - return nil, "", err - } - return compressed, path, nil + path = filepath.Join(env.ScreenShotsPath, fileName) + path, err = dExt.saveScreenShot(compressed, path) + if err != nil { + log.Error().Err(err).Msg("save screenshot file failed") + return nil, "", err } - - return compressed, "", nil + return compressed, path, nil } func compressImageBuffer(raw *bytes.Buffer) (compressed *bytes.Buffer, err error) { diff --git a/hrp/pkg/uixt/ocr_vedem.go b/hrp/pkg/uixt/ocr_vedem.go index 3345428e..beb5f0a4 100644 --- a/hrp/pkg/uixt/ocr_vedem.go +++ b/hrp/pkg/uixt/ocr_vedem.go @@ -59,7 +59,7 @@ type ImageResult struct { LiveType string `json:"liveType"` // 直播间类型 } -type ImageResponse struct { +type APIResponseImage struct { Code int `json:"code"` Message string `json:"message"` Result ImageResult `json:"result"` @@ -279,7 +279,7 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer) ( return } - var imageResponse ImageResponse + var imageResponse APIResponseImage err = json.Unmarshal(results, &imageResponse) if err != nil { log.Error().Err(err). @@ -334,19 +334,20 @@ type IImageService interface { } // GetScreenResult takes a screenshot, returns the image recognization result -func (dExt *DriverExt) GetScreenResult() (imageResult ImageResult, err error) { +func (dExt *DriverExt) GetScreenResult() (screenResult *ScreenResult, err error) { var bufSource *bytes.Buffer var imagePath string - if bufSource, imagePath, err = dExt.TakeScreenShot( + if bufSource, imagePath, err = dExt.takeScreenShot( builtin.GenNameWithTimestamp("%d_ocr")); err != nil { return } - imageResult, err = dExt.ImageService.GetImage(bufSource) + imageResult, err := dExt.ImageService.GetImage(bufSource) if err != nil { log.Error().Err(err).Msg("GetScreenResult failed") return } + imageResult.imagePath = imagePath imageUrl := imageResult.URL if imageUrl != "" { @@ -354,20 +355,25 @@ func (dExt *DriverExt) GetScreenResult() (imageResult ImageResult, err error) { log.Debug().Str("imagePath", imagePath).Str("imageUrl", imageUrl).Msg("log screenshot") } - dExt.cacheStepData.screenResults[imagePath] = &ScreenResult{ - Texts: imageResult.OCRResult.ToOCRTexts(), + screenResult = &ScreenResult{ + Texts: imageResult.OCRResult.ToOCRTexts(), + Tags: nil, + Popularity: Popularity{}, } + if imageResult.LiveType != "" { + screenResult.Tags = []string{imageResult.LiveType} + } + dExt.cacheStepData.screenResults[imagePath] = screenResult - imageResult.imagePath = imagePath - return imageResult, nil + return screenResult, nil } func (dExt *DriverExt) GetScreenTexts() (ocrTexts OCRTexts, err error) { - imageResult, err := dExt.GetScreenResult() + screenResult, err := dExt.GetScreenResult() if err != nil { return } - return imageResult.OCRResult.ToOCRTexts(), nil + return screenResult.Texts, nil } func (dExt *DriverExt) FindScreenText(text string, options ...ActionOption) (point PointF, err error) { diff --git a/hrp/pkg/uixt/opencv.go b/hrp/pkg/uixt/opencv.go index e72f0cde..75c1d0ca 100644 --- a/hrp/pkg/uixt/opencv.go +++ b/hrp/pkg/uixt/opencv.go @@ -101,7 +101,7 @@ func (dExt *DriverExt) FindAllImageRect(search string) (rects []image.Rectangle, if bufSearch, err = getBufFromDisk(search); err != nil { return nil, err } - if bufSource, _, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_cv")); err != nil { + if bufSource, _, err = dExt.takeScreenShot(builtin.GenNameWithTimestamp("%d_cv")); err != nil { return nil, err } diff --git a/hrp/pkg/uixt/popups.go b/hrp/pkg/uixt/popups.go index ef2fab94..5bde89df 100644 --- a/hrp/pkg/uixt/popups.go +++ b/hrp/pkg/uixt/popups.go @@ -24,16 +24,16 @@ var popups = [][]string{ {"管理使用时间", ".*忽略.*"}, } -func (dExt *DriverExt) autoPopupHandler(screenResult *ScreenResult) error { +func (dExt *DriverExt) AutoPopupHandler(screenTexts OCRTexts) error { for _, popup := range popups { if len(popup) != 2 { continue } - points, err := screenResult.Texts.FindTexts([]string{popup[0], popup[1]}, WithRegex(true)) + points, err := screenTexts.FindTexts([]string{popup[0], popup[1]}, WithRegex(true)) if err == nil { log.Warn().Interface("popup", popup). - Interface("texts", screenResult.Texts).Msg("text popup found") + Interface("texts", screenTexts).Msg("text popup found") point := points[1].Center() log.Info().Str("text", points[1].Text).Msg("close popup") if err := dExt.TapAbsXY(point.X, point.Y); err != nil { diff --git a/hrp/pkg/uixt/video_crawler.go b/hrp/pkg/uixt/video_crawler.go index 085bc69b..9021b86c 100644 --- a/hrp/pkg/uixt/video_crawler.go +++ b/hrp/pkg/uixt/video_crawler.go @@ -250,17 +250,13 @@ func (l *LiveCrawler) Run(driver *DriverExt, enterPoint PointF) error { } // take screenshot and get screen texts by OCR - imageResult, err := l.driver.GetScreenResult() + screenResult, err := l.driver.GetScreenResult() if err != nil { log.Error().Err(err).Msg("OCR GetTexts failed") time.Sleep(3 * time.Second) continue } - screenResult := l.driver.cacheStepData.screenResults[imageResult.imagePath] - screenResult.Tags = []string{"live"} - if imageResult.LiveType != "" { - screenResult.Tags = append(screenResult.Tags, imageResult.LiveType) - } + screenResult.Tags = append([]string{"live"}, screenResult.Tags...) // check live type and incr live count if err := l.currentStat.incrLive(screenResult, l.driver); err != nil { @@ -364,7 +360,7 @@ func (dExt *DriverExt) VideoCrawler(configs *VideoCrawlerConfigs) (err error) { return errors.Wrap(code.InterruptError, "feed crawler interrupted") default: // take screenshot and get screen texts by OCR - imageResult, err := dExt.GetScreenResult() + screenResult, err := dExt.GetScreenResult() if err != nil { if strings.Contains(err.Error(), "connect: connection refused") { return err @@ -373,17 +369,15 @@ func (dExt *DriverExt) VideoCrawler(configs *VideoCrawlerConfigs) (err error) { time.Sleep(3 * time.Second) continue } - screenResult := dExt.cacheStepData.screenResults[imageResult.imagePath] // automatic handling of pop-up windows - if err := dExt.autoPopupHandler(screenResult); err != nil { + if err := dExt.AutoPopupHandler(screenResult.Texts); err != nil { log.Error().Err(err).Msg("auto handle popup failed") return err } // check if live video && run live crawler - texts := imageResult.OCRResult.ToOCRTexts() - if enterPoint, isLive := liveCrawler.checkLiveVideo(texts); isLive { + if enterPoint, isLive := liveCrawler.checkLiveVideo(screenResult.Texts); isLive { log.Info().Msg("live video found") if !liveCrawler.currentStat.isLiveTargetAchieved() { if err := liveCrawler.Run(dExt, enterPoint); err != nil { diff --git a/hrp/step_mobile_ui.go b/hrp/step_mobile_ui.go index ac95207e..7e787775 100644 --- a/hrp/step_mobile_ui.go +++ b/hrp/step_mobile_ui.go @@ -6,7 +6,6 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" - "github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/pkg/uixt" ) @@ -598,12 +597,17 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err } } - // take screenshot after each step - if _, _, err2 := uiDriver.TakeScreenShot( - builtin.GenNameWithTimestamp("%d_step_") + step.Name); err2 != nil { + // take screenshot and get screen texts by OCR + screenResult, err2 := uiDriver.GetScreenResult() + if err2 != nil { log.Error().Err(err2).Str("step", step.Name).Msg("take screenshot failed on step finished") } + // automatic handling of pop-up windows on each step finished + if err3 := uiDriver.AutoPopupHandler(screenResult.Texts); err3 != nil { + log.Error().Err(err3).Msg("auto handle popup failed") + } + // save attachments cacheData := uiDriver.GetStepCacheData() for key, value := range cacheData { From 6411e2953c29ea24315da7178e45190b03ec7d9e Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 22 Jun 2023 13:11:27 +0800 Subject: [PATCH 02/10] change: add popups --- hrp/pkg/uixt/popups.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hrp/pkg/uixt/popups.go b/hrp/pkg/uixt/popups.go index 5bde89df..aea6d49f 100644 --- a/hrp/pkg/uixt/popups.go +++ b/hrp/pkg/uixt/popups.go @@ -12,8 +12,8 @@ var popups = [][]string{ {".*青少年.*", "我知道了"}, // 青少年弹窗 {".*个人信息保护.*", "同意"}, {".*通讯录.*", "拒绝"}, - {".*更新.*", "以后再说|稍后"}, - {".*升级.*", "以后再说|稍后"}, + {".*更新.*", "以后再说|稍后|取消"}, + {".*升级.*", "以后再说|稍后|取消"}, {".*定位.*", "仅.*允许"}, {".*拍照.*", "仅.*允许"}, {".*录音.*", "仅.*允许"}, From 0d6da534abb07876d9802d1784e44c858d42cc62 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 22 Jun 2023 14:50:45 +0800 Subject: [PATCH 03/10] feat: add auto popups handler in swipe find --- hrp/pkg/uixt/ocr_vedem.go | 2 +- hrp/pkg/uixt/swipe.go | 10 ++++++++-- hrp/step_mobile_ui.go | 8 +++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hrp/pkg/uixt/ocr_vedem.go b/hrp/pkg/uixt/ocr_vedem.go index beb5f0a4..b6b71099 100644 --- a/hrp/pkg/uixt/ocr_vedem.go +++ b/hrp/pkg/uixt/ocr_vedem.go @@ -344,7 +344,7 @@ func (dExt *DriverExt) GetScreenResult() (screenResult *ScreenResult, err error) imageResult, err := dExt.ImageService.GetImage(bufSource) if err != nil { - log.Error().Err(err).Msg("GetScreenResult failed") + log.Error().Err(err).Msg("GetImage from ImageService failed") return } imageResult.imagePath = imagePath diff --git a/hrp/pkg/uixt/swipe.go b/hrp/pkg/uixt/swipe.go index abcdc89b..4419b780 100644 --- a/hrp/pkg/uixt/swipe.go +++ b/hrp/pkg/uixt/swipe.go @@ -135,14 +135,20 @@ func (dExt *DriverExt) swipeToTapTexts(texts []string, options ...ActionOption) var point PointF findTexts := func(d *DriverExt) error { var err error - ocrTexts, err := d.GetScreenTexts() + screenTexts, err := d.GetScreenTexts() if err != nil { return err } - points, err := ocrTexts.FindTexts(texts, dExt.ParseActionOptions(options...)...) + points, err := screenTexts.FindTexts(texts, dExt.ParseActionOptions(options...)...) if err != nil { + // target texts not found, try to auto handle popup + if e := dExt.AutoPopupHandler(screenTexts); e != nil { + log.Error().Err(e).Msg("auto handle popup failed") + } return err } + + // target texts found, pick the first one point = points[0].Center() // FIXME return nil } diff --git a/hrp/step_mobile_ui.go b/hrp/step_mobile_ui.go index 7e787775..48672dcc 100644 --- a/hrp/step_mobile_ui.go +++ b/hrp/step_mobile_ui.go @@ -598,13 +598,11 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err } // take screenshot and get screen texts by OCR - screenResult, err2 := uiDriver.GetScreenResult() + screenTexts, err2 := uiDriver.GetScreenTexts() if err2 != nil { log.Error().Err(err2).Str("step", step.Name).Msg("take screenshot failed on step finished") - } - - // automatic handling of pop-up windows on each step finished - if err3 := uiDriver.AutoPopupHandler(screenResult.Texts); err3 != nil { + } else if err3 := uiDriver.AutoPopupHandler(screenTexts); err3 != nil { + // automatic handling of pop-up windows on each step finished log.Error().Err(err3).Msg("auto handle popup failed") } From b5612c5632c9738f614cc2de4c9f82d6fc38130c Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 22 Jun 2023 16:33:53 +0800 Subject: [PATCH 04/10] refactor: raise adb error --- hrp/internal/code/code.go | 22 ++++++++++++---------- hrp/pkg/gadb/client.go | 9 +++++++++ hrp/pkg/gadb/device.go | 28 +++++++++++++--------------- hrp/pkg/gadb/transport.go | 31 ++++++++++++++++++++++--------- hrp/pkg/uixt/android_device.go | 13 ++++++------- 5 files changed, 62 insertions(+), 41 deletions(-) diff --git a/hrp/internal/code/code.go b/hrp/internal/code/code.go index 2cfc0832..e03420ac 100644 --- a/hrp/internal/code/code.go +++ b/hrp/internal/code/code.go @@ -61,11 +61,12 @@ var ( // android device related: [60, 70) var ( - AndroidDeviceConnectionError = errors.New("android device connection error") // 60 - AndroidDeviceUSBDriverError = errors.New("android device USB driver error") // 61 - AndroidShellExecError = errors.New("android adb shell exec error") // 62 - AndroidScreenShotError = errors.New("android screenshot error") // 65 - AndroidCaptureLogError = errors.New("android capture log error") // 66 + AndroidDeviceConnectionError = errors.New("android device general connection error") // 60 + AndroidDeviceConnectionRefusedError = errors.New("android device connection refused") // 61 + AndroidShellExecError = errors.New("android adb shell exec error") // 62 + AndroidDeviceOfflineError = errors.New("android device offline") // 63 + AndroidScreenShotError = errors.New("android screenshot error") // 65 + AndroidCaptureLogError = errors.New("android capture log error") // 66 ) // UI automation related: [70, 80) @@ -127,11 +128,12 @@ var errorsMap = map[error]int{ IOSCaptureLogError: 56, // android related - AndroidDeviceConnectionError: 60, - AndroidDeviceUSBDriverError: 61, - AndroidShellExecError: 62, - AndroidScreenShotError: 65, - AndroidCaptureLogError: 66, + AndroidDeviceConnectionError: 60, + AndroidDeviceConnectionRefusedError: 61, + AndroidShellExecError: 62, + AndroidDeviceOfflineError: 63, + AndroidScreenShotError: 65, + AndroidCaptureLogError: 66, // UI automation related MobileUIDriverError: 70, diff --git a/hrp/pkg/gadb/client.go b/hrp/pkg/gadb/client.go index bc0349ff..79e69d91 100644 --- a/hrp/pkg/gadb/client.go +++ b/hrp/pkg/gadb/client.go @@ -5,7 +5,10 @@ import ( "strconv" "strings" + "github.com/pkg/errors" "github.com/rs/zerolog/log" + + "github.com/httprunner/httprunner/v4/hrp/internal/code" ) const ( @@ -84,6 +87,12 @@ func (c Client) DeviceSerialList() (serials []string, err error) { } func (c Client) DeviceList() (devices []*Device, err error) { + defer func() { + if err != nil && errors.Cause(err) == nil { + err = errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) + } + }() + var resp string if resp, err = c.executeCommand("host:devices-l"); err != nil { return diff --git a/hrp/pkg/gadb/device.go b/hrp/pkg/gadb/device.go index 8a953e0b..58175669 100644 --- a/hrp/pkg/gadb/device.go +++ b/hrp/pkg/gadb/device.go @@ -36,12 +36,18 @@ const ( StateOnline DeviceState = "online" StateOffline DeviceState = "offline" StateDisconnected DeviceState = "disconnected" + StateBootloader DeviceState = "bootloader" + StateRecovery DeviceState = "recovery" + StateUnauthorized DeviceState = "unauthorized" ) var deviceStateStrings = map[string]DeviceState{ - "": StateDisconnected, - "offline": StateOffline, - "device": StateOnline, + "": StateDisconnected, // no devices/emulators found + "offline": StateOffline, + "bootloader": StateBootloader, + "recovery": StateRecovery, + "unauthorized": StateUnauthorized, + "device": StateOnline, } func deviceStateConv(k string) (deviceState DeviceState) { @@ -245,13 +251,10 @@ func (d *Device) ReverseForwardKillAll() error { func (d *Device) RunShellCommand(cmd string, args ...string) (string, error) { raw, err := d.RunShellCommandWithBytes(cmd, args...) - if err != nil { - if errors.Is(err, code.AndroidDeviceConnectionError) { - return "", err - } - return "", errors.Wrap(code.AndroidShellExecError, err.Error()) + if err != nil && errors.Cause(err) == nil { + err = errors.Wrap(code.AndroidShellExecError, err.Error()) } - return string(raw), nil + return string(raw), err } func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, error) { @@ -268,11 +271,6 @@ func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, e return raw, err } -func (d *Device) RunShellCommandV2(cmd string, args ...string) (string, error) { - raw, err := d.RunShellCommandV2WithBytes(cmd, args...) - return string(raw), err -} - // RunShellCommandV2WithBytes shell v2, 支持后台运行而不会阻断 func (d *Device) RunShellCommandV2WithBytes(cmd string, args ...string) ([]byte, error) { if len(args) > 0 { @@ -594,7 +592,7 @@ func (d *Device) Uninstall(packageName string, keepData ...bool) (string, error) args = append(args, "-k") } args = append(args, packageName) - return d.RunShellCommandV2("pm", args...) + return d.RunShellCommand("pm", args...) } func (d *Device) ScreenCap() ([]byte, error) { diff --git a/hrp/pkg/gadb/transport.go b/hrp/pkg/gadb/transport.go index b59ed42e..d9891069 100644 --- a/hrp/pkg/gadb/transport.go +++ b/hrp/pkg/gadb/transport.go @@ -7,6 +7,7 @@ import ( "net" "regexp" "strconv" + "strings" "time" "github.com/pkg/errors" @@ -19,6 +20,8 @@ var ErrConnBroken = errors.New("socket connection broken") var DefaultAdbReadTimeout time.Duration = 60 +var regexDeviceOffline = regexp.MustCompile("device .* not found") + type transport struct { sock net.Conn readTimeout time.Duration @@ -29,9 +32,26 @@ func newTransport(address string, readTimeout ...time.Duration) (tp transport, e readTimeout = []time.Duration{DefaultAdbReadTimeout} } tp.readTimeout = readTimeout[0] - if tp.sock, err = net.Dial("tcp", address); err != nil { - err = fmt.Errorf("adb transport: %w", err) + tp.sock, err = net.Dial("tcp", address) + if err == nil { + // dial success + return tp, nil } + + // connection refused + if strings.Contains(err.Error(), "connect: connection refused") { + err = errors.Wrap(code.AndroidDeviceConnectionRefusedError, err.Error()) + return + } + + // device offline + if regexDeviceOffline.MatchString(err.Error()) { + err = errors.Wrap(code.AndroidDeviceOfflineError, err.Error()) + return + } + + // other connection errors + err = errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) return } @@ -48,8 +68,6 @@ func (t transport) Conn() net.Conn { return t.sock } -var regexDeviceOffline = regexp.MustCompile("device .* not found") - func (t transport) VerifyResponse() (err error) { var status string if status, err = t.ReadStringN(4); err != nil { @@ -64,11 +82,6 @@ func (t transport) VerifyResponse() (err error) { return err } - if regexDeviceOffline.MatchString(sError) { - // device offline - return errors.Wrap(code.AndroidDeviceConnectionError, sError) - } - log.Warn().Str("status", status).Str("err", sError). Msg("verify adb response failed") return errors.New(sError) diff --git a/hrp/pkg/uixt/android_device.go b/hrp/pkg/uixt/android_device.go index b511659d..ef24c637 100644 --- a/hrp/pkg/uixt/android_device.go +++ b/hrp/pkg/uixt/android_device.go @@ -91,7 +91,7 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er deviceList, err := GetAndroidDevices(device.SerialNumber) if err != nil { - return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) + return nil, err } dev := deviceList[0] @@ -106,12 +106,11 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er func GetAndroidDevices(serial ...string) (devices []*gadb.Device, err error) { var adbClient gadb.Client if adbClient, err = gadb.NewClientWith(AdbServerHost, AdbServerPort); err != nil { - return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) + return nil, err } if devices, err = adbClient.DeviceList(); err != nil { - return nil, errors.Wrap(code.AndroidDeviceConnectionError, - fmt.Sprintf("list android devices failed: %v", err)) + return nil, err } var deviceList []*gadb.Device @@ -190,11 +189,11 @@ func (dev *AndroidDevice) NewDriver(capabilities Capabilities) (driverExt *Drive func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, err error) { var localPort int if localPort, err = getFreePort(); err != nil { - return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, + return nil, errors.Wrap(code.AndroidDeviceConnectionError, fmt.Sprintf("get free port failed: %v", err)) } if err = dev.d.Forward(localPort, UIA2ServerPort); err != nil { - return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, + return nil, errors.Wrap(code.AndroidDeviceConnectionError, fmt.Sprintf("forward port %d->%d failed: %v", localPort, UIA2ServerPort, err)) } @@ -204,7 +203,7 @@ func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDri uiaDriver, err := NewUIADriver(capabilities, rawURL) if err != nil { _ = dev.d.ForwardKill(localPort) - return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, err.Error()) + return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) } uiaDriver.adbClient = dev.d uiaDriver.logcat = dev.logcat From 65cfb86ac50971cd7c164ee5a567f198bebacccc Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Fri, 23 Jun 2023 11:56:34 +0800 Subject: [PATCH 05/10] refactor: add SendWithCheck for adb transport --- hrp/pkg/gadb/client.go | 5 +---- hrp/pkg/gadb/device.go | 18 +++++------------- hrp/pkg/gadb/sync_transport.go | 1 + hrp/pkg/gadb/transport.go | 17 ++++++++++++----- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/hrp/pkg/gadb/client.go b/hrp/pkg/gadb/client.go index 79e69d91..1c867dd1 100644 --- a/hrp/pkg/gadb/client.go +++ b/hrp/pkg/gadb/client.go @@ -221,10 +221,7 @@ func (c Client) executeCommand(command string, onlyVerifyResponse ...bool) (resp } defer func() { _ = tp.Close() }() - if err = tp.Send(command); err != nil { - return "", err - } - if err = tp.VerifyResponse(); err != nil { + if err = tp.SendWithCheck(command); err != nil { return "", err } diff --git a/hrp/pkg/gadb/device.go b/hrp/pkg/gadb/device.go index 58175669..515553b1 100644 --- a/hrp/pkg/gadb/device.go +++ b/hrp/pkg/gadb/device.go @@ -357,10 +357,7 @@ func (d *Device) createDeviceTransport() (tp transport, err error) { return transport{}, err } - if err = tp.Send(fmt.Sprintf("host:transport:%s", d.serial)); err != nil { - return transport{}, err - } - err = tp.VerifyResponse() + err = tp.SendWithCheck(fmt.Sprintf("host:transport:%s", d.serial)) return } @@ -400,11 +397,7 @@ func (d *Device) executeCommand(command string, onlyVerifyResponse ...bool) (raw } defer func() { _ = tp.Close() }() - if err = tp.Send(command); err != nil { - return nil, err - } - - if err = tp.VerifyResponse(); err != nil { + if err = tp.SendWithCheck(command); err != nil { return nil, err } @@ -528,13 +521,12 @@ func (d *Device) installViaABBExec(apk io.ReadSeeker) (raw []byte, err error) { return nil, err } defer func() { _ = tp.Close() }() - if err = tp.Send(fmt.Sprintf("abb_exec:package\x00install\x00-t\x00-S\x00%d", filesize)); err != nil { + + cmd := fmt.Sprintf("abb_exec:package\x00install\x00-t\x00-S\x00%d", filesize) + if err = tp.SendWithCheck(cmd); err != nil { return nil, err } - if err = tp.VerifyResponse(); err != nil { - return nil, err - } _, err = apk.Seek(0, io.SeekStart) if err != nil { return nil, err diff --git a/hrp/pkg/gadb/sync_transport.go b/hrp/pkg/gadb/sync_transport.go index ff7346a4..0a37bc29 100644 --- a/hrp/pkg/gadb/sync_transport.go +++ b/hrp/pkg/gadb/sync_transport.go @@ -17,6 +17,7 @@ type syncTransport struct { readTimeout time.Duration } +// newSyncTransport creates a new sync transport with existed tcp socket connection func newSyncTransport(sock net.Conn, readTimeout time.Duration) syncTransport { return syncTransport{sock: sock, readTimeout: readTimeout} } diff --git a/hrp/pkg/gadb/transport.go b/hrp/pkg/gadb/transport.go index d9891069..f667dd4a 100644 --- a/hrp/pkg/gadb/transport.go +++ b/hrp/pkg/gadb/transport.go @@ -27,11 +27,14 @@ type transport struct { readTimeout time.Duration } +// newTransport creates a new tcp socket connection func newTransport(address string, readTimeout ...time.Duration) (tp transport, err error) { if len(readTimeout) == 0 { readTimeout = []time.Duration{DefaultAdbReadTimeout} } - tp.readTimeout = readTimeout[0] + tp = transport{ + readTimeout: readTimeout[0], + } tp.sock, err = net.Dial("tcp", address) if err == nil { // dial success @@ -139,11 +142,15 @@ func (t transport) Close() (err error) { return t.sock.Close() } -func (t transport) CreateSyncTransport() (sTp syncTransport, err error) { - if err = t.Send("sync:"); err != nil { - return syncTransport{}, err +func (t transport) SendWithCheck(command string) (err error) { + if err = t.Send(command); err != nil { + return err } - if err = t.VerifyResponse(); err != nil { + return t.VerifyResponse() +} + +func (t transport) CreateSyncTransport() (sTp syncTransport, err error) { + if err = t.SendWithCheck("sync:"); err != nil { return syncTransport{}, err } sTp = newSyncTransport(t.sock, t.readTimeout) From 0c8d86639bffc163b476f9042144a2b10b680033 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Fri, 23 Jun 2023 13:52:56 +0800 Subject: [PATCH 06/10] change: simplify tests --- hrp/pkg/gadb/client_test.go | 88 +++------ hrp/pkg/gadb/device_test.go | 360 ++++++++++++------------------------ 2 files changed, 150 insertions(+), 298 deletions(-) diff --git a/hrp/pkg/gadb/client_test.go b/hrp/pkg/gadb/client_test.go index 56dd1a94..028a3b59 100644 --- a/hrp/pkg/gadb/client_test.go +++ b/hrp/pkg/gadb/client_test.go @@ -7,11 +7,18 @@ import ( "testing" ) -func TestClient_ServerVersion(t *testing.T) { - adbClient, err := NewClient() +var adbClient Client + +func setupClient(t *testing.T) { + var err error + adbClient, err = NewClient() if err != nil { t.Fatal(err) } +} + +func TestClient_ServerVersion(t *testing.T) { + setupClient(t) adbServerVersion, err := adbClient.ServerVersion() if err != nil { @@ -22,10 +29,7 @@ func TestClient_ServerVersion(t *testing.T) { } func TestClient_DeviceSerialList(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) serials, err := adbClient.DeviceSerialList() if err != nil { @@ -38,15 +42,7 @@ func TestClient_DeviceSerialList(t *testing.T) { } func TestClient_DeviceList(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { t.Log(devices[i].serial, devices[i].DeviceInfo()) @@ -54,10 +50,7 @@ func TestClient_DeviceList(t *testing.T) { } func TestClient_ForwardList(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) deviceForwardList, err := adbClient.ForwardList() if err != nil { @@ -70,80 +63,59 @@ func TestClient_ForwardList(t *testing.T) { } func TestClient_ForwardKillAll(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) - err = adbClient.ForwardKillAll() + err := adbClient.ForwardKillAll() if err != nil { t.Fatal(err) } } func TestClient_Connect(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) - err = adbClient.Connect("192.168.1.28") + err := adbClient.Connect("192.168.1.28") if err != nil { t.Fatal(err) } } func TestClient_Disconnect(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) - err = adbClient.Disconnect("192.168.1.28") + err := adbClient.Disconnect("192.168.1.28") if err != nil { t.Fatal(err) } } func TestClient_DisconnectAll(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) - err = adbClient.DisconnectAll() + err := adbClient.DisconnectAll() if err != nil { t.Fatal(err) } } func TestClient_KillServer(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupClient(t) - err = adbClient.KillServer() + err := adbClient.KillServer() if err != nil { t.Fatal(err) } } func TestScreenCap(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - dl, err := adbClient.DeviceList() - if err != nil { - t.Error(err) + for _, d := range devices { + res, err := d.ScreenCap() + if err != nil { + t.Error(err) + } + t.Log(len(res)) + ioutil.WriteFile("/tmp/1.png", res, 0o644) } - d := dl[0] - res, err := d.ScreenCap() - if err != nil { - t.Error(err) - } - t.Log(len(res)) - ioutil.WriteFile("/tmp/1.png", res, 0o644) } diff --git a/hrp/pkg/gadb/device_test.go b/hrp/pkg/gadb/device_test.go index 29f48b4d..50b37175 100644 --- a/hrp/pkg/gadb/device_test.go +++ b/hrp/pkg/gadb/device_test.go @@ -12,16 +12,19 @@ import ( "time" ) -func TestDevice_State(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } +var devices []*Device - devices, err := adbClient.DeviceList() +func setupDevices(t *testing.T) { + var err error + setupClient(t) + devices, err = adbClient.DeviceList() if err != nil { t.Fatal(err) } +} + +func TestDevice_State(t *testing.T) { + setupDevices(t) for i := range devices { dev := devices[i] @@ -30,19 +33,17 @@ func TestDevice_State(t *testing.T) { t.Fatal(err) } t.Log(dev.Serial(), state) + + resp, err := dev.RunShellCommand("ls") + if err != nil { + t.Fatal(err) + } + t.Log(string(resp)) } } func TestDevice_DevicePath(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -55,15 +56,7 @@ func TestDevice_DevicePath(t *testing.T) { } func TestDevice_Product(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -73,15 +66,7 @@ func TestDevice_Product(t *testing.T) { } func TestDevice_Model(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -90,15 +75,7 @@ func TestDevice_Model(t *testing.T) { } func TestDevice_Usb(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -107,15 +84,7 @@ func TestDevice_Usb(t *testing.T) { } func TestDevice_DeviceInfo(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -124,74 +93,54 @@ func TestDevice_DeviceInfo(t *testing.T) { } func TestDevice_Forward(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + for _, device := range devices { + localPort := 61000 + err := device.Forward(localPort, 6790) + if err != nil { + t.Fatal(err) + } - localPort := 61000 - err = devices[0].Forward(localPort, 6790) - if err != nil { - t.Fatal(err) - } - - err = devices[0].ForwardKill(localPort) - if err != nil { - t.Fatal(err) + err = device.ForwardKill(localPort) + if err != nil { + t.Fatal(err) + } } } func TestDevice_ReverseForward(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + for _, device := range devices { + localPort := 5005 + err := device.ReverseForward(localPort, "localabstract:scrcpy") + if err != nil { + t.Fatal(err) + } + err = device.ReverseForward(localPort, "localabstract:scrcpy1") + if err != nil { + t.Fatal(err) + } - localPort := 5005 - err = devices[0].ReverseForward(localPort, "localabstract:scrcpy") - if err != nil { - t.Fatal(err) - } - err = devices[0].ReverseForward(localPort, "localabstract:scrcpy1") - if err != nil { - t.Fatal(err) - } + _, err = device.ReverseForwardList() + if err != nil { + t.Fatal(err) + } - _, err = devices[0].ReverseForwardList() - if err != nil { - t.Fatal(err) - } - - err = devices[0].ReverseForwardKill("localabstract:scrcpy1") - if err != nil { - t.Fatal(err) - } - err = devices[0].ReverseForwardKillAll() - if err != nil { - t.Fatal(err) + err = device.ReverseForwardKill("localabstract:scrcpy1") + if err != nil { + t.Fatal(err) + } + err = device.ReverseForwardKillAll() + if err != nil { + t.Fatal(err) + } } } func TestDevice_ForwardList(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) for i := range devices { dev := devices[i] @@ -204,32 +153,18 @@ func TestDevice_ForwardList(t *testing.T) { } func TestDevice_ForwardKill(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } - - err = devices[0].ForwardKill(6790) - if err != nil { - t.Fatal(err) + for _, device := range devices { + err := device.ForwardKill(6790) + if err != nil { + t.Fatal(err) + } } } func TestDevice_RunShellCommand(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + setupDevices(t) // for i := range devices { // dev := devices[i] @@ -243,112 +178,75 @@ func TestDevice_RunShellCommand(t *testing.T) { // t.Log("\n"+dev.serial, cmdOutput) // } - dev := devices[len(devices)-1] - dev = devices[0] - - // cmdOutput, err := dev.RunShellCommand("monkey", "-p", "tv.danmaku.bili", "-c", "android.intent.category.LAUNCHER", "1") - cmdOutput, err := dev.RunShellCommand("ls /sdcard") - // cmdOutput, err := dev.RunShellCommandWithBytes("screencap -p") - if err != nil { - t.Fatal(dev.serial, err) + for _, dev := range devices { + // cmdOutput, err := dev.RunShellCommand("monkey", "-p", "tv.danmaku.bili", "-c", "android.intent.category.LAUNCHER", "1") + cmdOutput, err := dev.RunShellCommand("ls /sdcard") + // cmdOutput, err := dev.RunShellCommandWithBytes("screencap -p") + if err != nil { + t.Fatal(dev.serial, err) + } + t.Log("\n⬇️"+dev.serial+"⬇️\n", cmdOutput) } - t.Log("\n⬇️"+dev.serial+"⬇️\n", cmdOutput) } func TestDevice_EnableAdbOverTCP(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } - - dev := devices[len(devices)-1] - dev = devices[0] - - err = dev.EnableAdbOverTCP() - if err != nil { - t.Fatal(err) + for _, dev := range devices { + err := dev.EnableAdbOverTCP() + if err != nil { + t.Fatal(err) + } } } func TestDevice_List(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + for _, dev := range devices { + // fileEntries, err := dev.List("/sdcard") + fileEntries, err := dev.List("/sdcard/Download") + if err != nil { + t.Fatal(err) + } - dev := devices[len(devices)-1] - dev = devices[0] - - // fileEntries, err := dev.List("/sdcard") - fileEntries, err := dev.List("/sdcard/Download") - if err != nil { - t.Fatal(err) - } - - for i := range fileEntries { - t.Log(fileEntries[i].Name, "\t", fileEntries[i].IsDir()) + for i := range fileEntries { + t.Log(fileEntries[i].Name, "\t", fileEntries[i].IsDir()) + } } } func TestDevice_Push(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + for _, dev := range devices { + file, _ := os.Open("/Users/hero/Documents/temp/MuMu共享文件夹/test.txt") + err := dev.PushFile(file, "/sdcard/Download/push.txt", time.Now()) + if err != nil { + t.Fatal(err) + } - dev := devices[len(devices)-1] - dev = devices[0] - - file, _ := os.Open("/Users/hero/Documents/temp/MuMu共享文件夹/test.txt") - err = dev.PushFile(file, "/sdcard/Download/push.txt", time.Now()) - if err != nil { - t.Fatal(err) - } - - err = dev.Push(strings.NewReader("world"), "/sdcard/Download/hello.txt", time.Now()) - if err != nil { - t.Fatal(err) + err = dev.Push(strings.NewReader("world"), "/sdcard/Download/hello.txt", time.Now()) + if err != nil { + t.Fatal(err) + } } } func TestDevice_Pull(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) - } + setupDevices(t) - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } + for _, dev := range devices { + buffer := bytes.NewBufferString("") + err := dev.Pull("/sdcard/Download/hello.txt", buffer) + if err != nil { + t.Fatal(err) + } - dev := devices[len(devices)-1] - dev = devices[0] - - buffer := bytes.NewBufferString("") - err = dev.Pull("/sdcard/Download/hello.txt", buffer) - if err != nil { - t.Fatal(err) - } - - userHomeDir, _ := os.UserHomeDir() - if err = ioutil.WriteFile(userHomeDir+"/Desktop/hello.txt", buffer.Bytes(), DefaultFileMode); err != nil { - t.Fatal(err) + userHomeDir, _ := os.UserHomeDir() + if err = ioutil.WriteFile(userHomeDir+"/Desktop/hello.txt", buffer.Bytes(), DefaultFileMode); err != nil { + t.Fatal(err) + } } } @@ -405,40 +303,22 @@ func TestDevice_RunShellCommandBackgroundWithBytes(t *testing.T) { } func TestDevice_InstallAPK(t *testing.T) { + setupDevices(t) + apk, _ := os.Open("test.apk") - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) + for _, dev := range devices { + res, err := dev.InstallAPK(apk) + if err != nil { + t.Fatal(err) + } + t.Log(res) } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } - - dev := devices[len(devices)-1] - dev = devices[0] - - res, err := dev.InstallAPK(apk) - if err != nil { - t.Fatal(err) - } - t.Log(res) } func TestDevice_HasFeature(t *testing.T) { - adbClient, err := NewClient() - if err != nil { - t.Fatal(err) + setupDevices(t) + + for _, dev := range devices { + t.Log(dev.GetFeatures()) } - - devices, err := adbClient.DeviceList() - if err != nil { - t.Fatal(err) - } - - dev := devices[len(devices)-1] - dev = devices[0] - - t.Log(dev.GetFeatures()) } From 1033ba77d74d57b1027d5acf00b1f2d5526716f7 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Fri, 23 Jun 2023 23:06:56 +0800 Subject: [PATCH 07/10] feat: log step elapsed in seconds --- hrp/pkg/uixt/ocr_vedem.go | 2 +- hrp/runner.go | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/hrp/pkg/uixt/ocr_vedem.go b/hrp/pkg/uixt/ocr_vedem.go index b6b71099..3ce8096a 100644 --- a/hrp/pkg/uixt/ocr_vedem.go +++ b/hrp/pkg/uixt/ocr_vedem.go @@ -248,7 +248,7 @@ func (s *veDEMImageService) GetImage(imageBuf *bytes.Buffer) ( log.Debug(). Str("X-TT-LOGID", logID). Int("image_bytes", size). - Float64("elapsed_seconds", elapsed.Seconds()). + Float64("elapsed(s)", elapsed.Seconds()). Msg("request OCR service success") break } diff --git a/hrp/runner.go b/hrp/runner.go index 829092cd..51e78eed 100644 --- a/hrp/runner.go +++ b/hrp/runner.go @@ -539,8 +539,9 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) error { parsedName = step.Name() } stepName := convertString(parsedName) - log.Info().Str("step", stepName). - Str("type", string(step.Type())).Msg("run step start") + stepType := string(step.Type()) + log.Info().Str("step", stepName).Str("type", stepType).Msg("run step start") + stepStartTime := time.Now() // run times of step loopTimes := step.Struct().Loops @@ -563,10 +564,10 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) error { } // run step - stepStartTime := time.Now().Unix() + startTime := time.Now().Unix() stepResult, err = step.Run(r) stepResult.Name = stepName + loopIndex - stepResult.StartTime = stepStartTime + stepResult.StartTime = startTime r.updateSummary(stepResult) } @@ -576,19 +577,22 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) error { r.sessionVariables[k] = v } + stepElapsed := time.Since(stepStartTime).Seconds() if err == nil { - log.Info().Str("step", stepResult.Name). - Str("type", string(stepResult.StepType)). + log.Info().Str("step", stepName). + Str("type", stepType). Bool("success", true). + Float64("elapsed(s)", stepElapsed). Interface("exportVars", stepResult.ExportVars). Msg("run step end") continue } // failed - log.Error().Err(err).Str("step", stepResult.Name). - Str("type", string(stepResult.StepType)). + log.Error().Err(err).Str("step", stepName). + Str("type", stepType). Bool("success", false). + Float64("elapsed(s)", stepElapsed). Msg("run step end") // interrupted or timeout, abort running From 419febd635936a5a5a2aade1bcf37390ae13f72a Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Fri, 23 Jun 2023 23:40:12 +0800 Subject: [PATCH 08/10] feat: log uixt action elapsed in seconds --- hrp/pkg/uixt/action.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hrp/pkg/uixt/action.go b/hrp/pkg/uixt/action.go index b47ba5a1..eba5a990 100644 --- a/hrp/pkg/uixt/action.go +++ b/hrp/pkg/uixt/action.go @@ -377,7 +377,19 @@ func (dExt *DriverExt) GenAbsScope(x1, y1, x2, y2 float64) AbsScope { } func (dExt *DriverExt) DoAction(action MobileAction) error { - log.Info().Str("method", string(action.Method)).Interface("params", action.Params).Msg("start UI action") + log.Debug(). + Str("method", string(action.Method)). + Interface("params", action.Params). + Msg("uixt action start") + actionStartTime := time.Now() + + defer func() { + log.Debug(). + Str("method", string(action.Method)). + Interface("params", action.Params). + Float64("elapsed(s)", time.Since(actionStartTime).Seconds()). + Msg("uixt action end") + }() switch action.Method { case ACTION_AppInstall: From 9e5511656778d05346f60e4197ab2b54b23e378e Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Sat, 24 Jun 2023 00:07:17 +0800 Subject: [PATCH 09/10] change: log elapsed seconds for shell execution --- hrp/pkg/gadb/device.go | 44 ++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/hrp/pkg/gadb/device.go b/hrp/pkg/gadb/device.go index 515553b1..9d497fcf 100644 --- a/hrp/pkg/gadb/device.go +++ b/hrp/pkg/gadb/device.go @@ -267,6 +267,16 @@ func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, e if strings.TrimSpace(cmd) == "" { return nil, errors.New("adb shell: command cannot be empty") } + + startTime := time.Now() + defer func() { + // log elapsed seconds for shell execution + log.Debug().Str("cmd", + fmt.Sprintf("adb -s %s shell %s", d.serial, cmd)). + Float64("elapsed(s)", time.Since(startTime).Seconds()). + Msg("run adb shell") + }() + raw, err := d.executeCommand(fmt.Sprintf("shell:%s", cmd)) return raw, err } @@ -280,6 +290,15 @@ func (d *Device) RunShellCommandV2WithBytes(cmd string, args ...string) ([]byte, return nil, errors.New("adb shell: command cannot be empty") } + startTime := time.Now() + defer func() { + // log elapsed seconds for shell execution + log.Debug().Str("cmd", + fmt.Sprintf("adb -s %s shell %s", d.serial, cmd)). + Float64("elapsed(s)", time.Since(startTime).Seconds()). + Msg("run adb shell in v2") + }() + raw, err := d.executeCommand(fmt.Sprintf("shell,v2,raw:%s", cmd)) if err != nil { return raw, err @@ -362,31 +381,6 @@ func (d *Device) createDeviceTransport() (tp transport, err error) { } func (d *Device) executeCommand(command string, onlyVerifyResponse ...bool) (raw []byte, err error) { - startTime := time.Now() - defer func() { - // log elapsed seconds for shell execution - elapsed := time.Since(startTime).Seconds() - if strings.HasPrefix(command, "shell,v2,raw:") { - cmd := strings.TrimPrefix(command, "shell,v2,raw:") - log.Debug().Str("cmd", - fmt.Sprintf("adb -s %s shell %s", d.serial, cmd)). - Float64("elapsed(s)", elapsed). - Msg("run adb shell in v2") - } else if strings.HasPrefix(command, "shell:") { - cmd := strings.TrimPrefix(command, "shell:") - log.Debug().Str("cmd", - fmt.Sprintf("adb -s %s shell %s", d.serial, cmd)). - Float64("elapsed(s)", elapsed). - Msg("run adb shell") - } else { - cmd := strings.ReplaceAll(command, ":", " ") - log.Debug().Str("command", - fmt.Sprintf("adb -s %s %s", d.serial, cmd)). - Float64("elapsed(s)", elapsed). - Msg("run adb command") - } - }() - if len(onlyVerifyResponse) == 0 { onlyVerifyResponse = []bool{false} } From 4b66fe8cf673ecec1d0ac488375bb8846bc7a26d Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Wed, 28 Jun 2023 21:00:54 +0800 Subject: [PATCH 10/10] change: bump 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 df1b5b93..ed74eac9 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.4-beta-2306212230 \ No newline at end of file +v4.3.4-beta-2306282100 \ No newline at end of file