feat: init device with optional serial, port, mjpeg port

This commit is contained in:
debugtalk
2022-08-23 20:45:34 +08:00
parent 4f3884df0f
commit 3b73571713
10 changed files with 74 additions and 40 deletions

View File

@@ -1,5 +1,9 @@
# Release History
## v4.2.1 (2022-08-23)
- feat: support iOS UI automation with WebDriverAgent
## v4.2.0 (2022-08-21)
**go version**

1
go.mod
View File

@@ -38,3 +38,4 @@ require (
)
// replace github.com/httprunner/funplugin => ../funplugin
replace github.com/electricbubble/gwda => github.com/debugtalk/gwda v0.0.0-20220823102718-fae698f66992

4
go.sum
View File

@@ -93,6 +93,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/gwda v0.0.0-20220823102718-fae698f66992 h1:z5dL+1EechBejcrY+zpeGUTuvUDnP6bTWroyhdqwzas=
github.com/debugtalk/gwda v0.0.0-20220823102718-fae698f66992/go.mod h1:0kmE3KaUs6RECo+wkeSbmfJjQb/anVphrf3mvFvssJ0=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
@@ -101,8 +103,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/electricbubble/gidevice v0.6.2 h1:eIeCHH7Xn5fTwnUv3qL8c7L4anKIHtjlTBkgr1LDVTc=
github.com/electricbubble/gidevice v0.6.2/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
github.com/electricbubble/gwda v0.4.0 h1:+Sbi8WRM8sXh0cXpmY97GiWuR1CNQ/v2tsMUyWxlnV4=
github.com/electricbubble/gwda v0.4.0/go.mod h1:kyzKpP1/iKJ2i4AxmT8sEmSvB8Pz5NcDVwc/m/Jsg6k=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=

View File

