From 75e8b87e7358dc5f503598293b8149113d03a8d5 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Thu, 29 Sep 2022 15:46:30 +0800 Subject: [PATCH] fix: tap x,y positions --- examples/uitest/wda_log_data.json | 112 ++++++++++++++++++++++++++++++ examples/uitest/wda_log_test.go | 48 +++++++++++++ hrp/internal/uixt/ext.go | 45 +++++++++--- hrp/internal/uixt/touch_test.go | 10 --- hrp/internal/version/VERSION | 2 +- hrp/step_ios_ui.go | 10 ++- httprunner/__init__.py | 2 +- pyproject.toml | 2 +- 8 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 examples/uitest/wda_log_data.json create mode 100644 examples/uitest/wda_log_test.go diff --git a/examples/uitest/wda_log_data.json b/examples/uitest/wda_log_data.json new file mode 100644 index 00000000..4623ab7d --- /dev/null +++ b/examples/uitest/wda_log_data.json @@ -0,0 +1,112 @@ +{ + "config": { + "name": "验证 WDA 打点数据准确性", + "variables": { + "app_name": "抖音" + }, + "ios": [ + { + "port": 8700, + "mjpeg_port": 8800, + "log_on": true + } + ] + }, + "teststeps": [ + { + "name": "启动抖音", + "ios": { + "actions": [ + { + "method": "home" + }, + { + "method": "app_terminate", + "params": "com.ss.iphone.ugc.Aweme" + }, + { + "method": "swipe_to_tap_app", + "params": "$app_name", + "identifier": "启动抖音", + "max_retry_times": 5 + }, + { + "method": "sleep", + "params": 5 + } + ] + }, + "validate": [ + { + "check": "ui_ocr", + "assert": "exists", + "expect": "推荐", + "msg": "抖音启动失败,「推荐」不存在" + } + ] + }, + { + "name": "处理青少年弹窗", + "ios": { + "actions": [ + { + "method": "tap_ocr", + "params": "我知道了", + "ignore_NotFoundError": true + } + ] + } + }, + { + "name": "向上滑动 2 次", + "ios": { + "actions": [ + { + "method": "swipe", + "params": "up", + "identifier": "第 1 次上划" + }, + { + "method": "sleep", + "params": 2 + }, + { + "method": "swipe", + "params": "up", + "identifier": "第 2 次上划" + }, + { + "method": "sleep", + "params": 2 + }, + { + "method": "swipe", + "params": "up", + "identifier": "第 3 次上划" + }, + { + "method": "sleep", + "params": 2 + }, + { + "method": "tap_xy", + "params": [ + 0.9, + 0.1 + ], + "identifier": "点击进入搜索框" + }, + { + "method": "sleep", + "params": 2 + }, + { + "method": "input", + "params": "httprunner", + "identifier": "输入搜索关键词" + } + ] + } + } + ] +} diff --git a/examples/uitest/wda_log_test.go b/examples/uitest/wda_log_test.go new file mode 100644 index 00000000..eebc6465 --- /dev/null +++ b/examples/uitest/wda_log_test.go @@ -0,0 +1,48 @@ +//go:build localtest + +package uitest + +import ( + "testing" + + "github.com/httprunner/httprunner/v4/hrp" +) + +func TestWDALog(t *testing.T) { + testCase := &hrp.TestCase{ + Config: hrp.NewConfig("验证 WDA 打点数据准确性"). + WithVariables(map[string]interface{}{ + "app_name": "抖音", + }). + SetIOS(hrp.WithLogOn(true), hrp.WithPort(8700), hrp.WithMjpegPort(8800)), + TestSteps: []hrp.IStep{ + hrp.NewStep("启动抖音"). + IOS(). + Home(). + AppTerminate("com.ss.iphone.ugc.Aweme"). // 关闭已运行的抖音 + SwipeToTapApp("$app_name", hrp.WithMaxRetryTimes(5), hrp.WithIdentifier("启动抖音")).Sleep(5). + Validate(). + AssertOCRExists("推荐", "抖音启动失败,「推荐」不存在"), + hrp.NewStep("处理青少年弹窗"). + IOS(). + TapByOCR("我知道了", hrp.WithIgnoreNotFoundError(true)), + hrp.NewStep("向上滑动 2 次"). + IOS(). + SwipeUp(hrp.WithIdentifier("第 1 次上划")).Sleep(2). + SwipeUp(hrp.WithIdentifier("第 2 次上划")).Sleep(2). + SwipeUp(hrp.WithIdentifier("第 3 次上划")).Sleep(2). + TapXY(0.9, 0.1, hrp.WithIdentifier("点击进入搜索框")).Sleep(2). + Input("httprunner", hrp.WithIdentifier("输入搜索关键词")), + }, + } + + if err := testCase.Dump2JSON("wda_log_data.json"); err != nil { + t.Fatal(err) + } + + runner := hrp.NewRunner(t).SetSaveTests(true) + err := runner.Run(testCase) + if err != nil { + t.Fatal(err) + } +} diff --git a/hrp/internal/uixt/ext.go b/hrp/internal/uixt/ext.go index ae4ab142..927b08c1 100644 --- a/hrp/internal/uixt/ext.go +++ b/hrp/internal/uixt/ext.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "strings" + "testing" "time" "github.com/pkg/errors" @@ -391,21 +392,25 @@ func (dExt *DriverExt) DoAction(action MobileAction) error { case ACTION_Home: return dExt.Driver.Homescreen() case ACTION_TapXY: - if location, ok := action.Params.([]float64); ok { + if location, ok := action.Params.([]interface{}); ok { // relative x,y of window size: [0.5, 0.5] if len(location) != 2 { return fmt.Errorf("invalid tap location params: %v", location) } - return dExt.TapXY(location[0], location[1], action.Identifier) + x, _ := location[0].(float64) + y, _ := location[1].(float64) + return dExt.TapXY(x, y, action.Identifier) } return fmt.Errorf("invalid %s params: %v", ACTION_TapXY, action.Params) case ACTION_TapAbsXY: - if location, ok := action.Params.([]float64); ok { + if location, ok := action.Params.([]interface{}); ok { // absolute coordinates x,y of window size: [100, 300] if len(location) != 2 { return fmt.Errorf("invalid tap location params: %v", location) } - return dExt.TapAbsXY(location[0], location[1], action.Identifier) + x, _ := location[0].(float64) + y, _ := location[1].(float64) + return dExt.TapAbsXY(x, y, action.Identifier) } return fmt.Errorf("invalid %s params: %v", ACTION_TapAbsXY, action.Params) case ACTION_Tap: @@ -424,12 +429,14 @@ func (dExt *DriverExt) DoAction(action MobileAction) error { } return fmt.Errorf("invalid %s params: %v", ACTION_TapByCV, action.Params) case ACTION_DoubleTapXY: - if location, ok := action.Params.([]float64); ok { + if location, ok := action.Params.([]interface{}); ok { // relative x,y of window size: [0.5, 0.5] if len(location) != 2 { return fmt.Errorf("invalid tap location params: %v", location) } - return dExt.DoubleTapXY(location[0], location[1]) + x, _ := location[0].(float64) + y, _ := location[1].(float64) + return dExt.DoubleTapXY(x, y) } return fmt.Errorf("invalid %s params: %v", ACTION_DoubleTapXY, action.Params) case ACTION_DoubleTap: @@ -438,13 +445,16 @@ func (dExt *DriverExt) DoAction(action MobileAction) error { } return fmt.Errorf("invalid %s params: %v", ACTION_DoubleTap, action.Params) case ACTION_Swipe: - if positions, ok := action.Params.([]float64); ok { + if positions, ok := action.Params.([]interface{}); ok { // relative fromX, fromY, toX, toY of window size: [0.5, 0.9, 0.5, 0.1] if len(positions) != 4 { return fmt.Errorf("invalid swipe params [fromX, fromY, toX, toY]: %v", positions) } - return dExt.SwipeRelative( - positions[0], positions[1], positions[2], positions[3], action.Identifier) + fromX, _ := positions[0].(float64) + fromY, _ := positions[1].(float64) + toX, _ := positions[2].(float64) + toY, _ := positions[3].(float64) + return dExt.SwipeRelative(fromX, fromY, toX, toY, action.Identifier) } if direction, ok := action.Params.(string); ok { return dExt.SwipeTo(direction, action.Identifier) @@ -455,6 +465,13 @@ func (dExt *DriverExt) DoAction(action MobileAction) error { // append \n to send text with enter // send \b\b\b to delete 3 chars param := fmt.Sprintf("%v", action.Params) + if action.Identifier != "" { + option := WithCustomOption("log", map[string]interface{}{ + "enable": true, + "data": action.Identifier, + }) + return dExt.Driver.SendKeys(param, option) + } return dExt.Driver.SendKeys(param) case CtlSleep: if param, ok := action.Params.(json.Number); ok { @@ -529,3 +546,13 @@ func (dExt *DriverExt) DoValidation(check, assert, expected string, message ...s Msg("validate UI success") return true } + +func checkErr(t *testing.T, err error, msg ...string) { + if err != nil { + if len(msg) == 0 { + t.Fatal(err) + } else { + t.Fatal(msg, err) + } + } +} diff --git a/hrp/internal/uixt/touch_test.go b/hrp/internal/uixt/touch_test.go index a4b25ade..c89d9879 100644 --- a/hrp/internal/uixt/touch_test.go +++ b/hrp/internal/uixt/touch_test.go @@ -37,13 +37,3 @@ func TestDriverExt_TouchAndHold(t *testing.T) { err = driverExt.TouchAndHoldOffset(pathSearch, 0.8, 0.1) checkErr(t, err) } - -func checkErr(t *testing.T, err error, msg ...string) { - if err != nil { - if len(msg) == 0 { - t.Fatal(err) - } else { - t.Fatal(msg, err) - } - } -} diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 12e4c43d..13572370 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.0-beta-09291106 \ No newline at end of file +v4.3.0-beta-09291549 \ No newline at end of file diff --git a/hrp/step_ios_ui.go b/hrp/step_ios_ui.go index 7b2c0c9e..e0a1a985 100644 --- a/hrp/step_ios_ui.go +++ b/hrp/step_ios_ui.go @@ -243,11 +243,15 @@ func (s *StepIOS) SwipeToTapText(text string, options ...uixt.ActionOption) *Ste return &StepIOS{step: s.step} } -func (s *StepIOS) Input(text string) *StepIOS { - s.step.IOS.Actions = append(s.step.IOS.Actions, uixt.MobileAction{ +func (s *StepIOS) Input(text string, options ...uixt.ActionOption) *StepIOS { + action := uixt.MobileAction{ Method: uixt.ACTION_Input, Params: text, - }) + } + for _, option := range options { + option(&action) + } + s.step.IOS.Actions = append(s.step.IOS.Actions, action) return &StepIOS{step: s.step} } diff --git a/httprunner/__init__.py b/httprunner/__init__.py index d2f494e9..ad5a4b28 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "v4.3.0-beta-09291106" +__version__ = "v4.3.0-beta-09291549" __description__ = "One-stop solution for HTTP(S) testing." diff --git a/pyproject.toml b/pyproject.toml index 6c2b64b0..8c82aeee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "v4.3.0-beta-09291106" +version = "v4.3.0-beta-09291549" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md"