mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 15:37:35 +08:00
fix: hrp run ios UI tests
This commit is contained in:
@@ -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,截图保存
|
SwipeUp().Sleep(10).ScreenShot(), // 再上划 1 次,等待 10s,截图保存
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fmt.Println(testCase)
|
|
||||||
if err := testCase.Dump2JSON("demo_weixin_live.json"); err != nil {
|
if err := testCase.Dump2JSON("demo_weixin_live.json"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -56,31 +56,31 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MobileAction struct {
|
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"`
|
Params interface{} `json:"params,omitempty" yaml:"params,omitempty"`
|
||||||
|
|
||||||
maxRetryTimes int // max retry times
|
MaxRetryTimes int `json:"max_retry_times,omitempty" yaml:"max_retry_times,omitempty"` // max retry times
|
||||||
timeout int // TODO: wait timeout in seconds for mobile action
|
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"` // TODO: wait timeout in seconds for mobile action
|
||||||
ignoreNotFoundError bool // ignore error if target element not found
|
IgnoreNotFoundError bool `json:"ignore_NotFoundError,omitempty" yaml:"ignore_NotFoundError,omitempty"` // ignore error if target element not found
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionOption func(o *MobileAction)
|
type ActionOption func(o *MobileAction)
|
||||||
|
|
||||||
func WithMaxRetryTimes(maxRetryTimes int) ActionOption {
|
func WithMaxRetryTimes(maxRetryTimes int) ActionOption {
|
||||||
return func(o *MobileAction) {
|
return func(o *MobileAction) {
|
||||||
o.maxRetryTimes = maxRetryTimes
|
o.MaxRetryTimes = maxRetryTimes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithTimeout(timeout int) ActionOption {
|
func WithTimeout(timeout int) ActionOption {
|
||||||
return func(o *MobileAction) {
|
return func(o *MobileAction) {
|
||||||
o.timeout = timeout
|
o.Timeout = timeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithIgnoreNotFoundError(ignoreError bool) ActionOption {
|
func WithIgnoreNotFoundError(ignoreError bool) ActionOption {
|
||||||
return func(o *MobileAction) {
|
return func(o *MobileAction) {
|
||||||
o.ignoreNotFoundError = ignoreError
|
o.IgnoreNotFoundError = ignoreError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -195,10 +195,6 @@ func (s *StepIOS) SwipeToTapApp(appName string, options ...ActionOption) *StepIO
|
|||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(&action)
|
option(&action)
|
||||||
}
|
}
|
||||||
// default to retry 5 times
|
|
||||||
if action.maxRetryTimes == 0 {
|
|
||||||
action.maxRetryTimes = 5
|
|
||||||
}
|
|
||||||
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
||||||
return &StepIOS{step: s.step}
|
return &StepIOS{step: s.step}
|
||||||
}
|
}
|
||||||
@@ -211,10 +207,6 @@ func (s *StepIOS) SwipeToTapText(text string, options ...ActionOption) *StepIOS
|
|||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(&action)
|
option(&action)
|
||||||
}
|
}
|
||||||
// default to retry 10 times
|
|
||||||
if action.maxRetryTimes == 0 {
|
|
||||||
action.maxRetryTimes = 10
|
|
||||||
}
|
|
||||||
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
|
||||||
return &StepIOS{step: s.step}
|
return &StepIOS{step: s.step}
|
||||||
}
|
}
|
||||||
@@ -620,8 +612,12 @@ func (ud *uiDriver) doAction(action MobileAction) error {
|
|||||||
ud.SwipeTo("right")
|
ud.SwipeTo("right")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default to retry 5 times
|
||||||
|
if action.MaxRetryTimes == 0 {
|
||||||
|
action.MaxRetryTimes = 5
|
||||||
|
}
|
||||||
// swipe next screen until app found
|
// 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",
|
return fmt.Errorf("invalid %s params, should be app name(string), got %v",
|
||||||
swipeToTapApp, action.Params)
|
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)
|
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
|
// 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",
|
return fmt.Errorf("invalid %s params, should be app text(string), got %v",
|
||||||
swipeToTapText, action.Params)
|
swipeToTapText, action.Params)
|
||||||
@@ -668,17 +668,17 @@ func (ud *uiDriver) doAction(action MobileAction) error {
|
|||||||
return fmt.Errorf("invalid %s params: %v", uiTapXY, action.Params)
|
return fmt.Errorf("invalid %s params: %v", uiTapXY, action.Params)
|
||||||
case uiTap:
|
case uiTap:
|
||||||
if param, ok := action.Params.(string); ok {
|
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)
|
return fmt.Errorf("invalid %s params: %v", uiTap, action.Params)
|
||||||
case uiTapByOCR:
|
case uiTapByOCR:
|
||||||
if ocrText, ok := action.Params.(string); ok {
|
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)
|
return fmt.Errorf("invalid %s params: %v", uiTapByOCR, action.Params)
|
||||||
case uiTapByCV:
|
case uiTapByCV:
|
||||||
if imagePath, ok := action.Params.(string); ok {
|
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)
|
return fmt.Errorf("invalid %s params: %v", uiTapByCV, action.Params)
|
||||||
case uiDoubleTapXY:
|
case uiDoubleTapXY:
|
||||||
|
|||||||
@@ -260,6 +260,14 @@ func (tc *TCase) toTestCase() (*TestCase, error) {
|
|||||||
testCase.TestSteps = append(testCase.TestSteps, &StepWebSocket{
|
testCase.TestSteps = append(testCase.TestSteps, &StepWebSocket{
|
||||||
step: step,
|
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 {
|
} else {
|
||||||
log.Warn().Interface("step", step).Msg("[convertTestCase] unexpected step")
|
log.Warn().Interface("step", step).Msg("[convertTestCase] unexpected step")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user