mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-13 17:29:56 +08:00
fix: hrp run ios UI tests
This commit is contained in:
102
examples/uitest/demo_weixin_live.json
Normal file
102
examples/uitest/demo_weixin_live.json
Normal file
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"config": {
|
||||
"name": "通过 feed 卡片进入微信直播间"
|
||||
},
|
||||
"teststeps": [
|
||||
{
|
||||
"name": "启动微信",
|
||||
"ios": {
|
||||
"actions": [
|
||||
{
|
||||
"method": "home"
|
||||
},
|
||||
{
|
||||
"method": "app_terminate",
|
||||
"params": "com.tencent.xin"
|
||||
},
|
||||
{
|
||||
"method": "swipe_to_tap_app",
|
||||
"params": "微信",
|
||||
"max_retry_times": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"validate": [
|
||||
{
|
||||
"check": "ui_label",
|
||||
"assert": "exists",
|
||||
"expect": "通讯录",
|
||||
"msg": "微信启动失败,「通讯录」不存在"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "进入直播页",
|
||||
"ios": {
|
||||
"actions": [
|
||||
{
|
||||
"method": "tap",
|
||||
"params": "发现"
|
||||
},
|
||||
{
|
||||
"method": "tap_ocr",
|
||||
"params": "视频号"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "处理青少年弹窗",
|
||||
"ios": {
|
||||
"actions": [
|
||||
{
|
||||
"method": "tap_ocr",
|
||||
"params": "我知道了",
|
||||
"ignore_NotFoundError": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "在推荐页上划,直到出现「轻触进入直播间」",
|
||||
"ios": {
|
||||
"actions": [
|
||||
{
|
||||
"method": "swipe_to_tap_text",
|
||||
"params": "轻触进入直播间",
|
||||
"max_retry_times": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "向上滑动,等待 10s",
|
||||
"ios": {
|
||||
"actions": [
|
||||
{
|
||||
"method": "swipe",
|
||||
"params": "up"
|
||||
},
|
||||
{
|
||||
"method": "sleep",
|
||||
"params": 10
|
||||
},
|
||||
{
|
||||
"method": "screenshot"
|
||||
},
|
||||
{
|
||||
"method": "swipe",
|
||||
"params": "up"
|
||||
},
|
||||
{
|
||||
"method": "sleep",
|
||||
"params": 10
|
||||
},
|
||||
{
|
||||
"method": "screenshot"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -34,7 +34,7 @@ func TestIOSWeixinLive(t *testing.T) {
|
||||
SwipeUp().Sleep(10).ScreenShot(), // 再上划 1 次,等待 10s,截图保存
|
||||
},
|
||||
}
|
||||
fmt.Println(testCase)
|
||||
|
||||
if err := testCase.Dump2JSON("demo_weixin_live.json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
14
hrp/step.go
14
hrp/step.go
@@ -56,31 +56,31 @@ const (
|
||||
)
|
||||
|
||||
type MobileAction struct {
|
||||
Method MobileMethod `json:"method" yaml:"method"`
|
||||
Method MobileMethod `json:"method,omitempty" yaml:"method,omitempty"`
|
||||
Params interface{} `json:"params,omitempty" yaml:"params,omitempty"`
|
||||
|
||||
maxRetryTimes int // max retry times
|
||||
timeout int // TODO: wait timeout in seconds for mobile action
|
||||
ignoreNotFoundError bool // ignore error if target element not found
|
||||
MaxRetryTimes int `json:"max_retry_times,omitempty" yaml:"max_retry_times,omitempty"` // max retry times
|
||||
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"` // TODO: wait timeout in seconds for mobile action
|
||||
IgnoreNotFoundError bool `json:"ignore_NotFoundError,omitempty" yaml:"ignore_NotFoundError,omitempty"` // ignore error if target element not found
|
||||
}
|
||||
|
||||
type ActionOption func(o *MobileAction)
|
||||
|
||||
func WithMaxRetryTimes(maxRetryTimes int) ActionOption {
|
||||
return func(o *MobileAction) {
|
||||
o.maxRetryTimes = maxRetryTimes
|
||||
o.MaxRetryTimes = maxRetryTimes
|
||||
}
|
||||
}
|
||||
|
||||
func WithTimeout(timeout int) ActionOption {
|
||||
return func(o *MobileAction) {
|
||||
o.timeout = timeout
|
||||
o.Timeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
func WithIgnoreNotFoundError(ignoreError bool) ActionOption {
|
||||
return func(o *MobileAction) {
|
||||
o.ignoreNotFoundError = ignoreError
|
||||
o.IgnoreNotFoundError = ignoreError
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,10 +195,6 @@ func (s *StepIOS) SwipeToTapApp(appName string, options ...ActionOption) *StepIO
|
||||
for _, option := range options {
|
||||
option(&action)
|
||||
}
|
||||
// default to retry 5 times
|
||||
if action.maxRetryTimes == 0 {
|
||||
action.maxRetryTimes = 5
|
||||
}
|
||||
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
||||
return &StepIOS{step: s.step}
|
||||
}
|
||||
@@ -211,10 +207,6 @@ func (s *StepIOS) SwipeToTapText(text string, options ...ActionOption) *StepIOS
|
||||
for _, option := range options {
|
||||
option(&action)
|
||||
}
|
||||
// default to retry 10 times
|
||||
if action.maxRetryTimes == 0 {
|
||||
action.maxRetryTimes = 10
|
||||
}
|
||||
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
||||
return &StepIOS{step: s.step}
|
||||
}
|
||||
@@ -620,8 +612,12 @@ func (ud *uiDriver) doAction(action MobileAction) error {
|
||||
ud.SwipeTo("right")
|
||||
}
|
||||
|
||||
// default to retry 5 times
|
||||
if action.MaxRetryTimes == 0 {
|
||||
action.MaxRetryTimes = 5
|
||||
}
|
||||
// swipe next screen until app found
|
||||
return ud.SwipeUntil("left", findApp, foundAppAction, action.maxRetryTimes)
|
||||
return ud.SwipeUntil("left", findApp, foundAppAction, action.MaxRetryTimes)
|
||||
}
|
||||
return fmt.Errorf("invalid %s params, should be app name(string), got %v",
|
||||
swipeToTapApp, action.Params)
|
||||
@@ -638,8 +634,12 @@ func (ud *uiDriver) doAction(action MobileAction) error {
|
||||
return d.TapFloat(x+width*0.5, y+height*0.5)
|
||||
}
|
||||
|
||||
// default to retry 10 times
|
||||
if action.MaxRetryTimes == 0 {
|
||||
action.MaxRetryTimes = 10
|
||||
}
|
||||
// swipe until live room found
|
||||
return ud.SwipeUntil("up", findText, foundTextAction, 20)
|
||||
return ud.SwipeUntil("up", findText, foundTextAction, action.MaxRetryTimes)
|
||||
}
|
||||
return fmt.Errorf("invalid %s params, should be app text(string), got %v",
|
||||
swipeToTapText, action.Params)
|
||||
@@ -668,17 +668,17 @@ func (ud *uiDriver) doAction(action MobileAction) error {
|
||||
return fmt.Errorf("invalid %s params: %v", uiTapXY, action.Params)
|
||||
case uiTap:
|
||||
if param, ok := action.Params.(string); ok {
|
||||
return ud.Tap(param, action.ignoreNotFoundError)
|
||||
return ud.Tap(param, action.IgnoreNotFoundError)
|
||||
}
|
||||
return fmt.Errorf("invalid %s params: %v", uiTap, action.Params)
|
||||
case uiTapByOCR:
|
||||
if ocrText, ok := action.Params.(string); ok {
|
||||
return ud.TapByOCR(ocrText, action.ignoreNotFoundError)
|
||||
return ud.TapByOCR(ocrText, action.IgnoreNotFoundError)
|
||||
}
|
||||
return fmt.Errorf("invalid %s params: %v", uiTapByOCR, action.Params)
|
||||
case uiTapByCV:
|
||||
if imagePath, ok := action.Params.(string); ok {
|
||||
return ud.TapByCV(imagePath, action.ignoreNotFoundError)
|
||||
return ud.TapByCV(imagePath, action.IgnoreNotFoundError)
|
||||
}
|
||||
return fmt.Errorf("invalid %s params: %v", uiTapByCV, action.Params)
|
||||
case uiDoubleTapXY:
|
||||
|
||||
@@ -260,6 +260,14 @@ func (tc *TCase) toTestCase() (*TestCase, error) {
|
||||
testCase.TestSteps = append(testCase.TestSteps, &StepWebSocket{
|
||||
step: step,
|
||||
})
|
||||
} else if step.IOS != nil {
|
||||
testCase.TestSteps = append(testCase.TestSteps, &StepIOS{
|
||||
step: step,
|
||||
})
|
||||
} else if step.Android != nil {
|
||||
testCase.TestSteps = append(testCase.TestSteps, &StepAndroid{
|
||||
step: step,
|
||||
})
|
||||
} else {
|
||||
log.Warn().Interface("step", step).Msg("[convertTestCase] unexpected step")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user