Class: Ferrum::Mouse

Inherits:
Object
  • Object
show all
Defined in:
lib/ferrum/mouse.rb

Overview

Simulates mouse input for a page via the CDP Input.dispatchMouseEvent command, and page scrolling via JavaScript. Keeps track of the current pointer position and pressed buttons so move, down, up and click can be composed while reporting consistent state to Chrome.

Constant Summary collapse

CLICK_WAIT =
ENV.fetch("FERRUM_CLICK_WAIT", 0.1).to_f
BUTTON_MASKS =
{
  "none" => 0,
  "left" => 1,
  "right" => 2,
  "middle" => 4,
  "back" => 8,
  "forward" => 16
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(page) ⇒ Mouse

Returns a new instance of Mouse.



21
22
23
24
25
# File 'lib/ferrum/mouse.rb', line 21

def initialize(page)
  @page = page
  @x = @y = 0
  @buttons = 0
end

Instance Method Details

#click(x:, y:, delay: 0, wait: CLICK_WAIT, **options) ⇒ self

Click given coordinates, fires mouse move, down and up events.

Parameters:

  • x (Integer)
  • y (Integer)
  • delay (Float) (defaults to: 0)

    Delay between mouse down and mouse up events.

  • wait (Float) (defaults to: CLICK_WAIT)
  • options (Hash{Symbol => Object})

    Additional keyword arguments.

Options Hash (**options):

  • :button (:left, :right) — default: :left

    The mouse button to click.

  • :count (Integer) — default: 1
  • :modifiers (Integer)

    Bitfield for key modifiers. Seekeyboard.modifiers.

Returns:

  • (self)


88
89
90
91
92
93
94
95
96
# File 'lib/ferrum/mouse.rb', line 88

def click(x:, y:, delay: 0, wait: CLICK_WAIT, **options)
  move(x: x, y: y)
  down(**options)
  sleep(delay)
  # Potential wait because if some network event is triggered then we have
  # to wait until it's over and frame is loaded or failed to load.
  up(wait: wait, **options)
  self
end

#down(**options) ⇒ self

Mouse down for given coordinates.

Parameters:

  • options (Hash{Symbol => Object})

    Additional keyword arguments.

Options Hash (**options):

  • :button (:left, :right) — default: :left

    The mouse button to click.

  • :count (Integer) — default: 1
  • :modifiers (Integer)

    Bitfield for key modifiers. Seekeyboard.modifiers.

Returns:

  • (self)


114
115
116
# File 'lib/ferrum/mouse.rb', line 114

def down(**options)
  tap { mouse_event(type: "mousePressed", **options) }
end

#move(x:, y:, steps: 1) ⇒ self

Mouse move to given x and y.

Parameters:

  • x (Number)
  • y (Number)
  • steps (Integer) (defaults to: 1)

    Sends intermediate mousemove events.

Returns:

  • (self)


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/ferrum/mouse.rb', line 150

def move(x:, y:, steps: 1)
  from_x = @x
  from_y = @y
  @x = x
  @y = y

  steps.times do |i|
    new_x = from_x + ((@x - from_x) * ((i + 1) / steps.to_f))
    new_y = from_y + ((@y - from_y) * ((i + 1) / steps.to_f))

    @page.command("Input.dispatchMouseEvent",
                  slowmoable: true,
                  type: "mouseMoved",
                  x: new_x,
                  y: new_y,
                  buttons: @buttons)
  end

  self
end

#scroll_by(x, y) ⇒ Object

Scroll page by the given amount x, y.

Examples:

browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
browser.mouse.scroll_by(0, 400)

Parameters:

  • x (Integer)

    The horizontal pixel value that you want to scroll by.

  • y (Integer)

    The vertical pixel value that you want to scroll by.



40
41
42
# File 'lib/ferrum/mouse.rb', line 40

def scroll_by(x, y)
  tap { @page.execute("window.scrollBy(#{x}, #{y})") }
end

#scroll_to(top, left) ⇒ Object

Scroll page to a given x, y coordinates.

Examples:

browser.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
browser.mouse.scroll_to(0, 400)

Parameters:

  • top (Integer)

    The pixel along the horizontal axis of the document that you want displayed in the upper left.

  • left (Integer)

    The pixel along the vertical axis of the document that you want displayed in the upper left.



59
60
61
# File 'lib/ferrum/mouse.rb', line 59

def scroll_to(top, left)
  tap { @page.execute("window.scrollTo(#{top}, #{left})") }
end

#up(**options) ⇒ self

Mouse up for given coordinates.

Parameters:

  • options (Hash{Symbol => Object})

    Additional keyword arguments.

Options Hash (**options):

  • :button (:left, :right) — default: :left

    The mouse button to click.

  • :count (Integer) — default: 1
  • :modifiers (Integer)

    Bitfield for key modifiers. Seekeyboard.modifiers.

Returns:

  • (self)


134
135
136
# File 'lib/ferrum/mouse.rb', line 134

def up(**options)
  tap { mouse_event(type: "mouseReleased", **options) }
end