@@ -29,6 +29,7 @@ type TConfig struct {
ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"`
ThinkTimeSetting *ThinkTimeConfig `json:"think_time,omitempty" yaml:"think_time,omitempty"`
WebSocketSetting *WebSocketConfig `json:"websocket,omitempty" yaml:"websocket,omitempty"`
IOS []*IOSConfig `json:"ios,omitempty" yaml:"ios,omitempty"`
Timeout float64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` // global timeout in seconds
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
Weight int `json:"weight,omitempty" yaml:"weight,omitempty"`
@@ -90,12 +91,34 @@ func (c *TConfig) SetWeight(weight int) *TConfig {
return c
}
func (c *TConfig) SetWebSocket(times, interval, timeout, size int64) {
func (c *TConfig) SetWebSocket(times, interval, timeout, size int64) *TConfig {
c.WebSocketSetting = &WebSocketConfig{
ReconnectionTimes: times,
ReconnectionInterval: interval,
MaxMessageSize: size,
}
return c
}
func (c *TConfig) SetIOS(device WDADevice) *TConfig {
// each device can have its own settings
if device.UDID != "" {
c.IOS = append(c.IOS, &IOSConfig{
WDADevice: device,
})
return c
}
// device UDID is not specified ,settings will be shared
iosConfig := &IOSConfig{
WDADevice: device,
}
if len(c.IOS) == 0 {
c.IOS = append(c.IOS, iosConfig)
} else {
c.IOS[0] = iosConfig
}
return c
}
type ThinkTimeConfig struct {

View File

@@ -12,12 +12,12 @@ import (
"time"
"github.com/gorilla/websocket"
"github.com/httprunner/funplugin"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"golang.org/x/net/http2"
"github.com/httprunner/funplugin"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/sdk"
)
@@ -384,6 +384,14 @@ func (r *testCaseRunner) parseConfig() error {
}
r.parametersIterator = parametersIterator
// init iOS WDA clients
for _, iosDeviceConfig := range r.parsedConfig.IOS {
_, err := r.hrpRunner.InitWDAClient(iosDeviceConfig.WDADevice)
if err != nil {
return errors.Wrap(err, "init iOS WDA client failed")
}
}
return nil
}

View File

@@ -75,8 +75,8 @@ type TStep struct {
Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"`
ThinkTime *ThinkTime `json:"think_time,omitempty" yaml:"think_time,omitempty"`
WebSocket *WebSocketAction `json:"websocket,omitempty" yaml:"websocket,omitempty"`
Android *AndroidAction `json:"android,omitempty" yaml:"android,omitempty"`
IOS *IOSAction `json:"ios,omitempty" yaml:"ios,omitempty"`
Android *AndroidStep `json:"android,omitempty" yaml:"android,omitempty"`
IOS *IOSStep `json:"ios,omitempty" yaml:"ios,omitempty"`
Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"`
SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"`
TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"`

View File

@@ -2,7 +2,7 @@ package hrp
import "fmt"
type AndroidAction struct {
type AndroidStep struct {
MobileAction
Serial string `json:"serial,omitempty" yaml:"serial,omitempty"`
Actions []MobileAction `json:"actions,omitempty" yaml:"actions,omitempty"`

View File

@@ -32,9 +32,19 @@ const (
dismissAlertButtonSelector = "**/XCUIElementTypeButton[`label IN {'不允许','暂不'}`]"
)
type IOSAction struct {
type IOSConfig struct {
WDADevice
}
type WDADevice struct {
UDID string `json:"udid,omitempty" yaml:"udid,omitempty"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`
MjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"`
}
type IOSStep struct {
WDADevice
MobileAction
UDID string `json:"udid,omitempty" yaml:"udid,omitempty"`
Actions []MobileAction `json:"actions,omitempty" yaml:"actions,omitempty"`
}
@@ -318,7 +328,7 @@ func (s *StepIOSValidation) Run(r *SessionRunner) (*StepResult, error) {
return runStepIOS(r, s.step)
}
func (r *HRPRunner) InitWDAClient(udid string) (client *wdaClient, err error) {
func (r *HRPRunner) InitWDAClient(device WDADevice) (client *wdaClient, err error) {
defer func() {
if err != nil {
return
@@ -336,13 +346,24 @@ func (r *HRPRunner) InitWDAClient(udid string) (client *wdaClient, err error) {
}()
// avoid duplicate init
if udid == "" && len(r.wdaClients) == 1 {
if device.UDID == "" && len(r.wdaClients) == 1 {
for _, v := range r.wdaClients {
return v, nil
}
}
targetDevice, err := getAttachedIOSDevice(udid)
// init wda device
var options []gwda.DeviceOptions
if device.UDID != "" {
options = append(options, gwda.WithSerialNumber(device.UDID))
}
if device.Port != 0 {
options = append(options, gwda.WithPort(device.Port))
}
if device.MjpegPort != 0 {
options = append(options, gwda.WithMjpegPort(device.MjpegPort))
}
targetDevice, err := gwda.NewDevice(options...)
if err != nil {
return nil, err
}
@@ -395,30 +416,6 @@ func (r *HRPRunner) InitWDAClient(udid string) (client *wdaClient, err error) {
return client, nil
}
func getAttachedIOSDevice(udid string) (*gwda.Device, error) {
// get all attached deivces
devices, err := gwda.DeviceList()
if err != nil {
return nil, errors.Wrap(err, "failed to get attached ios devices list")
}
if len(devices) == 0 {
return nil, errors.New("no ios devices attached")
}
if udid == "" {
return &devices[0], nil
}
// find device by udid
for _, device := range devices {
if device.SerialNumber() == udid {
return &device, nil
}
}
return nil, fmt.Errorf("device %s is not attached", udid)
}
func runStepIOS(r *SessionRunner, step *TStep) (stepResult *StepResult, err error) {
stepResult = &StepResult{
Name: step.Name,
@@ -428,7 +425,7 @@ func runStepIOS(r *SessionRunner, step *TStep) (stepResult *StepResult, err erro
}
// init wdaClient driver
wdaClient, err := r.hrpRunner.InitWDAClient(step.IOS.UDID)
wdaClient, err := r.hrpRunner.InitWDAClient(step.IOS.WDADevice)
if err != nil {
return
}

View File

@@ -70,7 +70,8 @@ func TestIOSAppLaunch(t *testing.T) {
func TestIOSWeixinLive(t *testing.T) {
testCase := &TestCase{
Config: NewConfig("ios ui action on 微信直播"),
Config: NewConfig("ios ui action on 微信直播").
SetIOS(WDADevice{Port: 8700, MjpegPort: 8800}),
TestSteps: []IStep{
NewStep("启动微信").
IOS().

View File

@@ -764,7 +764,7 @@ func (s *StepRequest) WebSocket() *StepWebSocket {
// Android creates a new android action
func (s *StepRequest) Android() *StepAndroid {
s.step.Android = &AndroidAction{}
s.step.Android = &AndroidStep{}
return &StepAndroid{
step: s.step,
}
@@ -772,7 +772,7 @@ func (s *StepRequest) Android() *StepAndroid {
// IOS creates a new ios action
func (s *StepRequest) IOS() *StepIOS {
s.step.IOS = &IOSAction{}
s.step.IOS = &IOSStep{}
return &StepIOS{
step: s.step,
}