pub struct MouseSimulator { /* private fields */ }Expand description
Simulates human-like mouse movement via distance-aware Bézier curve trajectories.
Each call to move_to computes a cubic Bézier path
between the current cursor position and the target, then replays it as a sequence
of Input.dispatchMouseEvent CDP commands with randomised inter-event delays
(10–50 ms per segment). Movement speed naturally slows for long distances and
accelerates for short ones — matching human motor-control patterns.
§Example
use stygian_browser::behavior::MouseSimulator;
let mut mouse = MouseSimulator::new();
mouse.move_to(page, 640.0, 400.0).await?;
mouse.click(page, 640.0, 400.0).await?;Implementations§
Source§impl MouseSimulator
impl MouseSimulator
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a simulator seeded from wall-clock time, positioned at (0, 0).
§Example
use stygian_browser::behavior::MouseSimulator;
let mouse = MouseSimulator::new();
assert_eq!(mouse.position(), (0.0, 0.0));Sourcepub const fn with_seed_and_position(seed: u64, x: f64, y: f64) -> Self
pub const fn with_seed_and_position(seed: u64, x: f64, y: f64) -> Self
Create a simulator with a known initial position and deterministic seed.
Useful for unit-testing path generation without CDP.
§Example
use stygian_browser::behavior::MouseSimulator;
let mouse = MouseSimulator::with_seed_and_position(42, 100.0, 200.0);
assert_eq!(mouse.position(), (100.0, 200.0));Sourcepub const fn position(&self) -> (f64, f64)
pub const fn position(&self) -> (f64, f64)
Returns the current cursor position as (x, y).
§Example
use stygian_browser::behavior::MouseSimulator;
let mouse = MouseSimulator::new();
let (x, y) = mouse.position();
assert_eq!((x, y), (0.0, 0.0));Sourcepub fn compute_path(
&mut self,
from_x: f64,
from_y: f64,
to_x: f64,
to_y: f64,
) -> Vec<(f64, f64)>
pub fn compute_path( &mut self, from_x: f64, from_y: f64, to_x: f64, to_y: f64, ) -> Vec<(f64, f64)>
Compute Bézier waypoints for a move from (from_x, from_y) to
(to_x, to_y).
The number of waypoints scales with Euclidean distance — roughly one point every 8 pixels — with a minimum of 12 and maximum of 120 steps. Random perpendicular offsets are applied to the two interior control points to produce natural curved paths. Each waypoint receives sub-pixel jitter (±0.8 px) for micro-tremor realism.
This method is pure (no I/O) and is exposed for testing.
§Example
use stygian_browser::behavior::MouseSimulator;
let mut mouse = MouseSimulator::with_seed_and_position(1, 0.0, 0.0);
let path = mouse.compute_path(0.0, 0.0, 200.0, 0.0);
// always at least 12 steps
assert!(path.len() >= 13);
// starts near origin
assert!((path[0].0).abs() < 5.0);
// ends near target
let last = path[path.len() - 1];
assert!((last.0 - 200.0).abs() < 5.0);Sourcepub async fn move_to(&mut self, page: &Page, to_x: f64, to_y: f64) -> Result<()>
pub async fn move_to(&mut self, page: &Page, to_x: f64, to_y: f64) -> Result<()>
Move the cursor to (to_x, to_y) using a human-like Bézier trajectory.
Dispatches Input.dispatchMouseEvent(mouseMoved) for each waypoint
with randomised 10–50 ms delays. Updates position
on success.
§Errors
Returns BrowserError::CdpError if any CDP event dispatch fails.
Sourcepub async fn click(&mut self, page: &Page, x: f64, y: f64) -> Result<()>
pub async fn click(&mut self, page: &Page, x: f64, y: f64) -> Result<()>
Move to (x, y) then perform a human-like left-click.
After arriving at the target the simulator pauses (20–80 ms), sends
mousePressed, holds (50–150 ms), then sends mouseReleased.
§Errors
Returns BrowserError::CdpError if any CDP event dispatch fails.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for MouseSimulator
impl RefUnwindSafe for MouseSimulator
impl Send for MouseSimulator
impl Sync for MouseSimulator
impl Unpin for MouseSimulator
impl UnsafeUnpin for MouseSimulator
impl UnwindSafe for MouseSimulator
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more