feat: support ignoreNotFoundError, ignore error if target element not found

This commit is contained in:
debugtalk
2022-08-31 16:38:53 +08:00
parent f2b25df87e
commit 90a4ee59f9
5 changed files with 66 additions and 24 deletions
+16 -7
View File
@@ -17,37 +17,46 @@ func (dExt *DriverExt) TapXY(x, y float64) error {
return dExt.WebDriver.TapFloat(x, y) return dExt.WebDriver.TapFloat(x, y)
} }
func (dExt *DriverExt) TapByOCR(ocrText string) error { func (dExt *DriverExt) TapByOCR(ocrText string, ignoreNotFoundError bool) error {
x, y, width, height, err := dExt.FindTextByOCR(ocrText) x, y, width, height, err := dExt.FindTextByOCR(ocrText)
if err != nil { if err != nil {
if ignoreNotFoundError {
return nil
}
return err return err
} }
return dExt.WebDriver.TapFloat(x+width*0.5, y+height*0.5) return dExt.WebDriver.TapFloat(x+width*0.5, y+height*0.5)
} }
func (dExt *DriverExt) TapByCV(imagePath string) error { func (dExt *DriverExt) TapByCV(imagePath string, ignoreNotFoundError bool) error {
x, y, width, height, err := dExt.FindImageRectInUIKit(imagePath) x, y, width, height, err := dExt.FindImageRectInUIKit(imagePath)
if err != nil { if err != nil {
if ignoreNotFoundError {
return nil
}
return err return err
} }
return dExt.WebDriver.TapFloat(x+width*0.5, y+height*0.5) return dExt.WebDriver.TapFloat(x+width*0.5, y+height*0.5)
} }
func (dExt *DriverExt) Tap(param string) error { func (dExt *DriverExt) Tap(param string, ignoreNotFoundError bool) error {
return dExt.TapOffset(param, 0.5, 0.5) return dExt.TapOffset(param, 0.5, 0.5, ignoreNotFoundError)
} }
func (dExt *DriverExt) TapOffset(param string, xOffset, yOffset float64) (err error) { func (dExt *DriverExt) TapOffset(param string, xOffset, yOffset float64, ignoreNotFoundError bool) (err error) {
// click on element, find by name attribute // click on element, find by name attribute
ele, err := dExt.FindUIElement(param) ele, err := dExt.FindUIElement(param)
if err == nil { if err == nil {
return ele.Click() return ele.Click()
} }
var x, y, width, height float64 x, y, width, height, err := dExt.FindUIRectInUIKit(param)
if x, y, width, height, err = dExt.FindUIRectInUIKit(param); err != nil { if err != nil {
if ignoreNotFoundError {
return nil
}
return err return err
} }
+1 -1
View File
@@ -43,6 +43,6 @@ func TestDriverExt_TapWithOCR(t *testing.T) {
checkErr(t, err) checkErr(t, err)
// 需要点击文字上方的图标 // 需要点击文字上方的图标
err = driverExt.TapOffset("抖音", 0.5, -1) err = driverExt.TapOffset("抖音", 0.5, -1, false)
checkErr(t, err) checkErr(t, err)
} }
+17
View File
@@ -54,6 +54,23 @@ const (
type MobileAction struct { type MobileAction struct {
Method MobileMethod `json:"method" yaml:"method"` Method MobileMethod `json:"method" yaml:"method"`
Params interface{} `json:"params,omitempty" yaml:"params,omitempty"` Params interface{} `json:"params,omitempty" yaml:"params,omitempty"`
timeout int // TODO: wait timeout in seconds for mobile action
ignoreNotFoundError bool // ignore error if target element not found
}
type ActionOption func(o *MobileAction)
func WithTimeout(timeout int) ActionOption {
return func(o *MobileAction) {
o.timeout = timeout
}
}
func WithIgnoreNotFoundError(ignoreError bool) ActionOption {
return func(o *MobileAction) {
o.ignoreNotFoundError = ignoreError
}
} }
type StepResult struct { type StepResult struct {
+31 -15
View File
@@ -87,29 +87,41 @@ func (s *StepIOS) TapXY(x, y float64) *StepIOS {
} }
// Tap taps on the target element // Tap taps on the target element
func (s *StepIOS) Tap(params string) *StepIOS { func (s *StepIOS) Tap(params string, options ...ActionOption) *StepIOS {
s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ action := MobileAction{
Method: uiTap, Method: uiTap,
Params: params, Params: params,
}) }
for _, option := range options {
option(&action)
}
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
return &StepIOS{step: s.step} return &StepIOS{step: s.step}
} }
// Tap taps on the target element by OCR recognition // Tap taps on the target element by OCR recognition
func (s *StepIOS) TapByOCR(ocrText string) *StepIOS { func (s *StepIOS) TapByOCR(ocrText string, options ...ActionOption) *StepIOS {
s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ action := MobileAction{
Method: uiTapByOCR, Method: uiTapByOCR,
Params: ocrText, Params: ocrText,
}) }
for _, option := range options {
option(&action)
}
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
return &StepIOS{step: s.step} return &StepIOS{step: s.step}
} }
// Tap taps on the target element by CV recognition // Tap taps on the target element by CV recognition
func (s *StepIOS) TapByCV(imagePath string) *StepIOS { func (s *StepIOS) TapByCV(imagePath string, options ...ActionOption) *StepIOS {
s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ action := MobileAction{
Method: uiTapByCV, Method: uiTapByCV,
Params: imagePath, Params: imagePath,
}) }
for _, option := range options {
option(&action)
}
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
return &StepIOS{step: s.step} return &StepIOS{step: s.step}
} }
@@ -122,11 +134,15 @@ func (s *StepIOS) DoubleTapXY(x, y float64) *StepIOS {
return &StepIOS{step: s.step} return &StepIOS{step: s.step}
} }
func (s *StepIOS) DoubleTap(params string) *StepIOS { func (s *StepIOS) DoubleTap(params string, options ...ActionOption) *StepIOS {
s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ action := MobileAction{
Method: uiDoubleTap, Method: uiDoubleTap,
Params: params, Params: params,
}) }
for _, option := range options {
option(&action)
}
s.step.IOS.Actions = append(s.step.IOS.Actions, action)
return &StepIOS{step: s.step} return &StepIOS{step: s.step}
} }
@@ -529,17 +545,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) 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) 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) 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:
+1 -1
View File
@@ -85,7 +85,7 @@ func TestIOSWeixinLive(t *testing.T) {
NewStep("进入直播页"). NewStep("进入直播页").
IOS(). IOS().
Tap("发现").Sleep(5). // 进入「发现页」;等待 5 秒确保加载完成 Tap("发现").Sleep(5). // 进入「发现页」;等待 5 秒确保加载完成
TapXY(0.5, 0.3). // 基于坐标位置点击「直播」;TODO通过 OCR 识别「直播」 TapByOCR("直播"). // 通过 OCR 识别「直播」
Validate(). Validate().
AssertLabelExists("直播"), AssertLabelExists("直播"),
NewStep("向上滑动 5 次"). NewStep("向上滑动 5 次").