feat: add support for scroll action

This commit is contained in:
Danieldd28 2026-02-16 20:50:20 +07:00
parent 8058f38abb
commit 59f3754bff
2 changed files with 22 additions and 3 deletions

View file

@ -215,6 +215,7 @@ var allowedBrowserActions = map[string]bool{
"cookies": true, "cookies": true,
"status": true, "status": true,
"viewport": true, "viewport": true,
"scroll": true,
} }
// BrowserTool wraps `actionbook browser` for browser automation. // BrowserTool wraps `actionbook browser` for browser automation.
@ -228,7 +229,7 @@ func NewBrowserTool(headless bool) *BrowserTool {
func (t *BrowserTool) Name() string { return "browser" } func (t *BrowserTool) Name() string { return "browser" }
func (t *BrowserTool) Description() string { func (t *BrowserTool) Description() string {
return `Execute browser automation commands via ActionBook. Supported actions: open, goto, click, fill, type, select, hover, focus, press, text, snapshot, screenshot, wait, wait-nav, back, forward, reload, close, pages, switch, eval, html, pdf, cookies, status, viewport. Typical workflow: browser_search → browser_get → browser (open → interact → close).` return `Execute browser automation commands via ActionBook. Supported actions: open, goto, click, fill, type, select, hover, focus, press, text, scroll, snapshot, screenshot, wait, wait-nav, back, forward, reload, close, pages, switch, eval, html, pdf, cookies, status, viewport. Typical workflow: browser_search → browser_get → browser (open → interact → close).`
} }
func (t *BrowserTool) Parameters() map[string]interface{} { func (t *BrowserTool) Parameters() map[string]interface{} {
@ -249,7 +250,7 @@ func (t *BrowserTool) Parameters() map[string]interface{} {
}, },
"value": map[string]interface{}{ "value": map[string]interface{}{
"type": "string", "type": "string",
"description": "Value for fill/type/select/press/eval/switch actions", "description": "Value for fill/type/select/press/eval/switch/scroll actions",
}, },
"timeout": map[string]interface{}{ "timeout": map[string]interface{}{
"type": "integer", "type": "integer",
@ -272,7 +273,7 @@ func (t *BrowserTool) Execute(ctx context.Context, args map[string]interface{})
action = strings.TrimSpace(strings.ToLower(action)) action = strings.TrimSpace(strings.ToLower(action))
if !allowedBrowserActions[action] { if !allowedBrowserActions[action] {
return ErrorResult(fmt.Sprintf("unknown browser action %q — allowed: open, goto, click, fill, type, select, hover, focus, press, text, snapshot, screenshot, wait, wait-nav, back, forward, reload, close, pages, switch, eval, html, pdf, cookies, status, viewport", action)) return ErrorResult(fmt.Sprintf("unknown browser action %q — allowed: open, goto, click, fill, type, select, hover, focus, press, text, scroll, snapshot, screenshot, wait, wait-nav, back, forward, reload, close, pages, switch, eval, html, pdf, cookies, status, viewport", action))
} }
// Build argument list // Build argument list
@ -338,6 +339,13 @@ func (t *BrowserTool) Execute(ctx context.Context, args map[string]interface{})
} }
cmdArgs = append(cmdArgs, key) cmdArgs = append(cmdArgs, key)
case "scroll":
val, ok := args["value"].(string)
if !ok || val == "" {
return ErrorResult("value is required for scroll action (e.g. 'down', 'up', 'bottom', 'top', or pixels)")
}
cmdArgs = append(cmdArgs, val)
case "wait": case "wait":
sel, ok := args["selector"].(string) sel, ok := args["selector"].(string)
if !ok || sel == "" { if !ok || sel == "" {

View file

@ -188,6 +188,17 @@ func TestBrowserTool_PressRequiresValue(t *testing.T) {
} }
} }
// TestBrowserTool_ScrollRequiresValue verifies scroll needs value
func TestBrowserTool_ScrollRequiresValue(t *testing.T) {
tool := NewBrowserTool(true)
result := tool.Execute(context.Background(), map[string]interface{}{
"action": "scroll",
})
if !result.IsError {
t.Error("expected error when value is missing for scroll")
}
}
// TestBrowserTool_EvalRequiresValue verifies eval needs script value // TestBrowserTool_EvalRequiresValue verifies eval needs script value
func TestBrowserTool_EvalRequiresValue(t *testing.T) { func TestBrowserTool_EvalRequiresValue(t *testing.T) {
tool := NewBrowserTool(true) tool := NewBrowserTool(true)