Skip to content

Conversation

@felores
Copy link

@felores felores commented Dec 3, 2025

Summary

Add a new bdg dom scroll command that provides three distinct scrolling modes for AI agents and automation workflows:

  • Element scroll: bdg dom scroll "footer" - scrolls element into view
  • Offset scroll: bdg dom scroll --down 500 - scrolls by pixel amount
  • Position scroll: bdg dom scroll --bottom - scrolls to page boundaries

Motivation

The Problem

When an AI agent using bdg is instructed to "scroll down the page" or "scroll to the footer", there was no discoverable way to accomplish this. The agent would need to:

  1. Know that Runtime.evaluate with JavaScript is the answer
  2. Search for Runtime or evaluate (not scroll)
  3. Compose the JavaScript themselves: window.scrollBy(0, 500)

bdg cdp --search scroll returned CDP methods like DOM.scrollIntoViewIfNeeded but didn't surface Runtime.evaluate - the most practical approach for arbitrary scrolling.

The Solution

A dedicated bdg dom scroll command that:

  • Is discoverable via bdg dom --help and bdg dom scroll --help
  • Follows existing interaction command patterns (fill, click, pressKey)
  • Provides rich JSON output for programmatic use
  • Handles lazy-loaded content with automatic stability waiting

Implementation Details

Files Changed

File Change
src/commands/shared/optionTypes.ts New ScrollCommandOptions interface
src/commands/dom/formFillHelpers.ts scrollPage() helper with 3 scroll modes
src/commands/dom/formInteraction.ts bdg dom scroll command registration
src/commands/optionBehaviors.ts Self-documenting option behaviors
CLAUDE.md Quick reference update
docs/CLI_REFERENCE.md Form Interaction section update
.claude/skills/bdg/SKILL.md New "DOM Interaction" section

Design Decisions

  1. Added to Form Interaction commands (not a new command group) - scroll is a page interaction like click/fill
  2. Waits for lazy-loaded content by default - uses same stability detection as screenshot --scroll option
  3. Returns rich JSON output - includes scrolledTo, scrolledBy, viewportSize, pageSize for agent decision-making
  4. Supports --index for nth element - consistent with other DOM commands

JSON Output Example

{
  "success": true,
  "scrollType": "element",
  "selector": "footer",
  "scrolledTo": { "x": 0, "y": 4108 },
  "viewportSize": { "width": 756, "height": 469 },
  "pageSize": { "width": 756, "height": 4577 }
}

Benefits

  1. Agent Discoverability: Agents can now find scroll functionality via bdg dom --help
  2. Consistent UX: Follows same patterns as click, fill, pressKey
  3. Rich Metadata: Returns scroll position and page dimensions for informed decisions
  4. Lazy-load Safe: Automatically waits for content to stabilize after scroll
  5. Flexible: Supports element targeting, pixel offsets, and page boundaries

Usage Examples

# Scroll to element
bdg dom scroll "footer"
bdg dom scroll ".product-list" --index 2

# Scroll by pixels
bdg dom scroll --down 500
bdg dom scroll --up 200

# Scroll to boundaries
bdg dom scroll --top
bdg dom scroll --bottom

# JSON output for agents
bdg dom scroll --bottom --json

Test Plan

  • bdg dom scroll --help shows all options
  • bdg dom scroll "footer" scrolls element into view
  • bdg dom scroll --down 500 scrolls by pixel amount
  • bdg dom scroll --bottom scrolls to page bottom
  • bdg dom scroll --top scrolls to page top
  • bdg dom scroll (no args) returns helpful error with suggestion
  • JSON output includes scroll position and page dimensions
  • Build passes with no TypeScript errors
  • Linting passes

Add `bdg dom scroll` command with three scroll modes:
- Element scroll: `bdg dom scroll "footer"`
- Offset scroll: `bdg dom scroll --down 500`
- Position scroll: `bdg dom scroll --bottom`

Features:
- Waits for lazy-loaded content after scroll (--no-wait to skip)
- Supports nth element selection with --index
- Returns scroll position and page dimensions in JSON output
- Follows existing interaction command patterns (fill, click, pressKey)
Copy link
Owner

@szymdzum szymdzum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good stuff dude . Thanks for that!

Minor suggestions (non-blocking, feel free to address now or later):

  1. Exit code in result object: The error handling in formInteraction.ts:407-409 uses string matching (error?.includes('not found')). Could be cleaner if ScrollResult included an optional exitCode field returned from scrollPage().

  2. --index without selector: Currently silently ignored. Could validate and show a hint.

  3. Conflicting options: --up 100 --down 200 combines to net scroll. Works fine, just potentially surprising.

None of these block the PR. Feel free to merge when ready!

1. Add exitCode field to ScrollResult interface
   - Replace string matching with explicit exitCode field
   - Return EXIT_CODES.RESOURCE_NOT_FOUND for element not found
   - Return EXIT_CODES.SOFTWARE_ERROR for script failures

2. Add validation for --index without selector
   - Error with helpful message: "--index requires a selector"
   - Provides example: "Use: bdg dom scroll "selector" --index 2"

3. Add validation for conflicting scroll options
   - Prevent --up and --down together
   - Prevent --left and --right together
   - Clear error messages explain which options conflict

Addresses feedback from PR szymdzum#135 review.
@felores
Copy link
Author

felores commented Dec 5, 2025

Thanks for the feedback! I've addressed all three suggestions:

1. ✅ Exit code in result object

Before:

exitCode: result.error?.includes('not found')
  ? EXIT_CODES.RESOURCE_NOT_FOUND
  : EXIT_CODES.INVALID_ARGUMENTS

After:

exitCode: result.exitCode ?? EXIT_CODES.INVALID_ARGUMENTS
  • Added exitCode?: number field to ScrollResult interface
  • scrollPage() now returns explicit exit codes:
    • RESOURCE_NOT_FOUND (83) for element not found
    • SOFTWARE_ERROR (110) for script failures
  • Removed string matching in error handling

2. ✅ --index without selector

Now validates and shows helpful error:

$ bdg dom scroll --index 2
Error: --index requires a selector
Use: bdg dom scroll "selector" --index 2

3. ✅ Conflicting options

Now validates both vertical and horizontal conflicts:

$ bdg dom scroll --up 100 --down 200
Error: Conflicting scroll directions specified
Use either --down or --up, not both

$ bdg dom scroll --left 100 --right 200
Error: Conflicting scroll directions specified
Use either --left or --right, not both

All changes tested and passing ✅

@felores
Copy link
Author

felores commented Dec 6, 2025

@szymdzum there are 2 pending approval workflows so we can merge

@szymdzum
Copy link
Owner

szymdzum commented Dec 6, 2025

@szymdzum there are 2 pending approval workflows so we can merge

All good. Cheers dude!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants