mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-06 16:07:45 +08:00
Merge branch 'refactor-hrp-interface' into 'feat/yuhongzheng/harmony'
# Conflicts: # hrp/internal/version/VERSION
This commit is contained in:
+8
-2
@@ -67,6 +67,7 @@ var (
|
|||||||
DeviceHTTPDriverError = errors.New("device HTTP driver error") // 51
|
DeviceHTTPDriverError = errors.New("device HTTP driver error") // 51
|
||||||
DeviceUSBDriverError = errors.New("device USB driver error") // 52
|
DeviceUSBDriverError = errors.New("device USB driver error") // 52
|
||||||
DeviceGetInfoError = errors.New("device get info error") // 60
|
DeviceGetInfoError = errors.New("device get info error") // 60
|
||||||
|
DeviceConfigureError = errors.New("device configure error") // 61
|
||||||
DeviceShellExecError = errors.New("device shell exec error") // 62
|
DeviceShellExecError = errors.New("device shell exec error") // 62
|
||||||
DeviceOfflineError = errors.New("device offline") // 63
|
DeviceOfflineError = errors.New("device offline") // 63
|
||||||
DeviceScreenShotError = errors.New("device screenshot error") // 65
|
DeviceScreenShotError = errors.New("device screenshot error") // 65
|
||||||
@@ -76,6 +77,8 @@ var (
|
|||||||
|
|
||||||
// UI automation related: [70, 80)
|
// UI automation related: [70, 80)
|
||||||
var (
|
var (
|
||||||
|
MobileUIDriverAppNotInstalled = errors.New("mobile UI driver app not installed") // 68
|
||||||
|
MobileUIDriverAppCrashed = errors.New("mobile UI driver app crashed") // 69
|
||||||
MobileUIDriverError = errors.New("mobile UI driver error") // 70
|
MobileUIDriverError = errors.New("mobile UI driver error") // 70
|
||||||
MobileUILaunchAppError = errors.New("mobile UI launch app error") // 71
|
MobileUILaunchAppError = errors.New("mobile UI launch app error") // 71
|
||||||
MobileUITapError = errors.New("mobile UI tap error") // 72
|
MobileUITapError = errors.New("mobile UI tap error") // 72
|
||||||
@@ -96,7 +99,7 @@ var (
|
|||||||
CVResponseError = errors.New("CV parse response error") // 83
|
CVResponseError = errors.New("CV parse response error") // 83
|
||||||
CVResultNotFoundError = errors.New("CV result not found") // 84
|
CVResultNotFoundError = errors.New("CV result not found") // 84
|
||||||
|
|
||||||
ContextUnknowError = errors.New("detect context failed") // 85
|
StateUnknowError = errors.New("detect state failed") // 85
|
||||||
)
|
)
|
||||||
|
|
||||||
// trackings related: [90, 100)
|
// trackings related: [90, 100)
|
||||||
@@ -159,6 +162,7 @@ var errorsMap = map[error]int{
|
|||||||
DeviceHTTPDriverError: 51,
|
DeviceHTTPDriverError: 51,
|
||||||
DeviceUSBDriverError: 52,
|
DeviceUSBDriverError: 52,
|
||||||
DeviceGetInfoError: 60,
|
DeviceGetInfoError: 60,
|
||||||
|
DeviceConfigureError: 61,
|
||||||
DeviceShellExecError: 62,
|
DeviceShellExecError: 62,
|
||||||
DeviceOfflineError: 63,
|
DeviceOfflineError: 63,
|
||||||
DeviceScreenShotError: 65,
|
DeviceScreenShotError: 65,
|
||||||
@@ -166,6 +170,8 @@ var errorsMap = map[error]int{
|
|||||||
DeviceUIResponseSlow: 67,
|
DeviceUIResponseSlow: 67,
|
||||||
|
|
||||||
// UI automation related
|
// UI automation related
|
||||||
|
MobileUIDriverAppNotInstalled: 68,
|
||||||
|
MobileUIDriverAppCrashed: 69,
|
||||||
MobileUIDriverError: 70,
|
MobileUIDriverError: 70,
|
||||||
MobileUILaunchAppError: 71,
|
MobileUILaunchAppError: 71,
|
||||||
MobileUITapError: 72,
|
MobileUITapError: 72,
|
||||||
@@ -183,7 +189,7 @@ var errorsMap = map[error]int{
|
|||||||
CVServiceConnectionError: 82,
|
CVServiceConnectionError: 82,
|
||||||
CVResponseError: 83,
|
CVResponseError: 83,
|
||||||
CVResultNotFoundError: 84,
|
CVResultNotFoundError: 84,
|
||||||
ContextUnknowError: 85,
|
StateUnknowError: 85,
|
||||||
|
|
||||||
// trackings related
|
// trackings related
|
||||||
TrackingGetError: 90,
|
TrackingGetError: 90,
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v4.6.10
|
v5.0.0-beta-2410112229
|
||||||
@@ -675,7 +675,7 @@ func (d *Device) ListPackages() ([]string, error) {
|
|||||||
return packages, nil
|
return packages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) IsPackagesInstalled(packageName string) bool {
|
func (d *Device) IsPackageInstalled(packageName string) bool {
|
||||||
packages, err := d.ListPackages()
|
packages, err := d.ListPackages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@@ -687,6 +687,14 @@ func (d *Device) IsPackagesInstalled(packageName string) bool {
|
|||||||
return builtin.Contains(packages, packageName)
|
return builtin.Contains(packages, packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Device) IsPackageRunning(packageName string) bool {
|
||||||
|
output, err := d.RunShellCommand("pidof", packageName)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(output) != ""
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Device) ScreenCap() ([]byte, error) {
|
func (d *Device) ScreenCap() ([]byte, error) {
|
||||||
if d.HasFeature(FeatShellV2) {
|
if d.HasFeature(FeatShellV2) {
|
||||||
return d.RunShellCommandV2WithBytes("screencap", "-p")
|
return d.RunShellCommandV2WithBytes("screencap", "-p")
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ func TestDevice_ListPackages(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log(res)
|
t.Log(res)
|
||||||
installed := dev.IsPackagesInstalled("io.appium.uiautomator2.server")
|
installed := dev.IsPackageInstalled("io.appium.uiautomator2.server")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DouyinServerPort = 32316
|
DouyinServerPort = 32316
|
||||||
AdbServerHost = "localhost"
|
|
||||||
AdbServerPort = gadb.AdbServerPort // 5037
|
// adb server
|
||||||
UIA2ServerHost = "localhost"
|
AdbServerHost = "localhost"
|
||||||
UIA2ServerPort = 6790
|
AdbServerPort = gadb.AdbServerPort // 5037
|
||||||
|
|
||||||
|
// uiautomator2 server
|
||||||
|
UIA2ServerHost = "localhost"
|
||||||
|
UIA2ServerPort = 6790
|
||||||
|
UIA2ServerPackageName = "io.appium.uiautomator2.server"
|
||||||
|
UIA2ServerTestPackageName = "io.appium.uiautomator2.server.test"
|
||||||
|
|
||||||
EvalInstallerPackageName = "sogou.mobile.explorer"
|
EvalInstallerPackageName = "sogou.mobile.explorer"
|
||||||
InstallViaInstallerCommand = "am start -S -n sogou.mobile.explorer/.PackageInstallerActivity -d"
|
InstallViaInstallerCommand = "am start -S -n sogou.mobile.explorer/.PackageInstallerActivity -d"
|
||||||
)
|
)
|
||||||
@@ -100,8 +107,6 @@ func GetAndroidDeviceOptions(dev *AndroidDevice) (deviceOptions []AndroidDeviceO
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// uiautomator2 server must be started before
|
|
||||||
// adb shell am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner
|
|
||||||
func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, err error) {
|
func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, err error) {
|
||||||
device = &AndroidDevice{
|
device = &AndroidDevice{
|
||||||
UIA2IP: UIA2ServerHost,
|
UIA2IP: UIA2ServerHost,
|
||||||
@@ -191,6 +196,33 @@ type AndroidDevice struct {
|
|||||||
func (dev *AndroidDevice) Init() error {
|
func (dev *AndroidDevice) Init() error {
|
||||||
dev.d.RunShellCommand("ime", "enable", "io.appium.settings/.UnicodeIME")
|
dev.d.RunShellCommand("ime", "enable", "io.appium.settings/.UnicodeIME")
|
||||||
dev.d.RunShellCommand("rm", "-r", env.DeviceActionLogFilePath)
|
dev.d.RunShellCommand("rm", "-r", env.DeviceActionLogFilePath)
|
||||||
|
|
||||||
|
if dev.UIA2 {
|
||||||
|
// uiautomator2 server must be started before
|
||||||
|
|
||||||
|
// check uiautomator server package installed
|
||||||
|
if !dev.d.IsPackageInstalled(UIA2ServerPackageName) {
|
||||||
|
return errors.Wrapf(code.MobileUIDriverAppNotInstalled,
|
||||||
|
"%s not installed", UIA2ServerPackageName)
|
||||||
|
}
|
||||||
|
if !dev.d.IsPackageInstalled(UIA2ServerTestPackageName) {
|
||||||
|
return errors.Wrapf(code.MobileUIDriverAppNotInstalled,
|
||||||
|
"%s not installed", UIA2ServerTestPackageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check uiautomator server package running
|
||||||
|
// if dev.d.IsPackageRunning(UIA2ServerPackageName) {
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// start uiautomator2 server
|
||||||
|
go func() {
|
||||||
|
if err := dev.startUIA2Server(); err != nil {
|
||||||
|
log.Error().Err(err).Msg("start UIA2 failed")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(5 * time.Second) // wait for uiautomator2 server start
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,15 +269,15 @@ func (dev *AndroidDevice) NewDriver(options ...DriverOption) (driverExt *DriverE
|
|||||||
|
|
||||||
// NewUSBDriver creates new client via USB connected device, this will also start a new session.
|
// NewUSBDriver creates new client via USB connected device, this will also start a new session.
|
||||||
func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver IWebDriver, err error) {
|
func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver IWebDriver, err error) {
|
||||||
localPort, err := dev.d.Forward(UIA2ServerPort)
|
localPort, err := dev.d.Forward(dev.UIA2Port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(code.DeviceConnectionError,
|
return nil, errors.Wrap(code.DeviceConnectionError,
|
||||||
fmt.Sprintf("forward port %d->%d failed: %v",
|
fmt.Sprintf("forward port %d->%d failed: %v",
|
||||||
localPort, UIA2ServerPort, err))
|
localPort, dev.UIA2Port, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
rawURL := fmt.Sprintf("http://%s%d:%d/wd/hub",
|
rawURL := fmt.Sprintf("http://%s%d:%d/wd/hub",
|
||||||
forwardToPrefix, localPort, UIA2ServerPort)
|
forwardToPrefix, localPort, dev.UIA2Port)
|
||||||
uiaDriver, err := NewUIADriver(capabilities, rawURL)
|
uiaDriver, err := NewUIADriver(capabilities, rawURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = dev.d.ForwardKill(localPort)
|
_ = dev.d.ForwardKill(localPort)
|
||||||
@@ -356,7 +388,7 @@ func (dev *AndroidDevice) Install(appPath string, opts *InstallOptions) error {
|
|||||||
case "vivo":
|
case "vivo":
|
||||||
return dev.installVivoSilent(app, args...)
|
return dev.installVivoSilent(app, args...)
|
||||||
case "oppo", "realme", "oneplus":
|
case "oppo", "realme", "oneplus":
|
||||||
if dev.d.IsPackagesInstalled(EvalInstallerPackageName) {
|
if dev.d.IsPackageInstalled(EvalInstallerPackageName) {
|
||||||
return dev.installViaInstaller(app, args...)
|
return dev.installViaInstaller(app, args...)
|
||||||
}
|
}
|
||||||
log.Warn().Msg("oppo not install eval installer")
|
log.Warn().Msg("oppo not install eval installer")
|
||||||
@@ -511,6 +543,32 @@ func (dev *AndroidDevice) getPackageMD5(packagePath string) (string, error) {
|
|||||||
return "", errors.New("failed to get package md5")
|
return "", errors.New("failed to get package md5")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dev *AndroidDevice) startUIA2Server() error {
|
||||||
|
const maxRetries = 3
|
||||||
|
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||||
|
log.Info().Str("package", UIA2ServerTestPackageName).
|
||||||
|
Int("attempt", attempt).Msg("start uiautomator server")
|
||||||
|
// $ adb shell am instrument -w $UIA2ServerTestPackageName
|
||||||
|
// -w: wait for instrumentation to finish before returning.
|
||||||
|
// Required for test runners.
|
||||||
|
out, err := dev.d.RunShellCommand("am", "instrument", "-w", UIA2ServerTestPackageName)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "start uiautomator server failed")
|
||||||
|
}
|
||||||
|
if strings.Contains(out, "Process crashed") {
|
||||||
|
log.Error().Msg("uiautomator server crashed, retrying...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Wrapf(code.MobileUIDriverAppCrashed,
|
||||||
|
"uiautomator server crashed %d times", maxRetries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dev *AndroidDevice) stopUIA2Server() error {
|
||||||
|
_, err := dev.d.RunShellCommand("am", "force-stop", UIA2ServerPackageName)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
type LineCallback func(string)
|
type LineCallback func(string)
|
||||||
|
|
||||||
type AdbLogcat struct {
|
type AdbLogcat struct {
|
||||||
|
|||||||
@@ -384,6 +384,7 @@ func TestDriver_AppLaunch(t *testing.T) {
|
|||||||
|
|
||||||
func TestDriver_IsAppInForeground(t *testing.T) {
|
func TestDriver_IsAppInForeground(t *testing.T) {
|
||||||
setupAndroidUIA2Driver(t)
|
setupAndroidUIA2Driver(t)
|
||||||
|
// setupAndroidAdbDriver(t)
|
||||||
|
|
||||||
err := driverExt.Driver.AppLaunch("com.android.settings")
|
err := driverExt.Driver.AppLaunch("com.android.settings")
|
||||||
checkErr(t, err)
|
checkErr(t, err)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package uixt
|
package uixt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
_ "image/gif"
|
_ "image/gif"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DriverExt struct {
|
type DriverExt struct {
|
||||||
|
Ctx context.Context
|
||||||
Device IDevice
|
Device IDevice
|
||||||
Driver IWebDriver
|
Driver IWebDriver
|
||||||
ImageService IImageService // used to extract image data
|
ImageService IImageService // used to extract image data
|
||||||
|
|||||||
@@ -481,6 +481,8 @@ type IDevice interface {
|
|||||||
Init() error // init android device
|
Init() error // init android device
|
||||||
UUID() string // ios udid or android serial
|
UUID() string // ios udid or android serial
|
||||||
LogEnabled() bool
|
LogEnabled() bool
|
||||||
|
|
||||||
|
// TODO: add ctx to NewDriver
|
||||||
NewDriver(...DriverOption) (driverExt *DriverExt, err error)
|
NewDriver(...DriverOption) (driverExt *DriverExt, err error)
|
||||||
|
|
||||||
StartPerf() error
|
StartPerf() error
|
||||||
|
|||||||
Reference in New Issue
Block a user