refactor: merge swipe methods

This commit is contained in:
lilong.129
2025-02-11 21:06:00 +08:00
parent cf1f553489
commit 3b450ce97f
14 changed files with 74 additions and 110 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ func launchAppDriver(pkgName string) (driverExt *uixt.XTDriver, err error) {
func watchVideo(driver *uixt.XTDriver) (err error) { func watchVideo(driver *uixt.XTDriver) (err error) {
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
err = driver.SwipeRelative(0.7, 0.7, 0.7, 0.2) err = driver.Swipe(0.7, 0.7, 0.7, 0.2)
if err != nil { if err != nil {
return err return err
} }
+1 -1
View File
@@ -73,7 +73,7 @@ func launchAppDriver(pkgName string) (driverExt *uixt.XTDriver, err error) {
func watchVideo(driver *uixt.XTDriver) (err error) { func watchVideo(driver *uixt.XTDriver) (err error) {
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
err = driver.SwipeRelative(0.7, 0.7, 0.7, 0.2) err = driver.Swipe(0.7, 0.7, 0.7, 0.2)
if err != nil { if err != nil {
return err return err
} }
+1 -1
View File
@@ -1 +1 @@
v5.0.0+2502111813 v5.0.0+2502112106
+17 -11
View File
@@ -347,12 +347,14 @@ func (ad *ADBDriver) TouchAndHold(x, y float64, opts ...option.ActionOption) (er
} }
func (ad *ADBDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) { func (ad *ADBDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) {
absFromX, absFromY, absToX, absToY, err := convertToAbsoluteCoordinates(ad, fromX, fromY, toX, toY) actionOptions := option.NewActionOptions(opts...)
if err != nil { if !actionOptions.AbsCoordinate {
return err fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(ad, fromX, fromY, toX, toY)
if err != nil {
return err
}
} }
actionOptions := option.NewActionOptions(opts...)
duration := 200.0 duration := 200.0
if actionOptions.Duration > 0 { if actionOptions.Duration > 0 {
duration = actionOptions.Duration * 1000 duration = actionOptions.Duration * 1000
@@ -364,8 +366,8 @@ func (ad *ADBDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO
// adb shell input swipe fromX fromY toX toY // adb shell input swipe fromX fromY toX toY
_, err = ad.runShellCommand( _, err = ad.runShellCommand(
"input", command, "input", command,
fmt.Sprintf("%.1f", absFromX), fmt.Sprintf("%.1f", absFromY), fmt.Sprintf("%.1f", fromX), fmt.Sprintf("%.1f", fromY),
fmt.Sprintf("%.1f", absToX), fmt.Sprintf("%.1f", absToY), fmt.Sprintf("%.1f", toX), fmt.Sprintf("%.1f", toY),
fmt.Sprintf("%d", int(duration)), fmt.Sprintf("%d", int(duration)),
) )
if err != nil { if err != nil {
@@ -375,16 +377,20 @@ func (ad *ADBDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO
} }
func (ad *ADBDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (ad *ADBDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
absFromX, absFromY, absToX, absToY, err := convertToAbsoluteCoordinates(ad, fromX, fromY, toX, toY) var err error
if err != nil { actionOptions := option.NewActionOptions(opts...)
return err if !actionOptions.AbsCoordinate {
fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(ad, fromX, fromY, toX, toY)
if err != nil {
return err
}
} }
// adb shell input swipe fromX fromY toX toY // adb shell input swipe fromX fromY toX toY
_, err = ad.runShellCommand( _, err = ad.runShellCommand(
"input", "swipe", "input", "swipe",
fmt.Sprintf("%.1f", absFromX), fmt.Sprintf("%.1f", absFromY), fmt.Sprintf("%.1f", fromX), fmt.Sprintf("%.1f", fromY),
fmt.Sprintf("%.1f", absToX), fmt.Sprintf("%.1f", absToY), fmt.Sprintf("%.1f", toX), fmt.Sprintf("%.1f", toY),
) )
if err != nil { if err != nil {
return errors.Wrap(err, "adb swipe failed") return errors.Wrap(err, "adb swipe failed")
+15 -22
View File
@@ -325,19 +325,15 @@ func (ud *UIA2Driver) TouchAndHold(x, y float64, opts ...option.ActionOption) (e
// the smoothness and speed of the swipe by specifying the number of steps. // the smoothness and speed of the swipe by specifying the number of steps.
// Each step execution is throttled to 5 milliseconds per step, so for a 100 // Each step execution is throttled to 5 milliseconds per step, so for a 100
// steps, the swipe will take around 0.5 seconds to complete. // steps, the swipe will take around 0.5 seconds to complete.
func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) { func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
var err error
actionOptions := option.NewActionOptions(opts...) actionOptions := option.NewActionOptions(opts...)
if len(actionOptions.Offset) == 4 { if !actionOptions.AbsCoordinate {
fromX += float64(actionOptions.Offset[0]) fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(ud, fromX, fromY, toX, toY)
fromY += float64(actionOptions.Offset[1]) if err != nil {
toX += float64(actionOptions.Offset[2]) return err
toY += float64(actionOptions.Offset[3]) }
} }
fromX += actionOptions.GetRandomOffset()
fromY += actionOptions.GetRandomOffset()
toX += actionOptions.GetRandomOffset()
toY += actionOptions.GetRandomOffset()
data := map[string]interface{}{ data := map[string]interface{}{
"startX": fromX, "startX": fromX,
"startY": fromY, "startY": fromY,
@@ -350,7 +346,7 @@ func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.Action
// register(postHandler, new Drag("/wd/hub/session/:sessionId/touch/drag")) // register(postHandler, new Drag("/wd/hub/session/:sessionId/touch/drag"))
_, err = ud.httpPOST(data, "/session", ud.Session.ID, "touch/drag") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "touch/drag")
return return err
} }
// Swipe performs a swipe from one coordinate to another using the number of steps // Swipe performs a swipe from one coordinate to another using the number of steps
@@ -360,17 +356,14 @@ func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.Action
// `steps` is the number of move steps sent to the system // `steps` is the number of move steps sent to the system
func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
// register(postHandler, new Swipe("/wd/hub/session/:sessionId/touch/perform")) // register(postHandler, new Swipe("/wd/hub/session/:sessionId/touch/perform"))
var err error
actionOptions := option.NewActionOptions(opts...) actionOptions := option.NewActionOptions(opts...)
if len(actionOptions.Offset) == 4 { if !actionOptions.AbsCoordinate {
fromX += float64(actionOptions.Offset[0]) fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(ud, fromX, fromY, toX, toY)
fromY += float64(actionOptions.Offset[1]) if err != nil {
toX += float64(actionOptions.Offset[2]) return err
toY += float64(actionOptions.Offset[3]) }
} }
fromX += actionOptions.GetRandomOffset()
fromY += actionOptions.GetRandomOffset()
toX += actionOptions.GetRandomOffset()
toY += actionOptions.GetRandomOffset()
duration := 200.0 duration := 200.0
if actionOptions.PressDuration > 0 { if actionOptions.PressDuration > 0 {
@@ -395,7 +388,7 @@ func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Actio
// update data options in post data for extra uiautomator configurations // update data options in post data for extra uiautomator configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err := ud.httpPOST(data, "/session", ud.Session.ID, "actions/swipe") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "actions/swipe")
return err return err
} }
+1 -1
View File
@@ -163,7 +163,7 @@ func TestDriver_Swipe(t *testing.T) {
func TestDriver_Swipe_Relative(t *testing.T) { func TestDriver_Swipe_Relative(t *testing.T) {
setupAndroidUIA2Driver(t) setupAndroidUIA2Driver(t)
err := driverExt.SwipeRelative(0.5, 0.7, 0.5, 0.5) err := driverExt.Swipe(0.5, 0.7, 0.5, 0.5)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+1 -10
View File
@@ -66,7 +66,7 @@ type IDriver interface {
TapByTexts(actions ...TapTextAction) error // TODO: remove TapByTexts(actions ...TapTextAction) error // TODO: remove
// swipe // swipe
Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error // by percentage
// input // input
Input(text string, opts ...option.ActionOption) error Input(text string, opts ...option.ActionOption) error
Backspace(count int, opts ...option.ActionOption) error Backspace(count int, opts ...option.ActionOption) error
@@ -102,15 +102,6 @@ type IDriverExt interface {
TapByOCR(text string, opts ...option.ActionOption) error TapByOCR(text string, opts ...option.ActionOption) error
TapByCV(opts ...option.ActionOption) error // TODO: refactor TapByCV(opts ...option.ActionOption) error // TODO: refactor
// swipe
SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
SwipeUp(opts ...option.ActionOption) error
SwipeDown(opts ...option.ActionOption) error
SwipeLeft(opts ...option.ActionOption) error
SwipeRight(opts ...option.ActionOption) error
SwipeToTapApp(appName string, opts ...option.ActionOption) error
CheckPopup() (popup *PopupInfo, err error) CheckPopup() (popup *PopupInfo, err error)
ClosePopupsHandler() error ClosePopupsHandler() error
+6 -36
View File
@@ -14,36 +14,6 @@ import (
"github.com/httprunner/httprunner/v5/pkg/uixt/option" "github.com/httprunner/httprunner/v5/pkg/uixt/option"
) )
// SwipeRelative swipe from relative position [fromX, fromY] to relative position [toX, toY]
func (dExt *XTDriver) SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
absFromX, absFromY, absToX, absToY, err := convertToAbsoluteCoordinates(dExt.IDriver, fromX, fromY, toX, toY)
if err != nil {
return err
}
err = dExt.Swipe(absFromX, absFromY, absToX, absToY, opts...)
if err != nil {
return errors.Wrap(code.MobileUISwipeError, err.Error())
}
return nil
}
func (dExt *XTDriver) SwipeUp(opts ...option.ActionOption) (err error) {
return dExt.SwipeRelative(0.5, 0.5, 0.5, 0.1, opts...)
}
func (dExt *XTDriver) SwipeDown(opts ...option.ActionOption) (err error) {
return dExt.SwipeRelative(0.5, 0.5, 0.5, 0.9, opts...)
}
func (dExt *XTDriver) SwipeLeft(opts ...option.ActionOption) (err error) {
return dExt.SwipeRelative(0.5, 0.5, 0.1, 0.5, opts...)
}
func (dExt *XTDriver) SwipeRight(opts ...option.ActionOption) (err error) {
return dExt.SwipeRelative(0.5, 0.5, 0.9, 0.5, opts...)
}
type Action func(driver *XTDriver) error type Action func(driver *XTDriver) error
func (dExt *XTDriver) LoopUntil(findAction, findCondition, foundAction Action, opts ...option.ActionOption) error { func (dExt *XTDriver) LoopUntil(findAction, findCondition, foundAction Action, opts ...option.ActionOption) error {
@@ -96,20 +66,20 @@ func prepareSwipeAction(dExt *XTDriver, params interface{}, opts ...option.Actio
// enum direction: up, down, left, right // enum direction: up, down, left, right
switch d { switch d {
case "up": case "up":
return dExt.SwipeUp(opts...) return dExt.Swipe(0.5, 0.5, 0.5, 0.1, opts...)
case "down": case "down":
return dExt.SwipeDown(opts...) return dExt.Swipe(0.5, 0.5, 0.5, 0.9, opts...)
case "left": case "left":
return dExt.SwipeLeft(opts...) return dExt.Swipe(0.5, 0.5, 0.1, 0.5, opts...)
case "right": case "right":
return dExt.SwipeRight(opts...) return dExt.Swipe(0.5, 0.5, 0.9, 0.5, opts...)
default: default:
return errors.Wrap(code.InvalidParamError, return errors.Wrap(code.InvalidParamError,
fmt.Sprintf("get unexpected swipe direction: %s", d)) fmt.Sprintf("get unexpected swipe direction: %s", d))
} }
} else if params, err := builtin.ConvertToFloat64Slice(swipeDirection); err == nil && len(params) == 4 { } else if params, err := builtin.ConvertToFloat64Slice(swipeDirection); err == nil && len(params) == 4 {
// custom direction: [fromX, fromY, toX, toY] // custom direction: [fromX, fromY, toX, toY]
if err := dExt.SwipeRelative(params[0], params[1], params[2], params[3], opts...); err != nil { if err := dExt.Swipe(params[0], params[1], params[2], params[3], opts...); err != nil {
log.Error().Err(err).Msgf("swipe from (%v, %v) to (%v, %v) failed", log.Error().Err(err).Msgf("swipe from (%v, %v) to (%v, %v) failed",
params[0], params[1], params[2], params[3]) params[0], params[1], params[2], params[3])
return err return err
@@ -177,7 +147,7 @@ func (dExt *XTDriver) SwipeToTapApp(appName string, opts ...option.ActionOption)
// swipe to first screen // swipe to first screen
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
dExt.SwipeRight() dExt.Swipe(0.5, 0.5, 0.9, 0.5, opts...)
} }
opts = append(opts, option.WithDirection("left")) opts = append(opts, option.WithDirection("left"))
+9 -10
View File
@@ -172,17 +172,14 @@ func (hd *HDCDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO
// Swipe works like Drag, but `pressForDuration` value is 0 // Swipe works like Drag, but `pressForDuration` value is 0
func (hd *HDCDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (hd *HDCDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
var err error
actionOptions := option.NewActionOptions(opts...) actionOptions := option.NewActionOptions(opts...)
if len(actionOptions.Offset) == 4 { if !actionOptions.AbsCoordinate {
fromX += float64(actionOptions.Offset[0]) fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(hd, fromX, fromY, toX, toY)
fromY += float64(actionOptions.Offset[1]) if err != nil {
toX += float64(actionOptions.Offset[2]) return err
toY += float64(actionOptions.Offset[3]) }
} }
fromX += actionOptions.GetRandomOffset()
fromY += actionOptions.GetRandomOffset()
toX += actionOptions.GetRandomOffset()
toY += actionOptions.GetRandomOffset()
duration := 200 duration := 200
if actionOptions.PressDuration > 0 { if actionOptions.PressDuration > 0 {
@@ -192,7 +189,9 @@ func (hd *HDCDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Action
startTime := int(time.Now().UnixMilli()) startTime := int(time.Now().UnixMilli())
hd.points = append(hd.points, ExportPoint{Start: startTime, End: startTime + 100, Ext: actionOptions.Identifier, RunTime: 100}) hd.points = append(hd.points, ExportPoint{Start: startTime, End: startTime + 100, Ext: actionOptions.Identifier, RunTime: 100})
} }
return hd.uiDriver.InjectGesture(ghdc.NewGesture().Start(ghdc.Point{X: int(fromX), Y: int(fromY)}).MoveTo(ghdc.Point{X: int(toX), Y: int(toY)}, duration)) return hd.uiDriver.InjectGesture(
ghdc.NewGesture().Start(ghdc.Point{X: int(fromX), Y: int(fromY)}).
MoveTo(ghdc.Point{X: int(toX), Y: int(toY)}, duration))
} }
func (hd *HDCDriver) SetIme(ime string) error { func (hd *HDCDriver) SetIme(ime string) error {
+1 -1
View File
@@ -46,7 +46,7 @@ func TestHarmonyTap(t *testing.T) {
func TestHarmonySwipe(t *testing.T) { func TestHarmonySwipe(t *testing.T) {
setupHarmonyDevice(t) setupHarmonyDevice(t)
err := hdcDriverExt.SwipeLeft() err := hdcDriverExt.Swipe(0.5, 0.5, 0.1, 0.5)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+9 -14
View File
@@ -573,25 +573,20 @@ func (wd *WDADriver) TouchAndHold(x, y float64, opts ...option.ActionOption) (er
return wd.TapXY(x, y, opts...) return wd.TapXY(x, y, opts...)
} }
func (wd *WDADriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) { func (wd *WDADriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
// [[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDragCoordinate:)] // [[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDragCoordinate:)]
var err error
actionOptions := option.NewActionOptions(opts...) actionOptions := option.NewActionOptions(opts...)
if !actionOptions.AbsCoordinate {
fromX, fromY, toX, toY, err = convertToAbsoluteCoordinates(wd, fromX, fromY, toX, toY)
if err != nil {
return err
}
}
fromX = wd.toScale(fromX) fromX = wd.toScale(fromX)
fromY = wd.toScale(fromY) fromY = wd.toScale(fromY)
toX = wd.toScale(toX) toX = wd.toScale(toX)
toY = wd.toScale(toY) toY = wd.toScale(toY)
if len(actionOptions.Offset) == 4 {
fromX += float64(actionOptions.Offset[0])
fromY += float64(actionOptions.Offset[1])
toX += float64(actionOptions.Offset[2])
toY += float64(actionOptions.Offset[3])
}
fromX += actionOptions.GetRandomOffset()
fromY += actionOptions.GetRandomOffset()
toX += actionOptions.GetRandomOffset()
toY += actionOptions.GetRandomOffset()
data := map[string]interface{}{ data := map[string]interface{}{
"fromX": math.Round(fromX*10) / 10, "fromX": math.Round(fromX*10) / 10,
"fromY": math.Round(fromY*10) / 10, "fromY": math.Round(fromY*10) / 10,
@@ -607,7 +602,7 @@ func (wd *WDADriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO
// wda 43 version // wda 43 version
_, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration") _, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration")
// _, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/drag") // _, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/drag")
return return err
} }
func (wd *WDADriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (wd *WDADriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
+1 -1
View File
@@ -308,7 +308,7 @@ func Test_Relative_Drag(t *testing.T) {
setup(t) setup(t)
// err := driver.Drag(200, 300, 200, 500, WithDataPressDuration(0.5)) // err := driver.Drag(200, 300, 200, 500, WithDataPressDuration(0.5))
err := iOSDriverExt.SwipeRelative(0.5, 0.7, 0.5, 0.5) err := iOSDriverExt.Swipe(0.5, 0.7, 0.5, 0.5)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+10
View File
@@ -19,6 +19,7 @@ type ActionOptions struct {
Direction interface{} `json:"direction,omitempty" yaml:"direction,omitempty"` // used by swipe to tap text or app Direction interface{} `json:"direction,omitempty" yaml:"direction,omitempty"` // used by swipe to tap text or app
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"` // TODO: wait timeout in seconds for mobile action Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"` // TODO: wait timeout in seconds for mobile action
Frequency int `json:"frequency,omitempty" yaml:"frequency,omitempty"` Frequency int `json:"frequency,omitempty" yaml:"frequency,omitempty"`
AbsCoordinate bool `json:"abs,omitempty" yaml:"abs,omitempty"` // use absolute coordinate
ScreenOptions ScreenOptions
@@ -55,6 +56,9 @@ func (o *ActionOptions) Options() []ActionOption {
if o.Steps != 0 { if o.Steps != 0 {
options = append(options, WithSteps(o.Steps)) options = append(options, WithSteps(o.Steps))
} }
if o.AbsCoordinate {
options = append(options, WithAbsoluteCoordinate(true))
}
switch v := o.Direction.(type) { switch v := o.Direction.(type) {
case string: case string:
@@ -241,6 +245,12 @@ func WithDirection(direction string) ActionOption {
} }
} }
func WithAbsoluteCoordinate(abs bool) ActionOption {
return func(o *ActionOptions) {
o.AbsCoordinate = abs
}
}
// WithCustomDirection inputs sx, sy, ex, ey // WithCustomDirection inputs sx, sy, ex, ey
func WithCustomDirection(sx, sy, ex, ey float64) ActionOption { func WithCustomDirection(sx, sy, ex, ey float64) ActionOption {
return func(o *ActionOptions) { return func(o *ActionOptions) {
+1 -1
View File
@@ -89,7 +89,7 @@ func dragHandler(c *gin.Context) {
} }
if dragReq.FromX < 1 && dragReq.FromY < 1 && dragReq.ToX < 1 && dragReq.ToY < 1 { if dragReq.FromX < 1 && dragReq.FromY < 1 && dragReq.ToX < 1 && dragReq.ToY < 1 {
err := dExt.SwipeRelative( err := dExt.Swipe(
dragReq.FromX, dragReq.FromY, dragReq.ToX, dragReq.ToY, dragReq.FromX, dragReq.FromY, dragReq.ToX, dragReq.ToY,
actionOptions...) actionOptions...)
if err != nil { if err != nil {