MouseMove(x, y float64) currently calls ib.page.Mouse().Move(x, y) without passing MouseMoveOptions{Steps}. Playwright's Steps parameter defaults to 1, meaning only oneInput.dispatchMouseEvent CDP call is generated per MouseMove() invocation.
This is a problem for slider captchas (e.g. DataDome) and other drag-based interactions where the target JavaScript listens for a stream of mousemove events during a drag. When the mouse jumps from position A to position B in a single event (no intermediate positions), the JS detects it as bot-like behavior and rejects the interaction.
steps - Defaults to 1. Sends intermediate mousemove events between the current position and the target position.
When Steps: 5 is passed, Playwright interpolates 5 intermediate positions and dispatches 5 separate Input.dispatchMouseEvent CDP calls, making the movement appear smooth and human-like.
The playwright-go bindings support this via MouseMoveOptions:
Change the signature to accept an optional steps count (backward compatible):
// Before (interactive.go:195-197)func(ib*interactiveBrowser)MouseMove(x,yfloat64)error{returnib.page.Mouse().Move(x,y)}// Afterfunc(ib*interactiveBrowser)MouseMove(x,yfloat64,steps...int)error{varoptsplaywright.MouseMoveOptionsiflen(steps)>0&&steps[0]>1{opts.Steps=playwright.Int(steps[0])}returnib.page.Mouse().Move(x,y,opts)}
The InteractiveBrowser interface would also need updating:
This is fully backward compatible — existing callers that pass no steps argument get the same behavior as today.
2. (Optional) Add Drag convenience method
A higher-level method that does MouseDown → MouseMove (with steps) → MouseUp:
Drag(fromX,fromY,toX,toYfloat64,stepsint)error
This would be convenient but is less critical since callers can compose the three calls themselves.
Impact
This fix is trivial (1-2 lines changed) but enables smooth drag gestures in the mort captcha proxy and browser proxy. Without it, mort has to implement manual position interpolation on its side as a workaround.
## Problem
`MouseMove(x, y float64)` currently calls `ib.page.Mouse().Move(x, y)` without passing `MouseMoveOptions{Steps}`. Playwright's `Steps` parameter defaults to 1, meaning only **one** `Input.dispatchMouseEvent` CDP call is generated per `MouseMove()` invocation.
This is a problem for slider captchas (e.g. DataDome) and other drag-based interactions where the target JavaScript listens for a **stream** of `mousemove` events during a drag. When the mouse jumps from position A to position B in a single event (no intermediate positions), the JS detects it as bot-like behavior and rejects the interaction.
## How Playwright's `Steps` Works
From Playwright's [Mouse.move() docs](https://playwright.dev/docs/api/class-mouse#mouse-move):
> **steps** - Defaults to 1. Sends intermediate `mousemove` events between the current position and the target position.
When `Steps: 5` is passed, Playwright interpolates 5 intermediate positions and dispatches 5 separate `Input.dispatchMouseEvent` CDP calls, making the movement appear smooth and human-like.
The `playwright-go` bindings support this via `MouseMoveOptions`:
```go
type MouseMoveOptions struct {
Steps *int `json:"steps"`
}
```
See also: [`playwright-go/tests/input_test.go`](https://github.com/playwright-community/playwright-go/blob/main/tests/input_test.go) which tests `Steps: playwright.Int(5)`.
## Proposed Fix
### 1. Add `steps` variadic parameter to `MouseMove`
Change the signature to accept an optional steps count (backward compatible):
```go
// Before (interactive.go:195-197)
func (ib *interactiveBrowser) MouseMove(x, y float64) error {
return ib.page.Mouse().Move(x, y)
}
// After
func (ib *interactiveBrowser) MouseMove(x, y float64, steps ...int) error {
var opts playwright.MouseMoveOptions
if len(steps) > 0 && steps[0] > 1 {
opts.Steps = playwright.Int(steps[0])
}
return ib.page.Mouse().Move(x, y, opts)
}
```
The `InteractiveBrowser` interface would also need updating:
```go
// Before
MouseMove(x, y float64) error
// After
MouseMove(x, y float64, steps ...int) error
```
This is fully backward compatible — existing callers that pass no `steps` argument get the same behavior as today.
### 2. (Optional) Add `Drag` convenience method
A higher-level method that does MouseDown → MouseMove (with steps) → MouseUp:
```go
Drag(fromX, fromY, toX, toY float64, steps int) error
```
This would be convenient but is less critical since callers can compose the three calls themselves.
## Impact
This fix is trivial (1-2 lines changed) but enables smooth drag gestures in the mort captcha proxy and browser proxy. Without it, mort has to implement manual position interpolation on its side as a workaround.
Starting work. Will add the steps ...int variadic parameter to MouseMove in the interface and implementation, and update the mock. Skipping the optional Drag convenience method for now since callers can compose the three calls themselves.
Starting work. Will add the `steps ...int` variadic parameter to `MouseMove` in the interface and implementation, and update the mock. Skipping the optional `Drag` convenience method for now since callers can compose the three calls themselves.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
MouseMove(x, y float64)currently callsib.page.Mouse().Move(x, y)without passingMouseMoveOptions{Steps}. Playwright'sStepsparameter defaults to 1, meaning only oneInput.dispatchMouseEventCDP call is generated perMouseMove()invocation.This is a problem for slider captchas (e.g. DataDome) and other drag-based interactions where the target JavaScript listens for a stream of
mousemoveevents during a drag. When the mouse jumps from position A to position B in a single event (no intermediate positions), the JS detects it as bot-like behavior and rejects the interaction.How Playwright's
StepsWorksFrom Playwright's Mouse.move() docs:
When
Steps: 5is passed, Playwright interpolates 5 intermediate positions and dispatches 5 separateInput.dispatchMouseEventCDP calls, making the movement appear smooth and human-like.The
playwright-gobindings support this viaMouseMoveOptions:See also:
playwright-go/tests/input_test.gowhich testsSteps: playwright.Int(5).Proposed Fix
1. Add
stepsvariadic parameter toMouseMoveChange the signature to accept an optional steps count (backward compatible):
The
InteractiveBrowserinterface would also need updating:This is fully backward compatible — existing callers that pass no
stepsargument get the same behavior as today.2. (Optional) Add
Dragconvenience methodA higher-level method that does MouseDown → MouseMove (with steps) → MouseUp:
This would be convenient but is less critical since callers can compose the three calls themselves.
Impact
This fix is trivial (1-2 lines changed) but enables smooth drag gestures in the mort captcha proxy and browser proxy. Without it, mort has to implement manual position interpolation on its side as a workaround.
Starting work. Will add the
steps ...intvariadic parameter toMouseMovein the interface and implementation, and update the mock. Skipping the optionalDragconvenience method for now since callers can compose the three calls themselves.Done. PR #82 merged.
MouseMovenow accepts an optionalsteps ...intparameter for smooth intermediate mousemove events.