From 5d91b6960368190162d29d523af03b571ea772da Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Tue, 18 Feb 2025 19:33:57 +0800 Subject: [PATCH] feat: add PushImage/ClearImages in IDriver --- internal/version/VERSION | 2 +- pkg/gadb/device.go | 13 +++++++++++++ pkg/uixt/android_device.go | 19 ++++++++++++++++++- pkg/uixt/android_driver_adb.go | 32 ++++++++++++++++++++++++++++++-- pkg/uixt/driver.go | 4 ++++ pkg/uixt/harmony_driver_hdc.go | 10 ++++++++++ pkg/uixt/ios_driver_wda.go | 28 ++++++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 4 deletions(-) diff --git a/internal/version/VERSION b/internal/version/VERSION index dfe860da..3d1a986b 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0+2502181804 +v5.0.0+2502181933 diff --git a/pkg/gadb/device.go b/pkg/gadb/device.go index d3481458..17e8358e 100644 --- a/pkg/gadb/device.go +++ b/pkg/gadb/device.go @@ -147,6 +147,19 @@ func (d *Device) Usb() (string, error) { return "", errors.New("does not have attribute: usb") } +func (d *Device) SdkVersion() (string, error) { + if d.HasAttribute("sdkVersion") { + return d.attrs["sdkVersion"], nil + } + sdkVersion, err := d.RunShellCommand("getprop", "ro.build.version.sdk") + sdkVersion = strings.TrimSpace(sdkVersion) + if err != nil { + return "", errors.New("does not have attribute: sdkVersion") + } + d.attrs["sdkVersion"] = sdkVersion + return sdkVersion, nil +} + func (d *Device) transportId() (string, error) { if d.HasAttribute("transport_id") { return d.attrs["transport_id"], nil diff --git a/pkg/uixt/android_device.go b/pkg/uixt/android_device.go index b0fa9b55..ae1f3535 100644 --- a/pkg/uixt/android_device.go +++ b/pkg/uixt/android_device.go @@ -254,7 +254,7 @@ func (dev *AndroidDevice) installCommon(apkPath string, args ...string) error { } func (dev *AndroidDevice) Uninstall(packageName string) error { - _, err := dev.Device.RunShellCommand("uninstall", packageName) + _, err := dev.Device.Uninstall(packageName) return err } @@ -339,6 +339,23 @@ func (dev *AndroidDevice) GetPackageInfo(packageName string) (types.AppInfo, err return appInfo, nil } +func (dev *AndroidDevice) GetAppInfo(packageName string) (app types.AppInfo, err error) { + packageInfo, err := dev.RunShellCommand( + "CLASSPATH=/data/local/tmp/evalite", "app_process", "/", + "com.bytedance.iesqa.eval_process.PackageService", packageName, "2>/dev/null") + if packageInfo == "" { + return app, nil + } + if err != nil { + return app, err + } + err = json.Unmarshal([]byte(strings.TrimSpace(packageInfo)), &app) + if err != nil { + log.Error().Err(err).Str("packageInfo", packageInfo) + } + return +} + func (dev *AndroidDevice) getPackageVersion(packageName string) (string, error) { output, err := dev.Device.RunShellCommand("dumpsys", "package", packageName, "|", "grep", "versionName") if err != nil { diff --git a/pkg/uixt/android_driver_adb.go b/pkg/uixt/android_driver_adb.go index 9992fe6a..acd2cb48 100644 --- a/pkg/uixt/android_driver_adb.go +++ b/pkg/uixt/android_driver_adb.go @@ -10,6 +10,7 @@ import ( "io/fs" "os" "os/exec" + "path" "path/filepath" "regexp" "strconv" @@ -423,7 +424,11 @@ func (ad *ADBDriver) Input(text string, opts ...option.ActionOption) error { return nil } // adb shell input text - _, err = ad.runShellCommand("input", "text", text) + return ad.input(text, opts...) +} + +func (ad *ADBDriver) input(text string, _ ...option.ActionOption) error { + _, err := ad.runShellCommand("input", "text", text) if err != nil { return errors.Wrap(err, "send keys failed") } @@ -456,7 +461,7 @@ func (ad *ADBDriver) SendUnicodeKeys(text string, opts ...option.ActionOption) ( log.Warn().Err(err).Msgf("encode text with modified utf7 failed") return } - err = ad.Input("\""+strings.ReplaceAll(encodedStr, "\"", "\\\"")+"\"", opts...) + err = ad.input("\""+strings.ReplaceAll(encodedStr, "\"", "\\\"")+"\"", opts...) return } @@ -850,6 +855,29 @@ func (ad *ADBDriver) TearDown() error { return nil } +func (ad *ADBDriver) OpenUrl(url string) (err error) { + _, err = ad.runShellCommand( + "am", "start", "-W", "-a", "android.intent.action.VIEW", + "-d", fmt.Sprintf("'%s'", url)) + return +} + +func (ad *ADBDriver) PushImage(localPath string) error { + remotePath := path.Join("/sdcard/DCIM/Camera/", path.Base(localPath)) + if err := ad.Device.PushFile(localPath, remotePath); err != nil { + return err + } + _, _ = ad.Device.RunShellCommand("am", "broadcast", + "-a", "android.intent.action.MEDIA_SCANNER_SCAN_FILE", + "-d", fmt.Sprintf("file://%s", remotePath)) + return nil +} + +func (ad *ADBDriver) ClearImages() error { + _, _ = ad.Device.RunShellCommand("rm", "-rf", "/sdcard/DCIM/Camera/*") + return nil +} + type ExportPoint struct { Start int `json:"start" yaml:"start"` End int `json:"end" yaml:"end"` diff --git a/pkg/uixt/driver.go b/pkg/uixt/driver.go index 78fd5dd7..41139d86 100644 --- a/pkg/uixt/driver.go +++ b/pkg/uixt/driver.go @@ -66,6 +66,10 @@ type IDriver interface { AppTerminate(packageName string) (bool, error) AppClear(packageName string) error + // image related + PushImage(localPath string) error + ClearImages() error + // triggers the log capture and returns the log entries StartCaptureLog(identifier ...string) error StopCaptureLog() (result interface{}, err error) diff --git a/pkg/uixt/harmony_driver_hdc.go b/pkg/uixt/harmony_driver_hdc.go index 75738673..e973accd 100644 --- a/pkg/uixt/harmony_driver_hdc.go +++ b/pkg/uixt/harmony_driver_hdc.go @@ -287,3 +287,13 @@ func (hd *HDCDriver) SetRotation(rotation types.Rotation) (err error) { err = types.ErrDriverNotImplemented return } + +func (hd *HDCDriver) PushImage(localPath string) error { + log.Warn().Msg("PushImage not implemented in HDCDriver") + return nil +} + +func (hd *HDCDriver) ClearImages() error { + log.Warn().Msg("ClearImages not implemented in HDCDriver") + return nil +} diff --git a/pkg/uixt/ios_driver_wda.go b/pkg/uixt/ios_driver_wda.go index 55b754c8..1288d141 100644 --- a/pkg/uixt/ios_driver_wda.go +++ b/pkg/uixt/ios_driver_wda.go @@ -12,6 +12,7 @@ import ( "net/http" "os" "os/exec" + "path" "path/filepath" "strconv" "strings" @@ -926,6 +927,33 @@ func (wd *WDADriver) StartCaptureLog(identifier ...string) error { return nil } +func (wd *WDADriver) PushImage(localPath string) error { + localFile, err := os.Open(localPath) + if err != nil { + return err + } + defer localFile.Close() + + imageBytes, err := io.ReadAll(localFile) + data := map[string]interface{}{ + "file_name": path.Base(localPath), + "file_data": base64.StdEncoding.EncodeToString(imageBytes), + } + if err != nil { + return err + } + + _, err = wd.Session.POST(data, "/gtf/albums/add") + return err +} + +func (wd *WDADriver) ClearImages() error { + data := map[string]interface{}{} + + _, err := wd.Session.POST(data, "/gtf/albums/clear") + return err +} + type wdaResponse struct { Status int `json:"status"` SessionID string `json:"sessionId"`