refactor: init driver for device

This commit is contained in:
debugtalk
2022-10-11 18:01:49 +08:00
parent dfd463b8d4
commit 36b10cfc23
12 changed files with 178 additions and 158 deletions

View File

@@ -27,48 +27,6 @@ var (
const forwardToPrefix = "forward-to-"
func InitUIAClient(device *AndroidDevice) (*DriverExt, error) {
var deviceOptions []AndroidDeviceOption
if device.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(device.SerialNumber))
}
if device.IP != "" {
deviceOptions = append(deviceOptions, WithAdbIP(device.IP))
}
if device.Port != 0 {
deviceOptions = append(deviceOptions, WithAdbPort(device.Port))
}
// init uia device
androidDevice, err := NewAndroidDevice(deviceOptions...)
if err != nil {
return nil, err
}
driver, err := androidDevice.NewUSBDriver(nil)
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 {
return nil, errors.Wrap(err, "failed to extend UIA Driver")
}
if device.LogOn {
err = driverExt.Driver.StartCaptureLog("hrp_adb_log")
if err != nil {
return nil, err
}
}
driverExt.UUID = androidDevice.UUID()
return driverExt, err
}
type AndroidDeviceOption func(*AndroidDevice)
func WithSerialNumber(serial string) AndroidDeviceOption {
@@ -125,6 +83,15 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er
return nil, fmt.Errorf("device %s not found", device.SerialNumber)
}
func DeviceList() (devices []gadb.Device, err error) {
var adbClient gadb.Client
if adbClient, err = gadb.NewClientWith(AdbServerHost, AdbServerPort); err != nil {
return nil, err
}
return adbClient.DeviceList()
}
type AndroidDevice struct {
d gadb.Device
logcat *DeviceLogcat
@@ -135,17 +102,52 @@ type AndroidDevice struct {
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
}
func (o AndroidDevice) UUID() string {
return o.SerialNumber
func (dev *AndroidDevice) UUID() string {
return dev.SerialNumber
}
func DeviceList() (devices []gadb.Device, err error) {
var adbClient gadb.Client
if adbClient, err = gadb.NewClientWith(AdbServerHost, AdbServerPort); err != nil {
return nil, err
func (dev *AndroidDevice) NewDriver() (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))
}
return adbClient.DeviceList()
androidDevice, err := NewAndroidDevice(deviceOptions...)
if err != nil {
return nil, err
}
return androidDevice.InitUIAClient()
}
func (dev *AndroidDevice) InitUIAClient() (*DriverExt, error) {
driver, err := dev.NewUSBDriver(nil)
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 {
return nil, errors.Wrap(err, "failed to extend UIA Driver")
}
if dev.LogOn {
err = driverExt.Driver.StartCaptureLog("hrp_adb_log")
if err != nil {
return nil, err
}
}
driverExt.UUID = dev.UUID()
return driverExt, err
}
// NewUSBDriver creates new client via USB connected device, this will also start a new session.
@@ -255,6 +257,7 @@ func (l *DeviceLogcat) Errors() (err error) {
func (l *DeviceLogcat) CatchLogcat() (err error) {
if l.cmd != nil {
err = fmt.Errorf("logcat already start")
return
}
cmdLine := fmt.Sprintf("adb -s %s logcat -c && adb -s %s logcat -v time -s iesqaMonitor:V", l.serial, l.serial)
l.cmd = builtin.Command(cmdLine)

View File

@@ -1,4 +1,4 @@
package uixt
package demo
import (
"testing"
@@ -7,12 +7,12 @@ import (
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
)
func TestDemo(t *testing.T) {
func TestIOSDemo(t *testing.T) {
device, err := uixt.NewIOSDevice(uixt.WithWDAPort(8700), uixt.WithWDAMjpegPort(8800))
if err != nil {
t.Fatal(err)
}
driverExt, err := uixt.InitWDAClient(device)
driverExt, err := device.InitWDAClient()
if err != nil {
t.Fatal(err)
}

View File

@@ -7,7 +7,9 @@ import (
)
func TestDriverExt_Drag(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
pathSearch := "/Users/hero/Documents/temp/2020-05/opencv/IMG_map.png"

View File

@@ -205,7 +205,7 @@ func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) {
// wait for action done
time.Sleep(500 * time.Millisecond)
// 优先使用 MJPEG 流进行截图,性能最优
// iOS 优先使用 MJPEG 流进行截图,性能最优
// 如果 MJPEG 流未开启,则使用 WebDriver 的截图接口
if dExt.frame != nil {
return dExt.frame, nil
@@ -259,7 +259,7 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin
func (dExt *DriverExt) ScreenShot(fileName string) (string, error) {
raw, err := dExt.takeScreenShot()
if err != nil {
return "", errors.Wrap(err, "screenshot by WDA failed")
return "", errors.Wrap(err, "screenshot failed")
}
path, err := dExt.saveScreenShot(raw, fileName)

View File

@@ -15,7 +15,9 @@ func TestDriverExt_GesturePassword(t *testing.T) {
password[i], _ = strconv.Atoi(split[i])
}
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
pathSearch := "/Users/hero/Documents/temp/2020-05/opencv/IMG_5.png"

View File

@@ -802,6 +802,7 @@ func WithFrequency(frequency int) DataOption {
// current implemeted device: IOSDevice, AndroidDevice
type Device interface {
UUID() string
NewDriver() (driverExt *DriverExt, err error)
}
// WebDriver defines methods supported by WebDriver drivers.

View File

@@ -29,7 +29,7 @@ const (
// It may help to prevent out of memory or timeout errors while getting the elements source tree,
// but it might restrict the depth of source tree.
// A part of elements source tree might be lost if the value was too small. Defaults to 50
snapshotMaxDepth = 10
snapshotMaxDepth = 16
// Allows to customize accept/dismiss alert button selector.
// It helps you to handle an arbitrary element as accept button in accept alert command.
// The selector should be a valid class chain expression, where the search root is the alert element itself.
@@ -44,81 +44,6 @@ const (
defaultMjpegPort = 9100
)
func InitWDAClient(device *IOSDevice) (*DriverExt, error) {
// init wda device
iosDevice, err := NewIOSDevice(device.opitons()...)
if err != nil {
return nil, err
}
// init WDA driver
capabilities := NewCapabilities()
capabilities.WithDefaultAlertAction(AlertActionAccept)
var driver WebDriver
if env.WDA_USB_DRIVER == "" {
// default use http driver
driver, err = iosDevice.NewHTTPDriver(capabilities)
} else {
driver, err = iosDevice.NewUSBDriver(capabilities)
}
if err != nil {
return nil, errors.Wrap(err, "failed to init WDA driver")
}
// switch to iOS springboard before init WDA session
// avoid getting stuck when some super app is activate such as douyin or wexin
log.Info().Msg("go back to home screen")
if err = driver.Homescreen(); err != nil {
return nil, errors.Wrap(err, "failed to go back to home screen")
}
driverExt, err := Extend(driver)
if err != nil {
return nil, errors.Wrap(err, "failed to extend WebDriver")
}
settings, err := driverExt.Driver.SetAppiumSettings(map[string]interface{}{
"snapshotMaxDepth": snapshotMaxDepth,
"acceptAlertButtonSelector": acceptAlertButtonSelector,
})
if err != nil {
return nil, errors.Wrap(err, "failed to set appium WDA settings")
}
log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings")
if device.LogOn {
err = driverExt.Driver.StartCaptureLog("hrp_wda_log")
if err != nil {
return nil, err
}
}
if device.PerfOptions != nil {
data, err := iosDevice.d.PerfStart(device.perfOpitons()...)
if err != nil {
return nil, err
}
driverExt.perfStop = make(chan struct{})
// start performance monitor
go func() {
for {
select {
case <-driverExt.perfStop:
iosDevice.d.PerfStop()
return
case d := <-data:
fmt.Println(string(d))
driverExt.perfData = append(driverExt.perfData, string(d))
}
}
}()
}
driverExt.UUID = iosDevice.UUID()
return driverExt, nil
}
type IOSDeviceOption func(*IOSDevice)
func WithUDID(udid string) IOSDeviceOption {
@@ -215,6 +140,94 @@ func (dev *IOSDevice) UUID() string {
return dev.UDID
}
func (dev *IOSDevice) NewDriver() (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))
}
iosDevice, err := NewIOSDevice(deviceOptions...)
if err != nil {
return nil, err
}
return iosDevice.InitWDAClient()
}
func (dev *IOSDevice) InitWDAClient() (driverExt *DriverExt, err error) {
// init WDA driver
capabilities := NewCapabilities()
capabilities.WithDefaultAlertAction(AlertActionAccept)
var driver WebDriver
if env.WDA_USB_DRIVER == "" {
// default use http driver
driver, err = dev.NewHTTPDriver(capabilities)
} else {
driver, err = dev.NewUSBDriver(capabilities)
}
if err != nil {
return nil, errors.Wrap(err, "failed to init WDA driver")
}
// switch to iOS springboard before init WDA session
// avoid getting stuck when some super app is activate such as douyin or wexin
log.Info().Msg("go back to home screen")
if err = driver.Homescreen(); err != nil {
return nil, errors.Wrap(err, "failed to go back to home screen")
}
driverExt, err = Extend(driver)
if err != nil {
return nil, errors.Wrap(err, "failed to extend WebDriver")
}
settings, err := driverExt.Driver.SetAppiumSettings(map[string]interface{}{
"snapshotMaxDepth": snapshotMaxDepth,
"acceptAlertButtonSelector": acceptAlertButtonSelector,
})
if err != nil {
return nil, errors.Wrap(err, "failed to set appium WDA settings")
}
log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings")
if dev.LogOn {
err = driverExt.Driver.StartCaptureLog("hrp_wda_log")
if err != nil {
return nil, err
}
}
if dev.PerfOptions != nil {
data, err := dev.d.PerfStart(dev.perfOpitons()...)
if err != nil {
return nil, err
}
driverExt.perfStop = make(chan struct{})
// start performance monitor
go func() {
for {
select {
case <-driverExt.perfStop:
dev.d.PerfStop()
return
case d := <-data:
fmt.Println(string(d))
driverExt.perfData = append(driverExt.perfData, string(d))
}
}
}()
}
driverExt.UUID = dev.UUID()
return driverExt, nil
}
func (dev *IOSDevice) forward(localPort, remotePort int) error {
log.Info().Int("localPort", localPort).Int("remotePort", remotePort).
Str("udid", dev.UDID).Msg("forward tcp port")
@@ -260,19 +273,6 @@ func (dev *IOSDevice) forward(localPort, remotePort int) error {
return nil
}
func (dev *IOSDevice) opitons() (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))
}
return
}
func (dev *IOSDevice) perfOpitons() (perfOptions []giDevice.PerfOption) {
if dev.PerfOptions == nil {
return

View File

@@ -7,7 +7,9 @@ import (
)
func TestDriverExtOCR(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
x, y, width, height, err := driverExt.FindTextByOCR("抖音")

View File

@@ -7,7 +7,9 @@ import (
)
func TestSwipeUntil(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
var point PointF

View File

@@ -7,7 +7,9 @@ import (
)
func TestDriverExt_TapWithNumber(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
pathSearch := "/Users/hero/Documents/temp/2020-05/opencv/flag7.png"
@@ -20,7 +22,9 @@ func TestDriverExt_TapWithNumber(t *testing.T) {
}
func TestDriverExt_TapXY(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
err = driverExt.TapXY(0.4, 0.5, "")
@@ -28,7 +32,9 @@ func TestDriverExt_TapXY(t *testing.T) {
}
func TestDriverExt_TapAbsXY(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
err = driverExt.TapAbsXY(100, 300, "")
@@ -36,7 +42,9 @@ func TestDriverExt_TapAbsXY(t *testing.T) {
}
func TestDriverExt_TapWithOCR(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
// 需要点击文字上方的图标

View File

@@ -7,7 +7,9 @@ import (
)
func TestDriverExt_ForceTouch(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
pathSearch := "/Users/hero/Documents/temp/2020-05/opencv/IMG_ft.png"
@@ -23,7 +25,9 @@ func TestDriverExt_ForceTouch(t *testing.T) {
}
func TestDriverExt_TouchAndHold(t *testing.T) {
driverExt, err := InitWDAClient(nil)
device, err := NewIOSDevice()
checkErr(t, err)
driverExt, err := device.InitWDAClient()
checkErr(t, err)
pathSearch := "/Users/hero/Documents/temp/2020-05/opencv/IMG_ft.png"

View File

@@ -503,11 +503,7 @@ func (r *HRPRunner) initUIClient(device uixt.Device) (client *uixt.DriverExt, er
}
}
if iosDevice, ok := device.(*uixt.IOSDevice); ok {
client, err = uixt.InitWDAClient(iosDevice)
} else if androidDevice, ok := device.(*uixt.AndroidDevice); ok {
client, err = uixt.InitUIAClient(androidDevice)
}
client, err = device.NewDriver()
if err != nil {
return nil, err
}