refactor: new ios/android device

This commit is contained in:
debugtalk
2022-10-12 19:38:41 +08:00
parent 43fa5ac0cd
commit f6623c0869
7 changed files with 84 additions and 94 deletions

2
go.mod
View File

@@ -88,4 +88,4 @@ require (
) )
// replace github.com/httprunner/funplugin => ../funplugin // replace github.com/httprunner/funplugin => ../funplugin
replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221011141335-8a73d55ade10 replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221012071407-9b59e12ecc77

4
go.sum
View File

@@ -96,8 +96,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/debugtalk/gidevice v0.6.3-0.20221011141335-8a73d55ade10 h1:LfX+4+EUZbLNKAN1KfFMxlIxZNW9cgFuo3XGgvjulzg= github.com/debugtalk/gidevice v0.6.3-0.20221012071407-9b59e12ecc77 h1:wP/2aKW6YV0ityxp0Ecv8JDwA/cy6gayVhA/t+roO+w=
github.com/debugtalk/gidevice v0.6.3-0.20221011141335-8a73d55ade10/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o= github.com/debugtalk/gidevice v0.6.3-0.20221012071407-9b59e12ecc77/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/electricbubble/gadb v0.0.7 h1:fxvVLVNs3IFKuYAEXDF2tDZUjT9jNCltoTSirjM5dgo= github.com/electricbubble/gadb v0.0.7 h1:fxvVLVNs3IFKuYAEXDF2tDZUjT9jNCltoTSirjM5dgo=

View File

