Class: SharedTools::Tools::Browser::FerrumDriver

Inherits:
BaseDriver
  • Object
show all
Defined in:
lib/shared_tools/tools/browser/ferrum_driver.rb

Overview

A browser driver backed by Ferrum (Chrome DevTools Protocol). No chromedriver binary required — Ferrum talks directly to Chrome.

Examples:

driver = SharedTools::Tools::Browser::FerrumDriver.new
driver.goto(url: "https://example.com")
driver.click(selector: "a.some-link")
driver.close

Constant Summary

Constants inherited from BaseDriver

BaseDriver::TIMEOUT

Instance Method Summary collapse

Constructor Details

#initialize(logger: Logger.new(IO::NULL), network_idle_timeout: 5, **ferrum_options) ⇒ FerrumDriver

Returns a new instance of FerrumDriver.

Parameters:

  • logger (Logger) (defaults to: Logger.new(IO::NULL))
  • network_idle_timeout (Numeric) (defaults to: 5)

    seconds to wait for network idle after navigation

  • ferrum_options (Hash)

    additional options passed directly to Ferrum::Browser



20
21
22
23
24
25
26
27
28
29
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 20

def initialize(logger: Logger.new(IO::NULL), network_idle_timeout: 5, **ferrum_options)
  super(logger:)
  @network_idle_timeout = network_idle_timeout
  options = {
    headless: true,
    timeout: TIMEOUT,
    browser_options: { 'disable-blink-features' => 'AutomationControlled' }
  }.merge(ferrum_options)
  @browser = Ferrum::Browser.new(**options)
end

Instance Method Details

#click(selector:) ⇒ Hash

Parameters:

  • selector (String)

    CSS selector

Returns:

  • (Hash)


86
87
88
89
90
91
92
93
94
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 86

def click(selector:)
  element = wait_for_element { @browser.at_css(selector) }
  return { status: :error, message: "unknown selector=#{selector.inspect}" } if element.nil?

  element.click
  { status: :ok }
rescue => e
  { status: :error, message: e.message }
end

#closeObject



31
32
33
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 31

def close
  @browser.quit
end

#fill_in(selector:, text:) ⇒ Hash

Parameters:

  • selector (String)

    CSS selector for an input or textarea

  • text (String)

Returns:

  • (Hash)


72
73
74
75
76
77
78
79
80
81
82
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 72

def fill_in(selector:, text:)
  element = wait_for_element { @browser.at_css(selector) }
  return { status: :error, message: "unknown selector=#{selector.inspect}" } if element.nil?

  element.evaluate("this.value = #{text.to_json}")
  element.evaluate("this.dispatchEvent(new Event('input', {bubbles: true}))")
  element.evaluate("this.dispatchEvent(new Event('change', {bubbles: true}))")
  { status: :ok }
rescue => e
  { status: :error, message: e.message }
end

#goto(url:) ⇒ Hash

Parameters:

  • url (String)

Returns:

  • (Hash)


52
53
54
55
56
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 52

def goto(url:)
  @browser.go_to(url)
  wait_for_network_idle
  { status: :ok }
end

#htmlString

Returns:

  • (String)


46
47
48
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 46

def html
  @browser.evaluate('document.documentElement.outerHTML')
end

#screenshot {|file| ... } ⇒ Object

Yields:

  • (file)

Yield Parameters:

  • file (File)


60
61
62
63
64
65
66
67
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 60

def screenshot
  tempfile = Tempfile.new(['screenshot', '.png'])
  @browser.screenshot(path: tempfile.path)
  yield File.open(tempfile.path, 'rb')
ensure
  tempfile&.close
  tempfile&.unlink
end

#titleString

Returns:

  • (String)


41
42
43
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 41

def title
  @browser.title
end

#urlString

Returns:

  • (String)


36
37
38
# File 'lib/shared_tools/tools/browser/ferrum_driver.rb', line 36

def url
  @browser.current_url
end