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

@@ -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,
}