From 3715cbb4325af697eb63aa9cf169812a070e5cb3 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Fri, 9 May 2025 23:01:27 +0800 Subject: [PATCH] feat: support pre hook and post hook for actions --- internal/version/VERSION | 2 +- uixt/android_driver_adb.go | 5 +++-- uixt/android_driver_uia2.go | 7 +++---- uixt/android_test.go | 28 ++++++++++++++++++++++++++++ uixt/browser_driver.go | 6 +++--- uixt/driver_handler.go | 17 +++++++++++++---- uixt/harmony_driver_hdc.go | 7 +++---- uixt/ios_driver_wda.go | 5 +++-- uixt/option/action.go | 1 + uixt/option/hook.go | 31 +++++++++++++++++++++++++++++++ 10 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 uixt/option/hook.go diff --git a/internal/version/VERSION b/internal/version/VERSION index 3c87b0d6..1c2ecd0c 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0-beta-2505091122 +v5.0.0-beta-2505092301 diff --git a/uixt/android_driver_adb.go b/uixt/android_driver_adb.go index e7711ecf..d0d129f8 100644 --- a/uixt/android_driver_adb.go +++ b/uixt/android_driver_adb.go @@ -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) diff --git a/uixt/android_driver_uia2.go b/uixt/android_driver_uia2.go index 0055f764..0aca302a 100644 --- a/uixt/android_driver_uia2.go +++ b/uixt/android_driver_uia2.go @@ -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 diff --git a/uixt/android_test.go b/uixt/android_test.go index be2dac5b..c5930693 100644 --- a/uixt/android_test.go +++ b/uixt/android_test.go @@ -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) diff --git a/uixt/browser_driver.go b/uixt/browser_driver.go index 35caa7b0..429a3bca 100644 --- a/uixt/browser_driver.go +++ b/uixt/browser_driver.go @@ -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 diff --git a/uixt/driver_handler.go b/uixt/driver_handler.go index f237d0e8..4e6452d1 100644 --- a/uixt/driver_handler.go +++ b/uixt/driver_handler.go @@ -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() + } +} diff --git a/uixt/harmony_driver_hdc.go b/uixt/harmony_driver_hdc.go index 0865e365..a160b124 100644 --- a/uixt/harmony_driver_hdc.go +++ b/uixt/harmony_driver_hdc.go @@ -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}) diff --git a/uixt/ios_driver_wda.go b/uixt/ios_driver_wda.go index 889c95c0..a2040c0e 100644 --- a/uixt/ios_driver_wda.go +++ b/uixt/ios_driver_wda.go @@ -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, diff --git a/uixt/option/action.go b/uixt/option/action.go index 81911ec8..b8ad41a1 100644 --- a/uixt/option/action.go +++ b/uixt/option/action.go @@ -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"` diff --git a/uixt/option/hook.go b/uixt/option/hook.go new file mode 100644 index 00000000..54fbb55a --- /dev/null +++ b/uixt/option/hook.go @@ -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 + } +}