implement TapByUITypes using WithScreenShotUITypes

This commit is contained in:
buyuxiang
2023-08-25 14:33:13 +08:00
parent 30da13891e
commit 4dace0f589
7 changed files with 194 additions and 213 deletions
+83 -90
View File
@@ -49,9 +49,7 @@
{ {
"method": "swipe_to_tap_app", "method": "swipe_to_tap_app",
"params": "$app_name", "params": "$app_name",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -147,9 +145,7 @@
}, },
{ {
"method": "back", "method": "back",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -222,9 +218,7 @@
{ {
"method": "tap_ocr", "method": "tap_ocr",
"params": "直播", "params": "直播",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -243,9 +237,7 @@
0.5, 0.5,
0.5 0.5
], ],
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -260,12 +252,12 @@
"actions": [ "actions": [
{ {
"method": "tap_cv", "method": "tap_cv",
"params": [
"dyhouse",
"shoppingbag"
],
"options": { "options": {
"identifier": "click_sales_rack" "identifier": "click_sales_rack",
"screenshot_with_ui_types": [
"dyhouse",
"shoppingbag"
]
} }
}, },
{ {
@@ -354,78 +346,78 @@
"method": "video_crawler", "method": "video_crawler",
"params": { "params": {
"feed": { "feed": {
"sleep_random": [ "sleep_random": [
0, 0,
5, 5,
0.6, 0.6,
5, 5,
15, 15,
0.2, 0.2,
15, 15,
50, 50,
0.2 0.2
], ],
"target_count": 10, "target_count": 10,
"target_labels": [ "target_labels": [
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^广告$" "text": "^广告$"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^图文$" "text": "^图文$"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^特效\\|" "text": "^特效\\|"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^模板\\|" "text": "^模板\\|"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^购物\\|" "text": "^购物\\|"
} }
] ]
}, },
"live": { "live": {
"sleep_random": [ "sleep_random": [
20, 20,
20 20
], ],
"target_count": 0 "target_count": 0
}, },
"timeout": 600 "timeout": 600
} }
} }
@@ -466,7 +458,8 @@
"android": { "android": {
"actions": [ "actions": [
{ {
"method": "screenshot" "method": "screenshot",
"options": {}
}, },
{ {
"method": "sleep_random", "method": "sleep_random",
@@ -480,4 +473,4 @@
"loops": 3 "loops": 3
} }
] ]
} }
+14 -12
View File
@@ -24,13 +24,13 @@ func TestAndroidExpertTest(t *testing.T) {
uixt.WithUIA2(true), uixt.WithUIA2(true),
), ),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
// 温启动
hrp.NewStep("app_launch 以及 ui_foreground_app equal 断言"). hrp.NewStep("app_launch 以及 ui_foreground_app equal 断言").
Android(). Android().
AppLaunch("$bundle_id"). AppLaunch("$bundle_id").
Sleep(2). Sleep(2).
Validate(). Validate().
AssertAppInForeground("$bundle_id"), AssertAppInForeground("$bundle_id"),
// 直播赛道
hrp.NewStep("home 以及 swipe_to_tap_app 默认配置"). hrp.NewStep("home 以及 swipe_to_tap_app 默认配置").
Android(). Android().
Home(). Home().
@@ -44,6 +44,7 @@ func TestAndroidExpertTest(t *testing.T) {
). ).
Validate(). Validate().
AssertOCRExists("推荐", "进入抖音失败"), AssertOCRExists("推荐", "进入抖音失败"),
// 直播赛道
hrp.NewStep("【直播】feed头像或卡片进房 swipe_to_tap_texts 自定义配置"). hrp.NewStep("【直播】feed头像或卡片进房 swipe_to_tap_texts 自定义配置").
Android(). Android().
SwipeToTapTexts( SwipeToTapTexts(
@@ -93,19 +94,19 @@ func TestAndroidExpertTest(t *testing.T) {
Android(). Android().
TapByOCR("直播"). TapByOCR("直播").
Sleep(5), Sleep(5),
// 生活服务赛道
hrp.NewStep("【生活服务】进入直播间 tap_xy"). hrp.NewStep("【生活服务】进入直播间 tap_xy").
Android(). Android().
TapXY(0.5, 0.5). TapXY(0.5, 0.5).
Sleep(5), Sleep(5),
// 生活服务赛道
hrp.NewStep("【生活服务】点击货架商品 tap_ocr 自定义配置"). hrp.NewStep("【生活服务】点击货架商品 tap_ocr 自定义配置").
Android(). Android().
TapByUITypes( TapByUITypes(
[]string{"dyhouse", "shoppingbag"}, uixt.WithScreenShotUITypes("dyhouse", "shoppingbag"),
uixt.WithIdentifier("click_sales_rack"), uixt.WithIdentifier("click_sales_rack"),
). ).
Sleep(5), Sleep(5),
// 重新进入应用程序 // 冷启动
hrp.NewStep("app_terminate 以及 ui_foreground_app not_equal 断言"). hrp.NewStep("app_terminate 以及 ui_foreground_app not_equal 断言").
Android(). Android().
AppTerminate("$bundle_id"). AppTerminate("$bundle_id").
@@ -182,12 +183,12 @@ func TestIOSExpertTest(t *testing.T) {
uixt.WithWDAMjpegPort(8800), uixt.WithWDAMjpegPort(8800),
), ),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
hrp.NewStep("app_launch 以及 ui_foreground_app equal 断言"). // 温启动
// iOS 不支持前台 App 断言操作
hrp.NewStep("启动应用程序 app_launch").
IOS(). IOS().
AppLaunch("$bundle_id"). AppLaunch("$bundle_id").
Sleep(2), Sleep(2),
// iOS 不支持前台 App 断言操作
// 直播赛道
hrp.NewStep("home 以及 swipe_to_tap_app 默认配置"). hrp.NewStep("home 以及 swipe_to_tap_app 默认配置").
IOS(). IOS().
Home(). Home().
@@ -201,6 +202,7 @@ func TestIOSExpertTest(t *testing.T) {
). ).
Validate(). Validate().
AssertOCRExists("推荐", "进入抖音失败"), AssertOCRExists("推荐", "进入抖音失败"),
// 直播赛道
hrp.NewStep("【直播】feed头像或卡片进房 swipe_to_tap_texts 自定义配置"). hrp.NewStep("【直播】feed头像或卡片进房 swipe_to_tap_texts 自定义配置").
IOS(). IOS().
SwipeToTapTexts( SwipeToTapTexts(
@@ -246,6 +248,7 @@ func TestIOSExpertTest(t *testing.T) {
uixt.WithIndex(0), uixt.WithIndex(0),
). ).
Sleep(5), Sleep(5),
// 生活服务赛道
hrp.NewStep("选择直播页签 tap_ocr 默认配置"). hrp.NewStep("选择直播页签 tap_ocr 默认配置").
IOS(). IOS().
TapByOCR("直播"). TapByOCR("直播").
@@ -254,20 +257,19 @@ func TestIOSExpertTest(t *testing.T) {
IOS(). IOS().
TapXY(0.5, 0.5). TapXY(0.5, 0.5).
Sleep(5), Sleep(5),
// 生活服务赛道
hrp.NewStep("【生活服务】点击货架商品 tap_ocr 自定义配置"). hrp.NewStep("【生活服务】点击货架商品 tap_ocr 自定义配置").
IOS(). IOS().
TapByUITypes( TapByUITypes(
[]string{"dyhouse", "shoppingbag"}, uixt.WithScreenShotUITypes("dyhouse", "shoppingbag"),
uixt.WithIdentifier("click_sales_rack"), uixt.WithIdentifier("click_sales_rack"),
). ).
Sleep(5), Sleep(5),
// 重新进入应用程序 // 冷启动
hrp.NewStep("app_terminate 以及 ui_foreground_app not_equal 断言"). // iOS 不支持前台 App 断言操作
hrp.NewStep("终止应用程序 app_terminate").
IOS(). IOS().
AppTerminate("$bundle_id"). AppTerminate("$bundle_id").
Sleep(2), Sleep(2),
// iOS 不支持前台 App 断言操作
hrp.NewStep("home 以及 swipe_to_tap_app 自定义配置"). hrp.NewStep("home 以及 swipe_to_tap_app 自定义配置").
IOS(). IOS().
Home(). Home().
+85 -92
View File
@@ -18,7 +18,7 @@
}, },
"teststeps": [ "teststeps": [
{ {
"name": "app_launch 以及 ui_foreground_app equal 断言", "name": "启动应用程序 app_launch",
"ios": { "ios": {
"actions": [ "actions": [
{ {
@@ -42,9 +42,7 @@
{ {
"method": "swipe_to_tap_app", "method": "swipe_to_tap_app",
"params": "$app_name", "params": "$app_name",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -140,9 +138,7 @@
}, },
{ {
"method": "back", "method": "back",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -215,9 +211,7 @@
{ {
"method": "tap_ocr", "method": "tap_ocr",
"params": "直播", "params": "直播",
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -236,9 +230,7 @@
0.5, 0.5,
0.5 0.5
], ],
"options": { "options": {}
}
}, },
{ {
"method": "sleep", "method": "sleep",
@@ -253,12 +245,12 @@
"actions": [ "actions": [
{ {
"method": "tap_cv", "method": "tap_cv",
"params": [
"dyhouse",
"shoppingbag"
],
"options": { "options": {
"identifier": "click_sales_rack" "identifier": "click_sales_rack",
"screenshot_with_ui_types": [
"dyhouse",
"shoppingbag"
]
} }
}, },
{ {
@@ -269,7 +261,7 @@
} }
}, },
{ {
"name": "app_terminate 以及 ui_foreground_app not_equal 断言", "name": "终止应用程序 app_terminate",
"ios": { "ios": {
"actions": [ "actions": [
{ {
@@ -339,78 +331,78 @@
"method": "video_crawler", "method": "video_crawler",
"params": { "params": {
"feed": { "feed": {
"sleep_random": [ "sleep_random": [
0, 0,
5, 5,
0.6, 0.6,
5, 5,
15, 15,
0.2, 0.2,
15, 15,
50, 50,
0.2 0.2
], ],
"target_count": 10, "target_count": 10,
"target_labels": [ "target_labels": [
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^广告$" "text": "^广告$"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^图文$" "text": "^图文$"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^特效\\|" "text": "^特效\\|"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^模板\\|" "text": "^模板\\|"
}, },
{ {
"regex": true, "regex": true,
"scope": [ "scope": [
0, 0,
0.5, 0.5,
1, 1,
1 1
], ],
"text": "^购物\\|" "text": "^购物\\|"
} }
] ]
}, },
"live": { "live": {
"sleep_random": [ "sleep_random": [
20, 20,
20 20
], ],
"target_count": 0 "target_count": 0
}, },
"timeout": 600 "timeout": 600
} }
} }
@@ -451,7 +443,8 @@
"ios": { "ios": {
"actions": [ "actions": [
{ {
"method": "screenshot" "method": "screenshot",
"options": {}
}, },
{ {
"method": "sleep_random", "method": "sleep_random",
@@ -465,4 +458,4 @@
"loops": 3 "loops": 3
} }
] ]
} }
+2 -11
View File
@@ -547,17 +547,8 @@ func (dExt *DriverExt) DoAction(action MobileAction) (err error) {
case ACTION_TapByCV: case ACTION_TapByCV:
if imagePath, ok := action.Params.(string); ok { if imagePath, ok := action.Params.(string); ok {
return dExt.TapByCV(imagePath, action.GetOptions()...) return dExt.TapByCV(imagePath, action.GetOptions()...)
} } else if err := dExt.TapByUIDetection(action.GetOptions()...); err == nil {
if uiParams, ok := action.Params.([]interface{}); ok { return nil
var uiTypes []string
for _, uiParam := range uiParams {
uiType, ok := uiParam.(string)
if !ok {
continue
}
uiTypes = append(uiTypes, uiType)
}
return dExt.TapByUIDetection(uiTypes, action.Options.Options()...)
} }
return fmt.Errorf("invalid %s params: %v", ACTION_TapByCV, action.Params) return fmt.Errorf("invalid %s params: %v", ACTION_TapByCV, action.Params)
case ACTION_DoubleTapXY: case ACTION_DoubleTapXY:
+7 -4
View File
@@ -478,6 +478,7 @@ func (u UIResults) FilterScope(scope AbsScope) (results UIResults) {
type UIResultMap map[string]UIResults type UIResultMap map[string]UIResults
// FilterUIResults filters ui icons, the former the uiTypes, the higher the priority
func (u UIResultMap) FilterUIResults(uiTypes []string) (uiResults UIResults, err error) { func (u UIResultMap) FilterUIResults(uiTypes []string) (uiResults UIResults, err error) {
var ok bool var ok bool
for _, uiType := range uiTypes { for _, uiType := range uiTypes {
@@ -512,20 +513,22 @@ func (u UIResults) GetUIResult(options ...ActionOption) (UIResult, error) {
return uiResults[idx], nil return uiResults[idx], nil
} }
func (dExt *DriverExt) FindUIResult(uiTypes []string, options ...ActionOption) (point PointF, err error) { func (dExt *DriverExt) FindUIResult(options ...ActionOption) (point PointF, err error) {
screenResult, err := dExt.GetScreenResult(WithScreenShotUITypes(uiTypes...)) actionOptions := NewActionOptions(options...)
screenResult, err := dExt.GetScreenResult(options...)
if err != nil { if err != nil {
return return
} }
uiResults, err := screenResult.Icons.FilterUIResults(uiTypes) uiResults, err := screenResult.Icons.FilterUIResults(actionOptions.ScreenShotWithUITypes)
if err != nil { if err != nil {
return return
} }
uiResult, err := uiResults.GetUIResult(dExt.ParseActionOptions(options...)...) uiResult, err := uiResults.GetUIResult(dExt.ParseActionOptions(options...)...)
point = uiResult.Center() point = uiResult.Center()
log.Info().Interface("text", uiTypes). log.Info().Interface("text", actionOptions.ScreenShotWithUITypes).
Interface("point", point).Msg("FindUIResult success") Interface("point", point).Msg("FindUIResult success")
return return
} }
+2 -2
View File
@@ -49,10 +49,10 @@ func (dExt *DriverExt) TapByCV(imagePath string, options ...ActionOption) error
return dExt.TapAbsXY(point.X, point.Y, options...) return dExt.TapAbsXY(point.X, point.Y, options...)
} }
func (dExt *DriverExt) TapByUIDetection(uiTypes []string, options ...ActionOption) error { func (dExt *DriverExt) TapByUIDetection(options ...ActionOption) error {
actionOptions := NewActionOptions(options...) actionOptions := NewActionOptions(options...)
point, err := dExt.FindUIResult(uiTypes, options...) point, err := dExt.FindUIResult(options...)
if err != nil { if err != nil {
if actionOptions.IgnoreNotFoundError { if actionOptions.IgnoreNotFoundError {
return nil return nil
+1 -2
View File
@@ -127,10 +127,9 @@ func (s *StepMobile) TapByCV(imagePath string, options ...uixt.ActionOption) *St
} }
// TapByUITypes taps on the target element specified by uiTypes, the higher the uiTypes, the higher the priority // TapByUITypes taps on the target element specified by uiTypes, the higher the uiTypes, the higher the priority
func (s *StepMobile) TapByUITypes(uiTypes []string, options ...uixt.ActionOption) *StepMobile { func (s *StepMobile) TapByUITypes(options ...uixt.ActionOption) *StepMobile {
action := uixt.MobileAction{ action := uixt.MobileAction{
Method: uixt.ACTION_TapByCV, Method: uixt.ACTION_TapByCV,
Params: uiTypes,
Options: uixt.NewActionOptions(options...), Options: uixt.NewActionOptions(options...),
} }