refactor: new ios/android device

This commit is contained in:
debugtalk
2022-10-12 19:38:41 +08:00
parent 71f49303be
commit 43b1c181e5
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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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.20221011141335-8a73d55ade10/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
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.20221012071407-9b59e12ecc77/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
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) {
deviceList, err := DeviceList()
if err != nil {
@@ -107,32 +120,10 @@ func (dev *AndroidDevice) UUID() string {
}
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)
if err != nil {
return nil, errors.Wrap(err, "failed to init UIA driver")
}
fmt.Println(driver)
var driverExt *DriverExt
driverExt, err = Extend(driver)
if err != nil {

View File

@@ -127,6 +127,37 @@ func IOSDevices(udid ...string) (devices []giDevice.Device, err error) {
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) {
device = &IOSDevice{
Port: defaultWDAPort,
@@ -134,6 +165,9 @@ func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) {
SnapshotMaxDepth: snapshotMaxDepth,
AcceptAlertButtonSelector: acceptAlertButtonSelector,
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 {
option(device)
@@ -176,40 +210,6 @@ func (dev *IOSDevice) UUID() string {
}
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
if capabilities == nil {
capabilities = NewCapabilities()

View File

@@ -395,6 +395,9 @@ func (r *testCaseRunner) parseConfig() error {
r.parametersIterator = parametersIterator
// init iOS/Android clients
if r.hrpRunner.uiClients == nil {
r.hrpRunner.uiClients = make(map[string]*uixt.DriverExt)
}
for _, iosDeviceConfig := range r.parsedConfig.IOS {
if iosDeviceConfig.UDID != "" {
udid, err := r.parser.ParseString(iosDeviceConfig.UDID, parsedVariables)
@@ -403,13 +406,16 @@ func (r *testCaseRunner) parseConfig() error {
}
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
iosDeviceConfig.ResetHomeOnStartup = true
_, err := r.hrpRunner.initUIClient(iosDeviceConfig)
device, err := uixt.NewIOSDevice(uixt.GetIOSDeviceOptions(iosDeviceConfig)...)
if err != nil {
return errors.Wrap(err, "init iOS device failed")
}
client, err := device.NewDriver(nil)
if err != nil {
return errors.Wrap(err, "init iOS WDA client failed")
}
r.hrpRunner.uiClients[device.UDID] = client
}
for _, androidDeviceConfig := range r.parsedConfig.Android {
if androidDeviceConfig.SerialNumber != "" {
@@ -419,10 +425,15 @@ func (r *testCaseRunner) parseConfig() error {
}
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 {
return errors.Wrap(err, "init Android UIAutomator client failed")
}
r.hrpRunner.uiClients[device.SerialNumber] = client
}
return nil

View File

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

View File

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