feat: support pre hook and post hook for actions

This commit is contained in:
lilong.129
2025-05-09 23:01:27 +08:00
parent 433b1cd48d
commit 3715cbb432
10 changed files with 89 additions and 20 deletions

View File

@@ -307,11 +307,12 @@ func (ad *ADBDriver) TapXY(x, y float64, opts ...option.ActionOption) error {
func (ad *ADBDriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
log.Info().Float64("x", x).Float64("y", y).Msg("ADBDriver.TapAbsXY")
var err error
x, y, err = handlerTapAbsXY(ad, x, y, opts...)
actionOptions := option.NewActionOptions(opts...)
x, y, err := preHandler_TapAbsXY(ad, actionOptions, x, y)
if err != nil {
return err
}
defer postHandler(ad, actionOptions)
// adb shell input tap x y
xStr := fmt.Sprintf("%.1f", x)

View File

@@ -298,14 +298,13 @@ func (ud *UIA2Driver) TapXY(x, y float64, opts ...option.ActionOption) error {
func (ud *UIA2Driver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
log.Info().Float64("x", x).Float64("y", y).Msg("UIA2Driver.TapAbsXY")
// register(postHandler, new Tap("/wd/hub/session/:sessionId/appium/tap"))
var err error
x, y, err = handlerTapAbsXY(ud, x, y, opts...)
actionOptions := option.NewActionOptions(opts...)
x, y, err := preHandler_TapAbsXY(ud, actionOptions, x, y)
if err != nil {
return err
}
defer postHandler(ud, actionOptions)
actionOptions := option.NewActionOptions(opts...)
duration := 100.0
if actionOptions.PressDuration > 0 {
duration = actionOptions.PressDuration * 1000 // convert to ms

View File

@@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -133,6 +134,33 @@ func TestDriver_ADB_TapXY(t *testing.T) {
assert.Nil(t, err)
}
func TestDriver_ADB_TapXY_WithHook(t *testing.T) {
driver := setupADBDriverExt(t)
x, y := 0.4, 0.5
err := driver.TapXY(x, y,
option.WithHooks(
func() {
log.Info().Msg("pre hook")
x += 1
},
func() {
log.Info().Msg("post hook")
},
),
)
assert.Nil(t, err)
err = driver.TapXY(0.4, 0.5,
option.WithPreHook(func() {
log.Info().Msg("pre hook")
}),
option.WithPostHook(func() {
log.Info().Msg("post hook")
}),
)
assert.Nil(t, err)
}
func TestDriver_ADB_TapAbsXY(t *testing.T) {
driver := setupADBDriverExt(t)
err := driver.TapAbsXY(100, 300)

View File

@@ -511,13 +511,13 @@ func (wd *BrowserDriver) Tap(x, y float64, options ...option.ActionOption) error
}
func (wd *BrowserDriver) TapFloat(x, y float64, opts ...option.ActionOption) error {
var err error
x, y, err = handlerTapAbsXY(wd, x, y, opts...)
actionOptions := option.NewActionOptions(opts...)
x, y, err := preHandler_TapAbsXY(wd, actionOptions, x, y)
if err != nil {
return err
}
defer postHandler(wd, actionOptions)
actionOptions := option.NewActionOptions(opts...)
duration := 0.1
if actionOptions.Duration > 0 {
duration = actionOptions.Duration

View File

@@ -5,14 +5,17 @@ import (
"github.com/rs/zerolog/log"
)
func handlerTapAbsXY(driver IDriver, rawX, rawY float64, opts ...option.ActionOption) (
func preHandler_TapAbsXY(driver IDriver, options *option.ActionOptions, rawX, rawY float64) (
x, y float64, err error) {
actionOptions := option.NewActionOptions(opts...)
x, y = actionOptions.ApplyTapOffset(rawX, rawY)
if options.PreHook != nil {
options.PreHook()
}
x, y = options.ApplyTapOffset(rawX, rawY)
// mark UI operation
if actionOptions.MarkOperationEnabled {
if options.MarkOperationEnabled {
if markErr := MarkUIOperation(driver, ACTION_TapAbsXY, []float64{x, y}); markErr != nil {
log.Warn().Err(markErr).Msg("Failed to mark tap operation")
}
@@ -81,3 +84,9 @@ func handlerSwipe(driver IDriver, rawFomX, rawFromY, rawToX, rawToY float64, opt
return fromX, fromY, toX, toY, nil
}
func postHandler(_ IDriver, options *option.ActionOptions) {
if options.PostHook != nil {
options.PostHook()
}
}

View File

@@ -154,14 +154,13 @@ func (hd *HDCDriver) TapXY(x, y float64, opts ...option.ActionOption) error {
func (hd *HDCDriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
log.Info().Float64("x", x).Float64("y", y).Msg("HDCDriver.TapAbsXY")
var err error
x, y, err = handlerTapAbsXY(hd, x, y, opts...)
actionOptions := option.NewActionOptions(opts...)
x, y, err := preHandler_TapAbsXY(hd, actionOptions, x, y)
if err != nil {
return err
}
defer postHandler(hd, actionOptions)
actionOptions := option.NewActionOptions(opts...)
if actionOptions.Identifier != "" {
startTime := int(time.Now().UnixMilli())
hd.points = append(hd.points, ExportPoint{Start: startTime, End: startTime + 100, Ext: actionOptions.Identifier, RunTime: 100})

View File

@@ -597,11 +597,12 @@ func (wd *WDADriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
x = wd.toScale(x)
y = wd.toScale(y)
var err error
x, y, err = handlerTapAbsXY(wd, x, y, opts...)
actionOptions := option.NewActionOptions(opts...)
x, y, err := preHandler_TapAbsXY(wd, actionOptions, x, y)
if err != nil {
return err
}
defer postHandler(wd, actionOptions)
data := map[string]interface{}{
"x": x,

View File

@@ -23,6 +23,7 @@ type ActionOptions struct {
Frequency int `json:"frequency,omitempty" yaml:"frequency,omitempty"`
ScreenOptions
HookOptions
// set custiom options such as textview, id, description
Custom map[string]interface{} `json:"custom,omitempty" yaml:"custom,omitempty"`

31
uixt/option/hook.go Normal file
View File

@@ -0,0 +1,31 @@
package option
// HookOptions contains options for action hooks
type HookOptions struct {
// pre hook before action
PreHook func()
// post hook after action
PostHook func()
}
// WithPreHook sets the pre hook before action
func WithPreHook(preHook func()) ActionOption {
return func(o *ActionOptions) {
o.PreHook = preHook
}
}
// WithPostHook sets the post hook after action
func WithPostHook(postHook func()) ActionOption {
return func(o *ActionOptions) {
o.PostHook = postHook
}
}
// WithHooks sets the pre hook and post hook
func WithHooks(preHook func(), postHook func()) ActionOption {
return func(o *ActionOptions) {
o.PreHook = preHook
o.PostHook = postHook
}
}