feat: 支持基于touchEvent执行

This commit is contained in:
余泓铮
2025-07-16 17:08:57 +08:00
parent b598c162a9
commit 31c66b8cc0
4 changed files with 364 additions and 1 deletions
+106
View File
@@ -428,6 +428,112 @@ func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Actio
return err
}
// TouchByEvents performs a complex swipe using a sequence of touch events with pressure and size data
func (ud *UIA2Driver) TouchByEvents(events []types.TouchEvent, opts ...option.ActionOption) error {
log.Info().Int("eventCount", len(events)).Msg("UIA2Driver.SwipeSimulator")
if len(events) == 0 {
return fmt.Errorf("no touch events provided")
}
actionOptions := option.NewActionOptions(opts...)
// Apply pre-handlers for the first and last events (start and end coordinates)
firstEvent := events[0]
lastEvent := events[len(events)-1]
fromX, fromY, toX, toY, err := preHandler_Swipe(ud, option.ACTION_SwipeCoordinate, actionOptions,
firstEvent.X, firstEvent.Y, lastEvent.X, lastEvent.Y)
if err != nil {
return err
}
defer postHandler(ud, option.ACTION_SwipeCoordinate, actionOptions)
var actions []interface{}
var prevTimestamp int64
for i, event := range events {
var duration float64
if i > 0 {
// Calculate duration from previous event in milliseconds
duration = float64(event.Timestamp - prevTimestamp)
}
prevTimestamp = event.Timestamp
// Apply coordinate transformation if it's the first or last event
x, y := event.X, event.Y
if i == 0 {
x, y = fromX, fromY
} else if i == len(events)-1 {
x, y = toX, toY
}
var actionMap map[string]interface{}
switch event.Action {
case 0: // ACTION_DOWN
actionMap = map[string]interface{}{
"type": "pointerDown",
"duration": 0,
"button": 0,
"pressure": event.Pressure,
"size": event.Size,
}
// Add initial move to position before down
if i == 0 {
moveAction := map[string]interface{}{
"type": "pointerMove",
"duration": 0,
"x": x,
"y": y,
"origin": "viewport",
"pressure": event.Pressure,
"size": event.Size,
}
actions = append(actions, moveAction)
}
case 1: // ACTION_UP
actionMap = map[string]interface{}{
"type": "pointerUp",
"duration": 0,
"button": 0,
"pressure": event.Pressure,
"size": event.Size,
}
case 2: // ACTION_MOVE
actionMap = map[string]interface{}{
"type": "pointerMove",
"duration": duration,
"x": x,
"y": y,
"origin": "viewport",
"pressure": event.Pressure,
"size": event.Size,
}
default:
log.Warn().Int("action", event.Action).Msg("Unknown action type, skipping")
continue
}
actions = append(actions, actionMap)
}
data := map[string]interface{}{
"actions": []interface{}{
map[string]interface{}{
"type": "pointer",
"parameters": map[string]string{"pointerType": "touch"},
"id": "touch",
"actions": actions,
},
},
}
option.MergeOptions(data, opts...)
urlStr := fmt.Sprintf("/session/%s/actions/swipe", ud.Session.ID)
_, err = ud.Session.POST(data, urlStr)
return err
}
func (ud *UIA2Driver) SetPasteboard(contentType types.PasteboardType, content string) (err error) {
log.Info().Str("contentType", string(contentType)).
Str("content", content).Msg("UIA2Driver.SetPasteboard")
+17
View File
@@ -225,3 +225,20 @@ const (
DirectionLeft Direction = "left"
DirectionRight Direction = "right"
)
// TouchEvent represents a single touch event with all its properties
type TouchEvent struct {
Timestamp int64 `json:"timestamp"`
X float64 `json:"x"`
Y float64 `json:"y"`
DeviceID int `json:"deviceId"`
Pressure float64 `json:"pressure"`
Size float64 `json:"size"`
RawX float64 `json:"rawX"`
RawY float64 `json:"rawY"`
DownTime int64 `json:"downTime"`
EventTime int64 `json:"eventTime"`
ToolType int `json:"toolType"`
Flag int `json:"flag"`
Action int `json:"action"`
}