Class: Ferrum::Browser::Client

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

Constant Summary collapse

INTERRUPTIONS =
%w[Fetch.requestPaused Fetch.authRequired].freeze

Instance Method Summary collapse

Constructor Details

#initialize(browser, ws_url, id_starts_with: 0) ⇒ Client

Returns a new instance of Client.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ferrum/browser/client.rb', line 12

def initialize(browser, ws_url, id_starts_with: 0)
  @browser = browser
  @command_id = id_starts_with
  @pendings = Concurrent::Hash.new
  @ws = WebSocket.new(ws_url, @browser.ws_max_receive_size, @browser.logger)
  @subscriber, @interruptor = Subscriber.build(2)

  @thread = Thread.new do
    Thread.current.abort_on_exception = true
    if Thread.current.respond_to?(:report_on_exception=)
      Thread.current.report_on_exception = true
    end

    while message = @ws.messages.pop
      if INTERRUPTIONS.include?(message["method"])
        @interruptor.async.call(message)
      elsif message.key?("method")
        @subscriber.async.call(message)
      else
        @pendings[message["id"]]&.set(message)
      end
    end
  end
end

Instance Method Details

#closeObject



65
66
67
68
69
70
# File 'lib/ferrum/browser/client.rb', line 65

def close
  @ws.close
  # Give a thread some time to handle a tail of messages
  @pendings.clear
  @thread.kill unless @thread.join(1)
end

#command(method, params = {}) ⇒ Object

Raises:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ferrum/browser/client.rb', line 37

def command(method, params = {})
  pending = Concurrent::IVar.new
  message = build_message(method, params)
  @pendings[message[:id]] = pending
  @ws.send_message(message)
  data = pending.value!(@browser.timeout)
  @pendings.delete(message[:id])

  raise DeadBrowserError if data.nil? && @ws.messages.closed?
  raise TimeoutError unless data
  error, response = data.values_at("error", "result")
  raise_browser_error(error) if error
  response
end

#on(event, &block) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/ferrum/browser/client.rb', line 52

def on(event, &block)
  case event
  when *INTERRUPTIONS
    @interruptor.on(event, &block)
  else
    @subscriber.on(event, &block)
  end
end

#subscribed?(event) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/ferrum/browser/client.rb', line 61

def subscribed?(event)
  [@interruptor, @subscriber].any? { |s| s.subscribed?(event) }
end