@@ -53,6 +53,19 @@ func WithAdbLogOn(logOn bool) AndroidDeviceOption {
} }
} }
func GetAndroidDeviceOptions(dev *AndroidDevice) (deviceOptions []AndroidDeviceOption) {
if dev.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber))
}
if dev.IP != "" {
deviceOptions = append(deviceOptions, WithAdbIP(dev.IP))
}
if dev.Port != 0 {
deviceOptions = append(deviceOptions, WithAdbPort(dev.Port))
}
return
}
func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, err error) { func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, err error) {
deviceList, err := DeviceList() deviceList, err := DeviceList()
if err != nil { if err != nil {
@@ -107,32 +120,10 @@ func (dev *AndroidDevice) UUID() string {
} }
func (dev *AndroidDevice) NewDriver(capabilities Capabilities) (driverExt *DriverExt, err error) { func (dev *AndroidDevice) NewDriver(capabilities Capabilities) (driverExt *DriverExt, err error) {
var deviceOptions []AndroidDeviceOption
if dev.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber))
}
if dev.IP != "" {
deviceOptions = append(deviceOptions, WithAdbIP(dev.IP))
}
if dev.Port != 0 {
deviceOptions = append(deviceOptions, WithAdbPort(dev.Port))
}
androidDevice, err := NewAndroidDevice(deviceOptions...)
if err != nil {
return nil, err
}
return androidDevice.initUIAClient(capabilities)
}
func (dev *AndroidDevice) initUIAClient(capabilities Capabilities) (*DriverExt, error) {
driver, err := dev.NewUSBDriver(capabilities) driver, err := dev.NewUSBDriver(capabilities)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to init UIA driver") return nil, errors.Wrap(err, "failed to init UIA driver")
} }
fmt.Println(driver)
var driverExt *DriverExt
driverExt, err = Extend(driver) driverExt, err = Extend(driver)
if err != nil { if err != nil {

View File

@@ -127,6 +127,37 @@ func IOSDevices(udid ...string) (devices []giDevice.Device, err error) {
return deviceList, nil return deviceList, nil
} }
func GetIOSDeviceOptions(dev *IOSDevice) (deviceOptions []IOSDeviceOption) {
if dev.UDID != "" {
deviceOptions = append(deviceOptions, WithUDID(dev.UDID))
}
if dev.Port != 0 {
deviceOptions = append(deviceOptions, WithWDAPort(dev.Port))
}
if dev.MjpegPort != 0 {
deviceOptions = append(deviceOptions, WithWDAMjpegPort(dev.MjpegPort))
}
if dev.LogOn {
deviceOptions = append(deviceOptions, WithLogOn(true))
}
if dev.PerfOptions != nil {
deviceOptions = append(deviceOptions, WithPerfOptions(dev.perfOpitons()...))
}
if dev.ResetHomeOnStartup {
deviceOptions = append(deviceOptions, WithResetHomeOnStartup(true))
}
if dev.SnapshotMaxDepth != 0 {
deviceOptions = append(deviceOptions, WithSnapshotMaxDepth(dev.SnapshotMaxDepth))
}
if dev.AcceptAlertButtonSelector != "" {
deviceOptions = append(deviceOptions, WithAcceptAlertButtonSelector(dev.AcceptAlertButtonSelector))
}
if dev.DismissAlertButtonSelector != "" {
deviceOptions = append(deviceOptions, WithAcceptAlertButtonSelector(dev.DismissAlertButtonSelector))
}
return
}
func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) { func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) {
device = &IOSDevice{ device = &IOSDevice{
Port: defaultWDAPort, Port: defaultWDAPort,
@@ -134,6 +165,9 @@ func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) {
SnapshotMaxDepth: snapshotMaxDepth, SnapshotMaxDepth: snapshotMaxDepth,
AcceptAlertButtonSelector: acceptAlertButtonSelector, AcceptAlertButtonSelector: acceptAlertButtonSelector,
DismissAlertButtonSelector: dismissAlertButtonSelector, DismissAlertButtonSelector: dismissAlertButtonSelector,
// switch to iOS springboard before init WDA session
// avoid getting stuck when some super app is active such as douyin or wexin
ResetHomeOnStartup: true,
} }
for _, option := range options { for _, option := range options {
option(device) option(device)
@@ -176,40 +210,6 @@ func (dev *IOSDevice) UUID() string {
} }
func (dev *IOSDevice) NewDriver(capabilities Capabilities) (driverExt *DriverExt, err error) { func (dev *IOSDevice) NewDriver(capabilities Capabilities) (driverExt *DriverExt, err error) {
var deviceOptions []IOSDeviceOption
if dev.UDID != "" {
deviceOptions = append(deviceOptions, WithUDID(dev.UDID))
}
if dev.Port != 0 {
deviceOptions = append(deviceOptions, WithWDAPort(dev.Port))
}
if dev.MjpegPort != 0 {
deviceOptions = append(deviceOptions, WithWDAMjpegPort(dev.MjpegPort))
}
if dev.LogOn {
deviceOptions = append(deviceOptions, WithLogOn(true))
}
if dev.ResetHomeOnStartup {
deviceOptions = append(deviceOptions, WithResetHomeOnStartup(true))
}
if dev.SnapshotMaxDepth != 0 {
deviceOptions = append(deviceOptions, WithSnapshotMaxDepth(dev.SnapshotMaxDepth))
}
if dev.AcceptAlertButtonSelector != "" {
deviceOptions = append(deviceOptions, WithAcceptAlertButtonSelector(dev.AcceptAlertButtonSelector))
}
if dev.DismissAlertButtonSelector != "" {
deviceOptions = append(deviceOptions, WithAcceptAlertButtonSelector(dev.DismissAlertButtonSelector))
}
iosDevice, err := NewIOSDevice(deviceOptions...)
if err != nil {
return nil, err
}
return iosDevice.initWDAClient(capabilities)
}
func (dev *IOSDevice) initWDAClient(capabilities Capabilities) (driverExt *DriverExt, err error) {
// init WDA driver // init WDA driver
if capabilities == nil { if capabilities == nil {
capabilities = NewCapabilities() capabilities = NewCapabilities()

View File

@@ -395,6 +395,9 @@ func (r *testCaseRunner) parseConfig() error {
r.parametersIterator = parametersIterator r.parametersIterator = parametersIterator
// init iOS/Android clients // init iOS/Android clients
if r.hrpRunner.uiClients == nil {
r.hrpRunner.uiClients = make(map[string]*uixt.DriverExt)
}
for _, iosDeviceConfig := range r.parsedConfig.IOS { for _, iosDeviceConfig := range r.parsedConfig.IOS {
if iosDeviceConfig.UDID != "" { if iosDeviceConfig.UDID != "" {
udid, err := r.parser.ParseString(iosDeviceConfig.UDID, parsedVariables) udid, err := r.parser.ParseString(iosDeviceConfig.UDID, parsedVariables)
@@ -403,13 +406,16 @@ func (r *testCaseRunner) parseConfig() error {
} }
iosDeviceConfig.UDID = udid.(string) iosDeviceConfig.UDID = udid.(string)
} }
// switch to iOS springboard before init WDA session
// avoid getting stuck when some super app is active such as douyin or wexin device, err := uixt.NewIOSDevice(uixt.GetIOSDeviceOptions(iosDeviceConfig)...)
iosDeviceConfig.ResetHomeOnStartup = true if err != nil {
_, err := r.hrpRunner.initUIClient(iosDeviceConfig) return errors.Wrap(err, "init iOS device failed")
}
client, err := device.NewDriver(nil)
if err != nil { if err != nil {
return errors.Wrap(err, "init iOS WDA client failed") return errors.Wrap(err, "init iOS WDA client failed")
} }
r.hrpRunner.uiClients[device.UDID] = client
} }
for _, androidDeviceConfig := range r.parsedConfig.Android { for _, androidDeviceConfig := range r.parsedConfig.Android {
if androidDeviceConfig.SerialNumber != "" { if androidDeviceConfig.SerialNumber != "" {
@@ -419,10 +425,15 @@ func (r *testCaseRunner) parseConfig() error {
} }
androidDeviceConfig.SerialNumber = sn.(string) androidDeviceConfig.SerialNumber = sn.(string)
} }
_, err := r.hrpRunner.initUIClient(androidDeviceConfig) device, err := uixt.NewAndroidDevice(uixt.GetAndroidDeviceOptions(androidDeviceConfig)...)
if err != nil {
return errors.Wrap(err, "init iOS device failed")
}
client, err := device.NewDriver(nil)
if err != nil { if err != nil {
return errors.Wrap(err, "init Android UIAutomator client failed") return errors.Wrap(err, "init Android UIAutomator client failed")
} }
r.hrpRunner.uiClients[device.SerialNumber] = client
} }
return nil return nil

View File

@@ -517,17 +517,19 @@ func runStepAndroid(s *SessionRunner, step *TStep) (stepResult *StepResult, err
parser := s.GetParser() parser := s.GetParser()
// parse device serial // parse device serial
if step.Android.AndroidDevice.SerialNumber != "" { serial := step.Android.AndroidDevice.SerialNumber
sn, err := parser.ParseString(step.Android.AndroidDevice.SerialNumber, stepVariables) if serial != "" {
sn, err := parser.ParseString(serial, stepVariables)
if err != nil { if err != nil {
return stepResult, err return stepResult, err
} }
step.Android.AndroidDevice.SerialNumber = sn.(string) serial = sn.(string)
} }
// init uiaClient driver // get uiaClient driver
uiaClient, err := s.hrpRunner.initUIClient(&step.Android.AndroidDevice) uiaClient, ok := s.hrpRunner.uiClients[serial]
if err != nil { if !ok {
err = fmt.Errorf("uia client not found for device %s", serial)
return return
} }
uiaClient.StartTime = s.startTime uiaClient.StartTime = s.startTime

View File

@@ -490,34 +490,19 @@ func (s *StepIOSValidation) Run(r *SessionRunner) (*StepResult, error) {
return runStepIOS(r, s.step) return runStepIOS(r, s.step)
} }
func (r *HRPRunner) initUIClient(device uixt.Device) (client *uixt.DriverExt, err error) { func (r *HRPRunner) getUIDriver(uuid string) (client *uixt.DriverExt, err error) {
uuid := device.UUID()
// avoid duplicate init
if uuid == "" && len(r.uiClients) > 0 { if uuid == "" && len(r.uiClients) > 0 {
for _, v := range r.uiClients { for _, v := range r.uiClients {
return v, nil return v, nil
} }
} }
// avoid duplicate init client, ok := r.uiClients[uuid]
if uuid != "" { if !ok {
if client, ok := r.uiClients[uuid]; ok { err = fmt.Errorf("driver not found for device %s", uuid)
return client, nil return
}
} }
client, err = device.NewDriver(nil)
if err != nil {
return nil, err
}
// cache wda client
if r.uiClients == nil {
r.uiClients = make(map[string]*uixt.DriverExt)
}
r.uiClients[client.UUID] = client
return client, nil return client, nil
} }
@@ -538,16 +523,17 @@ func runStepIOS(s *SessionRunner, step *TStep) (stepResult *StepResult, err erro
parser := s.GetParser() parser := s.GetParser()
// parse device udid // parse device udid
if step.IOS.IOSDevice.UDID != "" { udid := step.IOS.IOSDevice.UDID
udid, err := parser.ParseString(step.IOS.IOSDevice.UDID, stepVariables) if udid != "" {
sn, err := parser.ParseString(udid, stepVariables)
if err != nil { if err != nil {
return stepResult, err return stepResult, err
} }
step.IOS.IOSDevice.UDID = udid.(string) udid = sn.(string)
} }
// init wdaClient driver // init wdaClient driver
wdaClient, err := s.hrpRunner.initUIClient(&step.IOS.IOSDevice) wdaClient, err := s.hrpRunner.getUIDriver(udid)
if err != nil { if err != nil {
return return
} }