mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
fix
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v5/internal/config"
|
||||
"github.com/httprunner/httprunner/v5/internal/json"
|
||||
"github.com/httprunner/httprunner/v5/internal/simulation"
|
||||
"github.com/httprunner/httprunner/v5/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/uixt/types"
|
||||
)
|
||||
@@ -678,6 +679,13 @@ func (wd *WDADriver) TouchByEvents(events []types.TouchEvent, opts ...option.Act
|
||||
x, y = toX, toY
|
||||
}
|
||||
|
||||
if x, err = wd.toScale(x); err != nil {
|
||||
return err
|
||||
}
|
||||
if y, err = wd.toScale(y); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var actionMap map[string]interface{}
|
||||
|
||||
switch event.Action {
|
||||
@@ -743,6 +751,201 @@ func (wd *WDADriver) TouchByEvents(events []types.TouchEvent, opts ...option.Act
|
||||
return err
|
||||
}
|
||||
|
||||
// SIMSwipeWithDirection 向指定方向滑动任意距离
|
||||
// direction: 滑动方向 ("up", "down", "left", "right")
|
||||
// fromX, fromY: 起始坐标
|
||||
// simMinDistance, simMaxDistance: 距离范围,如果相等则为固定距离,否则为随机距离
|
||||
func (wd *WDADriver) SIMSwipeWithDirection(direction string, fromX, fromY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error {
|
||||
absStartX, absStartY, err := convertToAbsolutePoint(wd, fromX, fromY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 获取设备型号和配置参数
|
||||
deviceModel := "iphone"
|
||||
deviceParams := simulation.GetRandomDeviceParams(deviceModel)
|
||||
|
||||
log.Info().Str("direction", direction).
|
||||
Float64("startX", absStartX).Float64("startY", absStartY).
|
||||
Float64("minDistance", simMinDistance).Float64("maxDistance", simMaxDistance).
|
||||
Str("deviceModel", deviceModel).
|
||||
Int("deviceID", deviceParams.DeviceID).
|
||||
Float64("pressure", deviceParams.Pressure).
|
||||
Float64("size", deviceParams.Size).
|
||||
Msg("WDADriver.SIMSwipeWithDirection")
|
||||
|
||||
// 导入滑动仿真库
|
||||
simulator := simulation.NewSlideSimulatorAPI(nil)
|
||||
|
||||
// 转换方向字符串为Direction类型
|
||||
var slideDirection simulation.Direction
|
||||
switch direction {
|
||||
case "up":
|
||||
slideDirection = simulation.Up
|
||||
case "down":
|
||||
slideDirection = simulation.Down
|
||||
case "left":
|
||||
slideDirection = simulation.Left
|
||||
case "right":
|
||||
slideDirection = simulation.Right
|
||||
default:
|
||||
return fmt.Errorf("invalid direction: %s, must be one of: up, down, left, right", direction)
|
||||
}
|
||||
|
||||
// 使用滑动仿真算法生成触摸事件序列
|
||||
events, err := simulator.GenerateSlideWithRandomDistance(
|
||||
absStartX, absStartY, slideDirection, simMinDistance, simMaxDistance,
|
||||
deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate slide events failed: %v", err)
|
||||
}
|
||||
|
||||
// 执行触摸事件序列
|
||||
return wd.TouchByEvents(events, opts...)
|
||||
}
|
||||
|
||||
// SIMSwipeInArea 在指定区域内向指定方向滑动任意距离
|
||||
// direction: 滑动方向 ("up", "down", "left", "right")
|
||||
// simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY: 区域范围(相对坐标)
|
||||
// simMinDistance, simMaxDistance: 距离范围,如果相等则为固定距离,否则为随机距离
|
||||
func (wd *WDADriver) SIMSwipeInArea(direction string, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error {
|
||||
// 转换区域坐标为绝对坐标
|
||||
absAreaStartX, absAreaStartY, err := convertToAbsolutePoint(wd, simAreaStartX, simAreaStartY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
absAreaEndX, absAreaEndY, err := convertToAbsolutePoint(wd, simAreaEndX, simAreaEndY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 确保区域坐标正确(start应该小于等于end)
|
||||
if absAreaStartX > absAreaEndX {
|
||||
absAreaStartX, absAreaEndX = absAreaEndX, absAreaStartX
|
||||
}
|
||||
if absAreaStartY > absAreaEndY {
|
||||
absAreaStartY, absAreaEndY = absAreaEndY, absAreaStartY
|
||||
}
|
||||
|
||||
// 获取设备型号和配置参数
|
||||
deviceModel := "iphone"
|
||||
deviceParams := simulation.GetRandomDeviceParams(deviceModel)
|
||||
|
||||
log.Info().Str("direction", direction).
|
||||
Float64("areaStartX", absAreaStartX).Float64("areaStartY", absAreaStartY).
|
||||
Float64("areaEndX", absAreaEndX).Float64("areaEndY", absAreaEndY).
|
||||
Float64("minDistance", simMinDistance).Float64("maxDistance", simMaxDistance).
|
||||
Str("deviceModel", deviceModel).
|
||||
Int("deviceID", deviceParams.DeviceID).
|
||||
Float64("pressure", deviceParams.Pressure).
|
||||
Float64("size", deviceParams.Size).
|
||||
Msg("WDADriver.SIMSwipeInArea")
|
||||
|
||||
// 导入滑动仿真库
|
||||
simulator := simulation.NewSlideSimulatorAPI(nil)
|
||||
|
||||
// 转换方向字符串为Direction类型
|
||||
var slideDirection simulation.Direction
|
||||
switch direction {
|
||||
case "up":
|
||||
slideDirection = simulation.Up
|
||||
case "down":
|
||||
slideDirection = simulation.Down
|
||||
case "left":
|
||||
slideDirection = simulation.Left
|
||||
case "right":
|
||||
slideDirection = simulation.Right
|
||||
default:
|
||||
return fmt.Errorf("invalid direction: %s, must be one of: up, down, left, right", direction)
|
||||
}
|
||||
|
||||
// 使用滑动仿真算法生成区域内滑动的触摸事件序列
|
||||
events, err := simulator.GenerateSlideInArea(
|
||||
absAreaStartX, absAreaStartY, absAreaEndX, absAreaEndY,
|
||||
slideDirection, simMinDistance, simMaxDistance,
|
||||
deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate slide in area events failed: %v", err)
|
||||
}
|
||||
|
||||
// 执行触摸事件序列
|
||||
return wd.TouchByEvents(events, opts...)
|
||||
}
|
||||
|
||||
// SIMSwipeFromPointToPoint 指定起始点和结束点进行滑动
|
||||
// fromX, fromY: 起始坐标(相对坐标)
|
||||
// toX, toY: 结束坐标(相对坐标)
|
||||
func (wd *WDADriver) SIMSwipeFromPointToPoint(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
|
||||
// 转换起始点和结束点为绝对坐标
|
||||
absStartX, absStartY, err := convertToAbsolutePoint(wd, fromX, fromY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
absEndX, absEndY, err := convertToAbsolutePoint(wd, toX, toY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取设备型号和配置参数
|
||||
deviceModel := "iphone"
|
||||
deviceParams := simulation.GetRandomDeviceParams(deviceModel)
|
||||
|
||||
log.Info().Float64("startX", absStartX).Float64("startY", absStartY).
|
||||
Float64("endX", absEndX).Float64("endY", absEndY).
|
||||
Str("deviceModel", deviceModel).
|
||||
Int("deviceID", deviceParams.DeviceID).
|
||||
Float64("pressure", deviceParams.Pressure).
|
||||
Float64("size", deviceParams.Size).
|
||||
Msg("WDADriver.SIMSwipeFromPointToPoint")
|
||||
|
||||
// 导入滑动仿真库
|
||||
simulator := simulation.NewSlideSimulatorAPI(nil)
|
||||
|
||||
// 使用滑动仿真算法生成点对点滑动的触摸事件序列
|
||||
events, err := simulator.GeneratePointToPointSlideEvents(
|
||||
absStartX, absStartY, absEndX, absEndY,
|
||||
deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate point to point slide events failed: %v", err)
|
||||
}
|
||||
|
||||
// 执行触摸事件序列
|
||||
return wd.TouchByEvents(events, opts...)
|
||||
}
|
||||
|
||||
// SIMClickAtPoint 点击相对坐标
|
||||
// x, y: 点击坐标(相对坐标)
|
||||
func (wd *WDADriver) SIMClickAtPoint(x, y float64, opts ...option.ActionOption) error {
|
||||
// 转换为绝对坐标
|
||||
absX, absY, err := convertToAbsolutePoint(wd, x, y)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取设备型号和配置参数
|
||||
deviceModel := "iphone"
|
||||
deviceParams := simulation.GetRandomDeviceParams(deviceModel)
|
||||
|
||||
log.Info().Float64("x", absX).Float64("y", absY).
|
||||
Str("deviceModel", deviceModel).
|
||||
Int("deviceID", deviceParams.DeviceID).
|
||||
Float64("pressure", deviceParams.Pressure).
|
||||
Float64("size", deviceParams.Size).
|
||||
Msg("WDADriver.SIMClickAtPoint")
|
||||
|
||||
// 导入点击仿真库
|
||||
clickSimulator := simulation.NewClickSimulatorAPI(nil)
|
||||
|
||||
// 使用点击仿真算法生成触摸事件序列
|
||||
events, err := clickSimulator.GenerateClickEvents(
|
||||
absX, absY, deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate click events failed: %v", err)
|
||||
}
|
||||
|
||||
// 执行触摸事件序列
|
||||
return wd.TouchByEvents(events, opts...)
|
||||
}
|
||||
|
||||
func (wd *WDADriver) SetPasteboard(contentType types.PasteboardType, content string) (err error) {
|
||||
// [[FBRoute POST:@"/wda/setPasteboard"] respondWithTarget:self action:@selector(handleSetPasteboard:)]
|
||||
data := map[string]interface{}{
|
||||
@@ -784,6 +987,69 @@ func (wd *WDADriver) Input(text string, opts ...option.ActionOption) (err error)
|
||||
return
|
||||
}
|
||||
|
||||
// SIMInput 仿真输入函数,模拟人类分批输入行为
|
||||
// 将文本智能分割,英文单词和数字保持完整,中文按1-2个字符分割
|
||||
func (wd *WDADriver) SIMInput(text string, opts ...option.ActionOption) error {
|
||||
log.Info().Str("text", text).Msg("WDADriver.SIMInput")
|
||||
|
||||
if text == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建输入仿真器(使用默认配置)
|
||||
inputSimulator := simulation.NewInputSimulatorAPI(nil)
|
||||
|
||||
// 生成输入片段(使用智能分割算法,所有参数使用默认值)
|
||||
inputReq := simulation.InputRequest{
|
||||
Text: text,
|
||||
// MinSegmentLen, MaxSegmentLen, MinDelayMs, MaxDelayMs 使用默认值
|
||||
}
|
||||
|
||||
response := inputSimulator.GenerateInputSegments(inputReq)
|
||||
if !response.Success {
|
||||
return fmt.Errorf("failed to generate input segments: %s", response.Message)
|
||||
}
|
||||
|
||||
log.Info().Int("segments", response.Metrics.TotalSegments).
|
||||
Int("totalDelayMs", response.Metrics.TotalDelayMs).
|
||||
Int("estimatedTimeMs", response.Metrics.EstimatedTimeMs).
|
||||
Msg("Input segments generated")
|
||||
|
||||
// 逐个输入每个片段
|
||||
var segmentErrCnt int
|
||||
for _, segment := range response.Segments {
|
||||
// 使用Input进行输入(内部已包含Session.POST请求)
|
||||
segmentErr := wd.Input(segment.Text, opts...)
|
||||
if segmentErr != nil {
|
||||
segmentErrCnt++
|
||||
log.Info().Err(segmentErr).Int("segmentErrCnt", segmentErrCnt).
|
||||
Msg("segments err")
|
||||
}
|
||||
|
||||
log.Debug().Str("segment", segment.Text).Int("index", segment.Index).
|
||||
Int("charLen", segment.CharLen).Msg("Successfully input segment")
|
||||
|
||||
// 如果有延迟时间,则等待
|
||||
if segment.DelayMs > 0 {
|
||||
time.Sleep(time.Duration(segment.DelayMs) * time.Millisecond)
|
||||
|
||||
log.Debug().Int("delayMs", segment.DelayMs).
|
||||
Msg("Delay between input segments")
|
||||
}
|
||||
}
|
||||
if segmentErrCnt > 0 {
|
||||
data := map[string]interface{}{"value": strings.Split(text, "")}
|
||||
option.MergeOptions(data, opts...)
|
||||
_, err := wd.Session.POST(data, "/wings/interaction/keys")
|
||||
return err
|
||||
}
|
||||
log.Info().Int("totalSegments", response.Metrics.TotalSegments).
|
||||
Int("actualDelayMs", response.Metrics.TotalDelayMs).
|
||||
Msg("SIMInput completed successfully")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wd *WDADriver) Backspace(count int, opts ...option.ActionOption) (err error) {
|
||||
log.Info().Int("count", count).Msg("WDADriver.Backspace")
|
||||
if count == 0 {
|
||||
|
||||
Reference in New Issue
Block a user